M = len(T)<EOL>eigval = <NUM_LIT:10><EOL>eigvalold = <NUM_LIT:1><EOL>eigvec  = numpy.zeros(M+<NUM_LIT:1>, dtype=complex)<EOL>for k in range(<NUM_LIT:0>,M+<NUM_LIT:1>):<EOL><INDENT>eigvec[k] = <NUM_LIT:1>+<NUM_LIT><EOL><DEDENT>it=<NUM_LIT:0><EOL>maxit = <NUM_LIT:15><EOL>while abs(eigvalold-eigval)>TOL*eigvalold and it<maxit:<EOL><INDENT>it=it+<NUM_LIT:1><EOL>eigvalold = eigval<EOL>eig = toeplitz.HERMTOEP(T0, T, eigvec)<EOL>SUM = <NUM_LIT:0><EOL>save =<NUM_LIT:0.>+<NUM_LIT><EOL>for k in range(<NUM_LIT:0>, M+<NUM_LIT:1>):<EOL><INDENT>SUM = SUM + eig[k].real**<NUM_LIT:2>+eig[k].imag**<NUM_LIT:2><EOL>save = save +eig[k]*eigvec[k].conjugate()<EOL><DEDENT>SUM=<NUM_LIT:1.>/SUM<EOL>eigval = save.real*SUM<EOL>for k in range(<NUM_LIT:0>,M+<NUM_LIT:1>):<EOL><INDENT>eigvec[k] = SUM * eig[k]<EOL><DEDENT><DEDENT>if it==maxit:<EOL><INDENT>print('<STR_LIT>' % maxit)<EOL><DEDENT>return eigval, eigvec<EOL>

Finds the minimum eigenvalue of a Hermitian Toeplitz matrix

    The classical power method is used together with a  fast  Toeplitz
    equation solution routine.  The eigenvector is normalized to unit length.

    :param T0: Scalar corresponding to real matrix element t(0)
    :param T: Array of  M  complex matrix elements t(1),...,t(M) C            from the left column of the Toeplitz matrix
    :param TOL: Real scalar tolerance; routine exits when [ EVAL(k) - EVAL(k-1) ]/EVAL(k-1) < TOL , where the index k denotes the iteration number.

    :return:
        * EVAL - Real scalar denoting the minimum eigenvalue of matrix
        * EVEC - Array of  M  complex eigenvector elements associated

    .. note::
     * External array T must be dimensioned >= M
     * array EVEC must be >= M+1
     *  Internal array E must be dimensioned >= M+1 .

     * **dependencies**
        *  :meth:`spectrum.toeplitz.HERMTOEP`


def create_window(N, name=None, **kargs):

if name is None:<EOL><INDENT>name = '<STR_LIT>'<EOL><DEDENT>name = name.lower()<EOL>assert name in list(window_names.keys()),"""<STR_LIT>"""% (name, window_names)<EOL>f = eval(window_names[name])<EOL>windows_with_parameters ={'<STR_LIT>': {'<STR_LIT>': eval(window_names['<STR_LIT>']).__defaults__[<NUM_LIT:0>]},<EOL>'<STR_LIT>': {'<STR_LIT>': eval(window_names['<STR_LIT>']).__defaults__[<NUM_LIT:0>]},<EOL>'<STR_LIT>': {'<STR_LIT>': eval(window_names['<STR_LIT>']).__defaults__[<NUM_LIT:0>]},<EOL>'<STR_LIT>': {'<STR_LIT>': eval(window_names['<STR_LIT>']).__defaults__[<NUM_LIT:0>]},<EOL>'<STR_LIT>': {'<STR_LIT>': eval(window_names['<STR_LIT>']).__defaults__[<NUM_LIT:0>]},<EOL>'<STR_LIT>': {'<STR_LIT>':eval(window_names['<STR_LIT>']).__defaults__[<NUM_LIT:0>]},<EOL>'<STR_LIT>': {'<STR_LIT:r>':eval(window_names['<STR_LIT>']).__defaults__[<NUM_LIT:0>]},<EOL>'<STR_LIT>': {'<STR_LIT>': eval(window_names['<STR_LIT>']).__defaults__[<NUM_LIT:0>]},<EOL>'<STR_LIT>': {'<STR_LIT>':<EOL>eval(window_names['<STR_LIT>']).__defaults__[<NUM_LIT:0>]},<EOL>'<STR_LIT>': {'<STR_LIT>': eval(window_names['<STR_LIT>']).__defaults__[<NUM_LIT:0>],<EOL>'<STR_LIT>': eval(window_names['<STR_LIT>']).__defaults__[<NUM_LIT:0>]},     <EOL>}<EOL>if name not in list(windows_with_parameters.keys()):<EOL><INDENT>if len(kargs) == <NUM_LIT:0>:<EOL><INDENT>w = f(N)<EOL><DEDENT>else:<EOL><INDENT>raise ValueError("""<STR_LIT>""")<EOL><DEDENT><DEDENT>elif name in list(windows_with_parameters.keys()):<EOL><INDENT>dargs = {}<EOL>for arg in list(kargs.keys()):<EOL><INDENT>try:<EOL><INDENT>default = windows_with_parameters[name][arg]<EOL><DEDENT>except:<EOL><INDENT>raise ValueError("""<STR_LIT>""" %(arg, name, list(windows_with_parameters[name].keys())))<EOL><DEDENT>dargs[arg] = kargs.get(arg, default)<EOL><DEDENT>w = f(N, **dargs)<EOL><DEDENT>return w<EOL>

r"""Returns the N-point window given a valid name

    :param int N: window size
    :param str name: window name (default is *rectangular*). Valid names
        are stored in :func:`~spectrum.window.window_names`.
    :param kargs: optional arguments are:

        * *beta*: argument of the :func:`window_kaiser` function (default is 8.6)
        * *attenuation*: argument of the :func:`window_chebwin` function (default is 50dB)
        * *alpha*: argument of the
            1. :func:`window_gaussian` function (default is 2.5)
            2. :func:`window_blackman` function (default is 0.16)
            3. :func:`window_poisson` function (default is 2)
            4. :func:`window_cauchy` function (default is 3)
        * *mode*: argument :func:`window_flattop` function (default is *symmetric*, can be *periodic*)
        * *r*: argument of the :func:`window_tukey` function (default is 0.5).

    The following windows have been simply wrapped from existing librairies like
    NumPy:

        * **Rectangular**: :func:`window_rectangle`,
        * **Bartlett** or Triangular: see :func:`window_bartlett`,
        * **Hanning** or Hann: see :func:`window_hann`,
        * **Hamming**: see :func:`window_hamming`,
        * **Kaiser**: see :func:`window_kaiser`,
        * **chebwin**: see :func:`window_chebwin`.

    The following windows have been implemented from scratch:

        * **Blackman**: See :func:`window_blackman`
        * **Bartlett-Hann** : see :func:`window_bartlett_hann`
        * **cosine or sine**: see :func:`window_cosine`
        * **gaussian**: see :func:`window_gaussian`
        * **Bohman**: see :func:`window_bohman`
        * **Lanczos or sinc**: see :func:`window_lanczos`
        * **Blackman Harris**: see :func:`window_blackman_harris`
        * **Blackman Nuttall**: see :func:`window_blackman_nuttall`
        * **Nuttall**: see :func:`window_nuttall`
        * **Tukey**: see :func:`window_tukey`
        * **Parzen**: see :func:`window_parzen`
        * **Flattop**: see :func:`window_flattop`
        * **Riesz**: see :func:`window_riesz`
        * **Riemann**: see :func:`window_riemann`
        * **Poisson**: see :func:`window_poisson`
        * **Poisson-Hanning**: see :func:`window_poisson_hanning`

    .. todo:: on request taylor, potter, Bessel, expo,
        rife-vincent, Kaiser-Bessel derived (KBD)

    .. plot::
        :width: 80%
        :include-source:

        from pylab import plot, legend
        from spectrum import create_window

        data = create_window(51, 'hamming')
        plot(data, label='hamming')
        data = create_window(51, 'kaiser')
        plot(data, label='kaiser')
        legend()

    .. plot::
        :width: 80%
        :include-source:

        from pylab import plot, log10, linspace, fft, clip
        from spectrum import create_window, fftshift

        A = fft(create_window(51, 'hamming'), 2048) / 25.5
        mag = abs(fftshift(A))
        freq = linspace(-0.5,0.5,len(A))
        response = 20 * log10(mag)
        mindB = -60
        response = clip(response,mindB,100)
        plot(freq, response)

    .. seealso:: :func:`window_visu`, :func:`Window`, :mod:`spectrum.dpss`


N = len(data)<EOL>return N * np.sum(data**<NUM_LIT:2>) / np.sum(data)**<NUM_LIT:2><EOL>

r"""Computes the equivalent noise bandwidth

    .. math:: ENBW = N \frac{\sum_{n=1}^{N} w_n^2}{\left(\sum_{n=1}^{N} w_n \right)^2}

    .. doctest::

        >>> from spectrum import create_window, enbw
        >>> w = create_window(64, 'rectangular')
        >>> enbw(w)
        1.0

    The following table contains the ENBW values for some of the
    implemented windows in this module (with N=16384). They have been
    double checked against litterature (Source: [Harris]_, [Marple]_).

    If not present, it means that it has not been checked.

    =================== ============ =============
    name                 ENBW        litterature
    =================== ============ =============
    rectangular         1.           1.
    triangle            1.3334       1.33
    Hann                1.5001       1.5
    Hamming             1.3629       1.36
    blackman            1.7268       1.73
    kaiser              1.7
    blackmanharris,4    2.004        2.
    riesz               1.2000       1.2
    riemann             1.32         1.3
    parzen              1.917        1.92
    tukey 0.25          1.102        1.1
    bohman              1.7858       1.79
    poisson 2           1.3130       1.3
    hanningpoisson 0.5  1.609        1.61
    cauchy              1.489        1.48
    lanczos             1.3
    =================== ============ =============


from scipy.special import iv as besselI<EOL>m = n - <NUM_LIT:1><EOL>k = arange(<NUM_LIT:0>, m)<EOL>k = <NUM_LIT> * beta / m * sqrt (k * (m - k))<EOL>w = besselI (<NUM_LIT:0>, k) / besselI (<NUM_LIT:0>, beta)<EOL>return w<EOL>

Independant Kaiser window

    For the definition of the Kaiser window, see A. V. Oppenheim & R. W. Schafer, "Discrete-Time Signal Processing".

    The continuous version of width n centered about x=0 is:

    .. note:: 2 times slower than scipy.kaiser


def window_visu(N=<NUM_LIT>, name='<STR_LIT>', **kargs):

<EOL>mindB = kargs.pop('<STR_LIT>', -<NUM_LIT:100>)<EOL>maxdB = kargs.pop('<STR_LIT>', None)<EOL>norm = kargs.pop('<STR_LIT>', True)<EOL>w = Window(N, name, **kargs)<EOL>w.plot_time_freq(mindB=mindB, maxdB=maxdB, norm=norm)<EOL>

A Window visualisation tool

    :param N: length of the window
    :param name: name of the window
    :param NFFT: padding used by the FFT
    :param mindB: the minimum frequency power in dB
    :param maxdB: the maximum frequency power in dB
    :param kargs: optional arguments passed to :func:`create_window`

    This function plot the window shape and its equivalent in the Fourier domain.

    .. plot::
        :width: 80%
        :include-source:

        from spectrum import window_visu
        window_visu(64, 'kaiser', beta=8.)


return ones(N)<EOL>

r"""Kaiser window

    :param N: window length

    .. plot::
        :width: 80%
        :include-source:

        from spectrum import window_visu
        window_visu(64, 'rectangle')


def window_kaiser(N, beta=<NUM_LIT>, method='<STR_LIT>'):

if N == <NUM_LIT:1>:<EOL><INDENT>return ones(<NUM_LIT:1>)<EOL><DEDENT>if method == '<STR_LIT>':<EOL><INDENT>from numpy import kaiser<EOL>return kaiser(N, beta)<EOL><DEDENT>else:<EOL><INDENT>return _kaiser(N, beta)<EOL><DEDENT>

r"""Kaiser window

    :param N: window length
    :param beta: kaiser parameter (default is 8.6)

    To obtain a Kaiser window that designs an FIR filter with
    sidelobe attenuation of :math:`\alpha` dB, use the following :math:`\beta` where
    :math:`\beta = \pi \alpha`.

    .. math::

        w_n = \frac{I_0\left(\pi\alpha\sqrt{1-\left(\frac{2n}{M}-1\right)^2}\right)} {I_0(\pi \alpha)}

    where

      * :math:`I_0` is the zeroth order Modified Bessel function of the first kind.
      * :math:`\alpha` is a real number that determines the shape of the
        window. It determines the trade-off between main-lobe width and side
        lobe level.
      * the length of the sequence is N=M+1.

    The Kaiser window can approximate many other windows by varying
    the :math:`\beta` parameter:

    ===== ========================
    beta  Window shape
    ===== ========================
    0     Rectangular
    5     Similar to a Hamming
    6     Similar to a Hanning
    8.6   Similar to a Blackman
    ===== ========================

    .. plot::
        :width: 80%
        :include-source:

        from pylab import plot, legend, xlim
        from spectrum import window_kaiser
        N = 64
        for beta in [1,2,4,8,16]:
            plot(window_kaiser(N, beta), label='beta='+str(beta))
        xlim(0,N)
        legend()

    .. plot::
        :width: 80%
        :include-source:

        from spectrum import window_visu
        window_visu(64, 'kaiser', beta=8.)

    .. seealso:: numpy.kaiser, :func:`spectrum.window.create_window`


a0 = (<NUM_LIT:1.> - alpha)/<NUM_LIT><EOL>a1 = <NUM_LIT:0.5><EOL>a2 = alpha/<NUM_LIT><EOL>if (N == <NUM_LIT:1>):<EOL><INDENT>win = array([<NUM_LIT:1.>])<EOL><DEDENT>else:<EOL><INDENT>k = arange(<NUM_LIT:0>, N)/float(N-<NUM_LIT:1.>)<EOL>win =  a0 - a1 * cos (<NUM_LIT:2> * pi * k) + a2 * cos (<NUM_LIT:4> * pi * k)<EOL><DEDENT>return win<EOL>

r"""Blackman window

    :param N: window length

    .. math:: a_0 - a_1 \cos(\frac{2\pi n}{N-1}) +a_2 \cos(\frac{4\pi n }{N-1})

    with

    .. math::

        a_0 = (1-\alpha)/2, a_1=0.5, a_2=\alpha/2 \rm{\;and\; \alpha}=0.16

    When :math:`\alpha=0.16`, this is the unqualified Blackman window with
    :math:`a_0=0.48`  and :math:`a_2=0.08`.

    .. plot::
        :width: 80%
        :include-source:

        from spectrum import window_visu
        window_visu(64, 'blackman')

    .. note:: Although Numpy implements a blackman window for :math:`\alpha=0.16`,
        this implementation is valid for any :math:`\alpha`.

    .. seealso:: numpy.blackman, :func:`create_window`, :class:`Window`


from numpy import bartlett<EOL>return bartlett(N)<EOL>

r"""Bartlett window (wrapping of numpy.bartlett) also known as Fejer

    :param int N: window length

    The Bartlett window is defined as

    .. math:: w(n) = \frac{2}{N-1} \left(
              \frac{N-1}{2} - \left|n - \frac{N-1}{2}\right|
              \right)

    .. plot::
        :width: 80%
        :include-source:

        from spectrum import window_visu
        window_visu(64, 'bartlett')

    .. seealso:: numpy.bartlett, :func:`create_window`, :class:`Window`.


