示例#1
0
def AR_psd(ak, sigma_v, n_freqs=1024, sides="onesided"):
    r"""
    Compute the PSD of an AR process, based on the process coefficients and
    covariance

    n_freqs : int
        The number of spacings on the frequency grid from [-PI,PI).
        If sides=='onesided', n_freqs/2+1 frequencies are computed from [0,PI]

    sides : str (optional)
        Indicates whether to return a one-sided or two-sided PSD

    Returns
    -------
    (w, ar_psd)
    w : Array of normalized frequences from [-.5, .5) or [0,.5]
    ar_psd : A PSD estimate computed by sigma_v / |1-a(f)|**2 , where
             a(f) = DTFT(ak)


    """
    # compute the psd as |H(f)|**2, where H(f) is the transfer function
    # for this model s[n] = a1*s[n-1] + a2*s[n-2] + ... aP*s[n-P] + v[n]
    # Taken as a IIR system with unit-variance white noise input e[n]
    # and output s[n],
    # b0*e[n] = w0*s[n] + w1*s[n-1] + w2*s[n-2] + ... + wP*s[n-P],
    # where b0 = sqrt(VAR{v[n]}), w0 = 1, and wk = -ak for k>0
    # the transfer function here is H(f) = DTFT(w)
    # leading to Sxx(f)/Exx(f) = |H(f)|**2 = VAR{v[n]} / |W(f)|**2
    w, hw = freq_response(sigma_v ** 0.5, a=np.r_[1, -ak], n_freqs=n_freqs, sides=sides)
    ar_psd = (hw * hw.conj()).real
    return (w, 2 * ar_psd) if sides == "onesided" else (w, ar_psd)
示例#2
0
def AR_psd(ak, sigma_v, n_freqs=1024, sides='onesided'):
    r"""
    Compute the PSD of an AR process, based on the process coefficients and
    covariance

    n_freqs : int
        The number of spacings on the frequency grid from [-PI,PI).
        If sides=='onesided', n_freqs/2+1 frequencies are computed from [0,PI]

    sides : str (optional)
        Indicates whether to return a one-sided or two-sided PSD

    Returns
    -------
    (w, ar_psd)
    w : Array of normalized frequences from [-.5, .5) or [0,.5]
    ar_psd : A PSD estimate computed by sigma_v / |1-a(f)|**2 , where
             a(f) = DTFT(ak)


    """
    # compute the psd as |H(f)|**2, where H(f) is the transfer function
    # for this model s[n] = a1*s[n-1] + a2*s[n-2] + ... aP*s[n-P] + v[n]
    # Taken as a IIR system with unit-variance white noise input e[n]
    # and output s[n],
    # b0*e[n] = w0*s[n] + w1*s[n-1] + w2*s[n-2] + ... + wP*s[n-P],
    # where b0 = sqrt(VAR{v[n]}), w0 = 1, and wk = -ak for k>0
    # the transfer function here is H(f) = DTFT(w)
    # leading to Sxx(f)/Exx(f) = |H(f)|**2 = VAR{v[n]} / |W(f)|**2
    w, hw = freq_response(sigma_v**0.5,
                          a=np.r_[1, -ak],
                          n_freqs=n_freqs,
                          sides=sides)
    ar_psd = (hw * hw.conj()).real
    return (w, 2 * ar_psd) if sides == 'onesided' else (w, ar_psd)
示例#3
0
def transfer_function_xy(a, n_freqs=1024):
    r"""Helper routine to compute the transfer function H(w) based
    on sequence of coefficient matrices A(i). The z transforms
    follow from this definition:

    X[t] + sum_{k=1}^P a[k]X[t-k] = Err[t]

    Parameters
    ----------

    a : ndarray, shape (P, 2, 2)
      sequence of coef matrices describing an mAR process
    n_freqs : int, optional
      number of frequencies to compute in range [0,PI]

    Returns
    -------

    Hw : ndarray
      The transfer function from innovations process vector to
      mAR process X

    """
    # these concatenations follow from the observation that A(0) is
    # implicitly the identity matrix
    ai = np.r_[1, a[:, 0, 0]]
    bi = np.r_[0, a[:, 0, 1]]
    ci = np.r_[0, a[:, 1, 0]]
    di = np.r_[1, a[:, 1, 1]]

    # compute A(w) such that A(w)X(w) = Err(w)
    w, aw = freq_response(ai, n_freqs=n_freqs)
    _, bw = freq_response(bi, n_freqs=n_freqs)
    _, cw = freq_response(ci, n_freqs=n_freqs)
    _, dw = freq_response(di, n_freqs=n_freqs)

    # A = np.array([ [1-aw, -bw], [-cw, 1-dw] ])
    A = np.array([[aw, bw], [cw, dw]])
    # compute the transfer function from Err to X. Since Err(w) is 1(w),
    # the transfer function H(w) = A^(-1)(w)
    # (use 2x2 matrix shortcut)
    detA = A[0, 0] * A[1, 1] - A[0, 1] * A[1, 0]
    Hw = np.array([[dw, -bw], [-cw, aw]])
    Hw /= detA
    return w, Hw
示例#4
0
def transfer_function_xy(a, n_freqs=1024):
    r"""Helper routine to compute the transfer function H(w) based
    on sequence of coefficient matrices A(i). The z transforms
    follow from this definition:

    X[t] + sum_{k=1}^P a[k]X[t-k] = Err[t]

    Parameters
    ----------

    a : ndarray, shape (P, 2, 2)
      sequence of coef matrices describing an mAR process
    n_freqs : int, optional
      number of frequencies to compute in range [0,PI]

    Returns
    -------

    Hw : ndarray
      The transfer function from innovations process vector to
      mAR process X

    """
    # these concatenations follow from the observation that A(0) is
    # implicitly the identity matrix
    ai = np.r_[1, a[:, 0, 0]]
    bi = np.r_[0, a[:, 0, 1]]
    ci = np.r_[0, a[:, 1, 0]]
    di = np.r_[1, a[:, 1, 1]]

    # compute A(w) such that A(w)X(w) = Err(w)
    w, aw = freq_response(ai, n_freqs=n_freqs)
    _, bw = freq_response(bi, n_freqs=n_freqs)
    _, cw = freq_response(ci, n_freqs=n_freqs)
    _, dw = freq_response(di, n_freqs=n_freqs)

    #A = np.array([ [1-aw, -bw], [-cw, 1-dw] ])
    A = np.array([[aw, bw], [cw, dw]])
    # compute the transfer function from Err to X. Since Err(w) is 1(w),
    # the transfer function H(w) = A^(-1)(w)
    # (use 2x2 matrix shortcut)
    detA = (A[0, 0] * A[1, 1] - A[0, 1] * A[1, 0])
    Hw = np.array([[dw, -bw], [-cw, aw]])
    Hw /= detA
    return w, Hw