API reference¶
xpplab.Model
¶
Bases: AnalysisMixin
An XPPAUT model loaded from an .ode file.
m = Model("lecar.ode")
m.parameters["iapp"] = 0.1
sol = m.run(total=200)
sol["V"] # NumPy array
parameters
property
¶
Parameters, as a live dictionary: m.parameters["a"] = 2.
initial_conditions
property
¶
Initial conditions of the state variables, as a live dictionary.
options
property
¶
The numerical options (TOTAL, DT, METH, ...), as a snapshot.
log
property
¶
What the engine printed during the last call.
from_text(text, name='model.ode', **kw)
classmethod
¶
Load a model from the text of an .ode file.
get(name)
¶
Value of a parameter, an initial condition or a numerical option.
set(**values)
¶
Set parameters, initial conditions or numerical options.
m.set(iapp=0.1, total=200, meth="stiff"). Names ignore case.
This works exactly like a set line in an ODE file.
apply_set(name)
¶
Apply a named parameter set from the model file (set name {...}).
run(**values)
¶
Integrate from the current initial conditions.
Keyword arguments are applied with :meth:set first, so
m.run(total=100, iapp=0.2) is shorthand for a set followed by a run.
continue_run(trajectory, time=None)
¶
XPPAUT's Continue (C C): integrate time more (default: the
total time) from where trajectory ended, and return it with the
new points appended. The initial conditions, T0 and the total time
are left as they were.
last_run()
¶
The engine's most recent run, such as the one period of the limit
cycle that :meth:phase_response leaves behind.
equilibrium(guess=None, *, set_initial=False)
¶
Find an equilibrium with Newton's method.
The search starts from guess (a dict of variable values) or from
the current initial conditions. With set_initial=True the
equilibrium becomes the new initial condition, which is how AUTO
continuations usually start.
linearize(at=None, inputs=(), *, step=None, tol=None)
¶
Linearise at an equilibrium and test controllability.
at is a dict of variable values (others keep their initial
value); by default the equilibrium found by :meth:equilibrium.
inputs lists the parameters that act as controls. A is the
Jacobian of the right-hand side and B the derivative with respect to
each input, both by central differences of :meth:rhs extrapolated to
zero step (Ridders' method, which picks its own step; step= sets
a fixed relative step instead). Returns a
:class:~xpplab.control.Linearization with A, B,
eigenvalues, controllability (the matrix [B, AB, ...]),
rank and controllable. tol is the singular-value cutoff
for the rank.
manifolds(guess=None)
¶
Stable and unstable manifolds of a saddle, as XPPAUT draws them.
Finds the equilibrium near guess (or the initial values). If it
is a saddle with a one-dimensional stable or unstable direction,
each branch is integrated from just off the equilibrium along its
eigenvector: forward in time for unstable branches, backward for
stable ones. Returns (equilibrium, [(kind, Trajectory), ...])
with kind "stable" or "unstable"; the list is empty for non-saddles.
equilibrium_sweep(parameter, values, *, guess=None)
¶
Follow an equilibrium as a parameter changes: XPPAUT's Sing pts > Range, a quick diagram of steady states without AUTO.
For each value in turn the parameter takes it, and Newton's method
starts from the equilibrium found at the value before (the first
time from the initial conditions, or from guess). Returns a
Table: the parameter, each variable, then unstable and
stable, the numbers of eigenvalues with positive and negative
real parts (for maps, outside and inside the unit circle). Where
Newton's method failed the row holds NaN. The parameter is restored
afterwards.
find_equilibria(guesses=100, box=None, tol=0.001)
¶
Every equilibrium Newton's method finds from random starting points: XPPAUT's Sing pts > Monte Carlo.
The guesses starting points are spread uniformly over a box:
box maps variables to (low, high), and the others span -10
to 10, XPPAUT's default. Equilibria closer than tol (the sum of
the absolute differences) count as one. Returns the equilibria in
the order found, as a list of :class:Equilibrium. XPPAUT's random
numbers repeat from run to run, so the same calls find the same
list.
rhs(state=None, t=0.0)
¶
The right-hand side f(t, x) of the ODEs, as an array.
state is a dict of variable values (others keep their initial
value) or a full array; by default the initial condition. For maps it
is the next state.
nullclines(x, y, xlim, ylim, grid=100)
¶
XPPAUT's nullclines in the (x, y) plane over the given window.
Returns (x_nullcline, y_nullcline): arrays of line segments with
shape (n, 4) holding x1, y1, x2, y2. The other variables keep their
initial values.
nullcline_sweep(parameter, values, x, y, xlim, ylim, grid=100)
¶
The nullclines for each value of a parameter (XPPAUT's Nullcline
Freeze > Range): a list of
(x_nullcline, y_nullcline)pairs as :meth:nullclinesreturns them, one per value. The parameter is put back afterwards.
vector_field(x, y, xlim, ylim, n=20)
¶
The vector field on an n x n grid: returns X, Y, U, V for matplotlib's quiver. Other variables keep their initial values.
phase_plane(x=None, y=None, *, xlim=None, ylim=None, trajectory=True, nullclines=True, field=True, equilibrium=True, frozen=None, ax=None)
¶
Draw the phase plane: trajectory, nullclines, direction field and the nearby equilibrium, in one call. Returns the matplotlib axes.
frozen is a list of earlier nullclines to draw faded, such as
:meth:nullcline_sweep returns.
ic_last(*, shift=False)
¶
Start the next run where the last one ended (XPPAUT's Initial conds > Last, I L): the final state, in full precision, becomes the initial condition.
With shift=True (Initial conds > Shift, I S) the start time T0
also becomes the time the run ended, so that the time goes on: it
matters for models with forcing terms in t.
read_ics(path)
¶
Read the initial conditions from a text file (XPPAUT's Initial conds > File, I F): the first numbers in it, one per variable in order, separated by spaces, new lines or commas. A file with fewer numbers than variables raises EngineError and changes nothing.
write_ics(path)
¶
Write the initial conditions to a text file, one per line in the
order of the variables, exactly: :meth:read_ics reads it back.
ic_formula(target, formula)
¶
Set initial conditions from a formula (XPPAUT's Initial conds > formUla, I U), evaluated by XPPAUT with the model's parameters and functions.
target is a variable, m.ic_formula("V", "vk + 0.1"), or a
range of numbered variables in XPPAUT's array form, where [j] in
the formula stands for the index::
m.ic_formula("u[1..50]", "exp(-([j]-25)^2/20)")
sweep(parameter, values, *, measure=None, continue_runs=False, **run_kw)
¶
Run once per value of a parameter or initial condition and collect the results: XPPAUT's Initial conds > Range.
Without measure it returns a list of Trajectory objects. With a
function, e.g. measure=lambda s: s["V"].max(), it returns a NumPy
array of the measure at each value: a brute-force bifurcation
diagram (measure=lambda s: m.lyapunov() gives the Liapunov
exponent at each value).
Each run starts from the initial conditions (XPPAUT's "Use old ICs"
= Yes), or with continue_runs=True from where the previous run
ended ("Use old ICs" = No), which follows an attractor as the
parameter changes. The parameter and initial conditions are restored
afterwards.
Two values can move together along a line (XPPAUT's 2par range,
Crv): give a tuple of names and pairs of values,
m.sweep(("iapp", "gca"), zip(i_values, g_values)). For every
pair on a grid, see :meth:sweep_grid.
sweep_grid(parameter, values, parameter2, values2, *, measure=None, continue_runs=False, **run_kw)
¶
Run once for every pair of values on a grid: XPPAUT's 2par range
(Array). The runs go through values for each of values2 in
turn, setting parameter then parameter2; either may be an
initial condition.
With a measure, returns a NumPy array of shape
(len(values2), len(values)) (plus the measure's own shape): a map
over the two values, such as an amplitude or the Liapunov exponent,
ready for plt.imshow(..., origin="lower"). Without one, a list of
rows of Trajectory objects. continue_runs starts each run where
the previous one ended, row after row. The values and initial
conditions are restored afterwards.
interact(*parameters, y=None, **ranges)
¶
Jupyter sliders for parameters that re-integrate as you drag.
m.interact("I", "eps") uses ranges around the current values;
m.interact(I=(0, 2)) sets them. Needs ipywidgets and matplotlib.
close()
¶
Free the engine behind this model.
xpplab.Trajectory
¶
The result of an integration: time and every output column.
to_numpy()
¶
All columns as one array, one row per output time.
to_pandas()
¶
A pandas DataFrame indexed by time.
save(path)
¶
Write the data in XPPAUT's output.dat format.
to_csv(path)
¶
Write the run as CSV with a header, every number exact (the
desktop app's export FILE.csv writes the same file).
plot(*y, x='T', ax=None, **kw)
¶
Plot columns against time (or against another column with x=).
plot3d(x, y, z, ax=None, **kw)
¶
A 3-D plot of three columns (XPPAUT's 3D view), with matplotlib.
xpplab.Equilibrium
dataclass
¶
An equilibrium, with the eigenvalues of the Jacobian there.
kind
property
¶
A plain-language classification, e.g. "stable focus" or "saddle".
xpplab.Linearization
dataclass
¶
The linear system dx = A dx + B du around a point of a model.
A is the Jacobian of the right-hand side (for a map, of the map),
B has one column per input parameter. controllability is
[B, AB, ..., A^(n-1) B]; the pair is controllable when its rank is n.
error(dx, du=None)
¶
Relative error of the linear model for one perturbation.
Compares the model's right-hand side at (x0 + dx, p0 + du) with the prediction A dx + B du, and returns |difference| / |prediction|. This is the quantity that decides whether a controller designed on (A, B) will behave on the real model.
valid_radius(tol=0.05, directions=32, seed=0)
¶
Size of the perturbation (a norm in state space, with the inputs
scaled the same way) for which the linear model keeps its relative
error below tol in every one of a fixed set of random directions.
Found by scanning outwards in factors of two, then bisecting. A controller designed on (A, B) can be trusted within about this distance of the point; beyond it, use the nonlinear model.
xpplab.Table
¶
A table of results: named NumPy columns, the first one the x-axis.
to_pandas()
¶
A pandas DataFrame indexed by the first column.
from_grid(name, values, name2, values2, columns, title='')
classmethod
¶
A table of results on a grid (see :meth:Model.sweep_grid): one
row per point, going through values for each of values2, the
two values first and then each of columns, arrays of shape
(len(values2), len(values)).
from_nullclines(sets, first=0, title='')
classmethod
¶
Nullclines as a table, one row per line segment, as the desktop
app's export FILE.csv nullclines writes them: the set (first
for the first pair in sets, then counting up), which nullcline
(1 the x variable's, 2 the y variable's) and the segment's ends
x1, y1, x2, y2. sets holds (x_nullcline, y_nullcline) pairs
from :meth:Model.nullclines or :meth:Model.nullcline_sweep.
to_csv(path)
¶
Write the table as CSV, every number exact (the desktop app's
export FILE.csv analysis writes the same file).
plot(*y, ax=None, **kw)
¶
Plot columns (by default the second) against the first.
xpplab.Animation
¶
An .ani file parsed by XPPAUT, applied to a model's last run.
__len__()
¶
The number of frames: the rows of the model's last run.
frame(row)
¶
The shapes at a row of the run. Row 0 also evaluates the file's permanent commands.
plot(row, ax=None, trails=None)
¶
Draw one frame with matplotlib. trails (a dict kept between
calls) collects comet tails; plot frames in order to see them.
save_gif(path, *, every=5, fps=20, size=(4, 4))
¶
Write the animation as a GIF, one frame every every rows.
Needs matplotlib and Pillow.
xpplab.auto.Auto
¶
AUTO continuation for a model. Reach it as model.auto.
diagram
property
¶
Every point computed so far.
set(**settings)
¶
Set AUTO numerics: m.auto.set(ds=0.01, nmax=500, parmax=2).
parameters(main, second=None)
¶
Choose the continuation parameter (and the second one for two-parameter curves).
reset()
¶
Forget the whole bifurcation diagram.
save(path)
¶
Save the diagram as an .auto file, XPPAUT's AUTO > File > Save
diagram: AUTO's settings, every point and AUTO's restart data, so
that :meth:load brings back a diagram that can be continued from
its labelled points. XPPAUT opens these files too.
load(path)
¶
Replace the diagram with one saved by :meth:save or by XPPAUT
(AUTO > File > Load diagram). Its settings and restart data come
with it, so :meth:continue_from works on its labels. Returns the
diagram.
orbit(point)
¶
The periodic orbit at a labelled point as a run, one period long, from AUTO's own solution (XPPAUT's AUTO > File > Import orbit). It becomes the model's last run, so the analysis tools see it.
equilibria(parameter, *, from_equilibrium=True, **settings)
¶
Continue a branch of steady states in parameter.
By default Newton's method first moves the initial condition onto a
nearby equilibrium, the usual way to start AUTO. Extra keyword
arguments are AUTO settings (ds=-0.01, nmax=300, ...).
Returns the newly computed points.
start(kind, parameter, **settings)
¶
Start a new branch: kind is "steady", "periodic" (from the current orbit), "bvp", "homoclinic" or "heteroclinic".
continue_from(point, action=None, *, parameter=None, second=None, **settings)
¶
Continue from a labelled point, like Grab + Run in XPPAUT.
action depends on the point: from a Hopf point "periodic",
"two-parameter", "extend" or "new"; from a fold "two-parameter";
from a branch point "switch", "extend", "two-parameter"; from period
doubling "doubling", "two-parameter", "fixed-period"; from a torus
point "two-parameter", "fixed-period"; from an ordinary point
"extend". Two-parameter continuations need second=.
xpplab.Diagram
¶
A list of bifurcation-diagram points with helpers to explore them.
special(type=None)
¶
Labelled special points (HB, LP, BP, PD, TR, ...), optionally of one type.
labelled()
¶
Every labelled point, including end points and regular saves.
to_pandas()
¶
One row per point: branch, type, label, stability, parameters, norm, period, and the max/min of every variable.
to_csv(path)
¶
Write the points as CSV, every number exact: branch, point, type,
label, stability, the parameters, norm, period, then the max and
min of every variable. The desktop app's export FILE.csv auto
writes the same file.
plot(y=None, *, ax=None, labels=True, **kw)
¶
Plot the diagram. Stable branches are solid, unstable dashed; periodic orbits show their max and min; special points are labelled.
y is a variable name (default: the first variable), "norm", or
"period". Two-parameter curves are drawn in the parameter plane.
xpplab.Point
dataclass
¶
One computed point of a bifurcation diagram.
eigenvalues
property
¶
Eigenvalues of the Jacobian at a steady-state point, recovered
from multipliers = exp(eigenvalue). Real parts are exact;
imaginary parts are known only modulo 2*pi, as XPPAUT stores them.
None for periodic orbits (use multipliers).
xpplab.EngineError
¶
Bases: RuntimeError
An error reported by the XPPAUT engine.
log holds everything the engine printed during the failing call,
which usually explains the problem (for example a syntax error in the
model file).