def define(name, expr): """ Take an expression of 't' (possibly complicated) and make it a '%s(t)' % name, such that when it evaluates it has the right values. Parameters ---------- expr : sympy expression, with only 't' as a Symbol name : str Returns ------- nexpr: sympy expression Examples -------- >>> t = Term('t') >>> expr = t**2 + 3*t >>> print expr 3*t + t**2 >>> newexpr = define('f', expr) >>> print newexpr f(t) >>> import aliased >>> f = aliased.lambdify(t, newexpr) >>> f(4) 28 >>> 3*4+4**2 28 >>> """ v = vectorize(expr) return aliased_function(name, v)(Term('t'))
def _getint(f, dt=0.02, t=50): lf = vectorize(f) tt = np.arange(dt,t+dt,dt) return lf(tt).sum() * dt
def convolve_functions(fn1, fn2, interval, dt, padding_f=0.1, name=None): """ Convolve fn1 with fn2. Parameters ---------- fn1 : sympy expr An expression that is a function of t only. fn2 : sympy expr An expression that is a function of t only. interval : [float, float] The interval over which to convolve the two functions. dt : float Time step for discretization padding_f : float Padding added to the left and right in the convolution. name : str Name of the convolved function in the resulting expression. Defaults to one created by linear_interp. Returns ------- f : sympy expr An expression that is a function of t only. >>> import sympy >>> t = sympy.Symbol('t') >>> # This is a square wave on [0,1] >>> f1 = (t > 0) * (t < 1) >>> # The convolution of with itself is a triangular wave on [0,2], peaking at 1 with height 1 >>> tri = convolve_functions(f1, f1, [0,2], 1.0e-03, name='conv') >>> print tri conv(t) >>> ftri = vectorize(tri) >>> x = np.linspace(0,2,11) >>> y = ftri(x) >>> # This is the resulting y-value (which seem to be numerically off by dt >>> y array([ -3.90255908e-16, 1.99000000e-01, 3.99000000e-01, 5.99000000e-01, 7.99000000e-01, 9.99000000e-01, 7.99000000e-01, 5.99000000e-01, 3.99000000e-01, 1.99000000e-01, 6.74679706e-16]) >>> """ max_interval, min_interval = max(interval), min(interval) ltime = max_interval - min_interval time = np.arange(min_interval, max_interval + padding_f * ltime, dt) f1 = vectorize(fn1) f2 = vectorize(fn2) _fn1 = np.array(f1(time)) _fn2 = np.array(f2(time)) _fft1 = FFT.rfft(_fn1) _fft2 = FFT.rfft(_fn2) value = FFT.irfft(_fft1 * _fft2) * dt _minshape = min(time.shape[0], value.shape[-1]) time = time[0:_minshape] value = value[0:_minshape] return linear_interp(time + min_interval, value, bounds_error=False, name=name)
coef = peak_location**(-alpha) * np.exp(peak_location / beta) return coef * ((t >= 0) * (t+1.0e-14))**(alpha) * exp(-(t+1.0e-14)/beta) # Glover canonical HRF models # they are both Sympy objects def _getint(f, dt=0.02, t=50): lf = vectorize(f) tt = np.arange(dt,t+dt,dt) return lf(tt).sum() * dt deft = DeferredVector('t') _gexpr = gamma_params(5.4, 5.2) - 0.35 * gamma_params(10.8,7.35) _gexpr = _gexpr / _getint(_gexpr) _glover = vectorize(_gexpr) glover = aliased_function('glover', _glover) n = {} glovert = vectorize(glover(deft)) # Derivative of Glover HRF _dgexpr = _gexpr.diff(t) dpos = Derivative((t >= 0), t) _dgexpr = _dgexpr.subs(dpos, 0) _dgexpr = _dgexpr / _getint(abs(_dgexpr)) _dglover = vectorize(_dgexpr) dglover = aliased_function('dglover', _dglover) dglovert = vectorize(dglover(deft)) del(_glover); del(_gexpr); del(dpos); del(_dgexpr); del(_dglover)