# Guide

The algorithms in this package take as **input** a system of ODEs with polynomial right-hand side and **return** the new variable expressions and the corresponding system(s).

### Creating an ODE and finding reductions

As an example, consider the folliwing system of differential equations

\[\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}\]

To create a system as above in `ExactODEReduction.jl`

, use the `ODEsystem`

macro. This is the easiest way to do so.

```
using ExactODEReduction
odes = @ODEsystem(
x1'(t) = x1^2 + 2x1*x2,
x2'(t) = x2^2 + x3 + x4,
x3'(t) = x2 + x4,
x4'(t) = x1 + x3
)
```

```
x1'(t) = x1(t)^2 + 2*x1(t)*x2(t)
x2'(t) = x2(t)^2 + x3(t) + x4(t)
x3'(t) = x2(t) + x4(t)
x4'(t) = x1(t) + x3(t)
```

After using the macro, we can call `find_reductions`

function. This function accepts the ODE model and outputs possible linear reductions.

`reductions = find_reductions(odes)`

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

Note that because of the randomization the result may be different between several runs. If you need to fix the result, use the `seed`

keyword argument (see Finding reductions).

The `reductions`

object can be treated as an array of reductions. For example, to access the second reduction from the list, type

`reduction2 = reductions[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
```

Further, we can use `new_system`

and `new_vars`

functions to explore this reduction.

`new_ode = new_system(reduction2)`

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

Note that `new_ode`

from above is again an `ODE`

object. In particular, this means that all functions from (Section Functions for manipulating ODEs) will also work for it.

`new_var = new_vars(reduction2)`

```
Dict{Nemo.fmpq_mpoly, Nemo.fmpq_mpoly} with 3 entries:
y2 => x2
y1 => x1
y3 => x3 + x4
```

The function `find_reductions`

additionaly provides several useful keyword arguments, which are described in Finding reductions.