Skip to content

Commit 52e3fba

Browse files
author
Alexander Ororbia
committed
cleaned up return carriages in ode-integration doc
1 parent 03bcf75 commit 52e3fba

File tree

1 file changed

+48
-16
lines changed

1 file changed

+48
-16
lines changed

docs/tutorials/neurocog/integration.md

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,25 @@
11
# Numerical Integration
22

3-
In constructing one's own biophysical models, particularly those of phenomena that change with time, ngc-learn offers useful flexible tools for numerical integration that facilitate an easier time in constructing your own components that play well with the library's simulation backend. Knowing how things work beyond Euler integration -- the base/default form of integration often employed by ngc-learn -- might be useful for constructing and simulating dynamics more accurately (often at the cost of additional computational time).
3+
In constructing one's own biophysical models, particularly those of phenomena that change with time, ngc-learn offers
4+
useful flexible tools for numerical integration that facilitate an easier time in constructing your own components that
5+
play well with the library's simulation backend. Knowing how things work beyond Euler integration -- the base/default
6+
form of integration often employed by ngc-learn -- might be useful for constructing and simulating dynamics more
7+
accurately (often at the cost of additional computational time).
48

59
## Euler Integration
610

7-
Euler integration is very simple (and fast) way of using the ordinary differential equations you typically define for the cellular dynamics of various components in ngc-learn (which typically get called in any component's `advance_state()` command).
11+
Euler integration is very simple (and fast) way of using the ordinary differential equations you typically define for
12+
the cellular dynamics of various components in ngc-learn (which typically get called in any component's `advance_state()` command).
813

9-
While utilizing the numerical integrator will depend on your component's design and the (biophysical) elements you wish to model, let's observe ngc-learn's base backend utilities (its integration backend `ngclearn.utils.diffeq`) in the context of numerically integrating a simple differential equation; specifically the autonomous (linear) ordinary differential equation (ODE): $\frac{\partial y(t)}{\partial t} = y(t)$. The analytic solution to this equation is also simple -- it is $y(t) = e^{t}$.
14+
While utilizing the numerical integrator will depend on your component's design and the (biophysical) elements you wish
15+
to model, let's observe ngc-learn's base backend utilities (its integration backend `ngclearn.utils.diffeq`) in the
16+
context of numerically integrating a simple differential equation; specifically the autonomous (linear) ordinary
17+
differential equation (ODE): $\frac{\partial y(t)}{\partial t} = y(t)$. The analytic solution to this equation is
18+
also simple -- it is $y(t) = e^{t}$.
1019

11-
If you have defined your differential equation $\frac{\partial y(t)}{\partial t}$ in a rather simple format[^1], you can write the following code to examine how Euler integration approximates the analytical solution (in this example, we examine just two different step sizes, i.e., `dt = 0.1` and `dt = 0.09`)
20+
If you have defined your differential equation $\frac{\partial y(t)}{\partial t}$ in a rather simple format[^1], you
21+
can write the following code to examine how Euler integration approximates the analytical solution (in this example,
22+
we examine just two different step sizes, i.e., `dt = 0.1` and `dt = 0.09`)
1223

1324
```python
1425
from jax import numpy as jnp, random, jit, nn
@@ -71,13 +82,30 @@ which should yield you a plot like the one below:
7182

7283
<img src="../../images/tutorials/neurocog/euler_integration.jpg" width="500" />
7384

74-
Notice how the integration constant `dt` (or $\Delta t$) chosen affects the approximation of ngc-learn's Euler integrator and typically, when constructing your biophysical models, you will need to think about this constant in the context of your simulation time-scale and what you intend to model. Note that, in many biophysical component cells, you will have an integration time constant of some form, i.e., a $\tau$, that you can control, allowing you to fix your `dt` to your simulated time-scale (say to a value like `dt = 1` millisecond) while tuning/altering your time constant $\tau$ (since the differential equation will be weighted by $\frac{\Delta t}{\tau}$).
85+
Notice how the integration constant `dt` (or $\Delta t$) chosen affects the approximation of ngc-learn's Euler
86+
integrator and typically, when constructing your biophysical models, you will need to think about this constant in
87+
the context of your simulation time-scale and what you intend to model. Note that, in many biophysical component cells,
88+
you will have an integration time constant of some form, i.e., a $\tau$, that you can control, allowing you to fix
89+
your `dt` to your simulated time-scale (say to a value like `dt = 1` millisecond) while tuning/altering your time
90+
constant $\tau$ (since the differential equation will be weighted by $\frac{\Delta t}{\tau}$).
7591

7692
## Higher-Order Forms of (Explicit) Integration
7793

78-
Notably, ngc-learn has built-in several forms of (explicit) numerical integration beyond the Euler method, such as a second order Runge-Kutta (RK-2) method (also known as the midpoint method) and 4th-order Runge-Kutta (RK-4) method or an error-predictor method such as Heun's method (also known as the trapezoid method). These forms of integration might be useful particularly if a cell or plastic synaptic component you might be writing follows dynamics that are more nonlinear or biophysically complex (requiring a higher degree of simulation accuracy). For instance, ngc-learn's in-built cell components, particularly those of higher biophysical complexity -- like the [Izhikevich cell](ngclearn.components.neurons.spiking.izhikevichCell) or the [FitzhughNagumo cell](ngclearn.components.neurons.spiking.fitzhughNagumoCell) -- contain argument flags for switching their simulation steps to use RK-2.
79-
80-
To illustrate the value of higher-order numerical integration methods, let us examine a simple polynomial equation (thus nonlinear) that is further non-autonomous, i.e., it is a function of the time variable $t$ itself. A possible set of dynamics in this case might be: $\frac{\partial y(t)}{\partial t} = -2 t^3 + 12 t^2 - 20 t + 8.5$ which has the analytic solution $y(t) = -(1/2) t^4 + 4 t^3 - 10 t^2 + 8.5 t + C$ (where we will set $C = 1$). You can write code like below, importing from `ngclearn.utils.diffeq.ode_utils` the Euler routine (`step_euler`), the RK-2 routine (`step_rk2`), the RK-4 routine (`step_rk4`), and Heun's method (`step_heun`), and compare how these methods approximate the nonlinear dynamics inherent to our constructed $\frac{\partial y(t)}{\partial t}$ ODE below:
94+
Notably, ngc-learn has built-in several forms of (explicit) numerical integration beyond the Euler method, such as a
95+
second order Runge-Kutta (RK-2) method (also known as the midpoint method) and 4th-order Runge-Kutta (RK-4) method or
96+
an error-predictor method such as Heun's method (also known as the trapezoid method). These forms of integration might
97+
be useful particularly if a cell or plastic synaptic component you might be writing follows dynamics that are more
98+
nonlinear or biophysically complex (requiring a higher degree of simulation accuracy). For instance, ngc-learn's
99+
in-built cell components, particularly those of higher biophysical complexity -- like the [Izhikevich cell](ngclearn.components.neurons.spiking.izhikevichCell) or
100+
the [FitzhughNagumo cell](ngclearn.components.neurons.spiking.fitzhughNagumoCell) -- contain argument flags for switching their simulation steps to use RK-2.
101+
102+
To illustrate the value of higher-order numerical integration methods, let us examine a simple polynomial equation
103+
(thus nonlinear) that is further non-autonomous, i.e., it is a function of the time variable $t$ itself. A possible set
104+
of dynamics in this case might be: $\frac{\partial y(t)}{\partial t} = -2 t^3 + 12 t^2 - 20 t + 8.5$ which has the
105+
analytic solution $y(t) = -(1/2) t^4 + 4 t^3 - 10 t^2 + 8.5 t + C$ (where we will set $C = 1$). You can write code
106+
like below, importing from `ngclearn.utils.diffeq.ode_utils` the Euler routine (`step_euler`), the RK-2 routine
107+
(`step_rk2`), the RK-4 routine (`step_rk4`), and Heun's method (`step_heun`), and compare how these methods
108+
approximate the nonlinear dynamics inherent to our constructed $\frac{\partial y(t)}{\partial t}$ ODE below:
81109

82110
```python
83111
from jax import numpy as jnp, random, jit, nn
@@ -148,11 +176,15 @@ which should yield you a plot like the one below:
148176

149177
<img src="../../images/tutorials/neurocog/ode_method_comparison.jpg" width="500" />
150178

151-
As you might observe, RK-4 give the best approximation of the solution. In addition, when the integration step size is held constant, Euler integration does quite poorly over just a few steps while RK-2 and Heun's method do much better at approximating the analytical equation. In the end, the type of numerical integration method employed can matter depending on the ODE(s) you use in modeling, particularly if you seek higher accuracy for more nonlinear dynamics like in our example above.
152-
153-
[^1]: The format expected by ngc-learn's backend is that the differential equation
154-
provides a functional API/form like so: for instance `dy/dt = diff_eqn(t, y(t), params)`,
155-
representing $\frac{\partial \mathbf{y}(t, \text{params})}{\partial t}$,
156-
noting that you can name your 3-argument function (and its arguments) anything you like.
157-
Your function does not need to use all of the arguments (i.e., `t`, `y`, or `params`, the last of which is a tuple containing any fixed constants your equation might need) to produce its output.
158-
Finally, this function should only return the value(s) for `dy/dt` (vectors/matrices of values).
179+
As you might observe, RK-4 give the best approximation of the solution. In addition, when the integration step size is
180+
held constant, Euler integration does quite poorly over just a few steps while RK-2 and Heun's method do much better at
181+
approximating the analytical equation. In the end, the type of numerical integration method employed can matter
182+
depending on the ODE(s) you use in modeling, particularly if you seek higher accuracy for more nonlinear dynamics like
183+
in our example above.
184+
185+
[^1]: The format expected by ngc-learn's backend is that the differential equation provides a functional API/form
186+
like so: for instance `dy/dt = diff_eqn(t, y(t), params)`, representing
187+
$\frac{\partial \mathbf{y}(t, \text{params})}{\partial t}$, noting that you can name your 3-argument function (and
188+
its arguments) anything you like. Your function does not need to use all of the arguments (i.e., `t`, `y`, or
189+
`params`, the last of which is a tuple containing any fixed constants your equation might need) to produce its
190+
output. Finally, this function should only return the value(s) for `dy/dt` (vectors/matrices of values).

0 commit comments

Comments
 (0)