
    }Kg                      d Z ddlmZ ddlZddlmZ ddlmZ ddl	m
Z
mZmZmZmZ ddlmZ dd	lmZ dd
lmZmZmZmZmZmZmZ ddlmZ ddlmZmZ g dZ eddddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dDd       Z!eddddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dEd       Z!edddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dFd       Z!edddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dGd       Z!edddddddddd		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dHd       Z!edddddddddd		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dId       Z!eddddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dJd       Z!eddddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dKd       Z!	 	 dLddddddddddd
	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dMd Z! edd!      	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dNd"       Z" edd!      	 dO	 	 	 	 	 	 	 	 	 dPd#       Z#dddd$	 	 	 	 	 	 	 	 	 dQd%Z$edddd&	 	 	 	 	 	 	 	 	 	 	 dRd'       Z%eddddd(	 	 	 	 	 	 	 	 	 	 	 dSd)       Z%eddddd(	 	 	 	 	 	 	 	 	 	 	 dTd*       Z%ddddd(	 	 	 	 	 	 	 	 	 	 	 dTd+Z% edd!      	 	 	 	 	 	 	 	 	 	 dUd,       Z&d- Z' edd!      	 	 	 	 	 	 	 	 dVd.       Z(edd/	 	 	 	 	 	 	 	 	 dWd0       Z)eddd1	 	 	 	 	 	 	 	 	 dXd2       Z)ddd1	 	 	 	 	 	 	 	 	 dYd3Z)edddd4	 	 	 	 	 	 	 	 	 	 	 dZd5       Z*eddd6	 	 	 	 	 	 	 	 	 	 	 d[d7       Z*eddd6	 	 	 	 	 	 	 	 	 	 	 d\d8       Z*dddd4	 	 	 	 	 	 	 	 	 	 	 d\d9Z*edddd4	 	 	 	 	 	 	 	 	 	 	 dZd:       Z+eddd6	 	 	 	 	 	 	 	 	 	 	 d[d;       Z+edddd4	 	 	 	 	 	 	 	 	 	 	 d\d<       Z+dddd4	 	 	 	 	 	 	 	 	 	 	 d\d=Z+d]d>Z,d^d?Z-d^d@Z.dAddB	 	 	 	 	 	 	 	 	 d_dCZ/y)`a  
Sequential modeling
===================

Sequence alignment
------------------
.. autosummary::
    :toctree: generated/

    dtw
    rqa

Viterbi decoding
----------------
.. autosummary::
    :toctree: generated/

    viterbi
    viterbi_discriminative
    viterbi_binary

Transition matrices
-------------------
.. autosummary::
    :toctree: generated/

    transition_uniform
    transition_loop
    transition_cycle
    transition_local
    )annotationsN)cdist)jit   )
pad_centerfill_off_diagonalis_positive_inttiny	expand_to)ParameterError)
get_window)AnyIterableListOptionalTupleUnionoverload)Literal)_WindowSpec_IntLike_co)
dtwdtw_backtrackingrqaviterbiviterbi_discriminativeviterbi_binarytransition_uniformtransition_looptransition_cycletransition_local.)metricstep_sizes_sigmaweights_addweights_mulsubseqglobal_constraintsband_radreturn_stepsc       	             y N XYr"   r#   r$   r%   r&   	backtrackr'   r(   r)   s              T/home/alanp/www/video.onchill/myenv/lib/python3.12/site-packages/librosa/sequence.pyr   r   <            c        
             y r+   r,   
Cr"   r#   r$   r%   r&   r0   r'   r(   r)   s
             r1   r   r   N        r3   )r"   r#   r$   r%   r&   r'   r(   c       	             y r+   r,   r-   s              r1   r   r   _   r2   r3   c        
             y r+   r,   r5   s
             r1   r   r   q   r7   r3   )	r"   r#   r$   r%   r&   r0   r'   r(   r)   c       	             y r+   r,   r-   s              r1   r   r      r2   r3   c        
             y r+   r,   r5   s
             r1   r   r      r7   r3   )r"   r#   r$   r%   r&   r0   r'   r(   c       	             y r+   r,   r-   s              r1   r   r      r2   r3   c        
             y r+   r,   r5   s
             r1   r   r      r7   r3   	euclideanFTg      ?r5   c       
   
     X   t        j                  ddgddgddggt         j                        }t        j                  dt         j                        }t        j
                  dt         j                        }||}||}||}n|.t        j                  t        |      t         j                        }|.t        j
                  t        |      t         j                        }|j                  t         j                         |j                  t         j                         t        j                  ||f      }t        j                  ||f      }t        j                  ||f      }|J |J |J t        j                  |dk        rt        d      t        |      t        |      k7  rt        d      t        |      t        |      k7  rt        d      || |t        d	      || |t        d
      d}d}|d}| |J t        j                  |       } t        j                  |      }t        j                  | dd      } t        j                  |dd      }| j                  | j                  d   dfd      } |j                  |j                  d   dfd      }	 t!        | ||      }|r-| j                  d   |j                  d   kD  r|j$                  }d}t        j                  |      }t        j&                  |t        j                  ddgg            r*|j                  d   |j                  d   kD  rt        d      |dddf   j)                         }|dddf   j)                         }t        j                  t        j*                  |            rt        d      |	r3|st        j,                  |      }t/        ||
t         j                         t        j
                  |j                  t        j                  ||g      z         t         j                  z  }|d   |||f<   |r|dddf   |||df<   t        j                  |j                  t         j0                        }d|dddf<   d|dddf<   t3        ||||||||      \  }}||d|df   }||d|df   }|r!|rat        j4                  t        j6                  |d               rt        d      t        j8                  |dddf         }t;        ||||      }nCt        j6                  |d         rt        d      t;        |||      }|d   dk7  rt        d      t        j<                  |t>              }|rY| !|| j                  d   |j                  d   kD  s!|s|j                  d   |j                  d   kD  rt        j@                  |      }||g}n|g}|r|jC                  |       t        |      dkD  rtE        |      S |d   S # t"        $ r}t        d      |d}~ww xY w)uR  Dynamic time warping (DTW).

    This function performs a DTW and path backtracking on two sequences.
    We follow the nomenclature and algorithmic approach as described in [#]_.

    .. [#] Meinard Mueller
           Fundamentals of Music Processing — Audio, Analysis, Algorithms, Applications
           Springer Verlag, ISBN: 978-3-319-21944-8, 2015.

    Parameters
    ----------
    X : np.ndarray [shape=(..., K, N)]
        audio feature matrix (e.g., chroma features)

        If ``X`` has more than two dimensions (e.g., for multi-channel inputs), all leading
        dimensions are used when computing distance to ``Y``.

    Y : np.ndarray [shape=(..., K, M)]
        audio feature matrix (e.g., chroma features)

    C : np.ndarray [shape=(N, M)]
        Precomputed distance matrix. If supplied, X and Y must not be supplied and
        ``metric`` will be ignored.

    metric : str
        Identifier for the cost-function as documented
        in `scipy.spatial.distance.cdist()`

    step_sizes_sigma : np.ndarray [shape=[n, 2]]
        Specifies allowed step sizes as used by the dtw.

    weights_add : np.ndarray [shape=[n, ]]
        Additive weights to penalize certain step sizes.

    weights_mul : np.ndarray [shape=[n, ]]
        Multiplicative weights to penalize certain step sizes.

    subseq : bool
        Enable subsequence DTW, e.g., for retrieval tasks.

    backtrack : bool
        Enable backtracking in accumulated cost matrix.

    global_constraints : bool
        Applies global constraints to the cost matrix ``C`` (Sakoe-Chiba band).

    band_rad : float
        The Sakoe-Chiba band radius (1/2 of the width) will be
        ``int(radius*min(C.shape))``.

    return_steps : bool
        If true, the function returns ``steps``, the step matrix, containing
        the indices of the used steps from the cost accumulation step.

    Returns
    -------
    D : np.ndarray [shape=(N, M)]
        accumulated cost matrix.
        D[N, M] is the total alignment cost.
        When doing subsequence DTW, D[N,:] indicates a matching function.
    wp : np.ndarray [shape=(N, 2)]
        Warping path with index pairs.
        Each row of the array contains an index pair (n, m).
        Only returned when ``backtrack`` is True.
    steps : np.ndarray [shape=(N, M)]
        Step matrix, containing the indices of the used steps from the cost
        accumulation step.
        Only returned when ``return_steps`` is True.

    Raises
    ------
    ParameterError
        If you are doing diagonal matching and Y is shorter than X or if an
        incompatible combination of X, Y, and C are supplied.

        If your input dimensions are incompatible.

        If the cost matrix has NaN values.

    Examples
    --------
    >>> import numpy as np
    >>> import matplotlib.pyplot as plt
    >>> y, sr = librosa.load(librosa.ex('brahms'), offset=10, duration=15)
    >>> X = librosa.feature.chroma_cens(y=y, sr=sr)
    >>> noise = np.random.rand(X.shape[0], 200)
    >>> Y = np.concatenate((noise, noise, X, noise), axis=1)
    >>> D, wp = librosa.sequence.dtw(X, Y, subseq=True)
    >>> fig, ax = plt.subplots(nrows=2, sharex=True)
    >>> img = librosa.display.specshow(D, x_axis='frames', y_axis='frames',
    ...                                ax=ax[0])
    >>> ax[0].set(title='DTW cost', xlabel='Noisy sequence', ylabel='Target')
    >>> ax[0].plot(wp[:, 1], wp[:, 0], label='Optimal path', color='y')
    >>> ax[0].legend()
    >>> fig.colorbar(img, ax=ax[0])
    >>> ax[1].plot(D[-1, :] / wp.shape[0])
    >>> ax[1].set(xlim=[0, Y.shape[1]], ylim=[0, 2],
    ...           title='Matching cost function')
    r   r   dtype   Nz/step_sizes_sigma cannot contain negative valuesz7len(weights_add) must be equal to len(step_sizes_sigma)z7len(weights_mul) must be equal to len(step_sizes_sigma)z3If C is not supplied, both X and Y must be suppliedz3If C is supplied, both X and Y must not be suppliedFTF)order)r"   zscipy.spatial.distance.cdist returned an error.
