FITZHUGH_NAGUMO
Overview
The FITZHUGH_NAGUMO function numerically solves the FitzHugh-Nagumo system of ordinary differential equations, modeling neuron action potentials with two variables: membrane potential and recovery variable. This model is a simplification of the Hodgkin-Huxley model and is widely used in computational neuroscience to study excitability and oscillations in neurons. The ODE system is:
where is the membrane potential, is the recovery variable, and are model parameters, is the time scale, and is the external current. The function uses SciPy’s ODE solver (scipy.integrate.solve_ivp ) to integrate the system from t_start to t_end. Only the basic two-variable model is exposed; external stimulus or spatial extensions are not supported. The integration method can be selected from several common solvers, but only the most used options are exposed. This example function is provided as-is without any representation of accuracy.
Usage
To use the function in Excel:
=FITZHUGH_NAGUMO(v_initial, w_initial, a, b, tau, i_ext, t_start, t_end, [timesteps], [solve_ivp_method])v_initial(float, required): Initial membrane potential.w_initial(float, required): Initial recovery variable.a(float, required): Parameter a.b(float, required): Parameter b.tau(float, required): Time scale parameter.i_ext(float, required): External current.t_start(float, required): Start time for integration.t_end(float, required): End time for integration.timesteps(int, optional, default=10): Number of timesteps to solve for.solve_ivp_method(string (enum), optional, default=‘RK45’): Integration method. Valid options:RK45,RK23,DOP853,Radau,BDF,LSODA.
The function returns a 2D array (table) with columns: t, V, W, representing time, membrane potential, and recovery variable at each step. If the input is invalid or integration fails, a string error message is returned.
Examples
Example 1: Basic Case
Inputs:
| v_initial | w_initial | a | b | tau | i_ext | t_start | t_end | timesteps | method |
|---|---|---|---|---|---|---|---|---|---|
| 0.0 | 0.0 | 0.7 | 0.8 | 12.5 | 0.5 | 0.0 | 1.0 | 10 | RK45 |
Excel formula:
=FITZHUGH_NAGUMO(0.0, 0.0, 0.7, 0.8, 12.5, 0.5, 0.0, 1.0, 10)Expected output:
| t | V | W |
|---|---|---|
| 0.000 | 0.000 | 0.000 |
| 0.111 | 0.058 | 0.006 |
| 0.222 | 0.123 | 0.013 |
| 0.333 | 0.194 | 0.021 |
| 0.444 | 0.272 | 0.029 |
| 0.556 | 0.358 | 0.038 |
| 0.667 | 0.451 | 0.047 |
| 0.778 | 0.552 | 0.058 |
| 0.889 | 0.659 | 0.069 |
| 1.000 | 0.772 | 0.081 |
Example 2: With Optional Timesteps and Method (RK23)
Inputs:
| v_initial | w_initial | a | b | tau | i_ext | t_start | t_end | timesteps | method |
|---|---|---|---|---|---|---|---|---|---|
| 0.0 | 0.0 | 0.7 | 0.8 | 12.5 | 0.5 | 0.0 | 1.0 | 10 | RK23 |
Excel formula:
=FITZHUGH_NAGUMO(0.0, 0.0, 0.7, 0.8, 12.5, 0.5, 0.0, 1.0, 10, "RK23")Expected output:
| t | V | W |
|---|---|---|
| 0.000 | 0.000 | 0.000 |
| 0.111 | 0.058 | 0.006 |
| 0.222 | 0.123 | 0.013 |
| 0.333 | 0.194 | 0.021 |
| 0.444 | 0.272 | 0.029 |
| 0.556 | 0.358 | 0.038 |
| 0.667 | 0.451 | 0.047 |
| 0.778 | 0.551 | 0.058 |
| 0.889 | 0.659 | 0.069 |
| 1.000 | 0.772 | 0.081 |
Example 3: All Args Specified
Inputs:
| v_initial | w_initial | a | b | tau | i_ext | t_start | t_end | timesteps | method |
|---|---|---|---|---|---|---|---|---|---|
| 1.0 | 0.5 | 0.7 | 0.8 | 12.5 | 0.5 | 0.0 | 2.0 | 10 | RK45 |
Excel formula:
=FITZHUGH_NAGUMO(1.0, 0.5, 0.7, 0.8, 12.5, 0.5, 0.0, 2.0, 10, "RK45")Expected output:
| t | V | W |
|---|---|---|
| 0.000 | 1.000 | 0.500 |
| 0.222 | 1.144 | 0.524 |
| 0.444 | 1.272 | 0.551 |
| 0.667 | 1.379 | 0.579 |
| 0.889 | 1.462 | 0.608 |
| 1.111 | 1.520 | 0.638 |
| 1.333 | 1.558 | 0.669 |
| 1.556 | 1.579 | 0.699 |
| 1.778 | 1.589 | 0.730 |
| 2.000 | 1.590 | 0.760 |
Example 4: Different Parameters
Inputs:
| v_initial | w_initial | a | b | tau | i_ext | t_start | t_end | timesteps | method |
|---|---|---|---|---|---|---|---|---|---|
| -1.0 | 0.2 | 0.5 | 0.7 | 10.0 | 0.3 | 0.0 | 1.5 | 10 | RK45 |
Excel formula:
=FITZHUGH_NAGUMO(-1.0, 0.2, 0.5, 0.7, 10.0, 0.3, 0.0, 1.5, 10)Expected output:
| t | V | W |
|---|---|---|
| 0.000 | -1.000 | 0.200 |
| 0.167 | -1.093 | 0.189 |
| 0.333 | -1.181 | 0.176 |
| 0.500 | -1.261 | 0.162 |
| 0.667 | -1.332 | 0.147 |
| 0.833 | -1.391 | 0.131 |
| 1.000 | -1.440 | 0.114 |
| 1.167 | -1.479 | 0.097 |
| 1.333 | -1.507 | 0.079 |
| 1.500 | -1.527 | 0.061 |
Python Code
from scipy import integrate as scipy_integrate
import numpy as np
def fitzhugh_nagumo(v_initial, w_initial, a, b, tau, i_ext, t_start, t_end, timesteps=10, solve_ivp_method='RK45'):
"""
Wrapper around scipy.integrate.solve_ivp that numerically solves the FitzHugh-Nagumo system of
ordinary differential equations for neuron action potentials.
This function wraps the scipy.integrate.solve_ivp solver. See:
https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.solve_ivp.html
Args:
v_initial: Initial membrane potential.
w_initial: Initial recovery variable.
a: Parameter a.
b: Parameter b.
tau: Time scale parameter.
i_ext: External current.
t_start: Start time of integration.
t_end: End time of integration.
timesteps: Number of timesteps to solve for. Default is 10.
solve_ivp_method: Integration method ('RK45', 'RK23', 'DOP853', 'Radau', 'BDF', 'LSODA'). Default is 'RK45'.
Returns:
2D list with header row: t, V, W. Each row contains time and variable values, or an error message (str) if input is invalid.
This example function is provided as-is without any representation of accuracy.
"""
# Validate input types
try:
v0 = float(v_initial)
w0 = float(w_initial)
a = float(a)
b = float(b)
tau = float(tau)
i_ext = float(i_ext)
t0 = float(t_start)
t1 = float(t_end)
ntp = int(timesteps)
except Exception:
return "Invalid input: All initial values, parameters, and timesteps must be numbers."
if t1 <= t0:
return "Invalid input: t_end must be greater than t_start."
if tau <= 0:
return "Invalid input: tau must be positive."
if ntp <= 0:
return "Invalid input: timesteps must be a positive integer."
if solve_ivp_method not in ['RK45', 'RK23', 'DOP853', 'Radau', 'BDF', 'LSODA']:
return "Invalid input: solve_ivp_method must be one of 'RK45', 'RK23', 'DOP853', 'Radau', 'BDF', 'LSODA'."
# Create time array for evaluation
t_eval = np.linspace(t0, t1, ntp)
# FitzHugh-Nagumo ODE system
def fhn_ode(t, y):
v, w = y
dv_dt = v - v**3 / 3 - w + i_ext
dw_dt = (v + a - b * w) / tau
return [dv_dt, dw_dt]
# Integrate
try:
sol = scipy_integrate.solve_ivp(
fhn_ode,
[t0, t1],
[v0, w0],
method=solve_ivp_method,
dense_output=False,
t_eval=t_eval
)
except Exception as e:
return f"Integration error: {e}"
if not sol.success:
return f"Integration failed: {sol.message}"
# Format output: header row then data rows
result = [["t", "V", "W"]]
for i in range(len(sol.t)):
t_val = float(sol.t[i])
v_val = float(sol.y[0][i])
w_val = float(sol.y[1][i])
# Disallow nan/inf
if any([
not isinstance(t_val, float) or not isinstance(v_val, float) or not isinstance(w_val, float),
t_val != t_val or v_val != v_val or w_val != w_val, # NaN check
abs(t_val) == float('inf') or abs(v_val) == float('inf') or abs(w_val) == float('inf')
]):
return "Invalid output: nan or inf detected."
result.append([t_val, v_val, w_val])
return result