from numpy import hamming<EOL>return hamming(N)<EOL>

r"""Hamming window

    :param N: window length

    The Hamming window is defined as

    .. math:: 0.54 -0.46 \cos\left(\frac{2\pi n}{N-1}\right)
               \qquad 0 \leq n \leq M-1

    .. plot::
        :width: 80%
        :include-source:

        from spectrum import window_visu
        window_visu(64, 'hamming')

    .. seealso:: numpy.hamming, :func:`create_window`, :class:`Window`.


from numpy import hanning<EOL>return hanning(N)<EOL>

r"""Hann window (or Hanning). (wrapping of numpy.bartlett)

    :param int N: window length

    The Hanning window is also known as the Cosine Bell. Usually, it is called
    Hann window, to avoid confusion with the Hamming window.

    .. math:: w(n) =  0.5\left(1- \cos\left(\frac{2\pi n}{N-1}\right)\right)
               \qquad 0 \leq n \leq M-1

    .. plot::
        :width: 80%
        :include-source:

        from spectrum import window_visu
        window_visu(64, 'hanning')

    .. seealso:: numpy.hanning, :func:`create_window`, :class:`Window`.


t = linspace(-(N-<NUM_LIT:1>)/<NUM_LIT>, (N-<NUM_LIT:1>)/<NUM_LIT>, N)<EOL>w = exp(-<NUM_LIT:0.5>*(alpha * t/(N/<NUM_LIT>))**<NUM_LIT>)<EOL>return w<EOL>

r"""Gaussian window

    :param N: window length

    .. math:: \exp^{-0.5 \left( \sigma\frac{n}{N/2} \right)^2}

    with :math:`\frac{N-1}{2}\leq n \leq \frac{N-1}{2}`.

    .. note:: N-1 is used to be in agreement with octave convention. The ENBW of
         1.4 is also in agreement with [Harris]_

    .. plot::
        :width: 80%
        :include-source:

        from spectrum import window_visu
        window_visu(64, 'gaussian', alpha=2.5)

    .. seealso:: scipy.signal.gaussian, :func:`create_window`


import scipy.signal<EOL>return scipy.signal.chebwin(N, attenuation)<EOL>

Cheb window

    :param N: window length

    .. plot::
        :width: 80%
        :include-source:

        from spectrum import window_visu
        window_visu(64, 'chebwin', attenuation=50)

    .. seealso:: scipy.signal.chebwin, :func:`create_window`, :class:`Window`


if N ==<NUM_LIT:1>:<EOL><INDENT>return ones(<NUM_LIT:1>)<EOL><DEDENT>n = arange(<NUM_LIT:0>, N)<EOL>win = sin(pi*n/(N-<NUM_LIT:1.>))<EOL>return win<EOL>

r"""Cosine tapering window also known as sine window.

    :param N: window length

    .. math:: w(n) = \cos\left(\frac{\pi n}{N-1} - \frac{\pi}{2}\right) = \sin \left(\frac{\pi n}{N-1}\right)

    .. plot::
        :width: 80%
        :include-source:

        from spectrum import window_visu
        window_visu(64, 'cosine')

    .. seealso:: :func:`create_window`, :class:`Window`


if N ==<NUM_LIT:1>:<EOL><INDENT>return ones(<NUM_LIT:1>)<EOL><DEDENT>n = linspace(-N/<NUM_LIT>, N/<NUM_LIT>, N)<EOL>win = sinc(<NUM_LIT:2>*n/(N-<NUM_LIT:1.>))<EOL>return win<EOL>

r"""Lanczos window also known as sinc window.

    :param N: window length

    .. math:: w(n) = sinc \left(  \frac{2n}{N-1} - 1 \right)

    .. plot::
        :width: 80%
        :include-source:

        from spectrum import window_visu
        window_visu(64, 'lanczos')

    .. seealso:: :func:`create_window`, :class:`Window`


if N == <NUM_LIT:1>:<EOL><INDENT>return ones(<NUM_LIT:1>)<EOL><DEDENT>n = arange(<NUM_LIT:0>, N)<EOL>a0 = <NUM_LIT><EOL>a1 = <NUM_LIT><EOL>a2 = <NUM_LIT><EOL>win = a0 -  a1 *abs(n/(N-<NUM_LIT:1.>)-<NUM_LIT:0.5>) -a2 * cos(<NUM_LIT:2>*pi*n/(N-<NUM_LIT:1.>))<EOL>return win<EOL>

r"""Bartlett-Hann window

    :param N: window length

    .. math:: w(n) = a_0 + a_1 \left| \frac{n}{N-1} -\frac{1}{2}\right| - a_2 \cos \left( \frac{2\pi n}{N-1} \right)

    with :math:`a_0 = 0.62`, :math:`a_1 = 0.48` and :math:`a_2=0.38`

    .. plot::
        :width: 80%
        :include-source:

        from spectrum import window_visu
        window_visu(64, 'bartlett_hann')

    .. seealso:: :func:`create_window`, :class:`Window`


if N == <NUM_LIT:1>:<EOL><INDENT>return ones(<NUM_LIT:1>)<EOL><DEDENT>n = arange(<NUM_LIT:0>, N)<EOL>N1 = N - <NUM_LIT:1.><EOL>w = a0 -a1*cos(<NUM_LIT>*pi*n / N1) + a2*cos(<NUM_LIT>*pi*n / N1) - a3*cos(<NUM_LIT>*pi*n / N1)<EOL>return w<EOL>

a common internal function to some window functions with 4 coeffs

    For the blackmna harris for instance, the results are identical to octave if N is odd
    but not for even values...if n =0 whatever N is, the w(0) must be equal to a0-a1+a2-a3, which
    is the case here, but not in octave...


a0 = <NUM_LIT><EOL>a1 = <NUM_LIT><EOL>a2 = <NUM_LIT><EOL>a3 = <NUM_LIT><EOL>return _coeff4(N, a0, a1, a2, a3)<EOL>

r"""Nuttall tapering window

    :param N: window length

    .. math:: w(n) = a_0 - a_1 \cos\left(\frac{2\pi n}{N-1}\right)+ a_2 \cos\left(\frac{4\pi n}{N-1}\right)- a_3 \cos\left(\frac{6\pi n}{N-1}\right)

    with :math:`a_0 = 0.355768`, :math:`a_1 = 0.487396`, :math:`a_2=0.144232` and :math:`a_3=0.012604`

    .. plot::
        :width: 80%
        :include-source:

        from spectrum import window_visu
        window_visu(64, 'nuttall', mindB=-80)

    .. seealso:: :func:`create_window`, :class:`Window`


r"""Blackman Nuttall window

    returns a minimum, 4-term Blackman-Harris window. The window is minimum in the sense that its maximum sidelobes are minimized.
    The coefficients for this window differ from the Blackman-Harris window coefficients and produce slightly lower sidelobes.

    :param N: window length

    .. math:: w(n) = a_0 - a_1 \cos\left(\frac{2\pi n}{N-1}\right)+ a_2 \cos\left(\frac{4\pi n}{N-1}\right)- a_3 \cos\left(\frac{6\pi n}{N-1}\right)

    with :math:`a_0 = 0.3635819`, :math:`a_1 = 0.4891775`, :math:`a_2=0.1365995` and :math:`0_3=.0106411`

    .. plot::
        :width: 80%
        :include-source:

        from spectrum import window_visu
        window_visu(64, 'blackman_nuttall', mindB=-80)

    .. seealso:: :func:`spectrum.window.create_window`
    .. seealso:: :func:`create_window`, :class:`Window`


r"""Blackman Harris window

    :param N: window length

    .. math:: w(n) = a_0 - a_1 \cos\left(\frac{2\pi n}{N-1}\right)+ a_2 \cos\left(\frac{4\pi n}{N-1}\right)- a_3 \cos\left(\frac{6\pi n}{N-1}\right)

    =============== =========
    coeff            value
    =============== =========
    :math:`a_0`     0.35875
    :math:`a_1`     0.48829
    :math:`a_2`     0.14128
    :math:`a_3`     0.01168
    =============== =========

    .. plot::
        :width: 80%
        :include-source:

        from spectrum import window_visu
        window_visu(64, 'blackman_harris', mindB=-80)

    .. seealso:: :func:`spectrum.window.create_window`
    .. seealso:: :func:`create_window`, :class:`Window`


x = linspace(-<NUM_LIT:1>, <NUM_LIT:1>, N)<EOL>w = (<NUM_LIT:1.>-abs(x)) * cos(pi*abs(x)) + <NUM_LIT:1.>/pi * sin(pi*abs(x))<EOL>return w<EOL>

r"""Bohman tapering window

    :param N: window length

    .. math:: w(n) = (1-|x|) \cos (\pi |x|) + \frac{1}{\pi} \sin(\pi |x|)

    where x is a length N vector of linearly spaced values between
    -1 and 1.

    .. plot::
        :width: 80%
        :include-source:

        from spectrum import window_visu
        window_visu(64, 'bohman')

    .. seealso:: :func:`create_window`, :class:`Window`


assert r>=<NUM_LIT:0> and r<=<NUM_LIT:1> , "<STR_LIT>"<EOL>if N==<NUM_LIT:1>:<EOL><INDENT>return ones(<NUM_LIT:1>)<EOL><DEDENT>if r == <NUM_LIT:0>:<EOL><INDENT>return ones(N)<EOL><DEDENT>elif r == <NUM_LIT:1>:<EOL><INDENT>return window_hann(N)<EOL><DEDENT>else:<EOL><INDENT>from numpy import flipud, concatenate, where<EOL>x = linspace(<NUM_LIT:0>, <NUM_LIT:1>, N)<EOL>x1 = where(x<r/<NUM_LIT>)<EOL>w = <NUM_LIT:0.5>*(<NUM_LIT:1>+cos(<NUM_LIT:2>*pi/r*(x[x1[<NUM_LIT:0>]]-r/<NUM_LIT:2>)))<EOL>w = concatenate((w, ones(N-len(w)*<NUM_LIT:2>), flipud(w)))<EOL>return w<EOL><DEDENT>

Tukey tapering window (or cosine-tapered window)

    :param N: window length
    :param r: defines the ratio between the constant section and the cosine
      section. It has to be between 0 and 1.

    The function returns a Hanning window for `r=0` and a full box for `r=1`.

    .. plot::
        :width: 80%
        :include-source:

        from spectrum import window_visu
        window_visu(64, 'tukey')
        window_visu(64, 'tukey', r=1)

    .. math:: 0.5 (1+cos(2pi/r (x-r/2))) for 0<=x<r/2

    .. math:: 0.5 (1+cos(2pi/r (x-1+r/2))) for x>=1-r/2

    .. seealso:: :func:`create_window`, :class:`Window`


from numpy import  where, concatenate<EOL>n = linspace(-(N-<NUM_LIT:1>)/<NUM_LIT>, (N-<NUM_LIT:1>)/<NUM_LIT>, N)<EOL>n1 = n[where(abs(n)<=(N-<NUM_LIT:1>)/<NUM_LIT>)[<NUM_LIT:0>]]<EOL>n2 = n[where(n>(N-<NUM_LIT:1>)/<NUM_LIT>)[<NUM_LIT:0>]]<EOL>n3 = n[where(n<-(N-<NUM_LIT:1>)/<NUM_LIT>)[<NUM_LIT:0>]]<EOL>w1 = <NUM_LIT:1.> -<NUM_LIT>*(abs(n1)/(N/<NUM_LIT>))**<NUM_LIT:2> + <NUM_LIT:6>*(abs(n1)/(N/<NUM_LIT>))**<NUM_LIT:3><EOL>w2 = <NUM_LIT>*(<NUM_LIT:1>-abs(n2)/(N/<NUM_LIT>))**<NUM_LIT:3><EOL>w3 = <NUM_LIT>*(<NUM_LIT:1>-abs(n3)/(N/<NUM_LIT>))**<NUM_LIT:3><EOL>w = concatenate((w3, w1, w2))<EOL>return w<EOL>

r"""Parsen tapering window (also known as de la Valle-Poussin)

    :param N: window length

    Parzen windows are piecewise cubic approximations
    of Gaussian windows. Parzen window sidelobes fall off as :math:`1/\omega^4`.

    if :math:`0\leq|x|\leq (N-1)/4`:

    .. math:: w(n) = 1-6 \left( \frac{|n|}{N/2} \right)^2 +6 \left( \frac{|n|}{N/2}\right)^3

    if :math:`(N-1)/4\leq|x|\leq (N-1)/2`

    .. math:: w(n) = 2 \left(1- \frac{|n|}{N/2}\right)^3

    .. plot::
        :width: 80%
        :include-source:

        from spectrum import window_visu
        window_visu(64, 'parzen')

    .. seealso:: :func:`create_window`, :class:`Window`


assert mode in ['<STR_LIT>', '<STR_LIT>']<EOL>t = arange(<NUM_LIT:0>, N)<EOL>if mode == '<STR_LIT>':<EOL><INDENT>x = <NUM_LIT:2>*pi*t/float(N)<EOL><DEDENT>else:<EOL><INDENT>if N ==<NUM_LIT:1>:<EOL><INDENT>return ones(<NUM_LIT:1>)<EOL><DEDENT>x = <NUM_LIT:2>*pi*t/float(N-<NUM_LIT:1>)<EOL><DEDENT>a0 = <NUM_LIT><EOL>a1 = <NUM_LIT><EOL>a2 = <NUM_LIT><EOL>a3 = <NUM_LIT><EOL>a4 = <NUM_LIT><EOL>if precision == '<STR_LIT>':<EOL><INDENT>d  = <NUM_LIT><EOL>a0 = <NUM_LIT:1.>/d<EOL>a1 = <NUM_LIT>/d<EOL>a2 = <NUM_LIT>/d<EOL>a3 = <NUM_LIT>/d<EOL>a4 = <NUM_LIT>/d<EOL><DEDENT>w = a0-a1*cos(x)+a2*cos(<NUM_LIT:2>*x)-a3*cos(<NUM_LIT:3>*x)+a4*cos(<NUM_LIT:4>*x)<EOL>return w<EOL>

r"""Flat-top tapering window

    Returns symmetric or periodic flat top window.

    :param N: window length
    :param mode: way the data are normalised. If mode is *symmetric*, then
        divide n by N-1. IF mode is *periodic*, divide by N,
        to be consistent with octave code.

    When using windows for filter design, the *symmetric* mode
    should be used (default). When using windows for spectral analysis, the *periodic*
    mode should be used. The mathematical form of the flat-top window in the symmetric
    case is:

    .. math:: w(n) = a_0
        - a_1 \cos\left(\frac{2\pi n}{N-1}\right)
        + a_2 \cos\left(\frac{4\pi n}{N-1}\right)
        - a_3 \cos\left(\frac{6\pi n}{N-1}\right)
        + a_4 \cos\left(\frac{8\pi n}{N-1}\right)

    =====  =============
    coeff  value
    =====  =============
    a0     0.21557895
    a1     0.41663158
    a2     0.277263158
    a3     0.083578947
    a4     0.006947368
    =====  =============

    .. plot::
        :width: 80%
        :include-source:

        from spectrum import window_visu
        window_visu(64, 'bohman')

    .. seealso:: :func:`create_window`, :class:`Window`


