/*
 *  test_iaf_fudge.sli
 *
 *  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/>.
 *
 */

/* BeginDocumentation
Name: testsuite::test_iaf_fudge - sli script to test normalization of PSP for iaf_neuron model

Synopsis: (test_iaf_fudge) run -> compares response to spike input step with reference data 

Description:
    
The peak time of the postsynaptic potential (PSP) is calculated using
the LambertW function. The theoretical peak voltage amplitude for a
postsynaptic current of amplitude 1pA is then used to adjust the
synaptic weight such that a PSP of amplitude 1mV is generated.  The
success of this approach is verified by comparing the theoretical
value with the result of a simulation where a single spike is sent to
the neuron.

The name of this test script has a historical explanation. Prior to
July 2009 the analytical expression for the peak time of the PSP was
not known to the NEST developers. Therefore the normalization factor
required to adjust the PSP amplitude was computed by root finding
outside of NEST. The factor was called "fudge" in examples and
application code. The root finding was not done in NEST because infix
mathematical notation only become available in SLI in January
2009. The name "fudge" indicated that the origin of this value was not
obvious from the simulation scripts and usage was inherently dangerous
because a change of the time constants of the neuron model would
invalidate the value of "fudge".
    
Author:  July 2009, Helias
SeeAlso: iaf_neuron, testsuite::test_iaf, testsuite::test_lambertw, LambertWm1
*/


(unittest) run
/unittest using

0.1 /h Set
20.0 /tau_m Set
0.5 /tau_syn Set
250.0 /C_m Set

% calculate the normalization factor for the PSP
(tau_m / tau_syn) ExecMath /a Set
(1.0 / tau_syn - 1.0 / tau_m) ExecMath /b Set
% time of maximum
(1.0/b * (-LambertWm1(-exp(-1.0/a)/a)-1.0/a)) ExecMath /t_max Set
% maximum of PSP for current of unit amplitude
( exp(1)/(tau_syn*C_m*b) * ((exp(-t_max/tau_m) - exp(-t_max/tau_syn)) / b - t_max*exp(-t_max/tau_syn)) ) ExecMath /V_max Set

cout (t_max=) <- t_max <- pop 
cout (V_max_unit=) <- V_max <- pop

ResetKernel

0 << 
      /local_num_threads 1 
      /resolution h
  >> SetStatus

/iaf_neuron Create /neuron Set
neuron << /tau_m tau_m /tau_syn tau_syn /C_m C_m >> SetStatus

/voltmeter Create /vm Set
vm << /withtime true /time_in_steps true /interval h >> SetStatus

/spike_generator Create /sg Set
sg << /precise_times false /spike_times [h] >> SetStatus

sg neuron 1.0 V_max div h Connect
vm neuron 1.0 h Connect

20.0 Simulate

% position in voltage array to find maximum
t_max h div 2 add int /ti Set  % time in steps, where maximum of PSP is reached 

% check, if maximum is at right position
vm [/events [/V_m]] get 0 get cva ==
vm [/events [/V_m]] get 0 get cva ti get -69.0 sub abs 1e-4 leq assert_or_die
