class_docstr: Transition model for bar tracking with a HMM.
  
  Within the beats of the bar the tempo stays the same; at beat boundaries
  transitions from one tempo (i.e. interval) to another following an
  exponential distribution are allowed.
  
  Parameters
  ----------
  state_space : :class:`BarStateSpace` instance
      BarStateSpace instance.
  transition_lambda : float or list
      Lambda for the exponential tempo change distribution (higher values
      prefer a constant tempo from one beat to the next one).
      None can be used to set the tempo change probability to 0.
      If a list is given, the individual values represent the lambdas for
      each transition into the beat at this index position.
  
  Notes
  -----
  Bars performing tempo changes only at bar boundaries (and not at the beat
  boundaries) must have set all but the first `transition_lambda` values to
  None, e.g. [100, None, None] for a bar with 3 beats.
  
  References
  ----------
  .. [1] Florian Krebs, Sebastian Böck and Gerhard Widmer,
         "An Efficient State Space Model for Joint Tempo and Meter Tracking",
         Proceedings of the 16th International Society for Music Information
         Retrieval Conference (ISMIR), 2015.
class_docstr_tok: ["Transition","model","for","bar","tracking","with","a","HMM",".","Within","the","beats","of","the","bar","the","tempo","stays","the","same",";","at","beat","boundaries","transitions","from","one","tempo","(","i.e",".","interval",")","to","another","following","an","exponential","distribution","are","allowed",".","Parameters","--","--","--","--","--","state_space",":",":","class",":","`","BarStateSpace","`","instance","BarStateSpace","instance",".","transition_lambda",":","float","or","list","Lambda","for","the","exponential","tempo","change","distribution","(","higher","values","prefer","a","constant","tempo","from","one","beat","to","the","next","one",")",".","None","can","be","used","to","set","the","tempo","change","probability","to","0",".","If","a","list","is","given",",","the","individual","values","represent","the","lambdas","for","each","transition","into","the","beat","at","this","index","position",".","Notes","--","--","-","Bars","performing","tempo","changes","only","at","bar","boundaries","(","and","not","at","the","beat","boundaries",")","must","have","set","all","but","the","first","`","transition_lambda","`","values","to","None",",","e.g",".","[","100",",","None",",","None","]","for","a","bar","with","3","beats",".","References","--","--","--","--","--","..","[","1","]","Florian","Krebs",",","Sebastian","B\u00f6ck","and","Gerhard","Widmer",",","``","An","Efficient","State","Space","Model","for","Joint","Tempo","and","Meter","Tracking","''",",","Proceedings","of","the","16th","International","Society","for","Music","Information","Retrieval","Conference","(","ISMIR",")",",","2015","."]
code: def __init__(self, state_space, transition_lambda):
      # expand transition_lambda to a list if a single value is given
      if not isinstance(transition_lambda, list):
          transition_lambda = [
              transition_lambda
          ] * state_space.num_beats
      if state_space.num_beats != len(transition_lambda):
          raise ValueError(
              "length of `transition_lambda` must be equal to "
              "`num_beats` of `state_space`."
          )
      # save attributes
      self.state_space = state_space
      self.transition_lambda = transition_lambda
      # TODO: this could be unified with the BeatTransitionModel
      # same tempo transitions probabilities within the state space is 1
      # Note: use all states, but remove all first states of the individual
      #       beats, because there are no same tempo transitions into them
      states = np.arange(state_space.num_states, dtype=np.uint32)
      states = np.setdiff1d(states, state_space.first_states)
      prev_states = states - 1
      probabilities = np.ones_like(states, dtype=float)
      # tempo transitions occur at the boundary between beats (unless the
      # corresponding transition_lambda is set to None)
      for beat in range(state_space.num_beats):
          # connect to the first states of the actual beat
          to_states = state_space.first_states[beat]
          # connect from the last states of the previous beat
          from_states = state_space.last_states[beat - 1]
          # transition follow an exponential tempo distribution
          from_int = state_space.state_intervals[from_states]
          to_int = state_space.state_intervals[to_states]
          prob = exponential_transition(
              from_int, to_int, transition_lambda[beat]
          )
          # use only the states with transitions to/from != 0
          from_prob, to_prob = np.nonzero(prob)
          states = np.hstack((states, to_states[to_prob]))
          prev_states = np.hstack((prev_states, from_states[from_prob]))
          probabilities = np.hstack((probabilities, prob[prob != 0]))
      # make the transitions sparse
      transitions = self.make_sparse(states, prev_states, probabilities)
      # instantiate a TransitionModel
      super(BarTransitionModel, self).__init__(*transitions)
  
imports: from __future__ import absolute_import, division, print_function
  import numpy
  from madmom.ml.hmm import ObservationModel, TransitionModel
label_desc: Use image node_id 1 to create a new BarTransitionModel object from inherited base classes: TransitionModel with example: obj = BarTransitionModel(state_space, transition_lambda)