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]]))
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]]))
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))))
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))))
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)
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)