def firing_rates_integration(self):
        '''Returns vector of population firing rates in Hz.'''
        print 'Calculate firing rates.'
        # conversion factor for currents to voltages # JS: In the conversion factor tau_s should also appear, but I think it is absorbed in the weights, right? Should we just take out the comment here?
        fac = 1 / (self.params['C'])
        # conversion from ms to s
        taum = self.params['taum'] * 1e-3
        tauf = self.params['tauf'] * 1e-3
        taur = self.params['taur'] * 1e-3
        dV = self.params['Vth'] - self.params['V0']
        rate_function = lambda mu, sigma: siegert.nu0_fb433(
            taum, tauf, taur, dV, 0., mu, sigma)

        def get_rate_difference(rates):
            mu = self.get_mean(rates)
            sigma = np.sqrt(self.get_variance(rates))
            new_rates = np.array(
                map(rate_function, taum * fac * mu,
                    np.sqrt(taum) * fac * sigma))
            return -rates + new_rates

        dt = 0.05
        y = np.zeros((2, self.dimension))
        eps = 1.0
        while eps >= 1e-5:
            delta_y = get_rate_difference(y[0])
            y[1] = y[0] + delta_y * dt
            epsilon = (y[1] - y[0])
            eps = max(np.abs(epsilon))
            y[0] = y[1]

        return y[1]
    def firing_rates_integration(self):
        '''Returns vector of population firing rates in Hz.'''
        print 'Calculate firing rates.'
        fac = 1 / (self.params['C'])
        # conversion from ms to s
        taum = self.params['taum'] * 1e-3            
        tauf = self.params['tauf'] * 1e-3           
        taur = self.params['taur'] * 1e-3           
        dV =  self.params['Vth'] - self.params['V0']
        rate_function = lambda mu, sigma: siegert.nu0_fb433(
            taum, tauf, taur, dV, 0., mu, sigma)

        def get_rate_difference(rates):
            mu = self.get_mean(rates)
            sigma = np.sqrt(self.get_variance(rates))
            new_rates = np.array(map(rate_function, taum*fac*mu, 
                                     np.sqrt(taum)*fac*sigma))          
            return -rates + new_rates

        dt = 0.05
        y = np.zeros((2, self.dimension))
        eps = 1.0
        while eps >= 1e-5:
            delta_y = get_rate_difference(y[0])
            y[1] = y[0] + delta_y*dt
            epsilon = (y[1] - y[0])
            eps = max(np.abs(epsilon))
            y[0] = y[1]

        return y[1]
