Beispiel #1
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)
Beispiel #2
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)