def window_taylor(N, nbar=<NUM_LIT:4>, sll=-<NUM_LIT:30>):

B = <NUM_LIT:10>**(-sll/<NUM_LIT:20>)<EOL>A = log(B + sqrt(B**<NUM_LIT:2> - <NUM_LIT:1>))/pi<EOL>s2 = nbar**<NUM_LIT:2> / (A**<NUM_LIT:2> + (nbar - <NUM_LIT:0.5>)**<NUM_LIT:2>)<EOL>ma = arange(<NUM_LIT:1>,nbar)<EOL>def calc_Fm(m):<EOL><INDENT>numer = (-<NUM_LIT:1>)**(m+<NUM_LIT:1>) * prod(<NUM_LIT:1>-m**<NUM_LIT:2>/s2/(A**<NUM_LIT:2> + (ma - <NUM_LIT:0.5>)**<NUM_LIT:2>))<EOL>denom = <NUM_LIT:2>* prod([ <NUM_LIT:1>-m**<NUM_LIT:2>/j**<NUM_LIT:2> for j in ma if j != m])<EOL>return numer/denom<EOL><DEDENT>Fm = array([calc_Fm(m) for m in ma])<EOL>def W(n):<EOL><INDENT>return <NUM_LIT:2> * np.sum(Fm * cos(<NUM_LIT:2>*pi*ma*(n-N/<NUM_LIT:2> + <NUM_LIT:1>/<NUM_LIT:2>)/N)) + <NUM_LIT:1><EOL><DEDENT>w = array([W(n) for n in range(N)])<EOL>scale = W((N-<NUM_LIT:1>)/<NUM_LIT:2>)<EOL>w /= scale<EOL>return w<EOL>

Taylor tapering window

    Taylor windows allows you to make tradeoffs between the
    mainlobe width and sidelobe level (sll).

    Implemented as described by Carrara, Goodman, and Majewski
    in 'Spotlight Synthetic Aperture Radar: Signal Processing Algorithms'
    Pages 512-513

    :param N: window length
    :param float nbar:
    :param float sll:

    The default values gives equal height
    sidelobes (nbar) and maximum sidelobe level (sll).

    .. warning:: not implemented

    .. seealso:: :func:`create_window`, :class:`Window`


n = linspace(-N/<NUM_LIT>, (N)/<NUM_LIT>, N)<EOL>w = <NUM_LIT:1> - abs(n/(N/<NUM_LIT>))**<NUM_LIT><EOL>return w<EOL>

r"""Riesz tapering window

    :param N: window length

    .. math:: w(n) = 1 - \left| \frac{n}{N/2}  \right|^2

    with :math:`-N/2 \leq n \leq N/2`.

    .. plot::
        :width: 80%
        :include-source:

        from spectrum import window_visu
        window_visu(64, 'riesz')

    .. seealso:: :func:`create_window`, :class:`Window`


n = linspace(-N/<NUM_LIT>, (N)/<NUM_LIT>, N)<EOL>w = sin(n/float(N)*<NUM_LIT>*pi) / (n / float(N)*<NUM_LIT>*pi)<EOL>return w<EOL>

r"""Riemann tapering window

    :param int N: window length

    .. math:: w(n) = 1 - \left| \frac{n}{N/2}  \right|^2

    with :math:`-N/2 \leq n \leq N/2`.

    .. plot::
        :width: 80%
        :include-source:

        from spectrum import window_visu
        window_visu(64, 'riesz')

    .. seealso:: :func:`create_window`, :class:`Window`


n = linspace(-N/<NUM_LIT>, (N)/<NUM_LIT>, N)<EOL>w = exp(-alpha * abs(n)/(N/<NUM_LIT>))<EOL>return w<EOL>

r"""Poisson tapering window

    :param int N: window length

    .. math:: w(n) = \exp^{-\alpha \frac{|n|}{N/2} }

    with :math:`-N/2 \leq n \leq N/2`.

    .. plot::
        :width: 80%
        :include-source:

        from spectrum import window_visu
        window_visu(64, 'poisson')
        window_visu(64, 'poisson', alpha=3)
        window_visu(64, 'poisson', alpha=4)

    .. seealso:: :func:`create_window`, :class:`Window`


w1 = window_hann(N)<EOL>w2 = window_poisson(N, alpha=alpha)<EOL>return w1*w2<EOL>

r"""Hann-Poisson tapering window

    This window is constructed as the product of the Hanning and Poisson
    windows. The parameter **alpha** is the Poisson parameter.

    :param int N: window length
    :param float alpha: parameter of the poisson window

    .. plot::
        :width: 80%
        :include-source:

        from spectrum import window_visu
        window_visu(64, 'poisson_hanning', alpha=0.5)
        window_visu(64, 'poisson_hanning', alpha=1)
        window_visu(64, 'poisson_hanning')

    .. seealso:: :func:`window_poisson`, :func:`window_hann`


n = linspace(-N/<NUM_LIT>, (N)/<NUM_LIT>, N)<EOL>w = <NUM_LIT:1.>/(<NUM_LIT:1.>+ (alpha*n/(N/<NUM_LIT>))**<NUM_LIT:2>)<EOL>return w<EOL>

r"""Cauchy tapering window

    :param int N: window length
    :param float alpha: parameter of the poisson window

    .. math:: w(n) = \frac{1}{1+\left(\frac{\alpha*n}{N/2}\right)**2}

    .. plot::
        :width: 80%
        :include-source:

        from spectrum import window_visu
        window_visu(64, 'cauchy', alpha=3)
        window_visu(64, 'cauchy', alpha=4)
        window_visu(64, 'cauchy', alpha=5)

    .. seealso:: :func:`window_poisson`, :func:`window_hann`


def __init__(self, N, name=None, norm=True, **kargs):

<EOL>assert N><NUM_LIT:0> , "<STR_LIT>"<EOL>if name is None or name not in list(window_names.keys()):<EOL><INDENT>raise ValueError("<STR_LIT>" %<EOL>list(window_names.keys()))<EOL><DEDENT>self.__N = N<EOL>self.__name = name<EOL>self.__norm = norm<EOL>self.__data = create_window(N, name, **kargs)<EOL>self.__frequencies = None<EOL>self.__response = None<EOL>self.__enbw = enbw(self.data)<EOL>

Create a tapering window object

        :param N: the window length
        :param name: the type of window, e.g., 'Hann'
        :param norm: normalise the window in frequency domain (for plotting)
        :param kargs: any of :func:`create_window` valid optional arguments.

        .. rubric:: Attributes:

        * data: time series data
        * frequencies: getter to the frequency series
        * response: getter to the PSD
        * enbw:  getter to the Equivalent noise band width.


from numpy.fft import fft, fftshift<EOL>norm = kargs.get('<STR_LIT>', self.norm)<EOL>NFFT = kargs.get('<STR_LIT>', <NUM_LIT>)<EOL>if NFFT < len(self.data):<EOL><INDENT>NFFT = self.data.size * <NUM_LIT:2><EOL><DEDENT>A = fft(self.data, NFFT)<EOL>mag = abs(fftshift(A))<EOL>if norm is True:<EOL><INDENT>mag = mag / max(mag)<EOL><DEDENT>response = <NUM_LIT> * stools.log10(mag) <EOL>self.__response = response<EOL>

Compute the window data frequency response

        :param norm: True by default. normalised the frequency data.
        :param int NFFT: total length of the final data sets( 2048 by default.
            if less than data length, then NFFT is set to the data length*2).

        The response is stored in :attr:`response`.

        .. note:: Units are dB (20 log10) since we plot the frequency response)


def plot_frequencies(self, mindB=None, maxdB=None, norm=True):

from pylab import plot, title, xlim, grid, ylim, xlabel, ylabel<EOL>self.compute_response(norm=norm)<EOL>plot(self.frequencies, self.response)<EOL>title("<STR_LIT>" % (self.enbw))<EOL>ylabel('<STR_LIT>')<EOL>xlabel('<STR_LIT>')<EOL>xlim(-<NUM_LIT:0.5>, <NUM_LIT:0.5>)<EOL>y0, y1 = ylim()<EOL>if mindB:<EOL><INDENT>y0 = mindB<EOL><DEDENT>if maxdB is not None:<EOL><INDENT>y1 = maxdB<EOL><DEDENT>else:<EOL><INDENT>y1 = max(self.response)<EOL><DEDENT>ylim(y0, y1)<EOL>grid(True)<EOL>

Plot the window in the frequency domain

        :param mindB: change the default lower y bound
        :param maxdB: change the default upper lower bound
        :param bool norm: if True, normalise the frequency response.

        .. plot::
            :width: 80%
            :include-source:

            from spectrum.window import Window
            w = Window(64, name='hamming')
            w.plot_frequencies()


from pylab import plot, xlim, grid, title, ylabel, axis<EOL>x = linspace(<NUM_LIT:0>, <NUM_LIT:1>, self.N)<EOL>xlim(<NUM_LIT:0>, <NUM_LIT:1>)<EOL>plot(x, self.data)<EOL>grid(True)<EOL>title('<STR_LIT>' % (self.name.capitalize(), self.N))<EOL>ylabel('<STR_LIT>')<EOL>axis([<NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:0>, <NUM_LIT>])<EOL>

Plot the window in the time domain

        .. plot::
            :width: 80%
            :include-source:

            from spectrum.window import Window
            w = Window(64, name='hamming')
            w.plot_window()


def plot_time_freq(self, mindB=-<NUM_LIT:100>, maxdB=None, norm=True,<EOL>yaxis_label_position="<STR_LIT:right>"):

from pylab import subplot, gca<EOL>subplot(<NUM_LIT:1>, <NUM_LIT:2>, <NUM_LIT:1>)<EOL>self.plot_window()<EOL>subplot(<NUM_LIT:1>, <NUM_LIT:2>, <NUM_LIT:2>)<EOL>self.plot_frequencies(mindB=mindB, maxdB=maxdB, norm=norm)<EOL>if yaxis_label_position=="<STR_LIT:left>":<EOL><INDENT>try: tight_layout()<EOL>except: pass<EOL><DEDENT>else:<EOL><INDENT>ax = gca()<EOL>ax.yaxis.set_label_position("<STR_LIT:right>")<EOL><DEDENT>

Plotting method to plot both time and frequency domain results.

        See :meth:`plot_frequencies` for the optional arguments.

        .. plot::
            :width: 80%
            :include-source:

            from spectrum.window import Window
            w = Window(64, name='hamming')
            w.plot_time_freq()


print(self)<EOL>

Print object information such as length and name


a, e, _c = LEVINSON(data)<EOL>a = numpy.insert(a, <NUM_LIT:0>, <NUM_LIT:1>)<EOL>return a, e<EOL>

Convert autocorrelation sequence to prediction polynomial

    :param array data:    input data (list or numpy.array)
    :return:
        * AR parameters
        * noise variance

    This is an alias to::

        a, e, c = LEVINSON(data)

    :Example:

    .. doctest::

        >>> from spectrum import ac2poly
        >>> from numpy import array
        >>> r = [5, -2, 1.01]
        >>> ar, e = ac2poly(r)
        >>> ar
        array([ 1.  ,  0.38, -0.05])
        >>> e
        4.1895000000000007


a, e, _c = LEVINSON(data)<EOL>return a, data[<NUM_LIT:0>]<EOL>

Convert autocorrelation sequence to reflection coefficients

    :param data: an autorrelation vector
    :return: the reflection coefficient and data[0]

    This is an alias to::

        a, e, c = LEVINSON(data)
        c, data[0]


results = rlevinson(poly, efinal)<EOL>return results[<NUM_LIT:0>]<EOL>

Convert prediction filter polynomial to autocorrelation sequence

    :param array poly: the AR parameters
    :param efinal: an estimate of the final error
    :return: the autocorrelation  sequence in complex format.

    .. doctest::

        >>> from numpy import array
        >>> from spectrum import poly2ac
        >>> poly = [ 1. ,  0.38 , -0.05]
        >>> efinal = 4.1895
        >>> poly2ac(poly, efinal)
        array([ 5.00+0.j, -2.00+0.j,  1.01-0.j])


raise NotImplementedError<EOL>

Convert autoregressive parameters into reflection coefficients


results = rlevinson(a, efinal)<EOL>return results[<NUM_LIT:2>]<EOL>

Convert prediction filter polynomial to reflection coefficients

    :param a: AR parameters
    :param efinal:


<EOL>from .levinson import levup<EOL>p = len(kr)              <EOL>a = numpy.array([<NUM_LIT:1>, kr[<NUM_LIT:0>]])           <EOL>e = numpy.zeros(len(kr))<EOL>if r0 is None:<EOL><INDENT>e0 = <NUM_LIT:0><EOL><DEDENT>else:<EOL><INDENT>e0 = r0<EOL><DEDENT>e[<NUM_LIT:0>] = e0 * (<NUM_LIT:1.> - numpy.conj(numpy.conjugate(kr[<NUM_LIT:0>])*kr[<NUM_LIT:0>]))<EOL>for k in range(<NUM_LIT:1>, p):<EOL><INDENT>[a, e[k]] = levup(a, kr[k], e[k-<NUM_LIT:1>])<EOL><DEDENT>efinal = e[-<NUM_LIT:1>]<EOL>return a, efinal<EOL>

convert reflection coefficients to prediction filter polynomial

    :param k: reflection coefficients


[a,efinal] = rc2poly(k, R0)<EOL>R, u, kr, e = rlevinson(a, efinal)<EOL>return R<EOL>

Convert reflection coefficients to autocorrelation sequence.

    :param k: reflection coefficients
    :param R0: zero-lag autocorrelation
    :returns: the autocorrelation sequence

    .. seealso:: :func:`ac2rc`, :func:`poly2rc`, :func:`ac2poly`, :func:`poly2rc`, :func:`rc2poly`.


return numpy.sin(numpy.array(inv_sin)*numpy.pi/<NUM_LIT:2>)<EOL>

Convert inverse sine parameters to reflection coefficients.

    :param inv_sin: inverse sine parameters
    :return: reflection coefficients

    .. seealso::  :func:`rc2is`, :func:`poly2rc`, :func:`ac2rc`, :func:`lar2rc`.

    :Reference: J.R. Deller, J.G. Proakis, J.H.L. Hansen,
        "Discrete-Time Processing of Speech Signals", Prentice Hall, Section 7.4.5.


assert numpy.isrealobj(k), '<STR_LIT>'<EOL>if max(numpy.abs(k)) >= <NUM_LIT:1>:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>return (<NUM_LIT:2>/numpy.pi)*numpy.arcsin(k)<EOL>

Convert reflection coefficients to inverse sine parameters.

    :param k: reflection coefficients
    :return: inverse sine parameters

    .. seealso:: :func:`is2rc`, :func:`rc2poly`, :func:`rc2acC`, :func:`rc2lar`.

    Reference: J.R. Deller, J.G. Proakis, J.H.L. Hansen, "Discrete-Time
       Processing of Speech Signals", Prentice Hall, Section 7.4.5.


assert numpy.isrealobj(k), '<STR_LIT>'<EOL>if max(numpy.abs(k)) >= <NUM_LIT:1>:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>return -<NUM_LIT:2> * numpy.arctanh(-numpy.array(k))<EOL>

Convert reflection coefficients to log area ratios.

    :param k: reflection coefficients
    :return: inverse sine parameters

    The log area ratio is defined by G = log((1+k)/(1-k)) , where the K
    parameter is the reflection coefficient.

    .. seealso:: :func:`lar2rc`, :func:`rc2poly`, :func:`rc2ac`, :func:`rc2ic`.

    :References:
       [1] J. Makhoul, "Linear Prediction: A Tutorial Review," Proc. IEEE, Vol.63, No.4, pp.561-580, Apr 1975.


assert numpy.isrealobj(g), '<STR_LIT>'<EOL>return -numpy.tanh(-numpy.array(g)/<NUM_LIT:2>)<EOL>

Convert log area ratios to reflection coefficients.

    :param g:  log area ratios
    :returns: the reflection coefficients

    .. seealso: :func:`rc2lar`, :func:`poly2rc`, :func:`ac2rc`, :func:`is2rc`.

    :References:
       [1] J. Makhoul, "Linear Prediction: A Tutorial Review," Proc. IEEE,  Vol.63, No.4, pp.561-580, Apr 1975.


<EOL>lsf = numpy.array(lsf)<EOL>if max(lsf) > numpy.pi or min(lsf) < <NUM_LIT:0>:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>p = len(lsf) <EOL>z  = numpy.exp(<NUM_LIT> * lsf)<EOL>rQ = z[<NUM_LIT:0>::<NUM_LIT:2>]<EOL>rP = z[<NUM_LIT:1>::<NUM_LIT:2>]<EOL>rQ = numpy.concatenate((rQ, rQ.conjugate()))<EOL>rP = numpy.concatenate((rP, rP.conjugate()))<EOL>Q  = numpy.poly(rQ);<EOL>P  = numpy.poly(rP);<EOL>if p%<NUM_LIT:2>:<EOL><INDENT>P1 = numpy.convolve(P, [<NUM_LIT:1>, <NUM_LIT:0>, -<NUM_LIT:1>])<EOL>Q1 = Q<EOL><DEDENT>else:<EOL><INDENT>P1 = numpy.convolve(P, [<NUM_LIT:1>, -<NUM_LIT:1>])<EOL>Q1 = numpy.convolve(Q, [<NUM_LIT:1>,  <NUM_LIT:1>])<EOL><DEDENT>a = <NUM_LIT> * (P1+Q1)<EOL>return a[<NUM_LIT:0>:-<NUM_LIT:1>:<NUM_LIT:1>]<EOL>

Convert line spectral frequencies to prediction filter coefficients

    returns a vector a containing the prediction filter coefficients from a vector lsf of line spectral frequencies.

    .. doctest::

        >>> from spectrum import lsf2poly
        >>> lsf = [0.7842 ,   1.5605  ,  1.8776 ,   1.8984,    2.3593]
        >>> a = lsf2poly(lsf)

    # array([  1.00000000e+00,   6.14837835e-01,   9.89884967e-01,
    # 9.31594056e-05,   3.13713832e-03,  -8.12002261e-03 ])

    .. seealso:: poly2lsf, rc2poly, ac2poly, rc2is


<EOL>a = numpy.array(a)<EOL>if a[<NUM_LIT:0>] != <NUM_LIT:1>:<EOL><INDENT>a/=a[<NUM_LIT:0>]<EOL><DEDENT>if max(numpy.abs(numpy.roots(a))) >= <NUM_LIT:1.0>:<EOL><INDENT>error('<STR_LIT>');<EOL><DEDENT>p  = len(a)-<NUM_LIT:1>   <EOL>a1 = numpy.concatenate((a, numpy.array([<NUM_LIT:0>])))<EOL>a2 = a1[-<NUM_LIT:1>::-<NUM_LIT:1>]<EOL>P1 = a1 - a2        <EOL>Q1 = a1 + a2        <EOL>if p%<NUM_LIT:2>: <EOL><INDENT>P, r = deconvolve(P1,[<NUM_LIT:1>, <NUM_LIT:0> ,-<NUM_LIT:1>])<EOL>Q = Q1<EOL><DEDENT>else:          <EOL><INDENT>P, r = deconvolve(P1, [<NUM_LIT:1>, -<NUM_LIT:1>])<EOL>Q, r = deconvolve(Q1, [<NUM_LIT:1>,  <NUM_LIT:1>])<EOL><DEDENT>rP  = numpy.roots(P)<EOL>rQ  = numpy.roots(Q)<EOL>aP  = numpy.angle(rP[<NUM_LIT:1>::<NUM_LIT:2>])<EOL>aQ  = numpy.angle(rQ[<NUM_LIT:1>::<NUM_LIT:2>])<EOL>lsf = sorted(numpy.concatenate((-aP,-aQ)))<EOL>return lsf<EOL>

Prediction polynomial to line spectral frequencies.

    converts the prediction polynomial specified by A,
    into the corresponding line spectral frequencies, LSF.
    normalizes the prediction polynomial by A(1).

    .. doctest::

        >>> from spectrum import poly2lsf
        >>> a = [1.0000,  0.6149, 0.9899, 0.0000 ,0.0031, -0.0082]
        >>> lsf = poly2lsf(a)
        >>> lsf =  array([0.7842, 1.5605, 1.8776, 1.8984, 2.3593])

    .. seealso:: lsf2poly, poly2rc, poly2qc, rc2is


from numpy import log, array<EOL>res = N * log(array(rho)) + <NUM_LIT>* (array(k)+<NUM_LIT:1>)<EOL>return res<EOL>

r"""Akaike Information Criterion

    :param rho: rho at order k
    :param N: sample size
    :param k: AR order.

    If k is the AR order and N the size of the sample, then Akaike criterion is

    .. math:: AIC(k) = \log(\rho_k) + 2\frac{k+1}{N}

    ::

        AIC(64, [0.5,0.3,0.2], [1,2,3])

    :validation: double checked versus octave.