Please provide your input in the form X.shape=(K, N) and Y.shape=(K, M).
 1-dimensional sequences should be reshaped to X.shape=(1, N) and Y.shape=(1, M).zMFor diagonal matching: Y.shape[-1] >= X.shape[-11] (C.shape[1] >= C.shape[0])z"DTW cost matrix C has NaN values. )radiusvaluer   r      zRNo valid sub-sequence warping path could be constructed with the given step sizes.rC   rC   zVUnable to compute a full DTW warping path. You may want to try again with subseq=True.)#nparrayuint32zerosfloat64oneslenfillinfconcatenateanyr   
atleast_2dswapaxesreshapeshaper   
ValueErrorTarray_equalmaxisnancopyr   int32__dtw_calc_accu_costallisinfargmin__dtw_backtrackingasarrayintfliplrappendtuple)r.   r/   r6   r"   r#   r$   r%   r&   r0   r'   r(   r)   default_stepsdefault_weights_adddefault_weights_mulc_is_transposedC_localexcmax_0max_1Dstepsstart_wpwpreturn_valuess                             r1   r   r      s   j HHq!fq!fq!f5RYYGM((1BJJ7''!2::6( -K-K ((3'7#8

KK''#&6"7rzzJK 	  (  ( >>=:J*KLnn&9;%GHnn&9;%GH '''""""""	vv"#NOO
K 00VWW
K 00VWWyai19RSS}!-1=RSSO
 Gy}..MM!MM!
 KK2q!KK2q! IIqwwqz2&cI2IIqwwqz2&cI2	a6*A qwwqzAGGAJ.A"O
aA 
~~&1a&(:;	
QWWQZ)
 	

 QT"&&(EQT"&&(E 
vvbhhqkABB
A!HBFF; 	"((E5>223bff<A gAeUlOQT7%- HHQWWBHH-E E!Q$KE!Q$K
 $	1e%{KHAu
 	
%&%&.A%&%&.!E vvbhhquo&$@  IIaAh'E$U,<feLC xx&	"$@ 
 %U,<fEC2w& $B 
 ZZ3' ]q}aggaj1HwwqzAGGAJ&2BBU#
=A ]##Qg  	 D
 	s   )X 	X)X$$X))nopythoncachec           	     n   t        ||j                  d         D ]  }t        ||j                  d         D ]x  }	t        t        |j                  d         ||      D ]P  \  }
}}||||
df   z
  |	||
df   z
  f   }|| ||z
  |	|z
  f   z  }||z  }||z   }||||	f   k  sC||||	f<   |
