def r0_altern(mu, s, kp, km, vr, vt, tr): """Alternative expression for the stationary firing rate""" #return ( 1./(tr + (kp+km) * integrate(lambda x: integrate(lambda y: abs(mu-y+s)**kp/abs(mu-x+s)**(kp+1) * abs(mu-y-s)**(km-1)/abs(mu-x-s)**km, x, mu-s), vr, vt) return (1. / (tr + (kp + km) * integrate( lambda x: integrate( lambda y: abs((mu - y + s) / (mu - x + s))**(kp) * abs( (mu - y - s) / (mu - x - s))**(km) * 1. / (mu - x + s) * 1. / (mu - y - s), x, mu - s), vr, vt) + (1 - exp(-tr * (kp + km))) / (kp + km) * (-1 + (kp + km) * integrate( lambda x: abs((mu - x + s) / (mu - vr + s))**kp * abs( (mu - x - s) / (mu - vr - s))**km * 1. / (mu - x - s), vr, mu - s))))
def P0(model, v, mu, s, kp, km, vr, vt, tr): """Return the stationary density. v may not be an array!""" phi = lambda v: model.phi(v, mu, s, kp, km) f = lambda v: model.f(v, mu) fp = lambda v: model.fp(v, mu) ekt = exp(-(kp+km)*tr) ints = model.intervals(mu, s, vr, vt) if v < ints[0][0] or v > ints[-1][1]: return 0. r0 = 1./if_dicho_T1(model, mu, s, kp, km, vr, vt, tr) al = if_dicho_alpha(model, mu, s, kp, km, vr, vt, tr) Gd = (2*al-1)*ekt + (km-kp)/(kp+km) * (1.-ekt) # which interval are we in if v <= ints[0][0]: return 0. l, r, c = (None, None, None) for l, r, c in ints: if l < v < r: break return r0/(f(v)**2-s**2) * ( # (heav(c-vr)-heav(v-vr)) * (s*Gd-f(vr))*exp(phi(vr)-phi(v)) #-(heav(c-vt)-heav(v-vt)) * (s*(2*al-1)-f(vt))*exp(phi(vt)-phi(v)) ((1.if c>vr else 0.)-heav(v-vr)) * (s*Gd-f(vr))*exp(phi(vr)-phi(v)) -((1.if c>=vt else 0.)-heav(v-vt)) * (s*(2*al-1)-f(vt))*exp(phi(vt)-phi(v)) + integrate(lambda x: exp(phi(x)-phi(v))*(heav(x-vr)-heav(x-vt))*(fp(x)+kp+km), c, v))
def T1(model, mu, s, kp, km, vr, vt, tr): """Return the mean first passage time""" phi = lambda v: model.phi(v, mu, s, kp, km) f = lambda v: model.f(v, mu) ekt = exp(-(kp+km)*tr) def plusint(l, r): return integrate(lambda x: exp(phi(x)-phi(r))/(f(x)+s), l, r) def minusint(l, r): return integrate(lambda x: exp(-phi(x)+phi(l))/(f(x)-s), l, r) al = if_dicho_alpha(locals()) res = 0. ints = model.intervals(mu, s, vr, vt) for i in ints: l, r, c = i cbar = l if c == r else r res += (kp+km) * integrate(lambda x: heav(x-vr)/(f(x)+s) * minusint(x, cbar), l, r) ln, rn, cn = ints[-1] l0, r0, c0 = ints[0] c0bar = l0 if c0 == r0 else r0 return res + tr + plusint(cn, vt) + ((1-al)/kp*ekt+1./(kp+km)*(1-ekt)) * (exp(phi(vr)-phi(c0bar))-1.+(kp+km) * minusint(vr, c0bar))
def phi(self, v, mu, rin_e, a_e): d = self.d vtb = self.vtb ufp = (mu-d*lambertw(-exp((mu-vtb)/d),-1)).real sfp = (mu-d*lambertw(-exp((mu-vtb)/d),0)).real # extreme cases #if v > if (lambertw(-exp((mu-vtb)/d),0).imag > 0) or (lambertw(-exp((mu-vtb)/d),-1).imag > 0): c = 25 elif v > ufp: c = 25 elif v < sfp: c = -25 else: c = (ufp + sfp)/2 # have I done an integral with that c already? we assume that it's v was close, reusing that sub-integral makes things somewhat faster k = (c, mu, rin_e, a_e) i0 = 0 if self.intcache.has_key(k): c, i0 = self.intcache[k] i1 = integrate(lambda x: 1./self.f(x, mu), c, v) + i0 self.intcache[k] = (v, i1) return v/a_e + rin_e * i1
def r0(mu, rin_e, a_e, vr, vt, tr): """Return the stationary firing rate of an LIF driven by excitatory shot noise. Adapted from the expression derived in Richardson, M. J. & Swarbrick, R. Phys. Rev. Lett., APS, 2010, 105, 178102""" T = tr+float(integrate(lambda c: 1./c*(1-a_e*c)**rin_e * (exp(c*(vt-mu))/(1-a_e*c)-exp(c*(vr-mu))), 0, 1./a_e).real) return 1./T
def if_dicho_alpha(model, mu, s, kp, km, vr, vt, tr): """Return the fraction of trajectories crossing the threshold in the + state""" phi = lambda v: model.phi(v, mu, s, kp, km) f = lambda v: model.f(v, mu) ekt = exp(-(kp+km)*tr) if f(vt)-s < 0: return 1. else: ln, rn, cn = model.intervals(mu, s, vr, vt)[-1] return 1.- (heav(vr-cn) * kp/(kp+km) * exp(phi(vr)) * (1.-ekt) + kp * integrate(lambda x: exp(phi(x))*heav(x-vr)/(f(x)+s), cn, vt)) / (exp(phi(vt))-heav(vr-cn)*ekt*exp(phi(vr)))
def minusint(l, r): return integrate(lambda x: exp(-phi(x)+phi(l))/(f(x)-s), l, r)
def plusint(l, r): return integrate(lambda x: exp(phi(x)-phi(r))/(f(x)+s), l, r)
def T1(mu, D, tr): """Return the first moment of the ISI density. This single-integral form is due to Brunel & Latham, Neural Comp. 2003 It assumes vr, vt -> +- infty""" return sqrt(pi) * integrate(lambda z: exp(-mu * z**2 - D**2/12 * z**6), -inf, inf) + tr