from numpy import log, array<EOL>p = k  <EOL>res = log(rho) + <NUM_LIT> * (p+<NUM_LIT:1>) / (N-p-<NUM_LIT:2>)<EOL>return res<EOL>

r"""corrected Akaike information criterion

    .. math:: AICc(k) = log(\rho_k) + 2 \frac{k+1}{N-k-2}

    :validation: double checked versus octave.


from numpy import log, array<EOL>res = log(rho) + <NUM_LIT> * (k+<NUM_LIT:1.>) /float(N)<EOL>return res<EOL>

r"""Kullback information criterion

    .. math:: KIC(k) = log(\rho_k) + 3 \frac{k+1}{N}

    :validation: double checked versus octave.


from numpy import log, array<EOL>p = k<EOL>res = log(rho) + p/N/(N-p) + (<NUM_LIT>-(p+<NUM_LIT>)/N) * (p+<NUM_LIT:1.>) / (N-p-<NUM_LIT>)<EOL>return res<EOL>

r"""approximate corrected Kullback information

    .. math:: AKICc(k) = log(rho_k) + \frac{p}{N*(N-k)} + (3-\frac{k+2}{N})*\frac{k+1}{N-k-2}


<EOL>fpe = rho * (N + k + <NUM_LIT:1.>) / (N- k -<NUM_LIT:1>)<EOL>return fpe<EOL>

r"""Final prediction error criterion

    .. math:: FPE(k) = \frac{N + k + 1}{N - k - 1} \rho_k

    :validation: double checked versus octave.


from numpy import log<EOL>mdl = N* log(rho) + k * log(N)<EOL>return mdl<EOL>

r"""Minimum Description Length

    .. math:: MDL(k) = N log \rho_k + p \log N

    :validation: results


from numpy import zeros, arange<EOL>cat = zeros(len(rho))<EOL>for p in arange(<NUM_LIT:1>, len(rho)+<NUM_LIT:1>):<EOL><INDENT>rho_p = float(N)/(N-p)*rho[p-<NUM_LIT:1>]<EOL>s = <NUM_LIT:0><EOL>for j in range(<NUM_LIT:1>, p+<NUM_LIT:1>):<EOL><INDENT>rho_j = float(N)/(N-j)*rho[j-<NUM_LIT:1>]<EOL>s = s + <NUM_LIT:1.>/rho_j<EOL><DEDENT>cat[p-<NUM_LIT:1>] = s/float(N) - <NUM_LIT:1.>/rho_p<EOL><DEDENT>return cat<EOL>

r"""Criterion Autoregressive Transfer Function :

    .. math::  CAT(k) = \frac{1}{N} \sum_{i=1}^k \frac{1}{\rho_i} - \frac{\rho_i}{\rho_k}

    .. todo:: validation


import numpy as np<EOL>kaic = []<EOL>n = len(s)<EOL>for k in range(<NUM_LIT:0>, n-<NUM_LIT:1>):<EOL><INDENT>ak = <NUM_LIT:1.>/(n-k) * np.sum(s[k+<NUM_LIT:1>:])<EOL>gk = np.prod(s[k+<NUM_LIT:1>:]**(<NUM_LIT:1.>/(n-k)))<EOL>kaic.append( -<NUM_LIT>*(n-k)*N * np.log(gk/ak) + <NUM_LIT>*k*(<NUM_LIT>*n-k))<EOL><DEDENT>return kaic<EOL>

r"""AIC order-selection using eigen values

    :param s: a list of `p` sorted eigen values
    :param N: the size of the input data. To be defined precisely.

    :return:
        * an array containing the AIC values

    Given :math:`n` sorted eigen values :math:`\lambda_i` with
    :math:`0 <= i < n`, the proposed criterion from Wax and Kailath (1985)
    is:

    .. math:: AIC(k) = -2(n-k)N \ln \frac{g(k)}{a(k)} + 2k(2n-k)

    where the arithmetic sum :math:`a(k)` is:

    .. math:: a(k) = \sum_{i=k+1}^{n}\lambda_i

    and the geometric sum :math:`g(k)` is:

    .. math:: g(k) = \prod_{i=k+1}^{n} \lambda_i^{-(n-k)}

    The number of relevant sinusoids in the signal subspace is determined by
    selecting the minimum of `AIC`.

    .. seealso:: :func:`~spectrum.eigenfreq.eigen`
    .. todo:: define precisely the input parameter N. Should be the input
       data length but when using correlation matrix (SVD), I suspect it
       should be the length of the correlation matrix rather than the
       original data.

    :References:
        * [Marple]_ Chap 13,
        * [Wax]_


import numpy as np<EOL>kmdl = []<EOL>n = len(s)<EOL>for k in range(<NUM_LIT:0>, n-<NUM_LIT:1>):<EOL><INDENT>ak = <NUM_LIT:1.>/(n-k) * np.sum(s[k+<NUM_LIT:1>:])<EOL>gk = np.prod(s[k+<NUM_LIT:1>:]**(<NUM_LIT:1.>/(n-k)))<EOL>kmdl.append( -(n-k)*N * np.log(gk/ak) + <NUM_LIT:0.5>*k*(<NUM_LIT>*n-k)*np.log(N))<EOL><DEDENT>return kmdl<EOL>

r"""MDL order-selection using eigen values

    :param s: a list of `p` sorted eigen values
    :param N: the size of the input data. To be defined precisely.

    :return:
        * an array containing the AIC values

    .. math:: MDL(k) = (n-k)N \ln \frac{g(k)}{a(k)} + 0.5k(2n-k) log(N)

    .. seealso:: :func:`aic_eigen` for details

    :References:
        * [Marple]_ Chap 13,
        * [Wax]_


<EOL>self.__name = None<EOL>self.name = name<EOL>self.__N = N<EOL>self.__rho = <NUM_LIT:0><EOL>self.__k = None<EOL>self.__old_data = None<EOL>self.__data = None<EOL>self.__norm = True<EOL>

Create a criteria object

        :param name: a string or list of strings containing valid criteria
            method's name
        :param int N: size of the data sample.


def __call__(self, rho=None, k=None, N=None, norm=True):

self.__norm = norm<EOL>if N is not None:<EOL><INDENT>self.N = N<EOL><DEDENT>if rho is not None:<EOL><INDENT>self.rho = rho<EOL><DEDENT>if k is not None:<EOL><INDENT>self.__k = k<EOL><DEDENT>self.__norm = norm<EOL>f = eval(self.name)<EOL>self.data = f(self.N, self.rho, self.k)<EOL>if self.old_data is not None and self.data is not None:<EOL><INDENT>if self.data > self.old_data:<EOL><INDENT>return False<EOL><DEDENT>else:<EOL><INDENT>return True<EOL><DEDENT><DEDENT>return True<EOL>

Call the criteria function correspondign to :attr:`name`.


def __init__(self, N, sampling=<NUM_LIT:1.>):

self.__N = N<EOL>self.__sampling = sampling<EOL>self.__df = None<EOL>self._setN(N)<EOL>self._setsampling(sampling)<EOL>

.. rubric:: **Constructor**

        :param int N: the data length
        :param float sampling: sampling frequency of the input :attr:`data`.

        .. rubric:: Attributes:

        From the input parameters, read/write attributes are set:

            * :attr:`N`, the data length,
            * :attr:`sampling`, the sampling frequency.

        Additionally, the following read-only attribute is available:

            * :attr:`df`, the frequency step computed from :attr:`N` and
              :attr:`sampling`.


for a in range(<NUM_LIT:0>, self.N):<EOL><INDENT>yield (a-self.N/<NUM_LIT:2>) * self.df<EOL><DEDENT>

Return the centered frequency range as a generator.

        ::

            >>> print(list(Range(8).centerdc_gen()))
            [-0.5, -0.375, -0.25, -0.125, 0.0, 0.125, 0.25, 0.375]


for a in range(<NUM_LIT:0>, self.N):<EOL><INDENT>yield a * self.df<EOL><DEDENT>

Returns the twosided frequency range as a generator

        ::

            >>> print(list(Range(8).centerdc_gen()))
            [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875]