|||	f<   R z  ||fS )a  Calculate the accumulated cost matrix D.

    Use dynamic programming to calculate the accumulated costs.

    Parameters
    ----------
    C : np.ndarray [shape=(N, M)]
        pre-computed cost matrix
    D : np.ndarray [shape=(N, M)]
        accumulated cost matrix
    steps : np.ndarray [shape=(N, M)]
        Step matrix, containing the indices of the used steps from the cost
        accumulation step.
    step_sizes_sigma : np.ndarray [shape=[n, 2]]
        Specifies allowed step sizes as used by the dtw.
    weights_add : np.ndarray [shape=[n, ]]
        Additive weights to penalize certain step sizes.
    weights_mul : np.ndarray [shape=[n, ]]
        Multiplicative weights to penalize certain step sizes.
    max_0 : int
        maximum number of steps in step_sizes_sigma in dim 0.
    max_1 : int
        maximum number of steps in step_sizes_sigma in dim 1.

    Returns
    -------
    D : np.ndarray [shape=(N, M)]
        accumulated cost matrix.
        D[N, M] is the total alignment cost.
        When doing subsequence DTW, D[N,:] indicates a matching function.
    steps : np.ndarray [shape=(N, M)]
        Step matrix, containing the indices of the used steps from the cost
        accumulation step.

    See Also
    --------
    dtw
    r   r   )rangerY   zip)r6   rs   rt   r#   r%   r$   rq   rr   cur_ncur_mcur_step_idx	cur_w_add	cur_w_mulcur_Dcur_Ccur_costs                   r1   ra   ra      s   b uaggaj)5!''!*-E69&,,Q/0+{72i ,\1_==,\1_==? "AeemUU]&B$CC" 5= auo-&.AeUlO +7E%,'!7 . ** e8Or3   c                   |%| j                   d   dz
  | j                   d   dz
  f}n| j                   d   dz
  |f}g }|j                  |d   |d   f       |r|d   dkD  s|sk|dk7  rf| |d   |d   f   }|d   ||   d   z
  |d   ||   d   z
  f}t        |      dk  r	 |S |j                  |d   |d   f       |r	|d   dkD  r^|s|dk7  rf|S )a,  Backtrack optimal warping path.

    Uses the saved step sizes from the cost accumulation
    step to backtrack the index pairs for an optimal
    warping path.

    Parameters
    ----------
    steps : np.ndarray [shape=(N, M)]
        Step matrix, containing the indices of the used steps from the cost
        accumulation step.
    step_sizes_sigma : np.ndarray [shape=[n, 2]]
        Specifies allowed step sizes as used by the dtw.
    subseq : bool
        Enable subsequence DTW, e.g., for retrieval tasks.
    start : int
        Start column index for backtraing (only allowed for ``subseq=True``)

    Returns
    -------
    wp : list [shape=(N,)]
        Warping path with index pairs.
        Each list entry contains an index pair
        (n, m) as a tuple

    See Also
    --------
    dtw
    r   r   rH   )rY   ri   min)rt   r#   r&   ru   cur_idxrw   r   s          r1   re   re   I  s   H };;q>A%u{{1~'9:;;q>A%u-	BIIwqz71:&' gaj1nfF9Jgaj'!*56 AJ),7::AJ),7::
 w<!
 I 			71:wqz*+ gaj1nfF9J  Ir3   )r#   r&   ru   c                  |du r|t        d| d| d      t        j                  ddgddgddggt        j                        }||}nt        j                  ||f      }t        | |||      }t        j                  |t              S )a  Backtrack a warping path.

    Uses the saved step sizes from the cost accumulation
    step to backtrack the index pairs for a warping path.

    Parameters
    ----------
    steps : np.ndarray [shape=(N, M)]
        Step matrix, containing the indices of the used steps from the cost
        accumulation step.
    step_sizes_sigma : np.ndarray [shape=[n, 2]]
        Specifies allowed step sizes as used by the dtw.
    subseq : bool
        Enable subsequence DTW, e.g., for retrieval tasks.
    start : int
        Start column index for backtraing (only allowed for ``subseq=True``)

    Returns
    -------
    wp : list [shape=(N,)]
        Warping path with index pairs.
        Each list entry contains an index pair
        (n, m) as a tuple

    See Also
    --------
    dtw
    Fz9start is only allowed to be set if subseq is True (start=z	, subseq=)r   r   r@   )r   rK   rL   rM   rT   re   rf   rg   )rt   r#   r&   ru   rk   rw   s         r1   r   r     s    F 5,GwiX^W__`a
 	

 HHq!fq!fq!f5RYYGM( >>=:J*KL	E#3VU	CB::b$$r3   )	gap_onset
gap_extendknight_movesc                    y r+   r,   simr   r   r   r0   s        r1   r   r          r3   )r   r   r   r0   c                    y r+   r,   r   s        r1   r   r     r   r3   c                    y r+   r,   r   s        r1   r   r     r   r3   c                   |dk  rt        d      |dk  rt        d      t        | |||      \  }}|rt        ||      }||fS |S )u  Recurrence quantification analysis (RQA)

    This function implements different forms of RQA as described by
    Serra, Serra, and Andrzejak (SSA). [#]_  These methods take as input
    a self- or cross-similarity matrix ``sim``, and calculate the value
    of path alignments by dynamic programming.

    Note that unlike dynamic time warping (`dtw`), alignment paths here are
    maximized, not minimized, so the input should measure similarity rather
    than distance.

    The simplest RQA method, denoted as `L` (SSA equation 3) and equivalent
    to the method described by Eckman, Kamphorst, and Ruelle [#]_, accumulates
    the length of diagonal paths with positive values in the input:

        - ``score[i, j] = score[i-1, j-1] + 1``  if ``sim[i, j] > 0``
        - ``score[i, j] = 0`` otherwise.

    The second method, denoted as `S` (SSA equation 4), is similar to the first,
    but allows for "knight moves" (as in the chess piece) in addition to strict
    diagonal moves:

        - ``score[i, j] = max(score[i-1, j-1], score[i-2, j-1], score[i-1, j-2]) + 1``  if ``sim[i, j] >
          0``
        - ``score[i, j] = 0`` otherwise.

    The third method, denoted as `Q` (SSA equations 5 and 6) extends this by
    allowing gaps in the alignment that incur some cost, rather than a hard
    reset to 0 whenever ``sim[i, j] == 0``.
    Gaps are penalized by two additional parameters, ``gap_onset`` and ``gap_extend``,
    which are subtracted from the value of the alignment path every time a gap
    is introduced or extended (respectively).

    Note that setting ``gap_onset`` and ``gap_extend`` to `np.inf` recovers the second
    method, and disabling knight moves recovers the first.

    .. [#] Serrà, Joan, Xavier Serra, and Ralph G. Andrzejak.
        "Cross recurrence quantification for cover song identification."
        New Journal of Physics 11, no. 9 (2009): 093017.

    .. [#] Eckmann, J. P., S. Oliffson Kamphorst, and D. Ruelle.
        "Recurrence plots of dynamical systems."
        World Scientific Series on Nonlinear Science Series A 16 (1995): 441-446.

    Parameters
    ----------
    sim : np.ndarray [shape=(N, M), non-negative]
        The similarity matrix to use as input.

        This can either be a recurrence matrix (self-similarity)
        or a cross-similarity matrix between two sequences.

    gap_onset : float > 0
        Penalty for introducing a gap to an alignment sequence

    gap_extend : float > 0
        Penalty for extending a gap in an alignment sequence

    knight_moves : bool
        If ``True`` (default), allow for "knight moves" in the alignment,
        e.g., ``(n, m) => (n + 1, m + 2)`` or ``(n + 2, m + 1)``.

        If ``False``, only allow for diagonal moves ``(n, m) => (n + 1, m + 1)``.

    backtrack : bool
        If ``True``, return the alignment path.

        If ``False``, only return the score matrix.

    Returns
    -------
    score : np.ndarray [shape=(N, M)]
        The alignment score matrix.  ``score[n, m]`` is the cumulative value of
        the best alignment sequence ending in frames ``n`` and ``m``.
    path : np.ndarray [shape=(k, 2)] (optional)
        If ``backtrack=True``, ``path`` contains a list of pairs of aligned frames
        in the best alignment sequence.

        ``path[i] = [n, m]`` indicates that row ``n`` aligns to column ``m``.

    See Also
    --------
    librosa.segment.recurrence_matrix
    librosa.segment.cross_similarity
    dtw

    Examples
    --------
    Simple diagonal path enhancement (L-mode)

    >>> import numpy as np
    >>> import matplotlib.pyplot as plt
    >>> y, sr = librosa.load(librosa.ex('nutcracker'), duration=30)
    >>> chroma = librosa.feature.chroma_cqt(y=y, sr=sr)
    >>> # Use time-delay embedding to reduce noise
    >>> chroma_stack = librosa.feature.stack_memory(chroma, n_steps=10, delay=3)
    >>> # Build recurrence, suppress self-loops within 1 second
    >>> rec = librosa.segment.recurrence_matrix(chroma_stack, width=43,
    ...                                         mode='affinity',
    ...                                         metric='cosine')
    >>> # using infinite cost for gaps enforces strict path continuation
    >>> L_score, L_path = librosa.sequence.rqa(rec,
    ...                                        gap_onset=np.inf,
    ...                                        gap_extend=np.inf,
    ...                                        knight_moves=False)
    >>> fig, ax = plt.subplots(ncols=2)
    >>> librosa.display.specshow(rec, x_axis='frames', y_axis='frames', ax=ax[0])
    >>> ax[0].set(title='Recurrence matrix')
    >>> librosa.display.specshow(L_score, x_axis='frames', y_axis='frames', ax=ax[1])
    >>> ax[1].set(title='Alignment score matrix')
    >>> ax[1].plot(L_path[:, 1], L_path[:, 0], label='Optimal path', color='c')
    >>> ax[1].legend()
    >>> ax[1].label_outer()

    Full alignment using gaps and knight moves

    >>> # New gaps cost 5, extending old gaps cost 10 for each step
    >>> score, path = librosa.sequence.rqa(rec, gap_onset=5, gap_extend=10)
    >>> fig, ax = plt.subplots(ncols=2, sharex=True, sharey=True)
    >>> librosa.display.specshow(rec, x_axis='frames', y_axis='frames', ax=ax[0])
    >>> ax[0].set(title='Recurrence matrix')
    >>> librosa.display.specshow(score, x_axis='frames', y_axis='frames', ax=ax[1])
    >>> ax[1].set(title='Alignment score matrix')
    >>> ax[1].plot(path[:, 1], path[:, 0], label='Optimal path', color='c')
    >>> ax[1].legend()
    >>> ax[1].label_outer()
    r   z&gap_onset={} must be strictly positivez'gap_extend={} must be strictly positive)r   __rqa_dp__rqa_backtrack)r   r   r   r   r0   scorepointerspaths           r1   r   r     s_    N 1}EFFA~FGG sIz<HOE8uh/d{Lr3   c           	     |	   t        j                  | j                  | j                        }t        j                  | j                  t         j                        }t        j                  d      }t        j                  d      }t        j                  d      }|rd}	d}
nd}	d}
| dddf   |dddf<   | dddf   |dddf<   t        | j                  d         D ]  }| |df   rd||df<   d||df<    t        | j                  d         D ]  }| d|f   rd|d|f<   d|d|f<    | d	   dkD  r|d
   | d	   z   |d	<   d|d	<   n:| d
   dkD  }t        d|d
   ||z  z
  | |z  z
        |d	<   |d	   dkD  rd|d	<   nd|d	<   d}t        d| j                  d         D ]  }||dz
  |dz
  f   ||dz
  |dz
  f   f|dd | |dz
  |dz
  f   | |dz
  |dz
  f   f|dd |dkD  }| ||f   dkD  r5t        j                  |d|	       |||f<   ||||f      | ||f   z   |||f<   |d|	 |d|	 |z  z
  |d|	  |z  z
  |d|	 t        j                  |d|	       |||f<   t        d||||f            |||f<   |||f   dk(  sd|||f<    d}t        d| j                  d         D ]  }||dz
  |dz
  f   ||dz
  |dz
  f   f|dd | |dz
  |dz
  f   | |dz
  |dz
  f   f|dd |dkD  }| ||f   dkD  r5t        j                  |d|	       |||f<   ||||f      | ||f   z   |||f<   |d|	 |d|	 |z  z
  |d|	  |z  z
  |d|	 t        j                  |d|	       |||f<   t        d||||f            |||f<   |||f   dk(  sd|||f<    t        d| j                  d         D ]  }t        d| j                  d         D ]  }||dz
  |dz
  f   ||dz
  |dz
  f   ||dz
  |dz
  f   f|dd | |dz
  |dz
  f   | |dz
  |dz
  f   | |dz
  |dz
  f   f|dd |dkD  }| ||f   dkD  r5t        j                  |d|
       |||f<   ||||f      | ||f   z   |||f<   |d|
 |d|
 |z  z
  |d|
  |z  z
  |d|
 t        j                  |d|
       |||f<   t        d||||f            |||f<   |||f   dk(  sd|||f<     ||fS )z&RQA dynamic programming implementationr@   rB   rI   r   r   NrC   )r   r   rH   )rK   rN   rY   rA   int8r|   r]   argmax)r   r   r   knightr   r0   
