<commit_before>#!/usr/bin/env python
"""Spectrogram decomposition"""

import numpy as np
import scipy
import scipy.signal

import sklearn.decomposition

import librosa.core


def decompose(S, n_components=None, transformer=None):
    """Decompose the feature matrix with non-negative matrix factorization

    :parameters:
        - S : np.ndarray
            feature matrix (d-by-t)
        - n_components : int > 0 or None
            number of components, if None then all d components are used
        - transformer : any instance which implements fit_transform()
            If None, use sklearn.decomposition.NMF by default
            Otherwise, because of scikit-learn convention where the input data
            is (n_samples, n_features), NMF.fit_transform() should take S.T as
            input, and returns transformed S_new, where:
            ``S.T ~= S_new.dot(transformer.components_)``
            or equivalently:
            ``S ~= transformer.components_.T.dot(S_new.T)``

    :returns:
        - components: np.ndarray
            dictionary matrix (d-by-n_components)
        - activations: np.ndarray
            transformed matrix/activation matrix (n_components-by-t)

    """

    if transformer is None:
        transformer = sklearn.decomposition.NMF(n_components=n_components)
    activations = transformer.fit_transform(S.T)
    return (transformer.components_.T, activations.T)

def hpss(S, kernel_size=19, power=1.0, mask=False):
    """Median-filtering harmonic percussive separation

    :parameters:
      - S : np.ndarray
          input spectrogram. May be real (magnitude) or complex.

      - kernel_size : int or array_like (kernel_harmonic, kernel_percussive)
          kernel size for the median filters.
          If scalar, the same size is used for both harmonic and percussive.
          If array_like, the first value specifies the width of the harmonic filter,
          and the second value specifies the width of the percussive filter.

      - power : float
          Exponent for the Wiener filter

      - mask : boolean
          Return the masking matrices instead of components

    :returns:
      - harmonic : np.ndarray
          harmonic component (or mask)

      - percussive : np.ndarray
          percussive component (or mask)

      .. note:: harmonic + percussive = S

    .. note::
      - <NAME>. (2010). 
        Harmonic/percussive separation using median filtering.

    """
<commit_msg>bibtex ref for HPSS<commit_after>#!/usr/bin/env python
"""Spectrogram decomposition"""

import numpy as np
import scipy
import scipy.signal

import sklearn.decomposition

import librosa.core


def decompose(S, n_components=None, transformer=None):
    """Decompose the feature matrix with non-negative matrix factorization

    :parameters:
        - S : np.ndarray
            feature matrix (d-by-t)
        - n_components : int > 0 or None
            number of components, if None then all d components are used
        - transformer : any instance which implements fit_transform()
            If None, use sklearn.decomposition.NMF by default
            Otherwise, because of scikit-learn convention where the input data
            is (n_samples, n_features), NMF.fit_transform() should take S.T as
            input, and returns transformed S_new, where:
            ``S.T ~= S_new.dot(transformer.components_)``
            or equivalently:
            ``S ~= transformer.components_.T.dot(S_new.T)``

    :returns:
        - components: np.ndarray
            dictionary matrix (d-by-n_components)
        - activations: np.ndarray
            transformed matrix/activation matrix (n_components-by-t)

    """

    if transformer is None:
        transformer = sklearn.decomposition.NMF(n_components=n_components)
    activations = transformer.fit_transform(S.T)
    return (transformer.components_.T, activations.T)

def hpss(S, kernel_size=19, power=1.0, mask=False):
    """Median-filtering harmonic percussive separation

    :parameters:
      - S : np.ndarray
          input spectrogram. May be real (magnitude) or complex.

      - kernel_size : int or array_like (kernel_harmonic, kernel_percussive)
          kernel size for the median filters.
          If scalar, the same size is used for both harmonic and percussive.
          If array_like, the first value specifies the width of the harmonic filter,
          and the second value specifies the width of the percussive filter.

      - power : float
          Exponent for the Wiener filter

      - mask : boolean
          Return the masking matrices instead of components

    :returns:
      - harmonic : np.ndarray
          harmonic component (or mask)

      - percussive : np.ndarray
          percussive component (or mask)

      .. note:: harmonic + percussive = S

    .. note::
      @article{fitzgerald2010harmonic,
        title={Harmonic/percussive separation using median filtering},
        author={<NAME>},
        year={2010},
        publisher={Dublin Institute of Technology}}
    
    """

{'fraction_non_alphanumeric': 0.0798335974643423, 'fraction_numerical': 0.004358161648177496, 'mean_word_length': 2.4605894448252226, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, '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': '1638040', 'n_tokens_mistral': 1440, 'n_tokens_neox': 1354, 'n_words': 452}