<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Temporal segmentation
=====================

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

    recurrence_matrix
    recurrence_to_lag
    lag_to_recurrence
    timelag_filter

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

    agglomerative
    subsegment

Deprecated
----------
.. autosummary::
    :toctree: generated/

    structure_feature
"""

from decorator import decorator

import numpy as np
import scipy
import scipy.signal

import sklearn
import sklearn.cluster
import sklearn.feature_extraction

from . import cache
from . import util
from .util.exceptions import ParameterError

__all__ = ['recurrence_matrix',
           'recurrence_to_lag',
           'lag_to_recurrence',
           'timelag_filter',
           'agglomerative',
           'subsegment',
           # Deprecated functions
           'structure_feature']


@cache
def __band_infinite(n, width, v_in=0.0, v_out=np.inf, dtype=np.float32):
    '''Construct a square, banded matrix `X` where
    `X[i, j] == v_in` if `|i - j| <= width`
    `X[i, j] == v_out` if `|i - j| > width`

    This is used to suppress nearby links in `recurrence_matrix`.
    '''

    if width > n:
        raise ParameterError('width cannot exceed n')

    # Instantiate the matrix
    band = np.empty((n, n), dtype=dtype)

    # Fill the out-of-band values
    band.fill(v_out)

    # Fill the in-band values
    band[np.triu_indices_from(band, width)] = v_in
    band[np.tril_indices_from(band, -width)] = v_in

    return band


@cache
def recurrence_matrix(data, k=None, width=1, metric='sqeuclidean', sym=False):
    '''Compute the binary recurrence matrix from a time-series.

    `rec[i,j] == True` if (and only if) (`data[:,i]`, `data[:,j]`) are
    k-nearest-neighbors and `|i-j| >= width`


    Parameters
    ----------
    data : np.ndarray [shape=(d, t)]
        A feature matrix

    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`

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

        See `scipy.spatial.distance.cdist()` for details.

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

    Returns
    -------
    rec : np.ndarray [shape=(t,t), dtype=bool]
        Binary recurrence matrix

    See Also
    --------
    scipy.spatial.distance.cdist
    librosa.feature.stack_memory
    structure_feature

    Examples
    --------
    Find nearest neighbors in MFCC space

    >>> y, sr = librosa.load(librosa.util.example_audio_file())
    >>> mfcc = librosa.feature.mfcc(y=y, sr=sr)
    >>> R = librosa.segment.recurrence_matrix(mfcc)

    Or fix the number of nearest neighbors to 5

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

    Suppress neighbors within +- 7 samples

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

    Use cosine similarity instead of Euclidean distance

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

    Require mutual nearest neighbors

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

    Plot the feature and recurrence matrices

    >>> import matplotlib.pyplot as plt
    >>> plt.figure(figsize=(10, 6))
    >>> plt.subplot(1, 2, 1)
    >>> librosa.display.specshow(mfcc, x_axis='time')
    >>> plt.title('MFCC')
    >>> plt.subplot(1, 2, 2)
    >>> librosa.display.specshow(R, x_axis='time', y_axis='time',
    ...                          aspect='equal')
    >>> plt.title('MFCC recurrence (symmetric)')
    >>> plt.tight_layout()

    '''

    data = np.atleast_2d(data)

    t = data.shape[1]

    if width < 1:
        raise ParameterError('width must be at least 1')

    if k is None:
        if t > 2 * width + 1:
            k = 2 * np.ceil(np.sqrt(t - 2 * width + 1))
        else:
            k = 2

    k = int(k)

    # Build the distance matrix
    D = scipy.spatial.distance.cdist(data.T, data.T, metric=metric)

    # Max out the diagonal band
    D = D + __band_infinite(t, width)<commit_msg>#232 recurrence also supports target axis<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Temporal segmentation
=====================

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

    recurrence_matrix
    recurrence_to_lag
    lag_to_recurrence
    timelag_filter

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

    agglomerative
    subsegment

Deprecated
----------
.. autosummary::
    :toctree: generated/

    structure_feature
"""

