Exact reduction of ODE models via linear transformations
Author x3042
9 Stars
Updated Last
5 Months Ago
Started In
October 2020


Runtests Dev

This repository contains a Julia implementation of algorithms for finding exact reductions of ODE systems via a linear change of variables.

Online documentation could be found at https://x3042.github.io/ExactODEReduction.jl.


To install ExactODEReduction.jl, run the following in Julia:

import Pkg

For the usage examples, please see examples below in this file, or in the examples directory.

What is exact reduction?

Exact reduction of the system of differential equations is an exact variable substitution which preserves the invariants of the system. In this project we consider reductions obtained with linear transformations. We will explain it using a toy example. Consider the system

$$\begin{cases} \dot{x}_1 = x_1^2 + 2x_1x_2,\\ \dot{x}_2 = x_2^2 + x_3 + x_4,\\ \dot{x}_3 = x_2 + x_4, \\ \dot{x}_4 = x_1 + x_3 \end{cases}$$

An example of an exact reduction in this case would be the following set of new variables

$$y_1 = x_1 + x_2 \quad \text{ and } \quad y_2 = x_3 + x_4$$

The important feature of variables $y_1, y_2$ is that their derivatives can be written in terms of $y_1$ and $y_2$ only:

$$\dot{y}_1 = \dot{x}_1 + \dot{x}_2 = y_1^2 + y_2$$


$$\dot{y}_2 = \dot{x}_3 + \dot{x}_4 = y_1 + y_2$$

Therefore, the original system can be reduced exactly to the following system:

$$\begin{cases} \dot{y}_1 = y_1^2 + y_2,\\ \dot{y}_2 = y_1 + y_2 \end{cases}$$

What does this package do and how to use it?

We implement an algorithm that takes as input a system of ODEs with polynomial right-hand side and returns a list of possible linear transformations and corresponding systems.

We will demonstrate the usage on the example above. For more details on the package usage, including reading dynamical systems from *.ode files, please see the documentation.

  1. Import the package
using ExactODEReduction
  1. Construct the system (as in the example above)
odes = @ODEsystem(
  x1'(t) = x1^2 + 2x1*x2,
  x2'(t) = x2^2 + x3 + x4,
  x3'(t) = x2 + x4,
  x4'(t) = x1 + x3
  1. Call find_reductions providing the system
reductions = find_reductions(odes)

which returns the list of possible reductions. You will get the following result printed

A chain of 2 reductions of dimensions 2, 3
1. Reduction of dimension 2.
New system:
y1'(t) = y1(t)^2 + y2(t)
y2'(t) = y1(t) + y2(t)
New variables:
y1 = x1 + x2
y2 = x3 + x4
2. Reduction of dimension 3.
New system:
y1'(t) = y1(t)^2 + 2*y1(t)*y2(t)
y2'(t) = y2(t)^2 + y3(t)
y3'(t) = y1(t) + y2(t) + y3(t)
New variables:
y1 = x1
y2 = x2
y3 = x3 + x4

Notice that the first reduction is the same as we have seen earlier. We can access it through the reductions object

red1 = reductions[1]
## Prints:
y1'(t) = y1(t)^2 + y2(t)
y2'(t) = y1(t) + y2(t)
## Prints:
Dict{Nemo.fmpq_mpoly, Nemo.fmpq_mpoly} with 2 entries:
  y2 => x3 + x4
  y1 => x1 + x2

For more examples we refer to the documentation and the examples directory.