Exemplo n.º 1
0
 def test_mdot(self):
     x = np.array([[1, 2, 3],
                   [4, 5, 6],
                   [7, 8, 9]])
     assert_equal(npe.mdot(x, x, x),
                  np.array([[468, 576, 684],
                            [1062, 1305, 1548],
                            [1656, 2034, 2412]]))
Exemplo n.º 2
0
 def test_mdot(self):
     x = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
     assert_equal(
         npe.mdot(x, x, x),
         np.array([[468, 576, 684], [1062, 1305, 1548], [1656, 2034,
                                                         2412]]))
Exemplo n.º 3
0
def asdm_decode_fast(s, dur, dt, bw, M, b, d, k=1.0, sgn=-1):
    """
    Fast ASDM time decoding machine.

    Decode a signal encoded by an Asynchronous Sigma-Delta Modulator
    using a fast recovery algorithm.

    Parameters
    ----------
    s : numpy array of floats
        Encoded signal. The values represent the time between spikes (in s).
    dur : float
        Duration of signal (in s).
    dt : float
        Sampling resolution of original signal; the sampling frequency
        is 1/dt Hz.
    bw : float
        Signal bandwidth (in rad/s).
    M : int
        Number of bins used by the fast algorithm.
    b : float
        Encoder bias.
    d : float
        Encoder threshold.
    k : float
        Encoder integrator constant.
    sgn : {-1, 1}
        Sign of first spike.

    Returns
    -------
    u_rec : ndarray of floats
        Recovered signal.
    """

    Ns = len(s)
    if Ns < 2:
        raise ValueError('s must contain at least 2 elements')

    # Cast s to an ndarray to permit ndarray operations:
    s = np.asarray(s)

    # Compute the spike times:
    ts = np.cumsum(s)

    # Compute the midpoints between spike times:
    tsh = (ts[0:-1] + ts[1:]) / 2
    Nsh = len(tsh)

    # Convert M in the event that an integer was specified:
    M = np.float(M)
    jbwM = 1j * bw / M

    # Compute quanta:
    if sgn == -1:
        q = (-1)**np.arange(1, Nsh + 1) * (2 * k * d - b * s[1:])
    else:
        q = (-1)**np.arange(0, Nsh) * (2 * k * d - b * s[1:])

    # Compute approximation coefficients:
    a = bw / (np.pi * (2 * M + 1))
    m = np.arange(-M, M + 1)
    P_inv = -np.triu(np.ones((Nsh, Nsh)))
    S = np.exp(-jbwM * np.dot(m[:, np.newaxis], ts[:-1][np.newaxis]))
    D = np.diag(s[1:])
    SD = np.dot(S, D)
    T = ne.mdot(a, SD, np.conj(S.T))
    dd = ne.mdot(a, np.linalg.pinv(T, __pinv_rcond__), SD, P_inv,
                 q[:, np.newaxis])

    # Reconstruct signal:
    t = np.arange(0, dur, dt)
    return np.ravel(
        np.real(jbwM * np.dot(m * dd.T, np.exp(jbwM * m[:, np.newaxis] * t))))
Exemplo n.º 4
0
def asdm_decode_fast(s, dur, dt, bw, M, b, d, k=1.0, sgn=-1):
    """
    Fast ASDM time decoding machine.

    Decode a signal encoded by an Asynchronous Sigma-Delta Modulator
    using a fast recovery algorithm.

    Parameters
    ----------
    s : numpy array of floats
        Encoded signal. The values represent the time between spikes (in s).
    dur : float
        Duration of signal (in s).
    dt : float
        Sampling resolution of original signal; the sampling frequency
        is 1/dt Hz.
    bw : float
        Signal bandwidth (in rad/s).
    M : int
        Number of bins used by the fast algorithm.
    b : float
        Encoder bias.
    d : float
        Encoder threshold.
    k : float
        Encoder integrator constant.
    sgn : {-1, 1}
        Sign of first spike.

    Returns
    -------
    u_rec : ndarray of floats
        Recovered signal.
    """

    Ns = len(s)
    if Ns < 2:
        raise ValueError('s must contain at least 2 elements')

    # Cast s to an ndarray to permit ndarray operations:
    s = np.asarray(s)

    # Compute the spike times:
    ts = np.cumsum(s)

    # Compute the midpoints between spike times:
    tsh = (ts[0:-1]+ts[1:])/2
    Nsh = len(tsh)

    # Convert M in the event that an integer was specified:
    M = np.float(M)
    jbwM = 1j*bw/M

    # Compute quanta:
    if sgn == -1:
        q = (-1)**np.arange(1, Nsh+1)*(2*k*d-b*s[1:])
    else:
        q = (-1)**np.arange(0, Nsh)*(2*k*d-b*s[1:])

    # Compute approximation coefficients:
    a = bw/(np.pi*(2*M+1))
    m = np.arange(-M, M+1)
    P_inv = -np.triu(np.ones((Nsh, Nsh)))
    S = np.exp(-jbwM*np.dot(m[:, np.newaxis], ts[:-1][np.newaxis]))
    D = np.diag(s[1:])
    SD = np.dot(S, D)
    T = ne.mdot(a, SD, np.conj(S.T))
    dd = ne.mdot(a, np.linalg.pinv(T, __pinv_rcond__), SD, P_inv, q[:, np.newaxis])

    # Reconstruct signal:
    t = np.arange(0, dur, dt)
    return np.ravel(np.real(jbwM*np.dot(m*dd.T, np.exp(jbwM*m[:, np.newaxis]*t))))