def transfer_function(omega, params, mu, sigma):
    """Calculates transfer function of leaky-integrate and fire neuron
    model subjected to colored noise according to Eq. 93 in Schuecker et
    al. (2014) "Reduction of colored noise in excitable systems to white
    noise and dynamic boundary conditions" arXiv:1410.8799v3
    """

    taum = params['taum'] * 1e-3
    taus = params['tauf'] * 1e-3
    taur = params['taur'] * 1e-3
    V0 = 0.0
    dV = params['Vth'] - params['V0']
    if omega == 0.:
        # print siegert.d_nu_d_mu_fb433(taum, taus, taur, dV, V0, mu, sigma)
        # print siegert.d_nu_d_mu_numerical(taum, taus, taur, dV, V0, mu, sigma)
        # return siegert.d_nu_d_mu_fb433(taum, taus, taur, dV, V0, mu, sigma)
        return siegert.d_nu_d_mu_numerical(taum, taus, taur, dV, V0, mu, sigma)
    else:
        nu0 = siegert.nu_0(taum, taur, dV, V0, mu, sigma)
        nu0_fb = siegert.nu0_fb433(taum, taus, taur, dV, V0, mu, sigma)
        x_t = np.sqrt(2.) * (dV - mu) / sigma
        x_r = np.sqrt(2.) * (V0 - mu) / sigma
        z = complex(-0.5, complex(omega * taum))
        alpha = np.sqrt(2) * abs(zetac(0.5) + 1)
        k = np.sqrt(taus / taum)
        A = alpha * taum * nu0 * k / np.sqrt(2)

        def Phi_x_r(x, y):
            return Phi(z, x) - Phi(z, y)

        def dPhi_x_r(x, y):
            return d_Phi(z, x) - d_Phi(z, y)

        def d2Phi_x_r(x, y):
            return d_2_Phi(z, x) - d_2_Phi(z, y)

        a0 = Phi_x_r(x_t, x_r)
        a1 = dPhi_x_r(x_t, x_r) / a0
        a3 = A / taum / nu0_fb * (-a1**2 + d2Phi_x_r(x_t, x_r) / a0)
        result = np.sqrt(2.) / sigma * nu0_fb / \
            complex(1., omega * taum) * (a1 + a3)

        return result
    def Next_integration(self, rates):
        '''Returns vector of population firing rates in Hz.'''
        print 'Calculate external input.'
        # conversion factor for currents to voltages
        fac = 1 / (self.params['C'])
        # conversion from ms to s
        taum = self.params['taum'] * 1e-3
        tauf = self.params['tauf'] * 1e-3
        taur = self.params['taur'] * 1e-3
        facb = 2 * self.tauf / self.C * taum
        dV = self.params['Vth'] - self.params['V0']
        if self.params['Wilson-Cowan']:
            rate_function = lambda mu, sigma: siegert.WC(
                taum, tauf, taur, dV, 0., mu, sigma)
            transfer_function = lambda mu, sigma: siegert.d_nu_WC_d_mu_numerical(
                taum, tauf, taur, dV, 0, mu, sigma)
        else:
            rate_function = lambda mu, sigma: siegert.nu0_fb433(
                taum, tauf, taur, dV, 0., mu, sigma)
            transfer_function = lambda mu, sigma: siegert.d_nu_d_mu_numerical(
                taum, tauf, taur, dV, 0, mu, sigma)

        def get_rate_difference(Next):
            mu = self.get_mean_Next(rates, Next)
            sigma = np.sqrt(self.get_variance_Next(rates, Next))
            new_rates = np.array(
                map(rate_function, taum * fac * mu,
                    np.sqrt(taum) * fac * sigma))
            return -rates + new_rates

        z = fsolve(get_rate_difference, self.Next, full_output=True)
        # set external input to zero if fsolve did not converge
        if z[2] == 1:
            Next = z[0]
            mu = self.get_mean_Next(rates, Next)
            sigma = np.sqrt(self.get_variance(rates))
            betas = 2 * self.tauf / self.C * taum * np.array(
                map(transfer_function, taum * fac * mu,
                    np.sqrt(taum) * fac * sigma))
        else:
            Next = np.zeros(self.dimension)
            betas = np.zeros(self.dimension)
        return Next, betas
    def firing_rates_integration(self):
        '''Returns vector of population firing rates in Hz.'''
        print 'Calculate firing rates.'
        # conversion factor for currents to voltages
        fac = 1 / (self.params['C'])
        # conversion from ms to s
        taum = self.params['taum'] * 1e-3
        tauf = self.params['tauf'] * 1e-3
        taur = self.params['taur'] * 1e-3
        dV = self.params['Vth'] - self.params['V0']
        if self.params['Wilson-Cowan']:
            rate_function = lambda mu, sigma: siegert.WC(
                taum, tauf, taur, dV, 0., mu, sigma)
        else:
            rate_function = lambda mu, sigma: siegert.nu0_fb433(
                taum, tauf, taur, dV, 0., mu, sigma)

        def get_rate_difference(rates):
            mu = self.get_mean(rates)
            sigma = np.sqrt(self.get_variance(rates))
            new_rates = np.array(
                map(rate_function, taum * fac * mu,
                    np.sqrt(taum) * fac * sigma))
            return -rates + new_rates

        dt = 0.01
        y = np.zeros((2, self.dimension))
        y[0] = np.array([2, 3, 0])
        eps = 1.0
        n = 0
        while eps >= 1e-5:
            n += 1
            delta_y = get_rate_difference(y[0])
            y[1] = y[0] + delta_y * dt
            epsilon = (y[1] - y[0])
            eps = max(np.abs(epsilon))
            y[0] = y[1]
            if n > 50000:
                print 'stopped'
                return np.zeros(self.dimension)

        return y[1]