sim_valuesscore_valuesvec
init_limitlimitijlinkt_valuess                  r1   r   r   ~  sp    HHSYYcii0E "''2I !J88A;L
((1+C
 
 ad)E!Q$Kad)E!Q$K 399Q< q!t9 IadO IadO	 ! 399Q< q!t9 IadO IadO	 ! 4y1}DkCI-d	$4y1}!U4[DI+==$*@TTUd;?IdO IdO 	
A1ciil#"1q5!a%<0%Aq1u2EFSbq1ua!e|,c!a%Q,.?@
3B>q!t9q= ii[j(ABIadO&yA7#ad)CE!Q$K [j);J')34[j))Z78  !iiKZ(89IadOaYq!t_!56E!Q$KQT{a"$	!Q$% $* 	
A1ciil#"1q5!a%<0%Aq1u2EFSbq1ua!e|,c!a%Q,.?@
3B>q!t9q= ii[j(ABIadO&yA7#ad)CE!Q$K [j);J')34[j))Z78  !iiKZ(89IadOaYq!t_!56E!Q$KQT{a"$	!Q$' $, 1ciil#q#))A,'Aa!eQUl#a!eQUl#a!eQUl#LO
 !QA.AE1q5L0A3q1uaRSe|CTUJqM!A~H1a4y1}
 #%))L%,@"A	!Q$ 1a41C1I= ad !%(v&23 %((J67 FU #%))CK"8	!Q$!!S1a4%9:adA;!#&(IadO? ( $D )r3   c                   g d}t        t        j                  t        j                  |       | j                              }g }	 |t        |         }|dk(  rnF|j                  d|       |dk(  rn.t        t        |            D cg c]  }||   ||   |   z    }}Z|s%t        j                  dt        j                        S t        j                  |t        j                        S c c}w )zvRQA path backtracking

    Given the score matrix and backtracking index array,
    reconstruct the optimal path.
    )rJ   )rC   r   )r   rC   rC   r   r   )r   rI   r@   )listrK   unravel_indexr   rY   rj   insertr|   rQ   emptyuintrf   )r   r   offsetsidxr   bt_index_s          r1   r   r     s     -G r		% 0%++>
?C D
E#J' r> 	As r> 7<CHoFos1v)!,,oF' . xxbgg..::d"''** Gs   C*c                   | j                   \  }}t        j                  |t        j                        }t        j                  ||ft        j                        }t        j                  ||ft        j                        }| d   |z   |d<   t        d|      D ]^  }||dz
     |j                  z   }	t        |      D ]9  }
t        j                  |	|
         |||
f<   | ||
f   |	|
||   |
   f   z   |||
