def test_sparseconv(): # time vector for stimulus (long) maxT = .5 # seconds nt = 100000 t = np.linspace(0, maxT, nt) # stimulus (10 Hz anondic and cathodic pulse train) stim = np.zeros(nt) stim[0:nt:10000] = 1 stim[100:nt:1000] = -1 # time vector for impulse response (shorter) tt = t[t < .1] # impulse reponse (kernel) G = np.exp(-tt / .005) # make sure sparseconv returns the same result as np.convolve # for all modes modes = ["full", "valid", "same"] for mode in modes: # np.convolve conv = np.convolve(stim, G, mode=mode) # utils.sparseconv sparse_conv = utils.sparseconv(stim, G, mode=mode, use_jit=False) npt.assert_equal(conv.shape, sparse_conv.shape) npt.assert_almost_equal(conv, sparse_conv) with pytest.raises(ValueError): utils.sparseconv(G, stim, mode='invalid')
def test_sparseconv(): # time vector for stimulus (long) maxT = .5 # seconds nt = 100000 t = np.linspace(0, maxT, nt) # stimulus (10 Hz anondic and cathodic pulse train) stim = np.zeros(nt) stim[0:nt:10000] = 1 stim[100:nt:1000] = -1 # time vector for impulse response (shorter) tt = t[t < .1] # impulse reponse (kernel) G = np.exp(-tt / .005) # make sure sparseconv returns the same result as np.convolve # for all modes modes = ["full", "valid", "same"] for mode in modes: # np.convolve conv = np.convolve(stim, G, mode=mode) # utils.sparseconv sparse_conv = utils.sparseconv(G, stim, mode=mode, dojit=False) npt.assert_equal(conv.shape, sparse_conv.shape) npt.assert_almost_equal(conv, sparse_conv)
def fast_response(self, b1, gamma, dojit=True, usefft=False): """Fast response function (Box 2) for the bipolar layer Convolve a stimulus `b1` with a temporal low-pass filter (1-stage gamma) with time constant `self.tau_inl` ~ 14ms representing bipolars. Parameters ---------- b1 : array Temporal signal to process, b1(r,t) in Nanduri et al. (2012). dojit : bool, optional If True (default), use numba just-in-time compilation. usefft : bool, optional If False (default), use sparseconv, else fftconvolve. Returns ------- b2 : array Fast response, b2(r,t) in Nanduri et al. (2012). Notes ----- The function utils.sparseconv can be much faster than np.convolve and scipy.signals.fftconvolve if `b1` is sparse and much longer than the convolution kernel. The output is not converted to a TimeSeries object for speedup. """ if usefft: # In Krishnan model, b1 is no longer sparse (run FFT) conv = self.tsample * fftconvolve(b1, gamma, mode='full') else: conv = self.tsample * utils.sparseconv(gamma, b1, mode='full', dojit=dojit) # Cut off the tail of the convolution to make the output signal # match the dimensions of the input signal. return conv[:b1.shape[-1]]