Site navigation:

User Documentation

  1. PyDSTool basics
    1. Modularity and embedding
    2. Design philosophies
    3. Numerical classes
    4. Symbolic classes
    5. Solver classes
    6. Other classes
  2. Starting your own modeling project
    1. Filespace preparation
    2. Mathematical preparation
  3. Basic I/O and object manipulation
    1. Loading and saving data and objects
    2. Deletion
    3. Sessions
    4. Memory management
    5. Copying of PyDSTool data structures
  4. Visualization
  5. System specification
    1. Two routes to specification
  6. Solving for trajectories
    1. Generators
    2. Trajectories
    3. "Models" and hybrid dynamical systems
  7. Bounds and constraints
  8. Continuation and bifurcation analysis
  9. Toolboxes for special tasks
  10. Porting models between PyDSTool and other packages

1. PyDSTool basics

Python is a high level, interpreted, language with powerful object orientation. PyDSTool is primarily a scripting environment for working with dynamical systems models. This is achieved through a set of Python classes for use within a regular, interactive, Python session. These classes themselves rely on several SciPy and NumPy classes, particularly the array class.

The user can build objects from the PyDSTool classes interactively, and can manipulate them using PyDSTool utility functions, or using scripts or modules that the user has written. Visualization tools are provided via Matplotlib to study the results of computations, in much the same way as is done in Matlab. Being built to work with common packages such as SciPy, the user benefits from being able to apply well-known algorithms from other packages to PyDSTool objects.

For a full introduction please see the page ProjectOverview and the first Tutorial.

1.1. Modularity and embedding

As well as providing simulation and analysis routines of its own, PyDSTool is also intended to provide an environment for embedding numerical calculations within each other, in a hierarchical fashion (a.k.a. "nesting"). A design goal was to make the embedding as straightforward and as general-purpose as possible, with the least amount of effort required by the user. PyDSTool provides core Python classes from which a user can take existing numerical computation packages and apply them to high level objects. This is often done by "wrapping" the external packages, providing them with a common API for use within Python. The packages may take the form of simple executables, or as shared libraries that can be loaded into Python after they are wrapped (e.g. using SWIG). Embedding is also made more transparent through Python's dynamic typing system, whereby different classes can be treated in common ways by providing common interface methods.

1.2. Design philosophies

The core elements of PyDSTool are the classes that represent or relate to trajectories of dynamical systems, which are discussed next.

1.3. Numerical classes

From the bottom up:

Note that in discrete spaces, a "curve" refers to an ordered set of discrete points (a "discretized curve").

A companion class is the Interval. This class is used like its mathematical equivalent, to indicate scalar intervals of real numbers or integers, depending on their desired type. See Intervals for details.

1.4. Symbolic classes

See the page Symbolic for more details.

From the bottom up:

1.5. Solvers

Beyond the numerical classes are those that create them as part of solving systems of dynamical equations. Generator objects create Trajectories, for instance. A Model object allows one or more Generators to be combined into (possibly hybrid) dynamical systems models, also providing many additional user utilities for interacting with the model.

1.6 Other classes

2. Starting your own modeling project

2.1. Filespace preparation

Create a directory somewhere using the name of your project. Make sure the path to the PyDSTool package is in Python's path. In a new Python script that will execute your computations, an easy way to do this is to put

from PyDSTool import *

in the header. Any project-specific compilation of program components (e.g. using numerical integrators implemented in C) will require temporary files to be created. These will appear in automatically generated sub-directories of your project directory. If you are worried about "polluting your namespace" then just use

import PyDSTool as dst

(or a similar short abbreviation) for convenience. All commands will then be entered with the prefix dst.

2.2. Mathematical preparation

It is recommended that, to the fullest possible extent, variables and parameters of the dynamical systems studied using PyDSTool are scaled so that they are "order 1" in magnitude. This helps the software accurately deal with occasional rounding errors in the resolution of intervals (see the section on Bounds and Constraints on this page).

3. Basic input/output and object manipulation

3.1. Loading and saving data and objects

The reading and writing of text-format data files is supported. This can be used to import or export trajectory data, for instance. The commands for these are importPointset and exportPointset. To export arrays more easily than using, run exportPointset(arrayToPointset(a), {'fname.dat': []}) to save the array in text format to file 'fname.dat'.

It is also possible to load and save PyDSTool objects, as well as any numpy arrays, numeric values, lists, dictionaries, etc., for re-use in a different session. These functions are loadObjects and saveObjects. Multiple objects can be saved in a single file, and named objects (such as trajectories or generators) can be loaded individually from a file containing multiple objects. For instance, suppose a user wants to store a list of arrays, a Trajectory and a Generator for another session.