f<   ; ` t        j                  |d         |d<   t        |dz
  dd      D ]  }||dz   ||dz      f   ||<    |dd|d   f   }||fS )aK  Core Viterbi algorithm.

    This is intended for internal use only.

    Parameters
    ----------
    log_prob : np.ndarray [shape=(T, m)]
        ``log_prob[t, s]`` is the conditional log-likelihood
        ``log P[X = X(t) | State(t) = s]``
    log_trans : np.ndarray [shape=(m, m)]
        The log transition matrix
        ``log_trans[i, j] = log P[State(t+1) = j | State(t) = i]``
    log_p_init : np.ndarray [shape=(m,)]
        log of the initial state distribution

    Returns
    -------
    None
        All computations are performed in-place on ``state, value, ptr``.
    r@   r   r   rC   rI   N)rY   rK   rN   uint16rO   r|   r[   r   )log_prob	log_trans
log_p_initn_stepsn_statesstaterG   ptrt	trans_outr   logps               r1   _viterbir   K  sX   0 !GXHHWBII.EHHgx(

;E
((GX&bii
8C {Z'E!H1g !a%L9;;.	 xA		)A,/C1I"1a4.9QAq	\+BBE!Q$K ! * 		%)$E"I7Q;B'q1ueAEl*+a ( eBi D$;r3   )p_initc                    y r+   r,   prob
transitionr   return_logps       r1   r   r          r3   )r   r   c                    y r+   r,   r   s       r1   r   r     r   r3   c                  | j                   dd \  }}|j                   ||fk7  rt        d|j                    d||f       t        j                  |dk        s&t        j                  |j                  d      d      st        d      t        j                  | dk        st        j                  | dkD        rt        d	      t        |       }|*t        j                  |      }|j                  d
|z         nZt        j                  |dk        s4t        j                  |j                         d      r|j                   |fk7  rt        d|       t        j                  ||z         t        j                  | |z         }t        j                  ||z         fd}|j                  dk(  r ||      \  }	}
nFt        j                  |t        j                  t        j                  gd      } ||      \  }	}
|
d   }
|r|	|
fS |	S )a  Viterbi decoding from observation likelihoods.

    Given a sequence of observation likelihoods ``prob[s, t]``,
    indicating the conditional likelihood of seeing the observation
    at time ``t`` from state ``s``, and a transition matrix
    ``transition[i, j]`` which encodes the conditional probability of
    moving from state ``i`` to state ``j``, the Viterbi algorithm [#]_ computes
    the most likely sequence of states from the observations.

    .. [#] Viterbi, Andrew. "Error bounds for convolutional codes and an
        asymptotically optimum decoding algorithm."
        IEEE transactions on Information Theory 13.2 (1967): 260-269.

    Parameters
    ----------
    prob : np.ndarray [shape=(..., n_states, n_steps), non-negative]
        ``prob[..., s, t]`` is the probability of observation at time ``t``
        being generated by state ``s``.
    transition : np.ndarray [shape=(n_states, n_states), non-negative]
        ``transition[i, j]`` is the probability of a transition from i->j.
        Each row must sum to 1.
    p_init : np.ndarray [shape=(n_states,)]
        Optional: initial state distribution.
        If not provided, a uniform distribution is assumed.
    return_logp : bool
        If ``True``, return the log-likelihood of the state sequence.

    Returns
    -------
    Either ``states`` or ``(states, logp)``:
    states : np.ndarray [shape=(..., n_steps,)]
        The most likely state sequence.
        If ``prob`` contains multiple channels of input, then each channel is
        decoded independently.
    logp : scalar [float] or np.ndarray
        If ``return_logp=True``, the log probability of ``states`` given
        the observations.

    See Also
    --------
    viterbi_discriminative : Viterbi decoding from state likelihoods

    Examples
    --------
    Example from https://en.wikipedia.org/wiki/Viterbi_algorithm#Example

    In this example, we have two states ``healthy`` and ``fever``, with
    initial probabilities 60% and 40%.

    We have three observation possibilities: ``normal``, ``cold``, and
    ``dizzy``, whose probabilities given each state are:

    ``healthy => {normal: 50%, cold: 40%, dizzy: 10%}`` and
    ``fever => {normal: 10%, cold: 30%, dizzy: 60%}``

    Finally, we have transition probabilities:

    ``healthy => healthy (70%)`` and
    ``fever => fever (60%)``.

    Over three days, we observe the sequence ``[normal, cold, dizzy]``,
    and wish to know the maximum likelihood assignment of states for the
    corresponding days, which we compute with the Viterbi algorithm below.

    >>> p_init = np.array([0.6, 0.4])
    >>> p_emit = np.array([[0.5, 0.4, 0.1],
    ...                    [0.1, 0.3, 0.6]])
    >>> p_trans = np.array([[0.7, 0.3], [0.4, 0.6]])
    >>> path, logp = librosa.sequence.viterbi(p_emit, p_trans, p_init=p_init,
    ...                                       return_logp=True)
    >>> print(logp, path)
    -4.19173690823075 [0 0 1]
    r   Ntransition.shape=, must be (n_states, n_states)=r   r   axisIInvalid transition matrix: must be non-negative and sum to 1 on each row.z4Invalid probability values: must be between 0 and 1.      ?+Invalid initial state distribution: p_init=c                T    t        | j                        \  }}|j                  |fS r+   r   r[   lp_stater   r   r   s      r1   _helperzviterbi.<locals>._helper  '    i<xx~r3   rI   (s,t)->(t),(1)otypes	signature.r   )rY   r   rK   rU   allclosesumr
   r   rR   logndim	vectorizer   rO   )r   r   r   r   r   r   epsilonr   r   statesr   	__viterbir   r   s               @@r1   r   r     s   ` 

23HgHh//
 0 01 2$$,h$6#79
 	

 
vvj1nR[[Q1G%K(
 	

 
vvdQh266$(+STT 4jG~(#C(N#
vz{{6::<+<<H;&J6(STTzG+,IvvdWn%H()J }}x( LLRYY

3?O
	 !* F|t|Mr3   p_stater   r   c                    y r+   r,   r   r   r   r   r   s        r1   r   r   /  r   r3   )r   r   c                    y r+   r,   r   s        r1   r   r   ;  r   r3   c                    y r+   r,   r   s        r1   r   r   G  r   r3   c                  | j                   dd \  }}|j                   ||fk7  rt        d|j                    d||f       t        j                  |dk        s&t        j                  |j                  d      d      st        d      t        j                  | dk        s&t        j                  | j                  d      d      st        d	      t        |       }|*t        j                  |      }|j                  d
|z         nt|j                   |fk7  rt        d|j                          t        j                  |dk        s&t        j                  |j                  d      d      st        d|       |*t        j                  |      }|j                  d
|z         nZt        j                  |dk        s4t        j                  |j                         d      r|j                   |fk7  rt        d|       t        j                  ||z         t        j                  ||z         t        j                  ||z         }t        || j                  d      }t        j                  | |z         |z
  }	fd}
|	j                  dk(  r |
|	      \  }}nAt        j                  |
t        j                  t        j                  gd      } ||	      \  }}|d   }|r||fS |S )a  Viterbi decoding from discriminative state predictions.

    Given a sequence of conditional state predictions ``prob[s, t]``,
    indicating the conditional likelihood of state ``s`` given the
    observation at time ``t``, and a transition matrix ``transition[i, j]``
    which encodes the conditional probability of moving from state ``i``
    to state ``j``, the Viterbi algorithm computes the most likely sequence
    of states from the observations.

    This implementation uses the standard Viterbi decoding algorithm
    for observation likelihood sequences, under the assumption that
    ``P[Obs(t) | State(t) = s]`` is proportional to
    ``P[State(t) = s | Obs(t)] / P[State(t) = s]``, where the denominator
    is the marginal probability of state ``s`` occurring as given by ``p_state``.

    Note that because the denominator ``P[State(t) = s]`` is not explicitly
    calculated, the resulting probabilities (or log-probabilities) are not
    normalized.  If using the `return_logp=True` option (see below),
    be aware that the "probabilities" may not sum to (and may exceed) 1.

    Parameters
    ----------
    prob : np.ndarray [shape=(..., n_states, n_steps), non-negative]
        ``prob[s, t]`` is the probability of state ``s`` conditional on
        the observation at time ``t``.
        Must be non-negative and sum to 1 along each column.
    transition : np.ndarray [shape=(n_states, n_states), non-negative]
        ``transition[i, j]`` is the probability of a transition from i->j.
        Each row must sum to 1.
    p_state : np.ndarray [shape=(n_states,)]
        Optional: marginal probability distribution over states,
        must be non-negative and sum to 1.
        If not provided, a uniform distribution is assumed.
    p_init : np.ndarray [shape=(n_states,)]
        Optional: initial state distribution.
        If not provided, it is assumed to be uniform.
    return_logp : bool
        If ``True``, return the log-likelihood of the state sequence.

    Returns
    -------
    Either ``states`` or ``(states, logp)``:
    states : np.ndarray [shape=(..., n_steps,)]
        The most likely state sequence.
        If ``prob`` contains multiple input channels,
        then each channel is decoded independently.
    logp : scalar [float] or np.ndarray
        If ``return_logp=True``, the (unnormalized) log probability
        of ``states`` given the observations.

    See Also
    --------
    viterbi :
        Viterbi decoding from observation likelihoods
    viterbi_binary :
        Viterbi decoding for multi-label, conditional state likelihoods

    Examples
    --------
    This example constructs a simple, template-based discriminative chord estimator,
    using CENS chroma as input features.

    .. note:: this chord model is not accurate enough to use in practice. It is only
            intended to demonstrate how to use discriminative Viterbi decoding.

    >>> # Create templates for major, minor, and no-chord qualities
    >>> maj_template = np.array([1,0,0, 0,1,0, 0,1,0, 0,0,0])
    >>> min_template = np.array([1,0,0, 1,0,0, 0,1,0, 0,0,0])
    >>> N_template   = np.array([1,1,1, 1,1,1, 1,1,1, 1,1,1.]) / 4.
    >>> # Generate the weighting matrix that maps chroma to labels
    >>> weights = np.zeros((25, 12), dtype=float)
    >>> labels = ['C:maj', 'C#:maj', 'D:maj', 'D#:maj', 'E:maj', 'F:maj',
    ...           'F#:maj', 'G:maj', 'G#:maj', 'A:maj', 'A#:maj', 'B:maj',
    ...           'C:min', 'C#:min', 'D:min', 'D#:min', 'E:min', 'F:min',
    ...           'F#:min', 'G:min', 'G#:min', 'A:min', 'A#:min', 'B:min',
    ...           'N']
    >>> for c in range(12):
    ...     weights[c, :] = np.roll(maj_template, c) # c:maj
    ...     weights[c + 12, :] = np.roll(min_template, c)  # c:min
    >>> weights[-1] = N_template  # the last row is the no-chord class
    >>> # Make a self-loop transition matrix over 25 states
    >>> trans = librosa.sequence.transition_loop(25, 0.9)

    >>> # Load in audio and make features
    >>> y, sr = librosa.load(librosa.ex('nutcracker'), duration=15)
    >>> # Suppress percussive elements
    >>> y = librosa.effects.harmonic(y, margin=4)
    >>> chroma = librosa.feature.chroma_cqt(y=y, sr=sr)
    >>> # Map chroma (observations) to class (state) likelihoods
    >>> probs = np.exp(weights.dot(chroma))  # P[class | chroma] ~= exp(template' chroma)
    >>> probs /= probs.sum(axis=0, keepdims=True)  # probabilities must sum to 1 in each column
    >>> # Compute independent frame-wise estimates
    >>> chords_ind = np.argmax(probs, axis=0)
    >>> # And viterbi estimates
    >>> chords_vit = librosa.sequence.viterbi_discriminative(probs, trans)

    >>> # Plot the features and prediction map
    >>> import matplotlib.pyplot as plt
    >>> fig, ax = plt.subplots(nrows=2)
    >>> librosa.display.specshow(chroma, x_axis='time', y_axis='chroma', ax=ax[0])
    >>> librosa.display.specshow(weights, x_axis='chroma', ax=ax[1])
    >>> ax[1].set(yticks=np.arange(25) + 0.5, yticklabels=labels, ylabel='Chord')

    >>> # And plot the results
    >>> fig, ax = plt.subplots()
    >>> librosa.display.specshow(probs, x_axis='time', cmap='gray', ax=ax)
    >>> times = librosa.times_like(chords_vit)
    >>> ax.scatter(times, chords_ind + 0.25, color='lime', alpha=0.5, marker='+',
    ...            s=15, label='Independent')
    >>> ax.scatter(times, chords_vit - 0.25, color='deeppink', alpha=0.5, marker='o',
    ...            s=15, label='Viterbi')
    >>> ax.set(yticks=np.unique(chords_vit),
    ...        yticklabels=[labels[i] for i in np.unique(chords_vit)])
    >>> ax.legend()
    r   Nr   r   r   r   r   r   zIInvalid probability values: each column must sum to 1 and be non-negativer   zMMarginal distribution p_state must have shape (n_states,). Got p_state.shape=rC   z-Invalid marginal state distribution: p_state=r   )r   axesc                T    t        | j                        \  }}|j                  |fS r+   r   r   s      r1   r   z'viterbi_discriminative.<locals>._helper  r   r3   rI   r   r   r   )rY   r   rK   rU   r   r   r
   r   rR   r   r   r   r   r   rO   )r   r   r   r   r   r   r   r   log_marginalr   r   r   r   r   r   r   s                 @@r1   r   r   S  s   v 