Exemple #6
0
        def rate_function(mu, sigmas, sigmaf):
            sigma_I = sigmas / np.sqrt(2.0 * taus)

            def F(z):
                return siegert.nu0_fb433(taum, tauf, taur, dV, 0.0,
                                         taum / C * (sigma_I * z + mu),
                                         np.sqrt(taum) / C * sigmaf)

            def integrand(z):
                return np.exp(-z * z / 2.0) * F(z) * 1.0 / np.sqrt(2 * np.pi)

            if sigma_I == 0.0:
                result = siegert.nu0_fb433(taum, tauf, taur, dV, 0.0,
                                           taum / C * mu,
                                           np.sqrt(taum) / C * sigmaf)
            else:
                # result = integrate.quad(integrand, -40.0, 40.0)[0]
                result = integrate.quad(integrand, -5.0, 5.0)[0]
            # convert firing rate to Hz
            return result * 1000.0
Exemple #7
0
def transfer_function_taylor(omega, params, mu, sigma):
    """
    Calculates transfer function according to Eq. 93 in [2]. The
    results in [3] were obtained with this expression and it is
    used throughout this package

    """

    # convert from ms to s
    taum = params['taum'] * 1e-3
    tauf = params['tauf'] * 1e-3
    taur = params['taur'] * 1e-3
    Vth = params['Vth']
    V0 = params['V0']

    # convert mu to absolute values (not relative to reset)
    mu += V0

    # for frequency zero the exact expression is given by the derivative of
    # f-I-curve
    if np.abs(omega - 0.) < 1e-15:
        return siegert.d_nu_d_mu_fb433(taum, tauf, taur, Vth, V0, mu, sigma)
    else:
        nu0 = siegert.nu_0(taum, taur, Vth, V0, mu, sigma)
        nu0_fb = siegert.nu0_fb433(taum, tauf, taur, Vth, V0, mu, sigma)
        x_t = np.sqrt(2.) * (Vth - mu) / sigma
        x_r = np.sqrt(2.) * (V0 - mu) / sigma
        z = complex(-0.5, complex(omega * taum))
        alpha = np.sqrt(2) * abs(zetac(0.5) + 1)
        k = np.sqrt(tauf / taum)
        A = alpha * taum * nu0 * k / np.sqrt(2)
        a0 = Phi_x_r(z, x_t, x_r)
        a1 = dPhi_x_r(z, x_t, x_r) / a0
        a3 = A / taum / nu0_fb * (-a1**2 + d2Phi_x_r(z, x_t, x_r) / a0)
        result = np.sqrt(2.) / sigma * nu0_fb / \
            complex(1., omega * taum) * (a1 + a3)

        return result
def transfer_function_taylor(omega, params, mu, sigma):
    """
    Calculates transfer function according to Eq. 93 in [2]. The
    results in [3] were obtained with this expression and it is
    used throughout this package

    """

    # convert from ms to s
    taum = params['taum'] * 1e-3
    tauf = params['tauf'] * 1e-3
    taur = params['taur'] * 1e-3
    Vth = params['Vth']
    V0 = params['V0']

    # convert mu to absolute values (not relative to reset)
    mu += V0

    # for frequency zero the exact expression is given by the derivative of
    # f-I-curve
    if np.abs(omega - 0.) < 1e-15:
        return siegert.d_nu_d_mu_fb433(taum, tauf, taur, Vth, V0, mu, sigma)
    else:
        nu0 = siegert.nu_0(taum, taur, Vth, V0, mu, sigma)
        nu0_fb = siegert.nu0_fb433(taum, tauf, taur, Vth, V0, mu, sigma)
        x_t = np.sqrt(2.) * (Vth - mu) / sigma
        x_r = np.sqrt(2.) * (V0 - mu) / sigma
        z = complex(-0.5, complex(omega * taum))
        alpha = np.sqrt(2) * abs(zetac(0.5) + 1)
        k = np.sqrt(tauf / taum)
        A = alpha * taum * nu0 * k / np.sqrt(2)
        a0 = Phi_x_r(z, x_t, x_r)
        a1 = dPhi_x_r(z, x_t, x_r) / a0
        a3 = A / taum / nu0_fb * (-a1**2 + d2Phi_x_r(z, x_t, x_r) / a0)
        result = np.sqrt(2.) / sigma * nu0_fb / \
            complex(1., omega * taum) * (a1 + a3)

        return result