Exemplo n.º 5
0
def asdm_decode_vander_ins(s, dur, dt, bw, b, sgn=-1):
    """
    Threshold-insensitive ASDM time decoding machine that uses BPA.

    Decode a finite length signal encoded with an Asynchronous
    Sigma-Delta Modulator by efficiently solving a
    threshold-insensitive Vandermonde system using the Bjork-Pereyra
    Algorithm.

    Parameters
    ----------
    s: array_like of floats
        Encoded signal. The values represent the time between spikes (in s).
    dur: float
        Duration of signal (in s).
    dt: float
        Sampling resolution of original signal; the sampling frequency
        is 1/dt Hz.
    bw: float
        Signal bandwidth (in rad/s).
    b: float
        Encoder bias.
    sgn: {-1, 1}
        Sign of first spike.

    Returns
    -------
    u_rec : ndarray of floats
        Recovered signal.
    """

    # Since the compensation principle uses the differences between
    # spikes, the last spike in s must effectively be dropped:
    ns = len(s)-1
    n = ns-1               # corresponds to N in Prof. Lazar's paper

    # Cast s to an ndarray to permit ndarray operations:
    s = np.asarray(s)

    # Compute the spike times:
    ts = np.cumsum(s)

    # Create the vectors and matricies needed to obtain the
    # reconstruction coefficients:
    z = np.exp(1j*2*bw*ts[:-1]/n)
    V = np.fliplr(np.vander(z))  # pecularity of numpy's vander() function
    D = np.diag(np.exp(1j*bw*ts[:-1]))
    P = np.triu(np.ones((ns, ns), np.float))

    a = np.zeros(ns, np.float)
    a[::-2] = 1.0
    a = a[:, np.newaxis]      # column vector

    bh = np.zeros(ns, np.float)
    bh[-1] = 1.0
    bh = bh[np.newaxis]       # row vector

    ex = np.ones(ns, np.float)
    if sgn == -1:
        ex[0::2] = -1.0
    else:
        ex[1::2] = -1.0
    r = (ex*s[1:])[:, np.newaxis]

    # Solve the Vandermonde systems using BPA:
    ## Observation: constructing P-dot(a,bh) directly without
    ## creating P, a, and bh separately does not speed this up
    x = bpa.bpa(V, ne.mdot(D, P-np.dot(a, bh), r))
    y = bpa.bpa(V, np.dot(D, a))

    # Compute the coefficients:
    d = b*(x-ne.mdot(y, np.conj(y.T), x)/np.dot(np.conj(y.T), y))

    # Reconstruct the signal:
    t = np.arange(0, dur, dt)
    u_rec = np.zeros(len(t), np.complex)
    for i in xrange(ns):
        c = 1j*(bw-i*2*bw/n)
        u_rec += c*d[i]*np.exp(-c*t)

    return np.real(u_rec)
Exemplo n.º 6
0
def asdm_decode_vander(s, dur, dt, bw, b, d, k, sgn=-1):
    """
    Asynchronous Sigma-Delta Modulator time decoding machine that uses
    BPA.

    Decode a finite length signal encoded with an Asynchronous
    Sigma-Delta Modulator by efficiently solving a Vandermonde system
    using the Bjork-Pereyra Algorithm.

    Parameters
    ----------
    s: array_like of floats
        Encoded signal. The values represent the time between spikes (in s).
    dur: float
        Duration of signal (in s).
    dt: float
        Sampling resolution of original signal; the sampling frequency
        is 1/dt Hz.
    bw: float
        Signal bandwidth (in rad/s).
    b: float
        Encoder bias.
    d: float
        Encoder threshold.
    k: float
        Encoder integration constant.
    sgn: {-1, 1}
        Sign of first spike.

    Returns
    -------
    u_rec : ndarray of floats
        Recovered signal.
    """

    # Since the compensation principle uses the differences between
    # spikes, the last spike must effectively be dropped:
    ns = len(s)-1
    n = ns-1               # corresponds to N in Prof. Lazar's paper

    # Cast s to an ndarray to permit ndarray operations:
    s = np.asarray(s)

    # Compute the spike times:
    ts = np.cumsum(s)

    # Create the vectors and matricies needed to obtain the
    # reconstruction coefficients:
    z = np.exp(1j*2*bw*ts[:-1]/n)

    V = np.fliplr(np.vander(z))  # pecularity of numpy's vander() function
    P = np.triu(np.ones((ns, ns), np.float))
    D = np.diag(np.exp(1j*bw*ts[:-1]))

    # Compute the quanta:
    if sgn == -1:
        q = np.asarray([(-1)**i for i in xrange(0, ns)])*(2*k*d-b*s[1:])
    else:
        q = np.asarray([(-1)**i for i in xrange(1, ns+1)])*(2*k*d-b*s[1:])

    # Obtain the reconstruction coefficients by solving the
    # Vandermonde system using BPA:
    d = bpa.bpa(V, ne.mdot(D, P, q[:, np.newaxis]))

    # Reconstruct the signal:
    t = np.arange(0, dur, dt)
    u_rec = np.zeros(len(t), np.complex)
    for i in xrange(ns):
        c = 1j*(bw-i*2*bw/n)
        u_rec += c*d[i]*np.exp(-c*t)

    return np.real(u_rec)