Mathematical Framework and Syntax

Here, we document the mathematical framework PyRates was built upon and the syntax that should be used to implement dynamical systems models in PyRates.

Mathematical Framework

Dynamical systems (DS) define how a system evolves over time in state space, where time can be either discrete or continuous. Continuous time DS are typically defined as sets of differential equations (DEs) and it is this family of mathematical models that PyRates supports. Specifically, PyRates allows the implementation of any DS that can be cast either as a system of ordinary DEs

\[\frac{d y}{d t} = \dot y = f(y, \theta, t),\]

or as a system of delayed DEs with constant delays:

\[\dot y = f(y(t), \theta, t, y(t-\tau_1), ..., y(t-\tau_n)).\]

In those equations, \(y(t)\) represents the state-vector of the DS at time \(t\), \(\theta\) is a vector of parameters that control the system behavior, and \(\tau_i\) represents one of the \(n\) constant delays that may be used to define delayed DEs. The right-hand side of these equations define a vector-field over the \(N\)-dimensional state-space of the system, where \(N\) is the dimensionality of \(y\). It is this vector-field that must be evaluated for the vast majority of the existing numerical DS analysis methods. PyRates provides an intuitive, light-weight interface to implement this vector-field and translates it into various backends.

Mathematical Syntax

Any DS implemented in PyRates requires the definition of a set of DEs, which can be complemented by algebraic equations of the form \(a = g(y, \theta, t)\) to compute temporary variables to be used within the DE system. The mathematical syntax used for any model definition is described in detail in [1]. In short, it follows the Python syntax for the definition of most mathematical operations, while adding a PyRates-specific syntax for the definition of DEs. Any equation is defined as a string, no matter whether you are using the YAML or Python interface. A typical differential equation would look as follows:

"d/dt * u = u**2 - a"

Alternatively, DEs can be defined via the dot formalism:

"u' = u**2 - a"

where u' is the Python version of \(\dot u\). Non-differential equations can also be added, and follow standard Python conventions:

"a = sin(u*t*2*pi)"

In this example, you can see that PyRates allows for the usage of function calls and well-known constants in its equations. Below, you will find a list of all the function calls and constants that are currently supported by PyRates. In addition, you will find a list of variable names that are prohibited from usage, since they are blocked for PyRates-internal variable definitions. Finally, note that any higher-order DE has to be translated into a set of coupled first-order DEs, prior to implementation in PyRates. For example, it is NOT allowed to implement

\[\frac{d^2 x}{dt^2} = -x - \frac{d x}{d t} + c\]

directly. Instead, one would have to transform this second-order DE into a set of two coupled first-order DEs

\[\begin{split}\frac{d x}{d t} &= z,\\ \frac{d z}{d t} &= b - x - z.\end{split}\]

These can then be implemented in PyRates:

eqs= ["x' = z",
      "z' = b - x - z"]

Supported Functions

The following function calls can be used for model definitions in PyRates:

  • sin: implements the sine function.

  • cos: implements the cosine function

  • tan: implements the tangent function

  • sinh: implements the hyperbolic sine function.

  • cosh: implements the hyperbolic cosine function.

  • tanh: implements the hyperbolic tangent function.

  • arcsin: implements the inverse sine function.

  • arccos: implements the inverse cosine function.

  • arctan: implements the inverse tangent function.

  • exp: implements the exponential function, i.e. \(exp(x) = e^x\)

  • absv: returns the absolute value of its argument, i.e. \(absv(x) = |x|\)

  • sigmoid: implements the logistic function, i.e. \(sigmoid(x) = \frac{1}{1 + e^x}\)

  • imag: returns the imaginary part of its argument, e.g. imag(1.0+3.0j) = 3.0

  • real: returns the real part of its argument, e.g. real(1.0+3.0j) = 1.0

  • conj: returns the complex conjugate of its argument, e.g. conj(1.0+3.0j) = 1.0-3.0j

  • log: implements the natural logarithm, i.e. \(log(e^x) = x\)

  • sum: implements the sum operator, e.g. sum([1, 2, 3]) = 6

  • mean: calculates the unweighted average of a vector, e.g. mean([1, 2, 3]) = 2

  • max: returns the maximum value of a vector, e.g. max([1, 2, 3]) = 3

  • min: returns the minimum value of a vector, e.g. min([1, 2, 3]) = 1

  • past: function call that should be used to implement delayed DEs. The function past takes two arguments - the first one is the state variable and the second one is the constant delay. As an example, past(x, tau) implements \(x(t-\tau)\).

  • randn: function that generates a random number, generated by randomly drawing a sample from a standard Gaussian distribution. No arguments are required.

  • round: Rounds a real number to the closest natural number.

  • matmul: Implements a multiplication of two matrices (matching inner dimensions required).

  • matvec: Implements a multiplication of a matrix with a vector, i.e. y = matvec(A, x) implements \(y = A x\).

  • index: Indexes into the first dimension of a variable, i.e. index(x, 1) corresponds to x[1].

  • index_range: Slices into the first dimension of a variable, i.e. index_range(x, 1, 5) corresponds to x[1:5].

  • index_axis: Indexes into a given dimension of a variable, i.e. index_axis(x, 1, 1) corresponds to x[:, 1], where the third argument to index_axis indicates the dimension where the index (second argument) should be applied.

Supported Constants

The following constants can be used within PyRates equations:

  • pi: Will be recognized as \(\pi\)

  • E: Will be recognized as Euler’s number \(e\)

  • I: Will be recognized as the imaginary unit \(\sqrt{-1}\).

These conventions follow the conventions of sympy (and will also change with them). Note that a different convention for complex values is used for the definition of a complex numeric value of a variable or constant that is part of an equation. In this case, follow standard Python syntax, where j will be recognized as the imaginary unit \(\sqrt{-1}\), i.e. 1+2j defines the imaginary value \(1+2i = 1+2\sqrt{-1}\).

Prohibited Variable Names

The following variable names cannot be used in PyRates equations, since they are blocked for internal variables:

  • y: Used as the name of the combined state-vector of the system

  • dy: Used as the name of the combined vector-field of the system

  • source_idx: Used for automatically generated index variables.

  • target_idx: Used for automatically generated index variables.

Also, the names of the above listed constants (pi, E, I) cannot be used as variable names. Finally, the following strings are not allowed as part of variable names:

  • _buffer: Used to implement buffer variables for delayed DE systems.

  • _delays: Used to implement delayed DE systems.

  • maxdelay: Used to implement buffer variables for delayed DE systems.

  • _idx: Used for automatically generated index variables.

  • _hist: Used to implement delayed DE systems.