# supposed Generator g exists
a = array([1, Inf])
traj = g.compute('test')
saveObjects('mystuff.sav', [a, traj, g])

This last call stores ('serializes') those objects into the given filename. Any file extension can be used, as is your preference. This call will fail if the file already exists. To force the file to be overwritten regardless of whether it exists, append the argument force=True. To reload the objects in a different session:

a, traj, g = loadObjects('mystuff.sav')

If you only want some of the objects back, you can either specify an index or indices into the list returned from loadObjects, as in loadObjects('mystuff.sav')[1] or you can specify a list of string names as a second argument that match the 'name' attributes of any objects stored in the file which have that attribute, as in loadObjects('mystuff.sav', ['test']). Note that if you save a singleton object, e.g. saveObjects(a, 'mystuff.sav'), then it will actually be stored as a list of one element, requiring you to reload with a = loadObjects('mystuff.sav')[0] or by broadcasting with the syntax a, = loadObjects('mystuff.sav') (note the comma).

There are a few less commonly used classes defined in PyDSTool whose instances cannot be saved using these functions, and have to be recreated from their initialization arguments afresh in each session. Work is underway to ensure that all objects can be saved and loaded. For large Trajectories, this form of saving is actually not as memory efficient as recreating from a binary-stored file of the underlying array and metadata.

N.B. For Windows users, saving and loading PyDSTool objects may be a little slow. This is because there is a bug in Python's "pickler" in Windows implementations that concerns IEEE 754 special values such as Inf and NaN. As a result, the workaround is a non-binary data format which is less compact.

3.2. Deletion

The regular Python command del can be used on any PyDSTool object in order to delete it from memory. The whole session can be cleared using the restart command (see below, under Memory Management).

3.3. Sessions

The current PyDSTool session can be saved and reloaded using the commands saveSession and loadSession. By default, saving the session will only save objects that belong to PyDSTool classes. Setting the argument deepSearch=True in a call to saveSession will cause the system to search all top-level lists, dictionaries and tuples for PyDSTool objects, and save those top-level lists, etc. if there is a match. The list of classes searched for is given by the global list _pyDSToolTypes.

3.4. Memory management

PyDSTool objects presently resident in memory can be identified using the who command. who can take an optional argument, either an individual type name or a list of type names, that filter the output to only include PyDSTool objects of those types.

A more specialized option is to add the returnlevel=N option, where N > 0. In the argument's absence, N defaults to 0. When N is 1, the call to who does not print anything to the screen. Instead, it returns a list of the objects found. This can be useful when you want to pass to a function all objects of a certain type that have been defined in the default namespace. N = 2 causes who to return a dictionary of object name keys mapping to the objects.

The default namespace for the search is the globals() dictionary of the calling scope. To specify an alternative namespace, add the option objdict=<scope_name_dictionary> to the call.

