# AlgebraicDynamics.jl

AlgebraicDynamics.jl is a library for compositional dynamical systems. We build on Catlab.jl to provide a software interface for specifying and solving dynamical systems with compositional and hierarchical structure. The implementation of the composition of dynamical systems follows the mathematics of operads and operad algebras.

## Composing Dynamical Systems

The general process for composing dynamical systems is as follows:

**Pick a composition syntax.**A composition syntax may be either undirected or directed. In this library, composition is implemented for the following syntaxes:- undirected wiring diagrams (an undirected composition syntax)
- wiring diagrams (a directed composition syntax)
- open circular port graphs, also called open CPGs (a directed composition syntax)

**Define a composition pattern.**Implement a specific undirected wiring diagram, wiring diagram, or open CPG that defines how the primitive systems will be composed. The number of boxes in the composition pattern is the number of primitive systems that will be composed.**Define the primitive systems to compose.**For an undirected composition pattern, the primitive systems are implemented by resource sharers. A resource sharer has four components:

- ports
- states
- a dynamics function, $f$
- a port map, $m$

The dynamics function can be either continuous time $\dot u(t) = f(u(t), p, t)$ or discrete time $u_{n +1} = f(u_n, p, t)$. In both cases, $u$ contains the state and $p$ contains the parameters. Also in both cases, the port map assigns a state to each port. We say the port exposes the state it is assigned. For continuous time use

`ContinuousResourceSharer{T}`

and for discrete time use`DiscreteResourceSharer{T}`

. The type`T`

represents the values that the states can take on.For a directed composition pattern, the primitive systems are implemented by machines. A machine has five components:

- inputs (also called exogenous variables)
- states
- outputs
- a dynamics function, $f$
- a readout function, $r$

The dynamics function can be either continuous time $\dot u(t) = f(u(t), x(t), p, t)$ or discrete time $u_{n+1} = f(u_n, x_n, p, t)$. In both cases, $u$ contains the state, $x$ contains the exogenous variables, and $p$ contains the parameters. Also in both cases, the readout function $r(u(t))$ is a function of the state. For continuous time use

`ContinuousMachine{T}`

and for discrete time use`DiscreteMachine{T}`

. The type`T`

represents the values that the inputs, states, and outputs can take on.

**Compose.**The`oapply`

method takes a composition pattern and primitive systems, and it returns the composite system. Each`oapply`

method implements an operad algebra which specifies a regime for composing dynamical systems. See [Schultz et al. 2019] and [Vagner et al. 2015] for definitions of the operad algebras $\mathsf{CDS}$ and $\mathsf{DDS}$ for directed composition. See [Baez and Pollard 2017] for definitions of the operad algebra $\mathsf{Dynam}$ for undirected composition. See [Libkind 2020] for a general overview of these operad algebras.

## Solving Dynamical Systems

Once you have built the composite system, you can solve it and plot the solution.

- For continuous machines and resource sharers, you can construct an
`ODEProblem`

or a`DDEProblem`

. When the composition pattern is a wiring diagram, we recommend solvers`Tsit5()`

with`dtmax`

specified and`FRK65(w=0)`

. - For discrete machines and resource sharers, you can construct a
`DiscreteProblem`

or explicitly compute a`trajectory`

.

In either case, be sure to import OrdinaryDiffEq.jl.

## Future Work

- Add more integrators beyond the simple Euler's method
- Include higher order polynomial methods and symplectic and implicit methods for physical problems
- Integrate with AlgebraicPetri.jl