Exemple #9
0
def plot_PRE_Schuecker_Fig4(frequencies, sigma_1, mean_input_1, sigma_2,
                            mean_input_2):

    results_dict = defaultdict(str)

    results_dict['sigma'] = defaultdict(dict)

    for index in [1, 2]:
        sigma = eval('sigma_' + str(index))
        results_dict['sigma'][sigma]['mu'] = defaultdict(dict)
        for idx, mu in enumerate(eval('mean_input_' + str(index))):

            # Stationary firing rates for delta shaped PSCs.
            nu_0 = siegert.nu_0(tau_m, tau_r, theta, V_reset, mu, sigma)

            # Stationary firing rates for filtered synapses (via Taylor)
            nu0_fb = siegert.nu0_fb(tau_m, tau_s, tau_r, theta, V_reset, mu,
                                    sigma)

            # Stationary firing rates for exp PSCs. (via shift)
            nu0_fb433 = siegert.nu0_fb433(tau_m, tau_s, tau_r, theta, V_reset,
                                          mu, sigma)

            # colored noise zero-frequency limit of transfer function
            # colored noise
            transfer_function_zero_freq = siegert.d_nu_d_mu_fb433(
                tau_m, tau_s, tau_r, theta, V_reset, mu, sigma)

            transfer_function = [
                transfer_FP_algebra_j1_shift((2. * np.pi) * f, tau_m, tau_s,
                                             tau_r, nu0_fb, theta, V_reset, mu,
                                             sigma) for f in frequencies
            ]

            results_dict['sigma'][sigma]['mu'][mu] = {
                'frequencies': frequencies,
                'absolute_value': np.abs(transfer_function),
                'phase': np.angle(transfer_function) / 2 / np.pi * 360,
                'zero_freq': transfer_function_zero_freq,
                'nu_0': nu_0,
                'nu0_fb': nu0_fb,
                'nu0_fb433': nu0_fb433
            }

            colors = ['black', 'grey']
            lw = 4
            markersize_cross = 4
            if sigma == 4.0:
                ls = '-'
            else:
                ls = '--'

            axA.semilogx(frequencies,
                         np.abs(transfer_function),
                         color=colors[idx],
                         linestyle=ls,
                         linewidth=lw,
                         label=r'$\nu=$ {} Hz'.format(nu0_fb))
            axB.semilogx(frequencies,
                         np.angle(transfer_function) / 2 / np.pi * 360,
                         color=colors[idx],
                         linestyle=ls,
                         linewidth=lw,
                         label=r'$\mu=$ ' + str(mu))
            axA.semilogx(zero_freq,
                         transfer_function_zero_freq,
                         '+',
                         color=colors[idx],
                         markersize=markersize_cross)

    axA.set_xlabel(r'frequency $\omega/2\pi\quad(1/\mathrm{s})$')
    axA.set_ylabel(
        r'$|\frac{n(\omega)\nu}{\epsilon\mu}|\quad(\mathrm{s}\,'
        '\mathrm{mV})^{-1}$',
        labelpad=0)

    axB.set_xlabel(r'frequency $\omega/2\pi\quad(1/\mathrm{s})$')
    axB.set_ylabel(r'$-\angle n(\omega)\quad(^{\circ})$', labelpad=2)

    axA.legend()
    axB.legend()

    return results_dict
Exemple #10
0
 def F(z):
     return siegert.nu0_fb433(taum, tauf, 0.1, dV, 0.0,
                              taum / C * (sigma_I * z + mu),
                              np.sqrt(taum) / C * sigmaf)