1
$\begingroup$

I am wanting to save and use the value of a variable within NDSolve[] but without that variable being part of the equation itself.

Code below (ODE for the Leaky Integrate-and-Fire neuron) expresses what I want to do, with the value for the end of the refractory period updated within a WhenEvent[] statement.

Unfortunately it doesn't work and the error message suggests why not - but I don't know the solution though I am sure a simple one must exist.

trest = 0;
With[{τ = 10, R = 1, Jm = 1.5, vthresh = 1, vreset = 0, v0 = 0, tref = 3 },
 lif = NDSolve[{v'[t] == If[ t >= trest, -(v[t] - Jm R)/τ, 0], 
        v[0] == v0, 
        WhenEvent[ v[t] >= vthresh, {v[t] -> vreset, trest -> Evaluate[ t + tref ] } ]},
        v[t], {t, 0, 60}] ]
NDSolve::wenset: Warning: the rule trest->Evaluate[t+3] will not directly set 
the state because the left-hand side is not a list of state variables. >>

I realise that this can be done by adding another variable into the ODE, making its time derivative == 0 and just changing its value within the WhenEvent[] statement but this is rather messy and has potential to confuse the ODE solver.

$\endgroup$
  • $\begingroup$ Why do you think that it "has potential to confuse the ODE solver"? Take a look at what DiscreteVariables do. $\endgroup$ – Dr. belisarius Nov 18 '13 at 12:52
  • $\begingroup$ because having another variable in the problem with a zero derivative and then changing its value as a step function will have an impact on certain solution methods and their error/stiffness estimates $\endgroup$ – Michael Hopkins Nov 18 '13 at 18:10
  • $\begingroup$ DiscreteVariables doesn't help, because it doesn't help to save the value that updates as you step through time. A solution that does this but needs the auxiliary variable defined within the system is: With[{\[Tau] = 10, R = 10, Jm = 0.7, vthresh = 1, vreset = 0, v0 = 0, tref = 2 }, lif = NDSolve[{v'[t] == If[ t >= trest[t], -(v[t] - Jm R)/\[Tau], 0], v[0] == v0, trest'[t] == 0, trest[0] == 0, WhenEvent[ v[t] >= vthresh, {v[t] -> vreset, trest[t] -> Evaluate[ t + tref] } ]}, {v[t], trest[t]}, {t, 0, 60}]] $\endgroup$ – Michael Hopkins Nov 18 '13 at 21:12
  • $\begingroup$ any other thoughts? the above solution works but defining the auxiliary variable within the ODE feels wrong - surely there is a way of making WhenEvent[] save a value to a variable outside of the ODE itself? $\endgroup$ – Michael Hopkins Nov 19 '13 at 10:14
1
$\begingroup$

Another way is to make trest one of the DiscreteVariables.

Clear[trest]
With[{τ = 10, R = 1, Jm = 1.5, vthresh = 1, vreset = 0, v0 = 0, tref = 3}, 
 lif = NDSolve[{v'[t] == 
     Piecewise[{{-(v[t] - Jm R)/τ, t >= trest[t]}}, 0], 
    v[0] == v0, trest[0] == 0,
    WhenEvent[v[t] >= vthresh, {v[t] -> vreset, trest[t] -> t + tref}]},
 {v, trest}, {t, 0, 60}, DiscreteVariables -> {trest}]];

ListLinePlot[v /. First[lif], PlotRange -> All]

Mathematica graphics

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.