if self.N % <NUM_LIT:2> == <NUM_LIT:0>:<EOL><INDENT>for n in range(<NUM_LIT:0>, self.N//<NUM_LIT:2> + <NUM_LIT:1>):<EOL><INDENT>yield n * self.df<EOL><DEDENT><DEDENT>else:<EOL><INDENT>for n in range(<NUM_LIT:0>, (self.N+<NUM_LIT:1>)//<NUM_LIT:2>):<EOL><INDENT>yield n * self.df<EOL><DEDENT><DEDENT>

Return the one-sided frequency range as a generator.

        If :attr:`N` is even, the length is N/2 + 1.
        If :attr:`N` is odd, the length is (N+1)/2.

        ::

            >>> print(list(Range(8).onesided()))
            [0.0, 0.125, 0.25, 0.375, 0.5]
            >>> print(list(Range(9).onesided()))
            [0.0, 0.1111, 0.2222, 0.3333, 0.4444]


return list(self.onesided_gen())<EOL>

Return the one-sided frequency range as a list (see
        :meth:`onesided_gen` for details).


return list(self.twosided_gen())<EOL>

Return the two-sided frequency range as a list (see
        :meth:`twosided_gen` for details).


return list(self.centerdc_gen())<EOL>

Return the two-sided frequency range as a list (see
        :meth:`centerdc_gen` for details).


def __init__(self, data, data_y=None, sampling=<NUM_LIT:1.>,<EOL>detrend=None, scale_by_freq=True, NFFT=None):

<EOL>self.__data = None<EOL>self.__data_y = None<EOL>self.__sampling = None<EOL>self.__detrend = None<EOL>self.__scale_by_freq = None<EOL>self.__sides = None<EOL>self.__N = None<EOL>self.__NFFT = None<EOL>self.__df = None<EOL>self.__datatype = None<EOL>self.__psd = None<EOL>self.__method = None<EOL>self.data = data<EOL>if data_y is not None:<EOL><INDENT>self.data_y = data_y<EOL><DEDENT>self.sampling = sampling<EOL>self.sides = '<STR_LIT:default>'<EOL>self._range = Range(self.__data.size, sampling) <EOL>self.modified = True<EOL>self.sampling = sampling<EOL>self.scale_by_freq = scale_by_freq<EOL>self.NFFT = NFFT<EOL>self.method = self.__class__<EOL>

**Constructor**

        .. rubric:: Attributes:

        From the input parameters, the following attributes are set:

          * :attr:`data` (updates :attr:`N`, :attr:`df`, :attr:`datatype`)
          * :attr:`data_y` used for cross PSD only (correlogram)
          * :attr:`detrend`
          * :attr:`sampling` (updates :attr:`df`)
          * :attr:`scale_by_freq`
          * :attr:`NFFT` (reset :attr:`sides`, :attr:`df`)

        The following read-only attributes are set during the initialisation:

          * :attr:`datatype`
          * :attr:`df`
          * :attr:`N`

        And finally, additional read-write attributes are available:

          * :attr:`psd`: used to store the PSD data array, which size depends
            on :attr:`sides` i.e., one-sided for real data and two-sided for
            the complex data.
          * :attr:`sides`: if set, changed the :attr:`psd`.


<EOL>if sides is None:<EOL><INDENT>sides = self.sides<EOL><DEDENT>if sides not in self._sides_choices:<EOL><INDENT>raise errors.SpectrumChoiceError(sides, self._sides_choices)<EOL><DEDENT>if sides == '<STR_LIT>':<EOL><INDENT>return self._range.onesided()<EOL><DEDENT>if sides == '<STR_LIT>':<EOL><INDENT>return self._range.twosided()<EOL><DEDENT>if sides == '<STR_LIT>':<EOL><INDENT>return self._range.centerdc()<EOL><DEDENT>

Return the frequency vector according to :attr:`sides`


if sides == self.sides:<EOL><INDENT>return self.__psd<EOL><DEDENT>if self.datatype == '<STR_LIT>':<EOL><INDENT>assert sides != '<STR_LIT>',"<STR_LIT>"<EOL><DEDENT>if self.sides == '<STR_LIT>':<EOL><INDENT>logging.debug('<STR_LIT>')<EOL>if sides == '<STR_LIT>':<EOL><INDENT>logging.debug('<STR_LIT>')<EOL>newpsd = numpy.concatenate((self.psd[<NUM_LIT:0>:-<NUM_LIT:1>]/<NUM_LIT>, list(reversed(self.psd[<NUM_LIT:0>:-<NUM_LIT:1>]/<NUM_LIT>))))<EOL>newpsd[-<NUM_LIT:1>] = self.psd[-<NUM_LIT:1>]<EOL>newpsd[<NUM_LIT:0>] *= <NUM_LIT><EOL><DEDENT>elif sides == '<STR_LIT>':<EOL><INDENT>logging.debug('<STR_LIT>')<EOL>P0 = self.psd[<NUM_LIT:0>]<EOL>P1 = self.psd[-<NUM_LIT:1>]<EOL>newpsd = numpy.concatenate((self.psd[-<NUM_LIT:1>:<NUM_LIT:0>:-<NUM_LIT:1>]/<NUM_LIT>, self.psd[<NUM_LIT:0>:-<NUM_LIT:1>]/<NUM_LIT>))<EOL>newpsd[<NUM_LIT:0>] = P1<EOL><DEDENT><DEDENT>elif self.sides == '<STR_LIT>':<EOL><INDENT>logging.debug('<STR_LIT>')<EOL>if sides == '<STR_LIT>':<EOL><INDENT>logging.debug('<STR_LIT>')<EOL>midN = (len(self.psd)-<NUM_LIT:2>) / <NUM_LIT:2><EOL>newpsd = numpy.array(self.psd[<NUM_LIT:0>:int(midN)+<NUM_LIT:2>]*<NUM_LIT:2>)<EOL>newpsd[<NUM_LIT:0>] /= <NUM_LIT:2><EOL>newpsd[-<NUM_LIT:1>] = self.psd[-<NUM_LIT:1>]<EOL><DEDENT>elif sides == '<STR_LIT>':<EOL><INDENT>newpsd = stools.twosided_2_centerdc(self.psd)<EOL><DEDENT><DEDENT>elif self.sides == '<STR_LIT>': <EOL><INDENT>logging.debug('<STR_LIT>')<EOL>if sides == '<STR_LIT>':<EOL><INDENT>logging.debug('<STR_LIT>')<EOL>midN = int(len(self.psd) / <NUM_LIT:2>)<EOL>P1 = self.psd[<NUM_LIT:0>]<EOL>newpsd = numpy.append(self.psd[midN:]*<NUM_LIT:2>, P1)<EOL><DEDENT>elif sides == '<STR_LIT>':<EOL><INDENT>newpsd = stools.centerdc_2_twosided(self.psd)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>return newpsd<EOL>

This function returns the PSD in the **sides** format

        :param str sides: the PSD format in ['onesided', 'twosided', 'centerdc']
        :return: the expected PSD.

        .. doctest::

            from spectrum import *
            p = pcovar(marple_data, 15)
            centerdc_psd = p.get_converted_psd('centerdc')

        .. note:: this function does not change the object, in particular, it
            does not change the :attr:`psd` attribute. If you want to change
            the psd on the fly, change the attribute :attr:`sides`.


def plot(self, filename=None, norm=False, ylim=None,<EOL>sides=None,  **kargs):

import pylab<EOL>from pylab import ylim as plt_ylim<EOL>_ = self.psd<EOL>if sides is not None:<EOL><INDENT>if sides not in self._sides_choices:<EOL><INDENT>raise errors.SpectrumChoiceError(sides, self._sides_choices)<EOL><DEDENT><DEDENT>if sides is None or sides == self.sides:<EOL><INDENT>frequencies = self.frequencies()<EOL>psd = self.psd<EOL>sides = self.sides<EOL><DEDENT>elif sides is not None:<EOL><INDENT>if self.datatype == '<STR_LIT>':<EOL><INDENT>if sides == '<STR_LIT>':<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT><DEDENT>logging.debug("<STR_LIT>")<EOL>frequencies = self.frequencies(sides=sides)<EOL>psd = self.get_converted_psd(sides)<EOL><DEDENT>if len(psd) != len(frequencies):<EOL><INDENT>raise ValueError("<STR_LIT>" % (len(psd), len(frequencies)))<EOL><DEDENT>if '<STR_LIT>' in list(kargs.keys()):<EOL><INDENT>save_ax = pylab.gca()<EOL>pylab.sca(kargs['<STR_LIT>'])<EOL>rollback = True<EOL>del kargs['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>rollback = False<EOL><DEDENT>if norm:<EOL><INDENT>pylab.plot(frequencies, <NUM_LIT:10> * stools.log10(psd/max(psd)),  **kargs)<EOL><DEDENT>else:<EOL><INDENT>pylab.plot(frequencies, <NUM_LIT:10> * stools.log10(psd),**kargs)<EOL><DEDENT>pylab.xlabel('<STR_LIT>')<EOL>pylab.ylabel('<STR_LIT>')<EOL>pylab.grid(True)<EOL>if ylim:<EOL><INDENT>plt_ylim(ylim)<EOL><DEDENT>if sides == '<STR_LIT>':<EOL><INDENT>pylab.xlim(<NUM_LIT:0>, self.sampling/<NUM_LIT>)<EOL><DEDENT>elif sides == '<STR_LIT>':<EOL><INDENT>pylab.xlim(<NUM_LIT:0>, self.sampling)<EOL><DEDENT>elif sides == '<STR_LIT>':<EOL><INDENT>pylab.xlim(-self.sampling/<NUM_LIT>, self.sampling/<NUM_LIT>)<EOL><DEDENT>if filename:<EOL><INDENT>pylab.savefig(filename)<EOL><DEDENT>if rollback:<EOL><INDENT>pylab.sca(save_ax)<EOL><DEDENT>del psd, frequencies<EOL>

a simple plotting routine to plot the PSD versus frequency.

        :param str filename: save the figure into a file
        :param norm: False by default. If True, the PSD is normalised.
        :param ylim: readjust the y range .
        :param sides: if not provided, :attr:`sides` is used. See :attr:`sides`
            for details.
        :param kargs: any optional argument accepted by :func:`pylab.plot`.

        .. plot::
            :width: 80%
            :include-source:

            from spectrum import *
            p = Periodogram(marple_data)
            p.plot(norm=True, marker='o')


if self.scale_by_freq == False:<EOL><INDENT>return sum(self.psd) * len(self.psd)<EOL><DEDENT>else:<EOL><INDENT>return sum(self.psd) * self.df/(<NUM_LIT>*numpy.pi)<EOL><DEDENT>

r"""Return the power contained in the PSD

        if scale_by_freq is False, the power is:

        .. math:: P = N \sum_{k=1}^{N} P_{xx}(k)

        else, it is

        .. math:: P =  \sum_{k=1}^{N} P_{xx}(k) \frac{df}{2\pi}

        .. todo:: check these equations


def __init__(self, data, sampling=<NUM_LIT:1.>, ar_order=None, ma_order=None,<EOL>lag=-<NUM_LIT:1>, NFFT=None, detrend=None, scale_by_freq=True):

super(ParametricSpectrum, self).__init__(data, sampling=sampling,<EOL>NFFT=NFFT,<EOL>scale_by_freq=scale_by_freq,<EOL>detrend=detrend)<EOL>if ar_order is None and ma_order is None:<EOL><INDENT>raise errors.SpectrumARMAError<EOL><DEDENT>self.__ar_order = ar_order<EOL>self.__ma_order = ma_order<EOL>self.ar_order = ar_order<EOL>self.ma_order = ma_order<EOL>self.lag = lag<EOL>self.__ar = None<EOL>self.__ma = None<EOL>self.__reflection = None<EOL>self.__rho = None<EOL>

**Constructor**

        See the class documentation for the parameters.

        .. rubric:: Additional attributes to those inherited
            from :class:`Spectrum`:

        * :attr:`ar_order`, the ar order of the PSD estimates
        * :attr:`ma_order`, the ar order of the PSD estimates


def __init__(self, data, sampling=<NUM_LIT:1.>,<EOL>window='<STR_LIT>', NFFT=None, detrend=None,<EOL>scale_by_freq=True, lag=-<NUM_LIT:1>):

super(FourierSpectrum, self).__init__(data,<EOL>sampling=sampling, detrend=detrend,<EOL>scale_by_freq=scale_by_freq, NFFT=NFFT)<EOL>self.__window = None<EOL>self.__lag = None<EOL>self.lag = lag<EOL>self.window = window<EOL>

**Constructor**

        See the class documentation for the parameters.

        .. rubric:: Additional attributes to those inherited from

        :class:`Spectrum` are:

        * :attr:`lag`, a lag used to compute the autocorrelation
        * :attr:`window`, the tapering window to be used


from .periodogram import speriodogram<EOL>psd = speriodogram(self.data, window=self.window, sampling=self.sampling,<EOL>NFFT=self.NFFT, scale_by_freq=self.scale_by_freq,<EOL>detrend=self.detrend)<EOL>self.psd = psd<EOL>

An alias to :class:`~spectrum.periodogram.Periodogram`

        The parameters are extracted from the attributes. Relevant attributes
        ares :attr:`window`, attr:`sampling`, attr:`NFFT`, attr:`scale_by_freq`,
        :attr:`detrend`.

        .. plot::
            :width: 80%
            :include-source:

            from spectrum import datasets
            from spectrum import FourierSpectrum
            s = FourierSpectrum(datasets.data_cosine(), sampling=1024, NFFT=512)
            s.periodogram()
            s.plot()


assert len(x) >= order, "<STR_LIT>"<EOL>x = np.array(x)<EOL>N = len(x)<EOL>r0 = sum(abs(x)**<NUM_LIT>)<EOL>r1 = abs(x[<NUM_LIT:0>])**<NUM_LIT:2><EOL>rN = abs(x[N-<NUM_LIT:1>])**<NUM_LIT:2><EOL>pf = r0 - r1<EOL>pb = r0 - rN<EOL>delta = <NUM_LIT:1.> - r1 / r0<EOL>gamma = <NUM_LIT:1.> - rN / r0<EOL>c = np.zeros(N, dtype=complex)<EOL>d = np.zeros(N, dtype=complex)<EOL>r = np.zeros(N, dtype=complex)<EOL>af = np.zeros(N, dtype=complex)<EOL>ab = np.zeros(N, dtype=complex)<EOL>c[<NUM_LIT:0>] = x[N-<NUM_LIT:1>].conjugate() / r0<EOL>d[<NUM_LIT:0>] = x[<NUM_LIT:0>].conjugate() / r0<EOL>if order == <NUM_LIT:0>:<EOL><INDENT>pf = r0 / float(N)<EOL>pb = pf<EOL>return af, pf, ab, pb, <NUM_LIT:0><EOL><DEDENT>pbv = []<EOL>for m in range(<NUM_LIT:0>, order+<NUM_LIT:1>):<EOL><INDENT>logging.debug('<STR_LIT>', m)<EOL>logging.debug(c[<NUM_LIT:0>:<NUM_LIT:2>])<EOL>logging.debug(d[<NUM_LIT:0>:<NUM_LIT:2>])<EOL>r1 = <NUM_LIT:1.>/pf<EOL>r2 = <NUM_LIT:1.>/pb<EOL>r3 = <NUM_LIT:1.>/delta<EOL>r4 = <NUM_LIT:1.>/gamma<EOL>temp = <NUM_LIT:0.>+<NUM_LIT><EOL>for k in range(m+<NUM_LIT:1>, N):<EOL><INDENT>temp = temp + x[k]*x[k-m-<NUM_LIT:1>].conjugate()<EOL><DEDENT>r[m] =  temp.conjugate()<EOL>theta = x[<NUM_LIT:0>] * c[m]<EOL>if m == <NUM_LIT:0>:<EOL><INDENT>pass<EOL><DEDENT>else:<EOL><INDENT>for k in range(<NUM_LIT:0>, m):<EOL><INDENT>theta = theta + x[m-k] * c[k]                   <EOL>r[k] = r[k] - x[N-m-<NUM_LIT:1>] * x[N-m+k].conjugate() <EOL>temp = temp + af[m-k-<NUM_LIT:1>] * r[k].conjugate()<EOL><DEDENT><DEDENT>"""<STR_LIT>"""<EOL>c1 = -temp * r2<EOL>c2 = -r1 * temp.conjugate()<EOL>c3 = theta * r3<EOL>c4 = r4 *theta.conjugate()<EOL>af[m] = c1                    <EOL>ab[m] = c2                    <EOL>save = c[m]<EOL>c[m] = save + c3*d[m]<EOL>d[m] = d[m] + c4*save<EOL>if m == <NUM_LIT:0>:<EOL><INDENT>pass<EOL><DEDENT>else:<EOL><INDENT>for k in range(<NUM_LIT:0>, m):<EOL><INDENT>save = af[k]<EOL>af[k] = save + c1 * ab[m-k-<NUM_LIT:1>] <EOL>ab[m-k-<NUM_LIT:1>] = ab[m-k-<NUM_LIT:1>] + c2 * save   <EOL>save = c[k]<EOL>c[k] = save + c3*d[k]       <EOL>d[k] = d[k] + c4*save       <EOL><DEDENT><DEDENT>r5 = temp.real**<NUM_LIT:2> + temp.imag**<NUM_LIT:2><EOL>pf = pf - r5*r2         <EOL>pb = pb - r5*r1         <EOL>r5 = theta.real**<NUM_LIT:2> + theta.imag**<NUM_LIT:2><EOL>delta = delta - r5*r4               <EOL>gamma = gamma - r5*r3               <EOL>if m != order-<NUM_LIT:1>:<EOL><INDENT>pass<EOL><DEDENT>else:<EOL><INDENT>pf = pf / float(N-m-<NUM_LIT:1>)<EOL>pb = pb / float(N-m-<NUM_LIT:1>)<EOL>break<EOL><DEDENT>if pf > <NUM_LIT:0> and pb > <NUM_LIT:0>:<EOL><INDENT>pass<EOL><DEDENT>else:<EOL><INDENT>ValueError("<STR_LIT>")<EOL><DEDENT>if (delta > <NUM_LIT:0.> and delta <=<NUM_LIT:1> and gamma > <NUM_LIT:0.> and gamma <=<NUM_LIT:1>):<EOL><INDENT>pass<EOL><DEDENT>else:<EOL><INDENT>ValueError("<STR_LIT>")<EOL><DEDENT>r1 = <NUM_LIT:1.>/pf<EOL>r2 = <NUM_LIT:1.>/pb<EOL>r3 = <NUM_LIT:1.>/delta<EOL>r4 = <NUM_LIT:1.>/gamma<EOL>ef = x[m+<NUM_LIT:1>]<EOL>eb = x[(N-<NUM_LIT:1>)-m-<NUM_LIT:1>]<EOL>for k in range(<NUM_LIT:0>,m+<NUM_LIT:1>):<EOL><INDENT>ef = ef + af[k] * x[m-k]             <EOL>eb = eb + ab[k] * x[N-m+k-<NUM_LIT:1>]                   <EOL><DEDENT>c1 = ef*r3<EOL>c2 = eb*r4<EOL>c3 = eb.conjugate() * r2<EOL>c4 = ef.conjugate() * r1<EOL>for k in range(m, -<NUM_LIT:1>, -<NUM_LIT:1>):<EOL><INDENT>save = af[k]<EOL>af[k] = save + c1 * d[k]                    <EOL>d[k+<NUM_LIT:1>] = d[k] + c4 * save                    <EOL>save = ab[k]<EOL>ab[k] = save + c2 * c[m-k]                 <EOL>c[m-k] = c[m-k] + c3 * save              <EOL><DEDENT>c[m+<NUM_LIT:1>] = c3<EOL>d[<NUM_LIT:0>] = c4<EOL>r5 = ef.real**<NUM_LIT:2> + ef.imag**<NUM_LIT:2><EOL>pf = pf - r5 * r3                              <EOL>delta = delta-r5 * r1                        <EOL>r5 = eb.real**<NUM_LIT:2> + eb.imag**<NUM_LIT:2><EOL>pb = pb - r5 * r4                              <EOL>gamma = gamma-r5*r2                        <EOL>pbv.append(pb)<EOL>if (pf > <NUM_LIT:0.> and pb > <NUM_LIT:0.>):<EOL><INDENT>pass<EOL><DEDENT>else:<EOL><INDENT>ValueError("<STR_LIT>")<EOL><DEDENT>if (delta > <NUM_LIT:0.> and delta <= <NUM_LIT:1.>) and (gamma > <NUM_LIT:0.> and gamma <= <NUM_LIT:1.>):<EOL><INDENT>pass<EOL><DEDENT>else:<EOL><INDENT>ValueError("<STR_LIT>")<EOL><DEDENT><DEDENT>return af, pf, ab, pb, pbv<EOL>

r"""Estimate AR model parameters using covariance method

    This implementation is based on [Marple]_. This code is far more
    complicated and slower than :func:`arcovar` function, which is now the official version.
    See :func:`arcovar` for a detailed description of Covariance method.

    This function should be used in place of arcovar only if order<=4, for
    which :func:`arcovar` does not work.

    Fast algorithm for the solution of the covariance least squares normal
    equations from Marple.

    :param array X:  Array of complex data samples
    :param int oder: Order of linear prediction model

    :return:
        * AF   - Array of complex forward linear prediction coefficients
        * PF   - Real forward linear prediction variance at order IP
        * AB   - Array of complex backward linear prediction coefficients
        * PB   - Real backward linear prediction variance at order IP
        * PV   - store linear prediction coefficients

    .. note:: this code and the original code in Marple diverge for ip>10.
        it seems that this is related to single precision used with
        complex type in fortran whereas numpy uses double precision for
        complex type.

    :validation: the AR parameters are the same as those returned by
        a completely different function :func:`arcovar`.

    :References: [Marple]_


from spectrum import corrmtx<EOL>import scipy.linalg<EOL>X = corrmtx(x, order, '<STR_LIT>')<EOL>Xc = np.matrix(X[:, <NUM_LIT:1>:])<EOL>X1 = np.array(X[:, <NUM_LIT:0>])<EOL>a, _residues, _rank, _singular_values = scipy.linalg.lstsq(-Xc, X1)<EOL>Cz = np.dot(X1.conj().transpose(), Xc)<EOL>e = np.dot(X1.conj().transpose(), X1) + np.dot(Cz, a)<EOL>assert e.imag < <NUM_LIT>, '<STR_LIT>'<EOL>e = float(e.real) <EOL>return a, e<EOL>

r"""Simple and fast implementation of the covariance AR estimate

    This code is 10 times faster than :func:`arcovar_marple` and more importantly
    only 10 lines of code, compared to a 200 loc for :func:`arcovar_marple`

    :param array X:  Array of complex data samples
    :param int oder: Order of linear prediction model

    :return:
        * a - Array of complex forward linear prediction coefficients
        * e - error

    The covariance method fits a Pth order autoregressive (AR) model to the
    input signal, which is assumed to be the output of
    an AR system driven by white noise. This method minimizes the forward
    prediction error in the least-squares sense. The output vector
    contains the normalized estimate of the AR system parameters

    The white noise input variance estimate is also returned.

    If is the power spectral density of y(n), then:

    .. math:: \frac{e}{\left| A(e^{jw}) \right|^2} = \frac{e}{\left| 1+\sum_{k-1}^P a(k)e^{-jwk}\right|^2}

    Because the method characterizes the input data using an all-pole model,
    the correct choice of the model order p is important.

    .. plot::
        :width: 80%
        :include-source:

        from spectrum import arcovar, marple_data, arma2psd
        from pylab import plot, log10, linspace, axis

        ar_values, error = arcovar(marple_data, 15)
        psd = arma2psd(ar_values, sides='centerdc')
        plot(linspace(-0.5, 0.5, len(psd)), 10*log10(psd/max(psd)))
        axis([-0.5, 0.5, -60, 0])

    .. seealso:: :class:`pcovar`

    :validation: the AR parameters are the same as those returned by
        a completely different function :func:`arcovar_marple`.

    :References: [Mathworks]_


def __init__(self, data, order, NFFT=None, sampling=<NUM_LIT:1.>,<EOL>scale_by_freq=False):

super(pcovar, self).__init__(data, ar_order=order,<EOL>NFFT=NFFT, sampling=sampling,<EOL>scale_by_freq=scale_by_freq)<EOL>

**Constructor**

        For a detailled description of the parameters, see :func:`arcovar`.

        :param array data: input data (list or numpy.array)
        :param int order:
        :param int NFFT: total length of the final data sets (padded
            with zero if needed; default is 4096)
        :param float sampling: sampling frequency of the input :attr:`data`.


def speriodogram(x, NFFT=None, detrend=True, sampling=<NUM_LIT:1.>,<EOL>scale_by_freq=True, window='<STR_LIT>', axis=<NUM_LIT:0>):

x = np.array(x)<EOL>if x.ndim == <NUM_LIT:1>:<EOL><INDENT>axis = <NUM_LIT:0><EOL>r = x.shape[<NUM_LIT:0>]<EOL>w = Window(r, window)   <EOL>w = w.data<EOL><DEDENT>elif x.ndim == <NUM_LIT:2>:<EOL><INDENT>logging.debug('<STR_LIT>')<EOL>[r, c] = x.shape<EOL>w = np.array([Window(r, window).data for this in range(c)]).reshape(r,c) <EOL><DEDENT>if NFFT is None:<EOL><INDENT>NFFT = len(x)<EOL><DEDENT>isreal = np.isrealobj(x)<EOL>if detrend == True:<EOL><INDENT>m = np.mean(x, axis=axis)<EOL><DEDENT>else:<EOL><INDENT>m = <NUM_LIT:0><EOL><DEDENT>if isreal == True:<EOL><INDENT>if x.ndim == <NUM_LIT:2>:<EOL><INDENT>res =  (abs (rfft (x*w - m, NFFT, axis=<NUM_LIT:0>))) ** <NUM_LIT> / r<EOL><DEDENT>else:<EOL><INDENT>res =  (abs (rfft (x*w - m, NFFT, axis=-<NUM_LIT:1>))) ** <NUM_LIT> / r<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if x.ndim == <NUM_LIT:2>:<EOL><INDENT>res =  (abs (fft (x*w - m, NFFT, axis=<NUM_LIT:0>))) ** <NUM_LIT> / r<EOL><DEDENT>else:<EOL><INDENT>res =  (abs (fft (x*w - m, NFFT, axis=-<NUM_LIT:1>))) ** <NUM_LIT> / r<EOL><DEDENT><DEDENT>if scale_by_freq is True:<EOL><INDENT>df = sampling / float(NFFT)<EOL>res*= <NUM_LIT:2> * np.pi / df<EOL><DEDENT>if x.ndim == <NUM_LIT:1>:<EOL><INDENT>return res.transpose()<EOL><DEDENT>else:<EOL><INDENT>return res<EOL><DEDENT>

Simple periodogram, but matrices accepted.

    :param x: an array or matrix of data samples.
    :param NFFT: length of the data before FFT is computed (zero padding)
    :param bool detrend: detrend the data before co,puteing the FFT
    :param float sampling: sampling frequency of the input :attr:`data`.

    :param scale_by_freq:
    :param str window:

    :return: 2-sided PSD if complex data, 1-sided if real.

    if a matrix is provided (using numpy.matrix), then a periodogram
    is computed for each row. The returned matrix has the same shape as the input
    matrix.

    The mean of the input data is also removed from the data before computing
    the psd.

    .. plot::
        :width: 80%
        :include-source:

        from pylab import grid, semilogy
        from spectrum import data_cosine, speriodogram
        data = data_cosine(N=1024, A=0.1, sampling=1024, freq=200)
        semilogy(speriodogram(data, detrend=False, sampling=1024), marker='o')
        grid(True)

    .. plot::
        :width: 80%
        :include-source:

        import numpy
        from spectrum import speriodogram, data_cosine
        from pylab import figure, semilogy, figure ,imshow
        # create N data sets and make the frequency dependent on the time
        N = 100
        m = numpy.concatenate([data_cosine(N=1024, A=0.1, sampling=1024, freq=x)
            for x in range(1, N)]);
        m.resize(N, 1024)
        res = speriodogram(m)
        figure(1)
        semilogy(res)
        figure(2)
        imshow(res.transpose(), aspect='auto')

    .. todo:: a proper spectrogram class/function that takes care of normalisation


def WelchPeriodogram(data, NFFT=None,  sampling=<NUM_LIT:1.>, **kargs):

from pylab import psd<EOL>spectrum = Spectrum(data, sampling=<NUM_LIT:1.>)<EOL>P = psd(data, NFFT, Fs=sampling, **kargs)<EOL>spectrum.psd = P[<NUM_LIT:0>]<EOL>return P, spectrum<EOL>

r"""Simple periodogram wrapper of numpy.psd function.

    :param A: the input data
    :param int NFFT: total length of the final data sets (padded
        with zero if needed; default is 4096)
    :param str window:

    :Technical documentation:

    When we calculate the periodogram of a set of data we get an estimation
    of the spectral density. In fact as we use a Fourier transform and a
    truncated segments the spectrum is the convolution of the data with a
    rectangular window which Fourier transform is

    .. math::

        W(s)= \frac{1}{N^2} \left[ \frac{\sin(\pi s)}{\sin(\pi s/N)} \right]^2

    Thus oscillations and sidelobes appears around the main frequency. One aim of t he tapering is to reduced this effects. We multiply data by a window whose  sidelobes are much smaller than the main lobe. Classical window is hanning window.  But other windows are available. However we must take into account this energy and divide the spectrum by energy of taper used. Thus periodogram becomes :

    .. math::

        D_k \equiv \sum_{j=0}^{N-1}c_jw_j \; e^{2\pi ijk/N}  \qquad k=0,...,N-1

    .. math::

        P(0)=P(f_0)=\frac{1}{2\pi W_{ss}}\arrowvert{D_0}\arrowvert^2

    .. math::

        P(f_k)=\frac{1}{2\pi W_{ss}} \left[\arrowvert{D_k}\arrowvert^2+\arrowvert{D_{N-k}}\arrowvert^2\right]        \qquad k=0,1,...,     \left( \frac{1}{2}-1 \right)

    .. math::

        P(f_c)=P(f_{N/2})= \frac{1}{2\pi W_{ss}} \arrowvert{D_{N/2}}\arrowvert^2

    with

    .. math::

        {W_{ss}} \equiv N\sum_{j=0}^{N-1}w_j^2

    .. plot::
        :width: 80%
        :include-source:

        from spectrum import WelchPeriodogram, marple_data
        psd = WelchPeriodogram(marple_data, 256)


def DaniellPeriodogram(data, P, NFFT=None, detrend='<STR_LIT>', sampling=<NUM_LIT:1.>,<EOL>scale_by_freq=True, window='<STR_LIT>'):

psd = speriodogram(data, NFFT=NFFT, detrend=detrend, sampling=sampling,<EOL>scale_by_freq=scale_by_freq, window=window)<EOL>if len(psd) % <NUM_LIT:2> == <NUM_LIT:1>:<EOL><INDENT>datatype = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>datatype = '<STR_LIT>'<EOL><DEDENT>N = len(psd)<EOL>_slice = <NUM_LIT:2> * P + <NUM_LIT:1><EOL>if datatype == '<STR_LIT>': <EOL><INDENT>newN = np.ceil(psd.size/float(_slice))<EOL>if newN % <NUM_LIT:2> == <NUM_LIT:0>:<EOL><INDENT>newN = psd.size/_slice<EOL><DEDENT><DEDENT>else:<EOL><INDENT>newN = np.ceil(psd.size/float(_slice))<EOL>if newN % <NUM_LIT:2> == <NUM_LIT:1>:<EOL><INDENT>newN = psd.size/_slice<EOL><DEDENT><DEDENT>newpsd = np.zeros(int(newN)) <EOL>for i in range(<NUM_LIT:0>, newpsd.size):<EOL><INDENT>count = <NUM_LIT:0> <EOL>for n in range(i*_slice-P, i*_slice+P+<NUM_LIT:1>): <EOL><INDENT>if n > <NUM_LIT:0> and n<N: <EOL><INDENT>count += <NUM_LIT:1><EOL>newpsd[i] += psd[n]<EOL><DEDENT><DEDENT>newpsd[i] /= float(count)<EOL><DEDENT>if datatype == '<STR_LIT>':<EOL><INDENT>freq = np.linspace(<NUM_LIT:0>, sampling, len(newpsd))<EOL><DEDENT>else:<EOL><INDENT>df = <NUM_LIT:1.> / sampling<EOL>freq = np.linspace(<NUM_LIT:0>,sampling/<NUM_LIT>, len(newpsd))<EOL><DEDENT>return newpsd, freq<EOL>

r"""Return Daniell's periodogram.

    To reduce fast fluctuations of the spectrum one idea proposed by daniell
    is to average each value with points in its neighboorhood. It's like
    a low filter.

    .. math:: \hat{P}_D[f_i]= \frac{1}{2P+1} \sum_{n=i-P}^{i+P} \tilde{P}_{xx}[f_n]

    where P is the number of points to average.

    Daniell's periodogram is the convolution of the spectrum with a low filter:

    .. math:: \hat{P}_D(f)=   \hat{P}_{xx}(f)*H(f)

    Example::

        >>> DaniellPeriodogram(data, 8)

    if N/P is not integer, the final values of the original PSD are not used.

    using DaniellPeriodogram(data, 0) should give the original PSD.


def __init__(self, data, sampling=<NUM_LIT:1.>,<EOL>window='<STR_LIT>', NFFT=None, scale_by_freq=False,<EOL>detrend=None):

super(Periodogram, self).__init__(data,<EOL>window=window,<EOL>sampling=sampling,<EOL>NFFT=NFFT,<EOL>scale_by_freq=scale_by_freq,<EOL>detrend=detrend)<EOL>

**Periodogram Constructor**

        :param array data: input data (list or numpy.array)
        :param float sampling: sampling frequency of the input :attr:`data`.
        :param str window: a tapering window. See :class:`~spectrum.window.Window`.
        :param int NFFT: total length of the final data sets (padded with zero
            if needed; default is 4096)
        :param bool scale_by_freq:
        :param str detrend:


def __init__(self, data, P, sampling=<NUM_LIT:1.>,<EOL>window='<STR_LIT>', NFFT=None, scale_by_freq=True,<EOL>detrend=None):

super(pdaniell, self).__init__(data,<EOL>window=window,<EOL>sampling=sampling,<EOL>NFFT=NFFT,<EOL>scale_by_freq=scale_by_freq,<EOL>detrend=detrend)<EOL>self.P = P<EOL>

**pdaniell Constructor**

        :param array data:  input data (list or numpy.array)
        :param int P:       number of neighbours to average over.
        :param float sampling: sampling frequency of the input :attr:`data`.
        :param str window:  a tapering window. See :class:`~spectrum.window.Window`.
        :param int NFFT: total length of the final data sets (padded with
            zero if needed; default is 4096)
        :param bool scale_by_freq:
        :param str detrend:


def minvar(X, order, sampling=<NUM_LIT:1.>, NFFT=default_NFFT):

errors.is_positive_integer(order)<EOL>errors.is_positive_integer(NFFT)<EOL>psi = np.zeros(NFFT, dtype=complex)<EOL>A, P, k = arburg (X, order - <NUM_LIT:1>)<EOL>A = np.insert(A, <NUM_LIT:0>, <NUM_LIT:1.>+<NUM_LIT>)<EOL>"""<STR_LIT>"""<EOL>for K in range(<NUM_LIT:0>, order):<EOL><INDENT>SUM = <NUM_LIT:0.><EOL>MK = order-K<EOL>for I in range(<NUM_LIT:0>, order - K):<EOL><INDENT>SUM = SUM + float(MK-<NUM_LIT:2>*I) * A[I].conjugate()*A[I+K]  <EOL><DEDENT>SUM = SUM/P<EOL>if K != <NUM_LIT:0>:<EOL><INDENT>psi[NFFT-K] = SUM.conjugate()<EOL><DEDENT>psi[K] = SUM<EOL><DEDENT>psi = fft(psi, NFFT)<EOL>PSD = sampling / np.real(psi)<EOL>return PSD, A, k<EOL>

r"""Minimum Variance Spectral Estimation (MV)

    This function computes the minimum variance spectral estimate using
    the Musicus procedure.  The Burg algorithm from :func:`~spectrum.burg.arburg`
    is used for the estimation of the autoregressive parameters.
    The MV spectral estimator is given by:

    .. math:: P_{MV}(f) = \frac{T}{e^H(f) R^{-1}_p e(f)}

    where :math:`R^{-1}_p` is the inverse of the estimated autocorrelation
    matrix  (Toeplitz) and :math:`e(f)` is the complex sinusoid vector.

    :param X: Array of complex or real data samples (length N)
    :param int order: Dimension of correlation matrix (AR order = order - 1 )
    :param float T: Sample interval (PSD scaling)
    :param int NFFT: length of the final PSD

    :return:
        * PSD  - Power spectral density values (two-sided)
        * AR   - AR coefficients (Burg algorithm)
        * k    - Reflection coefficients (Burg algorithm)

    .. note:: The MV spectral estimator is not a true PSD function because the
        area under the MV estimate does not represent the total power in the
        measured process. MV minimises the variance of the output of a narrowband
        filter and adpats itself to the spectral content of the input data
        at each frequency.

    :Example: The following example computes a PSD estimate using :func:`minvar`
        The output PSD is transformed to a ``centerdc`` PSD and plotted.

    .. plot::
        :width: 80%
        :include-source:

        from spectrum import *
        from pylab import plot, log10, linspace, xlim
        psd, A, k = minvar(marple_data, 15)
        psd = twosided_2_centerdc(psd) # switch positive and negative freq
        f = linspace(-0.5, 0.5, len(psd))
        plot(f, 10 * log10(psd/max(psd)))
        xlim(-0.5, 0.5 )

    .. seealso::

        * External functions used are :meth:`~spectrum.burg.arburg`
          and  numpy.fft.fft
        * :class:`pminvar`, a Class dedicated to MV method.

    :Reference: [Marple]_


def __init__(self, data, order, NFFT=None, sampling=<NUM_LIT:1.>, scale_by_freq=False):

super(pminvar, self).__init__(data, ar_order=order, sampling=sampling,<EOL>NFFT=NFFT, scale_by_freq=scale_by_freq)<EOL>

**Constructor**

        For a detailled description of the parameters, see :func:`minvar`.

        :param array data: input data (list or numpy.array)
        :param int order:
        :param int NFFT: total length of the final data sets (padded with
            zero if needed; default is 4096)
        :param float sampling: sampling frequency of the input :attr:`data`.


def LEVINSON(r, order=None, allow_singularity=False):

<EOL>T0  = numpy.real(r[<NUM_LIT:0>])<EOL>T = r[<NUM_LIT:1>:]<EOL>M = len(T)<EOL>if order is None:<EOL><INDENT>M = len(T)<EOL><DEDENT>else:<EOL><INDENT>assert order <= M, '<STR_LIT>'<EOL>M = order<EOL><DEDENT>realdata = numpy.isrealobj(r)<EOL>if realdata is True:<EOL><INDENT>A = numpy.zeros(M, dtype=float)<EOL>ref = numpy.zeros(M, dtype=float)<EOL><DEDENT>else:<EOL><INDENT>A = numpy.zeros(M, dtype=complex)<EOL>ref = numpy.zeros(M, dtype=complex)<EOL><DEDENT>P = T0<EOL>for k in range(<NUM_LIT:0>, M):<EOL><INDENT>save = T[k]<EOL>if k == <NUM_LIT:0>:<EOL><INDENT>temp = -save / P<EOL><DEDENT>else:<EOL><INDENT>for j in range(<NUM_LIT:0>, k):<EOL><INDENT>save = save + A[j] * T[k-j-<NUM_LIT:1>]<EOL><DEDENT>temp = -save / P<EOL><DEDENT>if realdata:<EOL><INDENT>P = P * (<NUM_LIT:1.> - temp**<NUM_LIT>)<EOL><DEDENT>else:<EOL><INDENT>P = P * (<NUM_LIT:1.> - (temp.real**<NUM_LIT:2>+temp.imag**<NUM_LIT:2>))<EOL><DEDENT>if P <= <NUM_LIT:0> and allow_singularity==False:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>A[k] = temp<EOL>ref[k] = temp <EOL>if k == <NUM_LIT:0>:<EOL><INDENT>continue<EOL><DEDENT>khalf = (k+<NUM_LIT:1>)//<NUM_LIT:2><EOL>if realdata is True:<EOL><INDENT>for j in range(<NUM_LIT:0>, khalf):<EOL><INDENT>kj = k-j-<NUM_LIT:1><EOL>save = A[j]<EOL>A[j] = save + temp * A[kj]<EOL>if j != kj:<EOL><INDENT>A[kj] += temp*save<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>for j in range(<NUM_LIT:0>, khalf):<EOL><INDENT>kj = k-j-<NUM_LIT:1><EOL>save = A[j]<EOL>A[j] = save + temp * A[kj].conjugate()<EOL>if j != kj:<EOL><INDENT>A[kj] = A[kj] + temp * save.conjugate()<EOL><DEDENT><DEDENT><DEDENT><DEDENT>return A, P, ref<EOL>

r"""Levinson-Durbin recursion.

    Find the coefficients of a length(r)-1 order autoregressive linear process

    :param r: autocorrelation sequence of length N + 1 (first element being the zero-lag autocorrelation)
    :param order: requested order of the autoregressive coefficients. default is N.
    :param allow_singularity: false by default. Other implementations may be True (e.g., octave)

    :return:
        * the `N+1` autoregressive coefficients :math:`A=(1, a_1...a_N)`
        * the prediction errors
        * the `N` reflections coefficients values

    This algorithm solves the set of complex linear simultaneous equations
    using Levinson algorithm.

    .. math::

        \bold{T}_M \left( \begin{array}{c} 1 \\ \bold{a}_M \end{array} \right) =
        \left( \begin{array}{c} \rho_M \\ \bold{0}_M  \end{array} \right)

    where :math:`\bold{T}_M` is a Hermitian Toeplitz matrix with elements
    :math:`T_0, T_1, \dots ,T_M`.

    .. note:: Solving this equations by Gaussian elimination would
        require :math:`M^3` operations whereas the levinson algorithm
        requires :math:`M^2+M` additions and :math:`M^2+M` multiplications.

    This is equivalent to solve the following symmetric Toeplitz system of
    linear equations

    .. math::

        \left( \begin{array}{cccc}
        r_1 & r_2^* & \dots & r_{n}^*\\
        r_2 & r_1^* & \dots & r_{n-1}^*\\
        \dots & \dots & \dots & \dots\\
        r_n & \dots & r_2 & r_1 \end{array} \right)
        \left( \begin{array}{cccc}
        a_2\\
        a_3 \\
        \dots \\
        a_{N+1}  \end{array} \right)
        =
        \left( \begin{array}{cccc}
        -r_2\\
        -r_3 \\
        \dots \\
        -r_{N+1}  \end{array} \right)

    where :math:`r = (r_1  ... r_{N+1})` is the input autocorrelation vector, and
    :math:`r_i^*` denotes the complex conjugate of :math:`r_i`. The input r is typically
    a vector of autocorrelation coefficients where lag 0 is the first
    element :math:`r_1`.

    .. doctest::

        >>> import numpy; from spectrum import LEVINSON
        >>> T = numpy.array([3., -2+0.5j, .7-1j])
        >>> a, e, k = LEVINSON(T)


a = numpy.array(a)<EOL>realdata = numpy.isrealobj(a)<EOL>assert a[<NUM_LIT:0>] == <NUM_LIT:1>, '<STR_LIT>'<EOL>p = len(a)<EOL>if p < <NUM_LIT:2>:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>if realdata == True:<EOL><INDENT>U = numpy.zeros((p, p)) <EOL><DEDENT>else:<EOL><INDENT>U = numpy.zeros((p, p), dtype=complex)<EOL><DEDENT>U[:, p-<NUM_LIT:1>] = numpy.conj(a[-<NUM_LIT:1>::-<NUM_LIT:1>]) <EOL>p = p -<NUM_LIT:1><EOL>e = numpy.zeros(p)<EOL>e[-<NUM_LIT:1>] = efinal <EOL>for k in range(p-<NUM_LIT:1>, <NUM_LIT:0>, -<NUM_LIT:1>):<EOL><INDENT>[a, e[k-<NUM_LIT:1>]] = levdown(a, e[k])<EOL>U[:, k] = numpy.concatenate((numpy.conj(a[-<NUM_LIT:1>::-<NUM_LIT:1>].transpose()) ,<EOL>[<NUM_LIT:0>]*(p-k) ))<EOL><DEDENT>e0 = e[<NUM_LIT:0>]/(<NUM_LIT:1.>-abs(a[<NUM_LIT:1>]**<NUM_LIT:2>)) <EOL>U[<NUM_LIT:0>,<NUM_LIT:0>] = <NUM_LIT:1>                <EOL>kr = numpy.conj(U[<NUM_LIT:0>,<NUM_LIT:1>:])     <EOL>kr = kr.transpose()                 <EOL>R = numpy.zeros(<NUM_LIT:1>, dtype=complex)<EOL>k = <NUM_LIT:1><EOL>R0 = e0 <EOL>R[<NUM_LIT:0>] = -numpy.conj(U[<NUM_LIT:0>,<NUM_LIT:1>])*R0   <EOL>for k in range(<NUM_LIT:1>,p):<EOL><INDENT>r = -sum(numpy.conj(U[k-<NUM_LIT:1>::-<NUM_LIT:1>,k])*R[-<NUM_LIT:1>::-<NUM_LIT:1>]) - kr[k]*e[k-<NUM_LIT:1>]<EOL>R = numpy.insert(R, len(R), r)<EOL><DEDENT>R = numpy.insert(R, <NUM_LIT:0>, e0)<EOL>return R, U, kr, e<EOL>

computes the autocorrelation coefficients, R based
    on the prediction polynomial A and the final prediction error Efinal,
    using the stepdown algorithm.

    Works for real or complex data

    :param a:
    :param efinal:

    :return:
        * R, the autocorrelation
        * U  prediction coefficient
        * kr reflection coefficients
        * e errors

    A should be a minimum phase polynomial and A(1) is assumed to be unity.

    :returns: (P+1) by (P+1) upper triangular matrix, U,
        that holds the i'th order prediction polynomials
        Ai, i=1:P, where P is the order of the input
        polynomial, A.

             [ 1  a1(1)*  a2(2)* ..... aP(P)  * ]
             [ 0  1       a2(1)* ..... aP(P-1)* ]
       U  =  [ .................................]
             [ 0  0       0      ..... 1        ]

    from which the i'th order prediction polynomial can be extracted
    using Ai=U(i+1:-1:1,i+1)'. The first row of U contains the
    conjugates of the reflection coefficients, and the K's may be
    extracted using, K=conj(U(1,2:end)).

    .. todo:: remove the conjugate when data is real data, clean up the code
       test and doc.


<EOL>if anxt[<NUM_LIT:0>] != <NUM_LIT:1>:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>anxt = anxt[<NUM_LIT:1>:] <EOL>knxt = anxt[-<NUM_LIT:1>]<EOL>if knxt == <NUM_LIT:1.0>:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>acur = (anxt[<NUM_LIT:0>:-<NUM_LIT:1>]-knxt*numpy.conj(anxt[-<NUM_LIT:2>::-<NUM_LIT:1>]))/(<NUM_LIT:1.>-abs(knxt)**<NUM_LIT:2>)<EOL>ecur = None<EOL>if enxt is not None:<EOL><INDENT>ecur = enxt/(<NUM_LIT:1.>-numpy.dot(knxt.conj().transpose(),knxt))<EOL><DEDENT>acur = numpy.insert(acur, <NUM_LIT:0>, <NUM_LIT:1>)<EOL>return acur, ecur<EOL>

One step backward Levinson recursion

    :param anxt:
    :param enxt:
    :return:
        * acur the P'th order prediction polynomial based on the P+1'th order prediction polynomial, anxt.
        * ecur the the P'th order prediction error  based on the P+1'th order prediction error, enxt.

    ..  * knxt the P+1'th order reflection coefficient.


if acur[<NUM_LIT:0>] != <NUM_LIT:1>:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>acur = acur[<NUM_LIT:1>:] <EOL>anxt = numpy.concatenate((acur, [<NUM_LIT:0>])) + knxt * numpy.concatenate((numpy.conj(acur[-<NUM_LIT:1>::-<NUM_LIT:1>]), [<NUM_LIT:1>]))<EOL>enxt = None<EOL>if ecur is not None:<EOL><INDENT>enxt = (<NUM_LIT:1.> - numpy.dot(numpy.conj(knxt), knxt)) * ecur<EOL><DEDENT>anxt = numpy.insert(anxt, <NUM_LIT:0>, <NUM_LIT:1>)<EOL>return anxt, enxt<EOL>

LEVUP  One step forward Levinson recursion

    :param acur:
    :param knxt:
    :return:
        * anxt the P+1'th order prediction polynomial based on the P'th order prediction polynomial, acur, and the
          P+1'th order reflection coefficient, Knxt.
        * enxt the P+1'th order prediction  prediction error, based on the P'th order prediction error, ecur.

    :References:  P. Stoica R. Moses, Introduction to Spectral Analysis  Prentice Hall, N.J., 1997, Chapter 3.


def arma2psd(A=None, B=None, rho=<NUM_LIT:1.>, T=<NUM_LIT:1.>, NFFT=<NUM_LIT>, sides='<STR_LIT:default>',<EOL>norm=False):

if NFFT is None:<EOL><INDENT>NFFT = <NUM_LIT><EOL><DEDENT>if A is None and B is None:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>psd = np.zeros(NFFT, dtype=complex)<EOL>if A is not None:<EOL><INDENT>ip = len(A)<EOL>den = np.zeros(NFFT, dtype=complex)<EOL>den[<NUM_LIT:0>] = <NUM_LIT:1.>+<NUM_LIT><EOL>for k in range(<NUM_LIT:0>, ip):<EOL><INDENT>den[k+<NUM_LIT:1>] = A[k]<EOL><DEDENT>denf = fft(den, NFFT)<EOL><DEDENT>if B is not None:<EOL><INDENT>iq = len(B)<EOL>num = np.zeros(NFFT, dtype=complex)<EOL>num[<NUM_LIT:0>] = <NUM_LIT:1.>+<NUM_LIT><EOL>for k in range(<NUM_LIT:0>, iq):<EOL><INDENT>num[k+<NUM_LIT:1>] = B[k]<EOL><DEDENT>numf = fft(num, NFFT)<EOL><DEDENT>if A is not None and B is not None:<EOL><INDENT>psd = rho / T * abs(numf)**<NUM_LIT> / abs(denf)**<NUM_LIT><EOL><DEDENT>elif A is not None:<EOL><INDENT>psd = rho / T / abs(denf)**<NUM_LIT><EOL><DEDENT>elif B is not None:<EOL><INDENT>psd = rho / T * abs(numf)**<NUM_LIT><EOL><DEDENT>psd = np.real(psd)<EOL>if sides != '<STR_LIT:default>':<EOL><INDENT>from . import tools<EOL>assert sides in ['<STR_LIT>']<EOL>if sides == '<STR_LIT>':<EOL><INDENT>psd = tools.twosided_2_centerdc(psd)<EOL><DEDENT><DEDENT>if norm == True:<EOL><INDENT>psd /= max(psd)<EOL><DEDENT>return psd<EOL>

r"""Computes power spectral density given ARMA values.

    This function computes the power spectral density values
    given the ARMA parameters of an ARMA model. It assumes that
    the driving sequence is a white noise process of zero mean and
    variance :math:`\rho_w`. The sampling frequency and noise variance are
    used to scale the PSD output, which length is set by the user with the
    `NFFT` parameter.

    :param array A:   Array of AR parameters (complex or real)
    :param array B:   Array of MA parameters (complex or real)
    :param float rho: White noise variance to scale the returned PSD
    :param float T:   Sample interval in seconds to scale the returned PSD
    :param int NFFT:  Final size of the PSD
    :param str sides: Default PSD is two-sided, but sides can be set to centerdc.

    .. warning:: By convention, the AR or MA arrays does not contain the
        A0=1 value.

    If :attr:`B` is None, the model is a pure AR model. If :attr:`A` is None,
    the model is a pure MA model.

    :return: two-sided PSD

    .. rubric:: Details:

    AR case: the power spectral density is:

    .. math:: P_{ARMA}(f) = T \rho_w \left|\frac{B(f)}{A(f)}\right|^2

    where:

    .. math:: A(f) = 1 + \sum_{k=1}^q b(k) e^{-j2\pi fkT}
    .. math:: B(f) = 1 + \sum_{k=1}^p a(k) e^{-j2\pi fkT}

    .. rubric:: **Example:**

    .. plot::
        :width: 80%
        :include-source:

        import spectrum.arma
        from pylab import plot, log10, legend
        plot(10*log10(spectrum.arma.arma2psd([1,0.5],[0.5,0.5])), label='ARMA(2,2)')
        plot(10*log10(spectrum.arma.arma2psd([1,0.5],None)), label='AR(2)')
        plot(10*log10(spectrum.arma.arma2psd(None,[0.5,0.5])), label='MA(2)')
        legend()

    :References: [Marple]_


R = CORRELATION(X, maxlags=lag, norm='<STR_LIT>')<EOL>R0 = R[<NUM_LIT:0>]<EOL>MPQ = lag - Q + P<EOL>N = len(X)<EOL>Y = np.zeros(N-P, dtype=complex)<EOL>for K in range(<NUM_LIT:0>, MPQ):<EOL><INDENT>KPQ = K + Q - P+<NUM_LIT:1><EOL>if KPQ < <NUM_LIT:0>:<EOL><INDENT>Y[K] = R[-KPQ].conjugate()<EOL><DEDENT>if KPQ == <NUM_LIT:0>:<EOL><INDENT>Y[K] = R0<EOL><DEDENT>if KPQ > <NUM_LIT:0>:<EOL><INDENT>Y[K] = R[KPQ]<EOL><DEDENT><DEDENT>Y.resize(lag)<EOL>if P <= <NUM_LIT:4>:<EOL><INDENT>res = arcovar_marple(Y.copy(), P)    <EOL>ar_params = res[<NUM_LIT:0>]<EOL><DEDENT>else:<EOL><INDENT>res = arcovar(Y.copy(), P)    <EOL>ar_params = res[<NUM_LIT:0>]<EOL><DEDENT>Y.resize(N-P)<EOL>for k in range(P, N):<EOL><INDENT>SUM = X[k]<EOL>for j in range(<NUM_LIT:0>, P):<EOL><INDENT>SUM = SUM + ar_params[j] * X[k-j-<NUM_LIT:1>]   <EOL><DEDENT>Y[k-P] = SUM<EOL><DEDENT>ma_params, rho = ma(Y, Q, <NUM_LIT:2>*Q)     <EOL>return ar_params, ma_params, rho<EOL>

Autoregressive and moving average estimators.

    This function provides an estimate of the autoregressive
    parameters, the moving average parameters, and the driving
    white noise variance of  an ARMA(P,Q) for a complex or real data sequence.

    The parameters are estimated using three steps:

        * Estimate the AR parameters from the original data based on a least
          squares modified Yule-Walker technique,
        * Produce a residual time sequence by filtering the original data
          with a filter based on the AR parameters,
        * Estimate the MA parameters from the residual time sequence.

    :param array X: Array of data samples (length N)
    :param int P: Desired number of AR parameters
    :param int Q: Desired number of MA parameters
    :param int lag: Maximum lag to use for autocorrelation estimates

    :return:
        * A     - Array of complex P AR parameter estimates
        * B     - Array of complex Q MA parameter estimates
        * RHO   - White noise variance estimate

    .. note::
      *  lag must be >= Q (MA order)

    **dependencies**:
        * :meth:`spectrum.correlation.CORRELATION`
        * :meth:`spectrum.covar.arcovar`
        * :meth:`spectrum.arma.ma`

    .. plot::
        :width: 80%
        :include-source:

        from spectrum import arma_estimate, arma2psd, marple_data
        import pylab

        a,b, rho = arma_estimate(marple_data, 15, 15, 30)
        psd = arma2psd(A=a, B=b, rho=rho, sides='centerdc', norm=True)
        pylab.plot(10 * pylab.log10(psd))
        pylab.ylim([-50,0])

    :reference: [Marple]_


if Q <= <NUM_LIT:0> or Q >= M:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>a, rho, _c = yulewalker.aryule(X, M, '<STR_LIT>')   <EOL>a = np.insert(a, <NUM_LIT:0>, <NUM_LIT:1>)<EOL>ma_params, _p, _c = yulewalker.aryule(a, Q, '<STR_LIT>')    <EOL>return ma_params, rho<EOL>

Moving average estimator.

    This program provides an estimate of the moving average parameters
    and driving noise variance for a data sequence based on a
    long AR model and a least squares fit.

    :param array X: The input data array
    :param int Q: Desired MA model order (must be >0 and <M)
    :param int M: Order of "long" AR model (suggest at least 2*Q )

    :return:
        * MA    - Array of Q complex MA parameter estimates
        * RHO   - Real scalar of white noise variance estimate

    .. plot::
        :width: 80%
        :include-source:

        from spectrum import arma2psd, ma, marple_data
        import pylab

        # Estimate 15 Ma parameters
        b, rho = ma(marple_data, 15, 30)
        # Create the PSD from those MA parameters
        psd = arma2psd(B=b, rho=rho, sides='centerdc')
        # and finally plot the PSD
        pylab.plot(pylab.linspace(-0.5, 0.5, 4096), 10 * pylab.log10(psd/max(psd)))
        pylab.axis([-0.5, 0.5, -30, 0])

    :reference: [Marple]_


def __init__(self, data, P, Q, lag, NFFT=None, sampling=<NUM_LIT:1.>,<EOL>scale_by_freq=False):

super(parma, self).__init__(data, ma_order=Q, ar_order=P, lag=lag,<EOL>NFFT=NFFT, sampling=sampling,<EOL>scale_by_freq=scale_by_freq)<EOL>self.lag = lag<EOL>

**Constructor:**

        For a detailed description of the parameters, see :func:`arma_estimate`.

        :param array data:     input data (list or numpy.array)
        :param int P:
        :param int Q:
        :param int lag:
        :param int NFFT: total length of the final data sets (padded with
            zero if needed; default is 4096)
        :param float sampling: sampling frequency of the input :attr:`data`.


def __init__(self, data, Q, M, NFFT=None, sampling=<NUM_LIT:1.>,<EOL>scale_by_freq=False):

super(pma, self).__init__(data, ma_order=Q, ar_order=M,<EOL>NFFT=NFFT, sampling=sampling,<EOL>scale_by_freq=scale_by_freq)<EOL>

**Constructor:**

        For a detailed description of the parameters, see :func:`ma`.

        :param array data:     input data (list or numpy.array)
        :param int Q:          MA order
        :param int M:          AR model used to estimate the MA parameters
        :param int NFFT:       total length of the final data sets (padded with zero
                               if needed; default is 4096)
        :param float sampling: sampling frequency of the input :attr:`data`.


x = np.array(X)<EOL>N = len(x)<EOL>if order <= <NUM_LIT:0.>:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>rho = sum(abs(x)**<NUM_LIT>) / N  <EOL>den = rho * <NUM_LIT> * N<EOL>ef = np.zeros(N, dtype=complex)<EOL>eb = np.zeros(N, dtype=complex)<EOL>for j in range(<NUM_LIT:0>, N):  <EOL><INDENT>ef[j] = x[j]<EOL>eb[j] = x[j]<EOL><DEDENT>a = np.zeros(<NUM_LIT:1>, dtype=complex)<EOL>a[<NUM_LIT:0>] = <NUM_LIT:1><EOL>ref = np.zeros(order, dtype=complex)<EOL>temp = <NUM_LIT:1.><EOL>E = np.zeros(order+<NUM_LIT:1>)<EOL>E[<NUM_LIT:0>] = rho<EOL>for m in range(<NUM_LIT:0>, order):<EOL><INDENT>efp = ef[<NUM_LIT:1>:]<EOL>ebp = eb[<NUM_LIT:0>:-<NUM_LIT:1>]<EOL>num = -<NUM_LIT>* np.dot(ebp.conj().transpose(),  efp)<EOL>den = np.dot(efp.conj().transpose(),  efp)<EOL>den += np.dot(ebp,  ebp.conj().transpose())<EOL>ref[m] = num / den<EOL>ef = efp + ref[m] * ebp<EOL>eb = ebp + ref[m].conj().transpose() * efp<EOL>a.resize(len(a)+<NUM_LIT:1>)<EOL>a = a + ref[m] * np.flipud(a).conjugate()<EOL>E[m+<NUM_LIT:1>] = (<NUM_LIT:1> - ref[m].conj().transpose()*ref[m]) * E[m]<EOL><DEDENT>return a, E[-<NUM_LIT:1>], ref<EOL>

This version is 10 times faster than arburg, but the output rho is not correct.

    returns [1 a0,a1, an-1]