
    0;ji                        d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	Zddl
ZddlmZ ddl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 dd
lmZ ddlmZmZ g dZeddddddddej         dej         dee!         de"ded         de"deeej         ee"f                  de#dej         fd            Z$eddddddddej         dej         dee!         de"ded         de"deeej         ee"f                  de#dej%        j&        fd            Z$ ed          ddddddddej         dej         dee!         de"de#de"deeej         ee"f                  de#deej         ej%        j&        f         fd             Z$eddddddddddd!
dej         dee!         d"e!de"d#e#ded         de"deeej         ee"f                  d$e#d%e!de#dej%        j&        fd&            Z'eddddddddddd!
dej         dee!         d"e!de"d#e#ded         de"deeej         ee"f                  d$e#d%e!de#dej         fd'            Z' ed          ddddddddd(dd!
dej         dee!         d"e!de"d#e#de#de"deeej         ee"f                  d$e#d%e!de#deej         ej%        j&        f         fd)            Z' ed*eej         ej%        j(        f         +          Z)dd(d,d-e)d.e#d%e!de)fd/Z*d(d0d1e)d%e!de)fd2Z+ ed3edef         +          Z,dOd4e,d.e#d5e!de,fd6Z- ed          d7d(d8dej         d9ej         d:e!d%e!dej         f
d;            Z.dd(d<dej         de!d=eej/        j0                 d%e!dej         f
d>Z1d?d@ddAdddBdCej         dDe!dEedFe2dGee2         dHe!dIe#dJe#dKedej         fdLZ3d-ej%        j4        dMeeej         ee"f                  de!dee2ej         f         fdNZ5dS )Pa  
Temporal segmentation
=====================

Recurrence and self-similarity
------------------------------
.. autosummary::
    :toctree: generated/

    cross_similarity
    recurrence_matrix
    recurrence_to_lag
    lag_to_recurrence
    timelag_filter
    path_enhance

Temporal clustering
-------------------
.. autosummary::
    :toctree: generated/

    agglomerative
    subsegment
    	decoratorN   )cache)util)diagonal_filter)ParameterError)AnyCallableOptionalTypeVarUnionoverload)Literal)_WindowSpec_FloatLike_co)cross_similarityrecurrence_matrixrecurrence_to_laglag_to_recurrencetimelag_filteragglomerative