23HgHh//
 0 01 2$$,h$6#79
 	

 
vvj1nR[[Q1G%K(
 	

 
vvdQhr{{4888+<a@+
 	
 4jG ((8$S8^$	8+	%!!(1
 	
 
!	BKK0Da$HLWIVWW~(#C(N#
vz{{6::<+<<H;&J6(STT ()JzG+,I66'G+,L \		CLvvdWn%4H }}x( LLRYY

3?O
	 !* <Dt|Mr3   c                    y r+   r,   r   s        r1   r   r   &  r   r3   c                    y r+   r,   r   s        r1   r   r   2  r   r3   c                    y r+   r,   r   s        r1   r   r   >  r   r3   c                  t        j                  |       } | j                  dd \  }}|j                  dk(  rt        j                  ||ddf      }n-|j                  |ddfk7  rt	        d|j                   d|       t        j
                  |dk        s&t        j                  |j                  d	
      d      st	        d      t        j
                  | dk        st        j
                  | dkD        rt	        d      |'t        j                  |      }|j                  d       nt        j                  |      }|J |j                  |fk7  s0t        j
                  |dk        st        j
                  |dkD        rt	        d|       |'t        j                  |      }|j                  d       nt        j                  |      }|J |j                  |fk7  s0t        j
                  |dk        st        j
                  |dkD        rt	        d|       t        | j                  dd       }t        j                  |||gz   t         j                        }t        j                  ||gz         }	t        j                  |d|gz         }
t        j                  d      }t        j                  d      }t        |      D ]r  }d| d|ddf   z
  |
ddddf<   | d|ddf   |
ddddf<   d||   z
  |d<   ||   |d<   d||   z
  |d<   ||   |d<   t        |
||   ||d      \  |d|ddf<   |	d|f<   t |r||	fS |S )a+  Viterbi decoding from binary (multi-label), discriminative state predictions.

    Given a sequence of conditional state predictions ``prob[s, t]``,
    indicating the conditional likelihood of state ``s`` being active
    conditional on observation at time ``t``, and a 2*2 transition matrix
    ``transition`` which encodes the conditional probability of moving from
    state ``s`` to state ``~s`` (not-``s``), the Viterbi algorithm computes the
    most likely sequence of states from the observations.

    This function differs from `viterbi_discriminative` in that it does not assume the
    states to be mutually exclusive.  `viterbi_binary` is implemented by
    transforming the multi-label decoding problem to a collection
    of binary Viterbi problems (one for each *state* or label).

    The output is a binary matrix ``states[s, t]`` indicating whether each
    state ``s`` is active at time ``t``.

    Like `viterbi_discriminative`, the probabilities of the optimal state sequences
    are not normalized here.  If using the `return_logp=True` option (see below),
    be aware that the "probabilities" may not sum to (and may exceed) 1.

    Parameters
    ----------
    prob : np.ndarray [shape=(..., n_steps,) or (..., n_states, n_steps)], non-negative
        ``prob[s, t]`` is the probability of state ``s`` being active
        conditional on the observation at time ``t``.
        Must be non-negative and less than 1.

        If ``prob`` is 1-dimensional, it is expanded to shape ``(1, n_steps)``.

        If ``prob`` contains multiple input channels, then each channel is decoded independently.

    transition : np.ndarray [shape=(2, 2) or (n_states, 2, 2)], non-negative
        If 2-dimensional, the same transition matrix is applied to each sub-problem.
        ``transition[0, i]`` is the probability of the state going from inactive to ``i``,
        ``transition[1, i]`` is the probability of the state going from active to ``i``.
        Each row must sum to 1.

        If 3-dimensional, ``transition[s]`` is interpreted as the 2x2 transition matrix
        for state label ``s``.

    p_state : np.ndarray [shape=(n_states,)]
        Optional: marginal probability for each state (between [0,1]).
        If not provided, a uniform distribution (0.5 for each state)
        is assumed.

    p_init : np.ndarray [shape=(n_states,)]
        Optional: initial state distribution.
        If not provided, it is assumed to be uniform.

    return_logp : bool
        If ``True``, return the (unnormalized) log-likelihood of the state sequences.

    Returns
    -------
    Either ``states`` or ``(states, logp)``:
    states : np.ndarray [shape=(..., n_states, n_steps)]
        The most likely state sequence.
    logp : np.ndarray [shape=(..., n_states,)]
        If ``return_logp=True``, the (unnormalized) log probability of each
        state activation sequence ``states``

    See Also
    --------
    viterbi :
        Viterbi decoding from observation likelihoods
    viterbi_discriminative :
        Viterbi decoding for discriminative (mutually exclusive) state predictions

    Examples
    --------
    In this example, we have a sequence of binary state likelihoods that we want to de-noise
    under the assumption that state changes are relatively uncommon.  Positive predictions
    should only be retained if they persist for multiple steps, and any transient predictions
    should be considered as errors.  This use case arises frequently in problems such as
    instrument recognition, where state activations tend to be stable over time, but subject
    to abrupt changes (e.g., when an instrument joins the mix).

    We assume that the 0 state has a self-transition probability of 90%, and the 1 state
    has a self-transition probability of 70%.  We assume the marginal and initial
    probability of either state is 50%.

    >>> trans = np.array([[0.9, 0.1], [0.3, 0.7]])
    >>> prob = np.array([0.1, 0.7, 0.4, 0.3, 0.8, 0.9, 0.8, 0.2, 0.6, 0.3])
    >>> librosa.sequence.viterbi_binary(prob, trans, p_state=0.5, p_init=0.5)
    array([[0, 0, 0, 0, 1, 1, 1, 0, 0, 0]])
    r   N)rI   rI   r   rI   r   z%, must be (2, 2) or (n_states, 2, 2)=r   rC   r   r   z7Invalid probability values: prob must be between [0, 1]g      ?z.Invalid marginal state distributions: p_state=z,Invalid initial state distributions: p_init=r@   .Tr   )rK   rV   rY   tiler   rU   r   r   r   rR   