from decorator import decorator

import numpy as np
import scipy
import scipy.signal

import sklearn
import sklearn.cluster
import sklearn.feature_extraction

from . import cache
from . import util
from .util.exceptions import ParameterError

__all__ = ['recurrence_matrix',
           'recurrence_to_lag',
           'lag_to_recurrence',
           'timelag_filter',
           'agglomerative',
           'subsegment',
           # Deprecated functions
           'structure_feature']


@cache
def __band_infinite(n, width, v_in=0.0, v_out=np.inf, dtype=np.float32):
    '''Construct a square, banded matrix `X` where
    `X[i, j] == v_in` if `|i - j| <= width`
    `X[i, j] == v_out` if `|i - j| > width`

    This is used to suppress nearby links in `recurrence_matrix`.
    '''

    if width > n:
        raise ParameterError('width cannot exceed n')

    # Instantiate the matrix
    band = np.empty((n, n), dtype=dtype)

    # Fill the out-of-band values
    band.fill(v_out)

    # Fill the in-band values
    band[np.triu_indices_from(band, width)] = v_in
    band[np.tril_indices_from(band, -width)] = v_in

    return band


@cache
def recurrence_matrix(data, k=None, width=1, metric='sqeuclidean', sym=False, axis=-1):
    '''Compute the binary recurrence matrix from a time-series.

    `rec[i,j] == True` if (and only if) (`data[:,i]`, `data[:,j]`) are
    k-nearest-neighbors and `|i-j| >= width`


    Parameters
    ----------
    data : np.ndarray 
        A feature matrix

    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`

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

        See `scipy.spatial.distance.cdist()` for details.

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

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

    Returns
    -------
    rec : np.ndarray [shape=(t,t), dtype=bool]
        Binary recurrence matrix

    See Also
    --------
    scipy.spatial.distance.cdist
    librosa.feature.stack_memory
    structure_feature

    Examples
    --------
    Find nearest neighbors in MFCC space

    >>> y, sr = librosa.load(librosa.util.example_audio_file())
    >>> mfcc = librosa.feature.mfcc(y=y, sr=sr)
    >>> R = librosa.segment.recurrence_matrix(mfcc)

    Or fix the number of nearest neighbors to 5

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

    Suppress neighbors within +- 7 samples

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

    Use cosine similarity instead of Euclidean distance

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

    Require mutual nearest neighbors

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

    Plot the feature and recurrence matrices

    >>> import matplotlib.pyplot as plt
    >>> plt.figure(figsize=(10, 6))
    >>> plt.subplot(1, 2, 1)
    >>> librosa.display.specshow(mfcc, x_axis='time')
    >>> plt.title('MFCC')
    >>> plt.subplot(1, 2, 2)
    >>> librosa.display.specshow(R, x_axis='time', y_axis='time',
    ...                          aspect='equal')
    >>> plt.title('MFCC recurrence (symmetric)')
    >>> plt.tight_layout()

    '''

    data = np.atleast_2d(data)

    # Swap observations to the first dimension and flatten the rest
    data = np.swapaxes(data, axis, 0)
    t = data.shape[0]
    data = data.reshape((t, -1))

    if width < 1:
        raise ParameterError('width must be at least 1')

    if k is None:
        if t > 2 * width + 1:
            k = 2 * np.ceil(np.sqrt(t - 2 * width + 1))
        else:
            k = 2

    k = int(k)

    # Build the distance matrix
    D = scipy.spatial.distance.cdist(data, data, metric=metric)

    # Max out the diagonal band
    D = D + __band_infinite(t, width)
{'fraction_non_alphanumeric': 0.14507887136191958, 'fraction_numerical': 0.008998000444345702, 'mean_word_length': 2.436259541984733, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 113, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2803306', 'n_tokens_mistral': 3121, 'n_tokens_neox': 2929, 'n_words': 801}