subsegmentpath_enhance.F)kmetricsparsemode	bandwidthfulldatadata_refr   r   r   r   r   r    returnc                    d S N r!   r"   r   r   r   r   r   r    s           I/root/voice-cloning/.venv/lib/python3.11/site-packages/librosa/segment.pyr   r   <   	     C    Tc                    d S r%   r&   r'   s           r(   r   r   K   r)   r*      )level	euclideanconnectivityc          	      v   t          j        |          }t          j        |           } t          j        |j        dd         | j        dd                   s t	          d|j         d| j         d          t          j        |dd          }|j        d         }|                    |dfd          }t          j        | dd          } | j        d         }	|                     |	dfd          } |d	vrt	          d
| d          |7t          |dt          j        t          j	        |                    z            }t          |          }|}
|r|dk    r|	}	 t          j                            t          ||          |d          }n@# t          $ r3 t          j                            t          ||          |d          }Y nw xY w|                    |           |dk    rd}n|}|                    | |                                          }|s{t%          |	          D ]k}||                                         d         }|t          j        |||f                                                            d         }d||||d         f<   l|                                }|                                 |dk    r|                    t2                    }n@|dk    r:t5          |||
          }t          j        |j        d|z  z            |j        dd<   |j        }|s|                                }|S )u  Compute cross-similarity from one data sequence to a reference sequence.

    The output is a matrix ``xsim``, where ``xsim[i, j]`` is non-zero
    if ``data_ref[..., i]`` is a k-nearest neighbor of ``data[..., j]``.

    Parameters
    ----------
    data : np.ndarray [shape=(..., d, n)]
        A feature matrix for the comparison sequence.
        If the data has more than two dimensions (e.g., for multi-channel inputs),
        the leading dimensions are flattened prior to comparison.
        For example, a stereo input with shape `(2, d, n)` is
        automatically reshaped to `(2 * d, n)`.

    data_ref : np.ndarray [shape=(..., d, n_ref)]
        A feature matrix for the reference sequence
        If the data has more than two dimensions (e.g., for multi-channel inputs),
        the leading dimensions are flattened prior to comparison.
        For example, a stereo input with shape `(2, d, n_ref)` is
        automatically reshaped to `(2 * d, n_ref)`.

    k : int > 0 [scalar] or None
        the number of nearest-neighbors for each sample

        Default: ``k = 2 * ceil(sqrt(n_ref))``,
        or ``k = 2`` if ``n_ref <= 3``

    metric : str
        Distance metric to use for nearest-neighbor calculation.

        See `sklearn.neighbors.NearestNeighbors` for details.

    sparse : bool [scalar]
        if False, returns a dense type (ndarray)
        if True, returns a sparse type (scipy.sparse.csc_matrix)

    mode : str, {'connectivity', 'distance', 'affinity'}
        If 'connectivity', a binary connectivity matrix is produced.

        If 'distance', then a non-zero entry contains the distance between
        points.

        If 'affinity', then non-zero entries are mapped to
        ``exp( - distance(i, j) / bandwidth)`` where ``bandwidth`` is
        as specified below.

    bandwidth : None, float > 0, ndarray, or str
        str options include ``{'med_k_scalar', 'mean_k', 'gmean_k', 'mean_k_avg', 'gmean_k_avg', 'mean_k_avg_and_pair'}``

        If ndarray is supplied, use ndarray as bandwidth for each i,j pair.

        If using ``mode='affinity'``, this can be used to set the
        bandwidth on the affinity kernel.

        If no value is provided or ``None``, default to ``'med_k_scalar'``.

        If ``bandwidth='med_k_scalar'``, bandwidth is set automatically to the median
        distance to the k'th nearest neighbor of each ``data[:, i]``.

        If ``bandwidth='mean_k'``, bandwidth is estimated for each sample-pair (i, j) by taking the
        arithmetic mean between distances to the k-th nearest neighbor for sample i and sample j.

        If ``bandwidth='gmean_k'``, bandwidth is estimated for each sample-pair (i, j) by taking the
        geometric mean between distances to the k-th nearest neighbor for sample i and j [#z]_.

        If ``bandwidth='mean_k_avg'``, bandwidth is estimated for each sample-pair (i, j) by taking the
        arithmetic mean between the average distances to the first k-th nearest neighbors for
        sample i and sample j.
        This is similar to the approach in Wang et al. (2014) [#w]_ but does not include the distance
        between i and j.

        If ``bandwidth='gmean_k_avg'``, bandwidth is estimated for each sample-pair (i, j) by taking the
        geometric mean between the average distances to the first k-th nearest neighbors for
        sample i and sample j.

        If ``bandwidth='mean_k_avg_and_pair'``, bandwidth is estimated for each sample-pair (i, j) by
        taking the arithmetic mean between three terms: the average distances to the first
        k-th nearest neighbors for sample i and sample j respectively, as well as
        the distance between i and j.
        This is similar to the approach in Wang et al. (2014). [#w]_

        .. [#z] Zelnik-Manor, Lihi, and Pietro Perona. (2004).
            "Self-tuning spectral clustering." Advances in neural information processing systems 17.

        .. [#w] Wang, Bo, et al. (2014).
            "Similarity network fusion for aggregating data types on a genomic scale." Nat Methods 11, 333–337.
            https://doi.org/10.1038/nmeth.2810

    full : bool
        If using ``mode ='affinity'`` or ``mode='distance'``, this option can be used to compute
        the full affinity or distance matrix as opposed a sparse matrix with only none-zero terms
        for the first k-neighbors of each sample.
        This option has no effect when using ``mode='connectivity'``.

        When using ``mode='distance'``, setting ``full=True`` will ignore ``k`` and ``width``.
        When using ``mode='affinity'``, setting ``full=True`` will use ``k`` exclusively for
        bandwidth estimation, and ignore ``width``.

    Returns
    -------
    xsim : np.ndarray or scipy.sparse.csc_matrix, [shape=(n_ref, n)]
        Cross-similarity matrix

    See Also
    --------
    recurrence_matrix
    recurrence_to_lag
    librosa.feature.stack_memory
    sklearn.neighbors.NearestNeighbors
    scipy.spatial.distance.cdist

    Notes
    -----
    This function caches at level 30.

    Examples
    --------
    Find nearest neighbors in CQT space between two sequences

    >>> hop_length = 1024
    >>> y_ref, sr = librosa.load(librosa.ex('pistachio'))
    >>> y_comp, sr = librosa.load(librosa.ex('pistachio'), offset=10)
    >>> chroma_ref = librosa.feature.chroma_cqt(y=y_ref, sr=sr, hop_length=hop_length)
    >>> chroma_comp = librosa.feature.chroma_cqt(y=y_comp, sr=sr, hop_length=hop_length)
    >>> # Use time-delay embedding to get a cleaner recurrence matrix
    >>> x_ref = librosa.feature.stack_memory(chroma_ref, n_steps=10, delay=3)
    >>> x_comp = librosa.feature.stack_memory(chroma_comp, n_steps=10, delay=3)
    >>> xsim = librosa.segment.cross_similarity(x_comp, x_ref)

    Or fix the number of nearest neighbors to 5

    >>> xsim = librosa.segment.cross_similarity(x_comp, x_ref, k=5)

    Use cosine similarity instead of Euclidean distance

    >>> xsim = librosa.segment.cross_similarity(x_comp, x_ref, metric='cosine')

    Use an affinity matrix instead of binary connectivity

    >>> xsim_aff = librosa.segment.cross_similarity(x_comp, x_ref, metric='cosine', mode='affinity')

    Plot the feature and recurrence matrices

    >>> import matplotlib.pyplot as plt
    >>> fig, ax = plt.subplots(ncols=2, sharex=True, sharey=True)
    >>> imgsim = librosa.display.specshow(xsim, x_axis='s', y_axis='s',
    ...                          hop_length=hop_length, ax=ax[0])
    >>> ax[0].set(title='Binary cross-similarity (symmetric)')
    >>> imgaff = librosa.display.specshow(xsim_aff, x_axis='s', y_axis='s',
    ...                          cmap='magma_r', hop_length=hop_length, ax=ax[1])
    >>> ax[1].set(title='Cross-affinity')
    >>> ax[1].label_outer()
    >>> fig.colorbar(imgsim, ax=ax[0], orientation='horizontal', ticks=[0, 1])
    >>> fig.colorbar(imgaff, ax=ax[1], orientation='horizontal')
    Nzdata_ref.shape=z and data.shape=z% do not match on leading dimension(s)r   Forderr/   distanceaffinityInvalid mode=':'. Must be one of ['connectivity', 'distance', 'affinity']   r/   auton_neighborsr   	algorithmbruter7   r6   )Xr   r   )np
atleast_2dallcloseshaper	   swapaxesreshapeminceilsqrtintsklearn	neighborsNearestNeighbors
ValueErrorfitkneighbors_graphtolilrangenonzeroargsorttoarraytocsreliminate_zerosastypebool__affinity_bandwidthexpr!   T)r!   r"   r   r   r   r   r   r    n_refnbandwidth_kknnkng_modexsimilinksidxaff_bandwidths                     r(   r   r   Z   sk   N }X&&H=D;x~crc*DJssO<< 
ohnoodjooo
 
 	

 {8R++HN1E377H;tR##D
1A<<Bs<++D;;;; ; ; ;
 
 	
 	yq27275>>22233AA K ''

00E1f 1 
 
  
 
 
00E1f 1 
 


 GGH z $X66<<>>D 
!q 	! 	!AGOO%%a(E 
45>#9#9#;#;<<=a@C  !DCG ::<<D~{{4  			,T9kJJvdi2+=>??	!!! 6D ||~~Ks   0F :G
	G
)
r   widthr   symr   r   r   selfaxisr    rg   rh   ri   rj   c       
             d S r%   r&   r!   r   rg   r   rh   r   r   r   ri   rj   r    s              r(   r   r   [  	     Cr*   c       
             d S r%   r&   rl   s              r(   r   r   m  rm   r*   r1   c       
   	         t          j        |           } t          j        | |	d          } | j        d         }|                     |dfd          } |dk     s||dz
  dz  k    r*t          d                    ||	|dz
  dz                      |dvrt          d	| d
          |2dt          j        t          j        |d|z  z
  dz                       z  }t          |          }|}|