atleast_1dr   r   r|   r   )r   r   r   r   r   r   r   shape_prefixr   r   prob_binaryp_state_binaryp_init_binaryr   s                 r1   r   r   J  s2   ~ ==D

23Hg6!WWZ(Aq)9:
			h1-	-
 0 01 2  (z+
 	

 
vvj1nR[[R1H!%L(
 	

 
vvdQh266$(+VWW((8$S--(}}#rvvgk':bffWq[>QMgYWXX~(#Cv&||{"bffVaZ&8BFF6A:<NKF8TUU

3B(LXXlh%88		JF88LH:-.D((<1g,67KXXa[NHHQKMx!"T#ua-%8!8CAI!%c5!m!4CAI.q#ENqve},a!%=a2Hu" 3
/sE1}tCJ/ !$ t|Mr3   c                    t        |       st        d|  d      t        j                  | | ft        j                        }|j                  d| z         |S )a  Construct a uniform transition matrix over ``n_states``.

    Parameters
    ----------
    n_states : int > 0
        The number of states

    Returns
    -------
    transition : np.ndarray [shape=(n_states, n_states)]
        ``transition[i, j] = 1./n_states``

    Examples
    --------
    >>> librosa.sequence.transition_uniform(3)
    array([[0.333, 0.333, 0.333],
           [0.333, 0.333, 0.333],
           [0.333, 0.333, 0.333]])
    	n_states=z must be a positive integerr@   r   )r	   r   rK   r   rO   rR   )r   r   s     r1   r   r     sP    ( 8$y
2MNOO8X.bjjAJOOC(N#r3   c                6   t        |       r| dkD  st        d|  d      t        j                  | | ft        j                        }t        j
                  |t        j                        }|j                  dk(  rt        j                  ||       }|j                  | fk7  rt        d| d|        t        j                  |dk        st        j                  |dkD        rt        d| d      t        |      D ]  \  }}d	|z
  | dz
  z  ||<   ||||f<    |S )
a  Construct a self-loop transition matrix over ``n_states``.

    The transition matrix will have the following properties:

        - ``transition[i, i] = p`` for all ``i``
        - ``transition[i, j] = (1 - p) / (n_states - 1)`` for all ``j != i``

    This type of transition matrix is appropriate when states tend to be
    locally stable, and there is no additional structure between different
    states.  This is primarily useful for de-noising frame-wise predictions.

    Parameters
    ----------
    n_states : int > 1
        The number of states

    prob : float in [0, 1] or iterable, length=n_states
        If a scalar, this is the probability of a self-transition.

        If a vector of length ``n_states``, ``p[i]`` is the probability of self-transition in state ``i``

    Returns
    -------
    transition : np.ndarray [shape=(n_states, n_states)]
        The transition matrix

    Examples
    --------
    >>> librosa.sequence.transition_loop(3, 0.5)
    array([[0.5 , 0.25, 0.25],
           [0.25, 0.5 , 0.25],
           [0.25, 0.25, 0.5 ]])

    >>> librosa.sequence.transition_loop(3, [0.8, 0.5, 0.25])
    array([[0.8  , 0.1  , 0.1  ],
           [0.25 , 0.5  , 0.25 ],
           [0.375, 0.375, 0.25 ]])
    r   r    must be a positive integer > 1r@   r   prob=$ must have length equal to n_states=% must have values in the range [0, 1]r   )r	   r   rK   r   rO   rf   r   r   rY   rU   	enumerater   r   r   r   prob_is        r1   r   r     s   N H%8a<y
2QRSS8X.bjjAJ ::d"**-DyyA~wwtX&zzh[ D6=hZH
 	
 
vvdQh266$(+uTF*OPQQt_	6v(Q,7
1!
1a4 % r3   c                \   t        |       r| dkD  st        d|  d      t        j                  | | ft        j                        }t        j
                  |t        j                        }|j                  dk(  rt        j                  ||       }|j                  | fk7  rt        d| d|        t        j                  |dk        st        j                  |dkD        rt        d| d      t        |      D ]-  \  }}d	|z
  ||t        j                  |dz   |       f<   ||||f<   / |S )