The optional argument deepSearch=True will search for PyDSTool objects contained up to one-level deep in lists, tuples and dictionaries defined in the supplied namespace objdict (defaults to the calling namespace's globals dictionary).

The current session can be restarted using the restart command. By default this merely clears the global registries of declared symbolic and ModelSpec names, but the additional argument delall=X where X=1 or 2 will delete all PyDSTool objects (X=2 causes a "deep search" to find them contained in lists, tuples, and dictionaries).

Important: At this time, restart cannot clear from memory any dynamically loaded C-based ODE integrators such as Dopri and Radau. This is a problem with the underlying behaviour of Python itself, and we hope to fix this in the future.

3.5. Copying of PyDSTool data structures

The larger data structures in PyDSTool generally contain several levels of objects, which themselves include arrays, IEEE754 Floating Point special values, and sometimes dynamically created method functions, etc. This includes classes such as Model, Generator, Trajectory, Variable, Pointset, and the symbolic and model specification classes QuantSpec, Quantity, ModelSpec, and so on.

The standard Python copy and deepcopy functions will both behave identically for all these major PyDSTool classes, and will always create full copies without references. This has been implemented for the sake of safety, as shallow copy-by-reference is rarely a desirable outcome for these large data structures.

Copying may however be a little slow for very large data structures, as the only typesafe way to deep copy complex classes is through a tweaked version of the standard Python "pickler". A web search will show that there are problems with using deepcopy on complex data types, and even the C pickler cannot be relied upon to deal with IEEE754 special values properly (at least not on Windows platforms). Hence, we use a patched version of the standard pickler, which on Windows platforms uses a non-binary data format and is therefore less efficient. This issue is discussed further, in relation to handling dynamically-created functions, on the TechDocumentation page.

4. Visualization

Matplotlib is the graphics library currently recommended the most for 2D graphics, although no core PyDSTool functionality relies on any particular graphics library. The command interface of Matplotlib is intentionally similar to that of Matlab. For 3D plots, you are free to choose your own as there is no obvious standard yet, although MayaVi is a leading competitor. A 3D toolkit emerged for Matplotlib called mplot3D. See the Matplotlib web site for documentation and tutorials on plotting.

The most important thing to remember when plotting trajectories is that a sample of the trajectory must be extracted from the trajectory object. This is partly because trajectory objects hide their underlying time mesh, but also because the plotted mesh resolution often has to be chosen differently to the time mesh of the original data source anyway.

Matplotlib's pyplot plotting namespace is automatically imported when PyDSTool is imported (or ignored if it is not present) as plt. See the Tutorials for examples.

5. System specification

5.1. Two routes to specification

There are two routes to the specification of a dynamical system.

In addition, you can import a vector field definition from VFGEN using an XML format, or from SloppyCell using an included conversion tool (demonstrated in this example script).

6. Solving for trajectories

The Generator classes represent the basic simulation objects of PyDSTool, implementing ODE/DAE integration, and the computation of discrete maps. More generally, they are also sources of curves, which may or may not be interpreted as trajectories. For instance, explicit or implicit functions (including those that are parameterized) can be used to specify Generators.

In programming terms, Generators are class instances that produce Trajectory objects (also viewed as curves, especially if they are not parameterized) on demand (see description of Trajectory class below). They take many forms, and may or may not use user-specified parameters and initial condition specifications in order to determine the exact Trajectory object that they produce.

6.1. Generators

The abstract and target-language independent specification of dynamical systems described in Section 5 is converted into target simulation objects that perform trajectory computations on demand. The target class is Generator, and has many sub-types corresponding to the different types of dynamical system supported.

6.2. Trajectories

The trajectory class can represent continuous curves or discrete sets of ordered points. In the former case, it provides the illusion of dense output for trajectories that are defined only by an underlying discrete mesh. This is usually done by linear interpolation between mesh points. Trajectories defined by explicit functions (including Taylor series, which will be implemented at a later date), are intrinsically dense.

The Generator and Trajectory classes are discussed in detail on the page Generators. The implementation of Trajectory objects is described on the page TechDocumentation.

6.3. "Models" and hybrid dynamical systems

The PyDSTool Model class builds upon Generators and serves two purposes. The first is to generalize the forms of dynamical system that can be simulated in PyDSTool, by supporting hybrid dynamical systems (see the page HybridSystems). The second is to provide support for a "hierarchical naming" scheme used by ModelSpec, useful for building complex structured models. See the Models page for details.

7. Bounds and constraints

PyDSTool supports the optional specification of bounds on variables and parameters. This is most useful when performing parameter and model estimation, but also provides a means to check the consistency of iterative processes as they run. Variable domains may be intervals or singleton values, but parameter domains must be an interval. At initialization or using the 'set' method, such bounds on variables are specified to a generator using the xdomain key, while those on parameters use the pdomain key. An example of using these bounds in hybrid models is the Single-leg Inverted Pendulum (SLIP) model in the /tests/ directory.

These issues are described further on the BoundsSafety page.

8. Continuation and bifurcation analysis

PyDSTool incorporates the sub-package PyCont, written by Drew Lamar as part of the PyDSTool group. PyCont provides a suite of continuation and bifurcation tools that can be applied to existing PyDSTool Model objects. Further information about the package can be found in the link above.

9. Toolboxes for special tasks

Various toolboxes are available for parameter estimation, phase plane analysis, model reduction, mechanical modeling, data analysis, and neural modeling. Details are given on the page ToolboxDocumentation.

10. Porting models between PyDSTool and other packages

Access to automatic differentiation via the older ODETools Matlab package is provided by creating a model as an instance of the ADMC_ODEsystem class of Generators.

PyDSTool provides access to a large subset of the Systems Biology Markup Language (SBML) through third-party packages (see this tutorial page), and to the NineML language's abstraction layer (see this tutorial page). Exporting functionality is in development.

Other helpful tools to translate between dynamical systems model descriptions are already provided by VFGEN.

PyDSTool source code is hosted by:

Get PyDSTool at Fast, secure and Free Open Source software downloads