Source code for nest.tests.test_erfc_neuron

# -*- coding: utf-8 -*-
#
# test_erfc_neuron.py
#
# This file is part of NEST.
#
# Copyright (C) 2004 The NEST Initiative
#
# NEST is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# NEST is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with NEST.  If not, see <http://www.gnu.org/licenses/>.

"""
Test implementation of erfc-neuron.
"""

import unittest
import nest
import numpy as np
from scipy.special import erfc


[docs]def get_mean_activity(detector, T): """ returns the mean activity of a single binary neuron connected to a spin detector. """ states = nest.GetStatus(detector)[0]['events']['weights'] times = nest.GetStatus(detector)[0]['events']['times'] # add total duration at the end, since we need to take into account # the time between the last state change and end of simulation times = np.hstack((times, T)) if len(times) > 1: assert(states[0] == 1) # since neuron is starting in 0 state, summing every second period # will give us the total time in the up state activity = np.sum(np.diff(times)[::2]) / (T - times[0]) # if we have more than one update, we calculate a more accurate value # for the mean activity, taking into account that our measurements are # biased (we only record /given/ that a state change happened) if len(times) > 2: # biased average starting at down state, p(m(t)=1|m(t-1)=0) M0 = 1. - (np.sum(np.diff(times)[1::2]) / (T - times[1])) # biased average starting at up state, p(m(t)=1|m(t-1)=1) M1 = activity # unbiased estimate, # p(m(t)=1)=\sum_{s \in {0,1}} p(m(t)=1|m(t-1)=s)p(m(t-1)=s), # assuming stationary state: p(m(t)) = p(m(t-1)), solved for p(m=1) activity = M0 / (1. + M0 - M1) return activity else: return 0.
[docs]def activation_function_theory(sigma, theta): """ returns the probability for a binary neuron to be in the up state, given the parameters sigma and theta. """ return 0.5 * erfc(theta / (np.sqrt(2.) * sigma))
[docs]class ErfcNeuronTheoryTestCase(unittest.TestCase): """Compare results to theoretical predictions"""
[docs] def setUp(self): """defines parameters of simulation""" self.sigma = np.logspace(-1, 1.1, 4) self.theta = np.linspace(-6, 6, 15) self.neuron = None self.detector = None self.T = 30000.
[docs] def build_and_connect_nodes(self, sigma, theta): """ sets up an erfc neuron and spin detector. """ nest.set_verbosity('M_WARNING') nest.ResetKernel() self.neuron = nest.Create('erfc_neuron', 1, {'sigma': sigma, 'theta': theta}) self.detector = nest.Create('spin_detector', 1) nest.Connect(self.neuron, self.detector)
[docs] def test_activation_function(self): """ simulates erfc neuron for different parameter sets and compares activity to theoretical value. """ for sigma in self.sigma: for theta in self.theta: self.build_and_connect_nodes(sigma, theta) nest.Simulate(self.T) mean_activity = get_mean_activity(self.detector, self.T) mean_activity_theory = activation_function_theory(sigma, theta) delta = np.max([2e-1 * mean_activity_theory * (1. - mean_activity_theory), 1e-2]) self.assertAlmostEqual( mean_activity, mean_activity_theory, delta=delta)
[docs]def suite(): suite1 = unittest.TestLoader().loadTestsFromTestCase( ErfcNeuronTheoryTestCase) return unittest.TestSuite([suite1])
[docs]def run(): runner = unittest.TextTestRunner(verbosity=2) runner.run(suite())
if __name__ == "__main__": run()