r|dk    r|}	 t          j                            t          |dz
  |d|z  z             |d          }nI# t          $ r< t          j                            t          |dz
  |d|z  z             |d          }Y nw xY w|                    |            |dk    rd}n|}|                    |                                          }|
st%          | dz   |          D ]}|                    d|           t%          |          D ]k}||                                         d         }|t          j        |||f                                                            d         }d||||d         f<   l|r8|dk    r|                    d           n1|dk    r|                    d           n|                    d           |r|                    |j                  }|                                }|                                 |dk    r|                    t8                    }nS|dk    rMd|j        |j        dk     <   t=          |||          }t          j        |j        d|z  z            |j        dd<   |j        }|s|                                }|S )u  Compute a recurrence matrix from a data matrix.

    ``rec[i, j]`` is non-zero if ``data[..., i]`` is a k-nearest neighbor
    of ``data[..., j]`` and ``|i - j| >= width``

    The specific value of ``rec[i, j]`` can have several forms, governed
    by the ``mode`` parameter below:

        - Connectivity: ``rec[i, j] = 1 or 0`` indicates that frames ``i`` and ``j`` are repetitions

        - Affinity: ``rec[i, j] > 0`` measures how similar frames ``i`` and ``j`` are.  This is also
          known as a (sparse) self-similarity matrix.

        - Distance: ``rec[i, j] > 0`` measures how distant frames ``i`` and ``j`` are.  This is also
          known as a (sparse) self-distance matrix.

    The general term *recurrence matrix* can refer to any of the three forms above.

    Parameters
    ----------
    data : np.ndarray [shape=(..., d, n)]
        A feature matrix.
        If the data has more than two dimensions (e.g., for multi-channel inputs),
        the leading dimensions are flattened prior to comparison.
        For example, a stereo input with shape `(2, d, n)` is
        automatically reshaped to `(2 * d, n)`.

    k : int > 0 [scalar] or None
        the number of nearest-neighbors for each sample

        Default: ``k = 2 * ceil(sqrt(t - 2 * width + 1))``,
        or ``k = 2`` if ``t <= 2 * width + 1``

    width : int >= 1 [scalar]
        only link neighbors ``(data[..., i], data[..., j])``
        if ``|i - j| >= width``

        ``width`` cannot exceed the length of the data.

    metric : str
        Distance metric to use for nearest-neighbor calculation.

        See `sklearn.neighbors.NearestNeighbors` for details.

    sym : bool [scalar]
        set ``sym=True`` to only link mutual nearest-neighbors

    sparse : bool [scalar]
        if False, returns a dense type (ndarray)
        if True, returns a sparse type (scipy.sparse.csc_matrix)

    mode : str, {'connectivity', 'distance', 'affinity'}
        If 'connectivity', a binary connectivity matrix is produced.

        If 'distance', then a non-zero entry contains the distance between
        points.

        If 'affinity', then non-zero entries are mapped to
        ``exp( - distance(i, j) / bandwidth)`` where ``bandwidth`` is
        as specified below.

    bandwidth : None, float > 0, ndarray, or str
        str options include ``{'med_k_scalar', 'mean_k', 'gmean_k', 'mean_k_avg', 'gmean_k_avg', 'mean_k_avg_and_pair'}``

        If ndarray is supplied, use ndarray as bandwidth for each i,j pair.

        If using ``mode='affinity'``, the ``bandwidth`` option can be used to set the
        bandwidth on the affinity kernel.

        If no value is provided or ``None``, default to ``'med_k_scalar'``.

        If ``bandwidth='med_k_scalar'``, a scalar bandwidth is set to the median distance
        of the k-th nearest neighbor for all samples.

        If ``bandwidth='mean_k'``, bandwidth is estimated for each sample-pair (i, j) by taking the
        arithmetic mean between distances to the k-th nearest neighbor for sample i and sample j.

        If ``bandwidth='gmean_k'``, bandwidth is estimated for each sample-pair (i, j) by taking the
        geometric mean between distances to the k-th nearest neighbor for sample i and j [#z]_.

        If ``bandwidth='mean_k_avg'``, bandwidth is estimated for each sample-pair (i, j) by taking the
        arithmetic mean between the average distances to the first k-th nearest neighbors for
        sample i and sample j.
        This is similar to the approach in Wang et al. (2014) [#w]_ but does not include the distance
        between i and j.

        If ``bandwidth='gmean_k_avg'``, bandwidth is estimated for each sample-pair (i, j) by taking the
        geometric mean between the average distances to the first k-th nearest neighbors for
        sample i and sample j.

        If ``bandwidth='mean_k_avg_and_pair'``, bandwidth is estimated for each sample-pair (i, j) by
        taking the arithmetic mean between three terms: the average distances to the first
        k-th nearest neighbors for sample i and sample j respectively, as well as
        the distance between i and j.
        This is similar to the approach in Wang et al. (2014). [#w]_

        .. [#z] Zelnik-Manor, Lihi, and Pietro Perona. (2004).
            "Self-tuning spectral clustering." Advances in neural information processing systems 17.

        .. [#w] Wang, Bo, et al. (2014).
            "Similarity network fusion for aggregating data types on a genomic scale." Nat Methods 11, 333–337.
            https://doi.org/10.1038/nmeth.2810

    self : bool
        If ``True``, then the main diagonal is populated with self-links:
        0 if ``mode='distance'``, and 1 otherwise.

        If ``False``, the main diagonal is left empty.

    axis : int
        The axis along which to compute recurrence.
        By default, the last index (-1) is taken.

    full : bool
        If using ``mode ='affinity'`` or ``mode='distance'``, this option can be used to compute
        the full affinity or distance matrix as opposed a sparse matrix with only none-zero terms
        for the first k-neighbors of each sample.
        This option has no effect when using ``mode='connectivity'``.

        When using ``mode='distance'``, setting ``full=True`` will ignore ``k`` and ``width``.
        When using ``mode='affinity'``, setting ``full=True`` will use ``k`` exclusively for
        bandwidth estimation, and ignore ``width``.

    Returns
    -------
    rec : np.ndarray or scipy.sparse.csc_matrix, [shape=(t, t)]
        Recurrence matrix

    See Also
    --------
    sklearn.neighbors.NearestNeighbors
    scipy.spatial.distance.cdist
    librosa.feature.stack_memory
    recurrence_to_lag

    Notes
    -----
    This function caches at level 30.

    Examples
    --------
    Find nearest neighbors in CQT space

    >>> y, sr = librosa.load(librosa.ex('nutcracker'))
    >>> hop_length = 1024
    >>> chroma = librosa.feature.chroma_cqt(y=y, sr=sr, hop_length=hop_length)
    >>> # Use time-delay embedding to get a cleaner recurrence matrix
    >>> chroma_stack = librosa.feature.stack_memory(chroma, n_steps=10, delay=3)
    >>> R = librosa.segment.recurrence_matrix(chroma_stack)

    Or fix the number of nearest neighbors to 5

    >>> R = librosa.segment.recurrence_matrix(chroma_stack, k=5)

    Suppress neighbors within +- 7 frames

    >>> R = librosa.segment.recurrence_matrix(chroma_stack, width=7)

    Use cosine similarity instead of Euclidean distance

    >>> R = librosa.segment.recurrence_matrix(chroma_stack, metric='cosine')

    Require mutual nearest neighbors

    >>> R = librosa.segment.recurrence_matrix(chroma_stack, sym=True)

    Use an affinity matrix instead of binary connectivity

    >>> R_aff = librosa.segment.recurrence_matrix(chroma_stack, metric='cosine',
    ...                                           mode='affinity')

    Plot the feature and recurrence matrices

    >>> import matplotlib.pyplot as plt
    >>> fig, ax = plt.subplots(ncols=2, sharex=True, sharey=True)
    >>> imgsim = librosa.display.specshow(R, x_axis='s', y_axis='s',
    ...                          hop_length=hop_length, ax=ax[0])
    >>> ax[0].set(title='Binary recurrence (symmetric)')
    >>> imgaff = librosa.display.specshow(R_aff, x_axis='s', y_axis='s',
    ...                          hop_length=hop_length, cmap='magma_r', ax=ax[1])
    >>> ax[1].set(title='Affinity recurrence')
    >>> ax[1].label_outer()
    >>> fig.colorbar(imgsim, ax=ax[0], orientation='horizontal', ticks=[0, 1])
    >>> fig.colorbar(imgaff, ax=ax[1], orientation='horizontal')
    r   r1   r2   r3   r   r:   zDwidth={} must be at least 1 and at most (data.shape[{}] - 1) // 2={}r5   r8   r9   Nr/   r;   r<   r?   r7   r6   r   g        ) rA   rB   rE   rD   rF   r	   formatrH   rI   rJ   rK   rL   rM   rG   rN   rO   rP   rQ   rR   setdiagrS   rT   rU   minimumr\   rV   rW   rX   rY   r!   rZ   r[   )r!   r   rg   r   rh   r   r   r   ri   rj   r    tr_   r`   ra   recdiagrc   rd   re   rf   s                        r(   r   r     s   P =D ;tT1%%D
1A<<Bs<++DqyyEa!e\))RYYta!e\ 
 
 	
 ;;;; ; ; ;
 
 	
 	yAI 122333AA K ''
00AE1q5y=11&F 1 
 
  
 
 
00AE1q5y=11&G 1 
 


 GGDMMM z


H

-
-
3
3
5
5C  5&1*e,, 	! 	!DKK4     q 	  	 AFNN$$Q'E 
3q%x=#8#8#:#:;;<Q?C  C3qrr7
OO >!!KKNNNNZ KKOOOA  ! kk#%  
))++C~jj			 "%A,S)[IIfSXm);<== %C kkmmJs   49D. .AE43E4_ArrayOrSparseMatrix)bound)padrj   ru   ry   c                   t          j        |          }| j        dk    s| j        d         | j        d         k    rt	          d| j                   t
          j                            |           }|r| j        }| j        |         }|r|r`t          j	        ddgg| j
                                      |d          }|dk    rd}nd}t
          j                            || |          } n;t          j        d	d	g          }d|g|d|z
  d
d
f<   t          j        | |d          } t          j        | d|          }|r|                    |          }|S )u	  Convert a recurrence matrix into a lag matrix.

        ``lag[i, j] == rec[i+j, j]``

    This transformation turns diagonal structures in the recurrence matrix
    into horizontal structures in the lag matrix.
    These horizontal structures can be used to infer changes in the repetition
    structure of a piece, e.g., the beginning of a new section as done in [#]_.

    .. [#] Serra, J., Müller, M., Grosche, P., & Arcos, J. L. (2014).
           Unsupervised music structure annotation by time series structure
           features and segment similarity.
           IEEE Transactions on Multimedia, 16(5), 1229-1240.

    Parameters
    ----------
    rec : np.ndarray, or scipy.sparse.spmatrix [shape=(n, n)]
        A (binary) recurrence matrix, as returned by `recurrence_matrix`

    pad : bool
        If False, ``lag`` matrix is square, which is equivalent to
        assuming that the signal repeats itself indefinitely.

        If True, ``lag`` is padded with ``n`` zeros, which eliminates
        the assumption of repetition.

    axis : int
        The axis to keep as the ``time`` axis.
        The alternate axis will be converted to lag coordinates.

    Returns
    -------
    lag : np.ndarray
        The recurrence matrix in (lag, time) (if ``axis=1``)
        or (time, lag) (if ``axis=0``) coordinates

    Raises
    ------
    ParameterError : if ``rec`` is non-square

    See Also
    --------
    recurrence_matrix
    lag_to_recurrence
    util.shear

    Examples
    --------
    >>> y, sr = librosa.load(librosa.ex('nutcracker'))
    >>> hop_length = 1024
    >>> chroma = librosa.feature.chroma_cqt(y=y, sr=sr, hop_length=hop_length)
    >>> chroma_stack = librosa.feature.stack_memory(chroma, n_steps=10, delay=3)
    >>> recurrence = librosa.segment.recurrence_matrix(chroma_stack)
    >>> lag_pad = librosa.segment.recurrence_to_lag(recurrence, pad=True)
    >>> lag_nopad = librosa.segment.recurrence_to_lag(recurrence, pad=False)

    >>> import matplotlib.pyplot as plt
    >>> fig, ax = plt.subplots(nrows=2, sharex=True)
    >>> librosa.display.specshow(lag_pad, x_axis='time', y_axis='lag',
    ...                          hop_length=hop_length, ax=ax[0])
    >>> ax[0].set(title='Lag (zero-padded)')
    >>> ax[0].label_outer()
    >>> librosa.display.specshow(lag_nopad, x_axis='time', y_axis='lag',
    ...                          hop_length=hop_length, ax=ax[1])
    >>> ax[1].set(title='Lag (no padding)')
    r:   r   r   z$non-square recurrence matrix shape: )dtypecsrcsc)rq   )r   r   Nconstantrp   r1   factorrj   )rA   absndimrD   r	   scipyr   issparserq   asarrayr{   rE   kronarrayry   r   shearasformat)	ru   ry   rj   r   fmtrt   paddingrec_fmtlags	            r(   r   r     sd   J 6$<<D
x1}}	!	!44OCIOOPPP\""3''F j	$A
 8 	8j1a&;;;DDT1MMGqyy,##GS#AACCh/00G&'VGQXM"&gJ777C $
3r E E EC   ll3Jr*   rj   r   c                   |dvrt          d|           t          j        |          }| j        dk    s>| j        d         | j        d         k    r9| j        d|z
           d| j        |         z  k    rt          d| j                   | j        |         }t          j        | d|          }t          d          g|j        z  }t          |          |d|z
  <   |t          |                   }|S )	a  Convert a lag matrix into a recurrence matrix.

    Parameters
    ----------
    lag : np.ndarray or scipy.sparse.spmatrix
        A lag matrix, as produced by ``recurrence_to_lag``
    axis : int
        The axis corresponding to the time dimension.
        The alternate axis will be interpreted in lag coordinates.

    Returns
    -------
    rec : np.ndarray or scipy.sparse.spmatrix [shape=(n, n)]
        A recurrence matrix in (time, time) coordinates
        For sparse matrices, format will match that of ``lag``.

    Raises
    ------
    ParameterError : if ``lag`` does not have the correct shape

    See Also
    --------
    recurrence_to_lag

    Examples
    --------
    >>> y, sr = librosa.load(librosa.ex('nutcracker'))
    >>> hop_length = 1024
    >>> chroma = librosa.feature.chroma_cqt(y=y, sr=sr, hop_length=hop_length)
    >>> chroma_stack = librosa.feature.stack_memory(chroma, n_steps=10, delay=3)
    >>> recurrence = librosa.segment.recurrence_matrix(chroma_stack)
    >>> lag_pad = librosa.segment.recurrence_to_lag(recurrence, pad=True)
    >>> lag_nopad = librosa.segment.recurrence_to_lag(recurrence, pad=False)
    >>> rec_pad = librosa.segment.lag_to_recurrence(lag_pad)
    >>> rec_nopad = librosa.segment.lag_to_recurrence(lag_nopad)

    >>> import matplotlib.pyplot as plt
    >>> fig, ax = plt.subplots(nrows=2, ncols=2, sharex=True)
    >>> librosa.display.specshow(lag_pad, x_axis='s', y_axis='lag',
    ...                          hop_length=hop_length, ax=ax[0, 0])
    >>> ax[0, 0].set(title='Lag (zero-padded)')
    >>> ax[0, 0].label_outer()
    >>> librosa.display.specshow(lag_nopad, x_axis='s', y_axis='time',
    ...                          hop_length=hop_length, ax=ax[0, 1])
    >>> ax[0, 1].set(title='Lag (no padding)')
    >>> ax[0, 1].label_outer()
    >>> librosa.display.specshow(rec_pad, x_axis='s', y_axis='time',
    ...                          hop_length=hop_length, ax=ax[1, 0])
    >>> ax[1, 0].set(title='Recurrence (with padding)')
    >>> librosa.display.specshow(rec_nopad, x_axis='s', y_axis='time',
    ...                          hop_length=hop_length, ax=ax[1, 1])
    >>> ax[1, 1].set(title='Recurrence (without padding)')
    >>> ax[1, 1].label_outer()
    )r   r   r1   zInvalid target axis: r:   r   r   zInvalid lag matrix shape: r   N)	r	   rA   r   r   rD   r   r   slicetuple)r   rj   rt   ru   	sub_slice	rec_slices         r(   r   r   #  s    r :;T;;<<<6$<<D
x1}}	!	!$$1t8)<CIdO@S)S)SE#)EEFFF 		$A
*S$
/
/
/Ct(I((Ia$h&)%	*:*:&;Ir*   _Ffunctionindexc                 2    fd}t          ||           S )a
  Apply a filter in the time-lag domain.

    This is primarily useful for adapting image filters to operate on
    `recurrence_to_lag` output.

    Using `timelag_filter` is equivalent to the following sequence of
    operations:

    >>> data_tl = librosa.segment.recurrence_to_lag(data)
    >>> data_filtered_tl = function(data_tl)
    >>> data_filtered = librosa.segment.lag_to_recurrence(data_filtered_tl)

    Parameters
    ----------
    function : callable
        The filtering function to wrap, e.g., `scipy.ndimage.median_filter`
    pad : bool
        Whether to zero-pad the structure feature matrix
    index : int >= 0
        If ``function`` accepts input data as a positional argument, it should be
        indexed by ``index``

    Returns
    -------
    wrapped_function : callable
        A new filter function which applies in time-lag space rather than
        time-time space.

    Examples
    --------
    Apply a 31-bin median filter to the diagonal of a recurrence matrix.
    With default, parameters, this corresponds to a time window of about
    0.72 seconds.

    >>> y, sr = librosa.load(librosa.ex('nutcracker'), duration=30)
    >>> chroma = librosa.feature.chroma_cqt(y=y, sr=sr)
    >>> chroma_stack = librosa.feature.stack_memory(chroma, n_steps=3, delay=3)
    >>> rec = librosa.segment.recurrence_matrix(chroma_stack)
    >>> from scipy.ndimage import median_filter
    >>> diagonal_median = librosa.segment.timelag_filter(median_filter)
    >>> rec_filtered = diagonal_median(rec, size=(1, 31), mode='mirror')

    Or with affinity weights

    >>> rec_aff = librosa.segment.recurrence_matrix(chroma_stack, mode='affinity')
    >>> rec_aff_fil = diagonal_median(rec_aff, size=(1, 31), mode='mirror')

    >>> import matplotlib.pyplot as plt
    >>> fig, ax = plt.subplots(nrows=2, ncols=2, sharex=True, sharey=True)
    >>> librosa.display.specshow(rec, y_axis='s', x_axis='s', ax=ax[0, 0])
    >>> ax[0, 0].set(title='Raw recurrence matrix')
    >>> ax[0, 0].label_outer()
    >>> librosa.display.specshow(rec_filtered, y_axis='s', x_axis='s', ax=ax[0, 1])
    >>> ax[0, 1].set(title='Filtered recurrence matrix')
    >>> ax[0, 1].label_outer()
    >>> librosa.display.specshow(rec_aff, x_axis='s', y_axis='s',
    ...                          cmap='magma_r', ax=ax[1, 0])
    >>> ax[1, 0].set(title='Raw affinity matrix')
    >>> librosa.display.specshow(rec_aff_fil, x_axis='s', y_axis='s',
    ...                          cmap='magma_r', ax=ax[1, 1])
    >>> ax[1, 1].set(title='Filtered affinity matrix')
    >>> ax[1, 1].label_outer()
    c                     t          |          }t          |                   |<    | |i |}t          |          S )z$Wrap the filter with lag conversions)ry   )listr   r   )	wrapped_fargskwargsresultr   ry   s       r(   __my_filterz#timelag_filter.<locals>.__my_filter  sP     Dzz'U===U D+F++ !(((r*   r   )r   ry   r   r   s    `` r(   r   r   t  s5    @) ) ) ) ) ) [(+++r*      )
n_segmentsrj   framesr   c                   t          j        |d| j        |         d          }|dk     rt          d          g }t	          d          g| j        z  }t          |dd         |dd                   D ]d\  }}t	          ||          ||<   |                    |t          | t          |                   t          ||z
  |          |          z              et          j        |          S )	ax	  Sub-divide a segmentation by feature clustering.

    Given a set of frame boundaries (``frames``), and a data matrix (``data``),
    each successive interval defined by ``frames`` is partitioned into
    ``n_segments`` by constrained agglomerative clustering.

    .. note::
        If an interval spans fewer than ``n_segments`` frames, then each
        frame becomes a sub-segment.

    Parameters
    ----------
    data : np.ndarray
        Data matrix to use in clustering
    frames : np.ndarray [shape=(n_boundaries,)], dtype=int, non-negative]
        Array of beat or segment boundaries, as provided by
        `librosa.beat.beat_track`,
        `librosa.onset.onset_detect`,
        or `agglomerative`.
    n_segments : int > 0
        Maximum number of frames to sub-divide each interval.
    axis : int
        Axis along which to apply the segmentation.
        By default, the last index (-1) is taken.

    Returns
    -------
    boundaries : np.ndarray [shape=(n_subboundaries,)]
        List of sub-divided segment boundaries

    See Also
    --------
    agglomerative : Temporal segmentation
    librosa.onset.onset_detect : Onset detection
    librosa.beat.beat_track : Beat tracking

    Notes
    -----
    This function caches at level 30.

    Examples
    --------
    Load audio, detect beat frames, and subdivide in twos by CQT

    >>> y, sr = librosa.load(librosa.ex('choice'), duration=10)
    >>> tempo, beats = librosa.beat.beat_track(y=y, sr=sr, hop_length=512)
    >>> beat_times = librosa.frames_to_time(beats, sr=sr, hop_length=512)
    >>> cqt = np.abs(librosa.cqt(y, sr=sr, hop_length=512))
    >>> subseg = librosa.segment.subsegment(cqt, beats, n_segments=2)
    >>> subseg_t = librosa.frames_to_time(subseg, sr=sr, hop_length=512)

    >>> import matplotlib.pyplot as plt
    >>> fig, ax = plt.subplots()
    >>> librosa.display.specshow(librosa.amplitude_to_db(cqt,
    ...                                                  ref=np.max),
    ...                          y_axis='cqt_hz', x_axis='time', ax=ax)
    >>> lims = ax.get_ylim()
    >>> ax.vlines(beat_times, lims[0], lims[1], color='lime', alpha=0.9,
    ...            linewidth=2, label='Beats')
    >>> ax.vlines(subseg_t, lims[0], lims[1], color='linen', linestyle='--',
    ...            linewidth=1.5, alpha=0.5, label='Sub-beats')
    >>> ax.legend()
    >>> ax.set(title='CQT + Beat and sub-beat markers')
    r   T)x_minx_maxry   r   z%n_segments must be a positive integerNr1   r   )r   
fix_framesrD   r	   r   r   zipextendr   r   rG   rA   r   )r!   r   r   rj   
boundaries
idx_slices	seg_startseg_ends           r(   r   r     s   H _V1DJt4D$OOOFA~~DEEEJ++*J!&"+vabbz:: 
 
	7 G44
4U:&&'Wy-@*)M)MTX  	
 	
 	
 	
 8Jr*   )	clustererrj   r   c          
      |   t          j        |           } t          j        | |d          } | j        d         }|                     |dfd          } |St
          j        j                            |dd          }t
          j	        
                    ||t          j                  }|                    |            dg}|                    t          dt          j        t          j        |j                            d                             t(                    z                        t          j        |          S )	a  Bottom-up temporal segmentation.

    Use a temporally-constrained agglomerative clustering routine to partition
    ``data`` into ``k`` contiguous segments.

    Parameters
    ----------
    data : np.ndarray
        data to cluster
    k : int > 0 [scalar]
        number of segments to produce
    clusterer : sklearn.cluster.AgglomerativeClustering, optional
        An optional AgglomerativeClustering object.
        If `None`, a constrained Ward object is instantiated.
    axis : int
        axis along which to cluster.
        By default, the last axis (-1) is chosen.

    Returns
    -------
    boundaries : np.ndarray [shape=(k,)]
        left-boundaries (frame numbers) of detected segments. This
        will always include `0` as the first left-boundary.

    See Also
    --------
    sklearn.cluster.AgglomerativeClustering

    Examples
    --------
    Cluster by chroma similarity, break into 20 segments

    >>> y, sr = librosa.load(librosa.ex('nutcracker'), duration=15)
    >>> chroma = librosa.feature.chroma_cqt(y=y, sr=sr)
    >>> bounds = librosa.segment.agglomerative(chroma, 20)
    >>> bound_times = librosa.frames_to_time(bounds, sr=sr)
    >>> bound_times
    array([ 0.   ,  0.65 ,  1.091,  1.927,  2.438,  2.902,  3.924,
            4.783,  5.294,  5.712,  6.13 ,  7.314,  8.522,  8.916,
            9.66 , 10.844, 11.238, 12.028, 12.492, 14.095])

    Plot the segmentation over the chromagram

    >>> import matplotlib.pyplot as plt
    >>> import matplotlib.transforms as mpt
    >>> fig, ax = plt.subplots()
    >>> trans = mpt.blended_transform_factory(
    ...             ax.transData, ax.transAxes)
    >>> librosa.display.specshow(chroma, y_axis='chroma', x_axis='time', ax=ax)
    >>> ax.vlines(bound_times, 0, 1, color='linen', linestyle='--',
    ...           linewidth=2, alpha=0.9, label='Segment boundaries',
    ...           transform=trans)
    >>> ax.legend()
    >>> ax.set(title='Power spectrogram')
    r   r1   r2   r3   Nr   )n_xn_yn_z)
n_clustersr/   memory)rA   rB   rE   rD   rF   rK   feature_extractionimagegrid_to_graphclusterAgglomerativeClusteringr   r   rO   r   r   rS   difflabels_rX   rJ   r   )r!   r   r   rj   r^   gridr   s          r(   r   r     s   ~ =D ;tT1%%D 	
1A<<Bs<++D)/==!PQ=RR O;;tEL < 
 
	
 MM$ Jd1rz"')2C*D*DEEaHOOPSTTTUUVVV:j!!!r*   hanng       @   )window	max_ratio	min_ratio	n_filters	zero_meanclipRr^   r   r   r   r   r   r   r   c          	      4   |d|z  }n||k    rt          d| d|           d}	t          j        t          j        |          t          j        |          |d          D ]}
t	          |||
|          }dg| j        z  }|j        |d	d<   t          j        ||          }|	t          j	        j
        | |fi |}	\t          j        |	t          j	        j
        | |fi ||	
           |rt          j        |	dd|	
           t          j        |	          S )u9  Multi-angle path enhancement for self- and cross-similarity matrices.

    This function convolves multiple diagonal smoothing filters with a self-similarity (or
    recurrence) matrix R, and aggregates the result by an element-wise maximum.

    Technically, the output is a matrix R_smooth such that::

        R_smooth[i, j] = max_theta (R * filter_theta)[i, j]

    where `*` denotes 2-dimensional convolution, and ``filter_theta`` is a smoothing filter at
    orientation theta.

    This is intended to provide coherent temporal smoothing of self-similarity matrices
    when there are changes in tempo.

    Smoothing filters are generated at evenly spaced orientations between min_ratio and
    max_ratio.

    This function is inspired by the multi-angle path enhancement of [#]_, but differs by
    modeling tempo differences in the space of similarity matrices rather than re-sampling
    the underlying features prior to generating the self-similarity matrix.

    .. [#] Müller, Meinard and Frank Kurth.
            "Enhancing similarity matrices for music audio analysis."
            2006 IEEE International Conference on Acoustics Speech and Signal Processing Proceedings.
            Vol. 5. IEEE, 2006.

    .. note:: if using recurrence_matrix to construct the input similarity matrix, be sure to include the main
              diagonal by setting ``self=True``.  Otherwise, the diagonal will be suppressed, and this is likely to
              produce discontinuities which will pollute the smoothing filter response.

    Parameters
    ----------
    R : np.ndarray
        The self- or cross-similarity matrix to be smoothed.
        Note: sparse inputs are not supported.

        If the recurrence matrix is multi-dimensional, e.g. `shape=(c, n, n)`,
        then enhancement is conducted independently for each leading channel.

    n : int > 0
        The length of the smoothing filter

    window : window specification
        The type of smoothing filter to use.  See `filters.get_window` for more information
        on window specification formats.

    max_ratio : float > 0
        The maximum tempo ratio to support

    min_ratio : float > 0
        The minimum tempo ratio to support.
        If not provided, it will default to ``1/max_ratio``

    n_filters : int >= 1
        The number of different smoothing filters to use, evenly spaced
        between ``min_ratio`` and ``max_ratio``.

        If ``min_ratio = 1/max_ratio`` (the default), using an odd number
        of filters will ensure that the main diagonal (ratio=1) is included.

    zero_mean : bool
        By default, the smoothing filters are non-negative and sum to one (i.e. are averaging
        filters).

        If ``zero_mean=True``, then the smoothing filters are made to sum to zero by subtracting
        a constant value from the non-diagonal coordinates of the filter.  This is primarily
        useful for suppressing blocks while enhancing diagonals.

    clip : bool
        If True, the smoothed similarity matrix will be thresholded at 0, and will not contain
        negative entries.

    **kwargs : additional keyword arguments
        Additional arguments to pass to `scipy.ndimage.convolve`

    Returns
    -------
    R_smooth : np.ndarray, shape=R.shape
        The smoothed self- or cross-similarity matrix

    See Also
    --------
    librosa.filters.diagonal_filter
    recurrence_matrix

    Examples
    --------
    Use a 51-frame diagonal smoothing filter to enhance paths in a recurrence matrix

    >>> y, sr = librosa.load(librosa.ex('nutcracker'))
    >>> hop_length = 2048
    >>> chroma = librosa.feature.chroma_cqt(y=y, sr=sr, hop_length=hop_length)
    >>> chroma_stack = librosa.feature.stack_memory(chroma, n_steps=10, delay=3)
    >>> rec = librosa.segment.recurrence_matrix(chroma_stack, mode='affinity', self=True)
    >>> rec_smooth = librosa.segment.path_enhance(rec, 51, window='hann', n_filters=7)

    Plot the recurrence matrix before and after smoothing

    >>> import matplotlib.pyplot as plt
    >>> fig, ax = plt.subplots(ncols=2, sharex=True, sharey=True)
    >>> img = librosa.display.specshow(rec, x_axis='s', y_axis='s',
    ...                          hop_length=hop_length, ax=ax[0])
    >>> ax[0].set(title='Unfiltered recurrence')
    >>> imgpe = librosa.display.specshow(rec_smooth, x_axis='s', y_axis='s',
    ...                          hop_length=hop_length, ax=ax[1])
    >>> ax[1].set(title='Multi-angle enhanced recurrence')
    >>> ax[1].label_outer()
    >>> fig.colorbar(img, ax=ax[0], orientation='horizontal')
    >>> fig.colorbar(imgpe, ax=ax[1], orientation='horizontal')
    Ng      ?z
min_ratio=z cannot exceed max_ratio=r:   )numbase)sloper   r   )outr   )r	   rA   logspacelog2r   r   rD   rF   r   ndimageconvolvemaximumr   
asanyarray)r   r^   r   r   r   r   r   r   r   R_smoothratiokernelrD   s                r(   r   r   v  sf   v )O			Y		HHHYHH
 
 	
 H
	BGI..IA     !%9MMM af\bcc
FE**}-aBB6BBHH J%-0FEEfEE8      1
!Tx0000="""r*   bw_modec                 \	   t          |t          j                  r|}|j        | j        k    r t	          d|j         d| j         d          |dk                                    rt	          d          t          j        ||                                                    S t          |t          t          f          r*t          |          }|dk    rt	          d| d          |S |d}|d	vrt	          d
| d          | j        d         }g }t          |          D ]}| |                                         d         }t          |          dk    rJ|dvrt	          d| d          |                    t          j        t          j        g                     t          j        | ||f                                         d                   d |         }	|                    |	           t          j        d |D                       }
t          j        d |D                       }|dk    rVt          j        t          j        |
                    st	          d          t          t          j        |
                    S |dv rt          j        | j                  }t          j        | j                  }t          |          D ]v}|
|         || j        |         | j        |dz            <   | j        | j        |         | j        |dz                     }|
|         || j        |         | j        |dz            <   w|dk    rt          j        ||z   dz            }n |dk    rt          j        ||z  dz            }|dv r"t          j        | j                  }t          j        | j                  }t          |          D ]v}||         || j        |         | j        |dz            <   | j        | j        |         | j        |dz                     }||         || j        |         | j        |dz            <   w|dk    rt          j        ||z   dz            }nI|dk    rt          j        ||z  dz            }n(|dk    r"t          j        ||z   | j        z   dz            }|S )Nz Invalid matrix bandwidth shape: z.Should be .r   z9Invalid bandwidth. All entries must be strictly positive.zInvalid scalar bandwidth=z. Must be strictly positive.med_k_scalar)r   mean_kgmean_k
mean_k_avggmean_k_avgmean_k_avg_and_pairzInvalid bandwidth='z'. Must be either a positive scalar or one of ['med_k_scalar', 'mean_k', 'gmean_k', 'mean_k_avg', 'gmean_k_avg', 'mean_k_avg_and_pair']r   )r   zThe sample at time point z has no neighborsc                     g | ]
}|d          S )r1   r&   .0distss     r(   
<listcomp>z(__affinity_bandwidth.<locals>.<listcomp>\  s    ===%E"I===r*   c                 6    g | ]}t          j        |          S r&   )rA   meanr   s     r(   r   z(__affinity_bandwidth.<locals>.<listcomp>]  s     &M&M&M%rwu~~&M&M&Mr*   z-Cannot estimate bandwidth from an empty graph)r   r   r   r:   r   g      ?)r   r   r   r   r   r      )
isinstancerA   ndarrayrD   r	   anyr   rS   rJ   floatrR   lenappendnansortrU   r   isfinite	nanmedian
empty_liker!   indptrindices)ru   r   r   r   scalar_bandwidthrt   	knn_distsrc   rd   knn_dist_row	dist_to_kavg_dist_to_first_kssigma_i_datasigma_j_datarowcol_idxr   s                    r(   rZ   rZ     s    '2:&&  	?ci'' *9? * * Y* * *   N!! 	 K   x	#++--0111	Gc5\	*	*   >>q   Z,<ZZZ         h' h h h
 
 	
 		!AI1XX + +A  #u::??...$%U%U%U%UVVV   26(!3!34444 73q%x=#8#8#:#:1#=>>rrBL\**** 
==9===>>I:&M&M9&M&M&MNN.  vbk),,-- 	R !PQQQR\),,---'''}SX..}SX..88 	U 	UCBKC.LC3:cAg+>>?k#*S/CJsQw4G"GHGBKGBTLC3:cAg+>>??h(L<71<==CC	!!(L<7C?@@CFFF}SX..}SX..88 	 	CBVCLC3:cAg+>>? k#*S/CJsQw4G"GHGBVCLC3:cAg+>>?? l""(L<71<==CC%%(L<7C?@@CC---(L<7#(BaGHHCJr*   )Tr   )6__doc__r   numpyrA   r   scipy.signalscipy.ndimagerK   sklearn.clustersklearn.feature_extractionsklearn.neighbors_cacher    r   filtersr   util.exceptionsr	   typingr
   r   r   r   r   r   typing_extensionsr   _typingr   r   __all__r   rJ   strrY   r   r   
csc_matrixr   spmatrixrw   r   r   r   r   r   r   r   r   r   r   
csr_matrixrZ   r&   r*   r(   <module>r     s_	   2                          ! ! ! !                 $ $ $ $ $ $ + + + + + + D D D D D D D D D D D D D D D D % % % % % % / / / / / / / /	 	 	 

  AE  
*j }	
  EN  bj-<=>  Z   
 

 AE  
*j }	
  DM  bj-<=>  \   
 R
 AE} } }
*}j} }	}
 } } } bj-<=>} } 2:u|../} } } }@ 
 AD  
* } 	
  
 DM  bj-<=>    \   
" 
  AD  
* } 	
  
 EN  bj-<=>    Z   
" R AEq q q
*q }q 	q
 q 
q q q bj-<=>q q q q 2:u|../q q q qh	 w%
EL4I(I"J    /3g g g	g'+g:=gg g g gV /1K K K	K(+KK K K K\ WT#s(+,,,M, M,R M,d M,# M,b M, M, M, M,` R?@bT  T  T 
*T  jT 9<T HKT ZT  T  T  T v DHW" W" W"
*W"
W" ?@	W"
 W" ZW" W" W" W"| !!%`# `# `#	z`#
`# 	`#
 `# `# `# `# `# `# Z`# `# `# `#Fm		 meBJs:;<m m 5"*	m m m m m mr*   