# ExactODEReduction

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.

## Installation

To install `ExactODEReduction.jl`

, run the following in Julia:

```
import Pkg
Pkg.add(url="https://github.com/x3042/ExactODEReduction.jl")
```

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

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

The important feature of variables

and

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

## 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.

- Import the package

`using ExactODEReduction`

- 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
)
```

- 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]`

```
new_system(red1)
## Prints:
y1'(t) = y1(t)^2 + y2(t)
y2'(t) = y1(t) + y2(t)
```

```
new_vars(system)
## 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.