aT  Construct a cyclic transition matrix over ``n_states``.

    The transition matrix will have the following properties:

        - ``transition[i, i] = p``
        - ``transition[i, i + 1] = (1 - p)``

    This type of transition matrix is appropriate for state spaces
    with cyclical structure, such as metrical position within a bar.
    For example, a song in 4/4 time has state transitions of the form

        1->{1, 2}, 2->{2, 3}, 3->{3, 4}, 4->{4, 1}.

    Parameters
    ----------
    n_states : int > 1
        The number of states

    prob : float in [0, 1] or iterable, length=n_states
        If a scalar, this is the probability of a self-transition.

        If a vector of length ``n_states``, ``p[i]`` is the probability of
        self-transition in state ``i``

    Returns
    -------
    transition : np.ndarray [shape=(n_states, n_states)]
        The transition matrix

    Examples
    --------
    >>> librosa.sequence.transition_cycle(4, 0.9)
    array([[0.9, 0.1, 0. , 0. ],
           [0. , 0.9, 0.1, 0. ],
           [0. , 0. , 0.9, 0.1],
           [0.1, 0. , 0. , 0.9]])
    r   r   r   r@   r   r   r   r   r   )r	   r   rK   rN   rO   rf   r   r   rY   rU   r   modr   s        r1   r    r    Q  s   L H%(Q,y
2QRSS8X.bjjAJ ::d"**-DyyA~wwtX&zzh[ D6=hZH
 	
 
vvdQh266$(+uTF*OPQQt_	614v
1bffQUH--.!
1a4 % r3   triangle)windowwrapc          
        t        |       r| dkD  st        d|  d      t        j                  |t              }|j
                  dk(  rt        j                  ||       }|j                  | fk7  rt        d| d|        t        j                  |dk        rt        d| d      t        j                  | | ft        j                        }t        |      D ]q  \  }}t        t        ||d	
      |       }t        j                  || dz  |z   dz         }|s-d|t        | ||dz  z   dz         d d|dt!        d||dz  z
         |||<   s ||j#                  dd      z  }|S )aJ
  Construct a localized transition matrix.

    The transition matrix will have the following properties:

        - ``transition[i, j] = 0`` if ``|i - j| > width``
        - ``transition[i, i]`` is maximal
        - ``transition[i, i - width//2 : i + width//2]`` has shape ``window``

    This type of transition matrix is appropriate for state spaces
    that discretely approximate continuous variables, such as in fundamental
    frequency estimation.

    Parameters
    ----------
    n_states : int > 1
        The number of states

    width : int >= 1 or iterable
        The maximum number of states to treat as "local".
        If iterable, it should have length equal to ``n_states``,
        and specify the width independently for each state.

    window : str, callable, or window specification
        The window function to determine the shape of the "local" distribution.

        Any window specification supported by `filters.get_window` will work here.

        .. note:: Certain windows (e.g., 'hann') are identically 0 at the boundaries,
            so and effectively have ``width-2`` non-zero values.  You may have to expand
            ``width`` to get the desired behavior.

    wrap : bool
        If ``True``, then state locality ``|i - j|`` is computed modulo ``n_states``.
        If ``False`` (default), then locality is absolute.

    See Also
    --------
    librosa.filters.get_window

    Returns
    -------
    transition : np.ndarray [shape=(n_states, n_states)]
        The transition matrix

    Examples
    --------
    Triangular distributions with and without wrapping

    >>> librosa.sequence.transition_local(5, 3, window='triangle', wrap=False)
    array([[0.667, 0.333, 0.   , 0.   , 0.   ],
           [0.25 , 0.5  , 0.25 , 0.   , 0.   ],
           [0.   , 0.25 , 0.5  , 0.25 , 0.   ],
           [0.   , 0.   , 0.25 , 0.5  , 0.25 ],
           [0.   , 0.   , 0.   , 0.333, 0.667]])

    >>> librosa.sequence.transition_local(5, 3, window='triangle', wrap=True)
    array([[0.5 , 0.25, 0.  , 0.  , 0.25],
           [0.25, 0.5 , 0.25, 0.  , 0.  ],
           [0.  , 0.25, 0.5 , 0.25, 0.  ],
           [0.  , 0.  , 0.25, 0.5 , 0.25],
           [0.25, 0.  , 0.  , 0.25, 0.5 ]])

    Uniform local distributions with variable widths and no wrapping

    >>> librosa.sequence.transition_local(5, [1, 2, 3, 3, 1], window='ones', wrap=False)
    array([[1.   , 0.   , 0.   , 0.   , 0.   ],
           [0.5  , 0.5  , 0.   , 0.   , 0.   ],
           [0.   , 0.333, 0.333, 0.333, 0.   ],
           [0.   , 0.   , 0.333, 0.333, 0.333],
           [0.   , 0.   , 0.   , 0.   , 1.   ]])
    r   r   r   r@   r   zwidth=r   z must be at least 1F)fftbins)sizerI   NT)r   keepdims)r	   r   rK   rf   rg   r   r   rY   rU   rN   rO   r   r   r   rollr   r]   r   )r   widthr  r  r   r   width_i	trans_rows           r1   r!   r!     sv   \ H%(Q,y
2QRSSJJuC(EzzQx({{xk!UG?zJ
 	
 
vveaiveW,?@AA8X.bjjAJ  &
7vw6X
	 GGIx1}q'81'<=	?@Ic(A1$4q$89;<45I0Aq7a</01!
1 ' *..a$.77Jr3   )r.   
np.ndarrayr/   r  r"   strr#   Optional[np.ndarray]r$   r  r%   r  r&   boolr0   Literal[False]r'   r  r(   floatr)   r  returnr  )r6   r  r"   r  r#   r  r$   r  r%   r  r&   r  r0   r  r'   r  r(   r  r)   r  r  r  )r.   r  r/   r  r"   r  r#   r  r$   r  r%   r  r&   r  r0   r  r'   r  r(   r  r)   Literal[True]r  Tuple[np.ndarray, np.ndarray])r6   r  r"   r  r#   r  r$   r  r%   r  r&   r  r0   r  r'   r  r(   r  r)   r  r  r  )r.   r  r/   r  r"   r  r#   r  r$   r  r%   r  r&   r  r0   r  r'   r  r(   r  r)   r  r  r  )r6   r  r"   r  r#   r  r$   r  r%   r  r&   r  r0   r  r'   r  r(   r  r)   r  r  r  )r.   r  r/   r  r"   r  r#   r  r$   r  r%   r  r&   r  r0   r  r'   r  r(   r  r)   r  r  )Tuple[np.ndarray, np.ndarray, np.ndarray])r6   r  r"   r  r#   r  r$   r  r%   r  r&   r  r0   r  r'   r  r(   r  r)   r  r  r  )NN)r.   r  r/   r  r6   r  r"   r  r#   r  r$   r  r%   r  r&   r  r0   r  r'   r  r(   r  r)   r  r  z[Union[np.ndarray, Tuple[np.ndarray, np.ndarray], Tuple[np.ndarray, np.ndarray, np.ndarray]])r6   r  rs   r  rt   r  r#   r  r%   r  r$   r  rq   rg   rr   rg   r  r  r+   )
rt   r  r#   r  r&   r  ru   zOptional[int]r  zList[Tuple[int, int]])
rt   r  r#   r  r&   r  ru   z%Optional[Union[int, np.integer[Any]]]r  r  )r   r  r   r  r   r  r   r  r0   r  r  r  )r   r  r   r  r   r  r   r  r0   r  r  r  )r   r  r   r  r   r  r   r  r0   r  r  0Union[np.ndarray, Tuple[np.ndarray, np.ndarray]])
r   r  r   r  r   r  r   r  r  r  )r   r  r   r  r   r  r  r  )
r   r  r   r  r   r  r   r  r  r  )
r   r  r   r  r   r  r   r  r  r  )
r   r  r   r  r   r  r   r  r  r  )r   r  r   r  r   r  r   r  r   r  r  r  )r   r  r   r  r   r  r   r  r   r  r  r  )r   r  r   r  r   r  r   r  r   r  r  r  )r   rg   r  r  )r   rg   r   zUnion[float, Iterable[float]]r  r  )
r   rg   r  zUnion[int, Iterable[int]]r  r   r  r  r  r  )0__doc__
__future__r   numpyrK   scipy.spatial.distancer   numbar   utilr   r   r	   r
   r   util.exceptionsr   filtersr   typingr   r   r   r   r   r   r   typing_extensionsr   _typingr   r   __all__r   ra   re   r   r   r   r   r   r   r   r   r   r   r    r!   r,   r3   r1   <module>r%     s  > #  (  Q Q +  H H H % - 

 -0(+(+"#& 	
 + & &     !  
" 
 -0(+(+"#&  +	
 & &     !  
  

 -0(+(+" 	
 + & &       # 
" 
 -0(+(+"  +	
 & &       # 
  

 -0(+(+""#& 	
 + & &     ! # 
" 
 -0(+(+""#&  +	
 & &     ! # 
  

 -0(+(+"" 	
 + & &       / 
" 
 -0(+(+""  +	
 & &       / 
" #"u  #-1(,(,$u u u  	u 
 u  +u  &u  &u  u  u  u  u  u u p	 d$EEE E !	E
 E E E E #E  EP d$
  	AA A A 	A
 A  AN .2373%3% +3% 	3%
 13% 3%l 
 	  	
    
 
 "	  	
   # 
 
 	  	
   6 
 S	S S 	S
 S S 6Sl d$V	V %V38VBFV"V  Vr0+f d$<<%/<=G<"<  <~ 

 $'	
 !	
  # 
 

 $'"%
 !	
    
 $(K
KK !	K
 K 6K\ 

 %(#&"%
 "	
 !    
 

 %(#&
 "	
 !  # 
 

 %(#&
 "	
 !  6 
 %)#'P
PP "	P
 !P P 6Pf 

 %(#&"%
 "	
 !    
 

 %(#&
 "	
 !  # 
 

 %(#&
 "	
 !  6 
 %)#'g
gg "	g
 !g g 6gT8>B=H %pp$p 	p
 p pr3   