Lotka-Voltera Two Ways

We demonstrate an integration of AlgebraicDynamics.jl.

The tutorial is based on AlgebraicDynamics.jl: Lotka-Volterra Three Ways.

Undirected Composition

using AlgebraicDynamics
using AlgebraicDynamics.UWDDynam
using Catlab.WiringDiagrams, Catlab.Programs
using LabelledArrays
using Plots

const UWD = UndirectedWiringDiagram
Catlab.WiringDiagrams.UndirectedWiringDiagrams.AbstractUWD
using AlgebraicAgents

Define the primitive systems

dotr(u,p,t) = p.α*u
dotrf(u,p,t) = [-p.β*u[1]*u[2], p.γ*u[1]*u[2]]
dotf(u,p,t) = -p.δ*u

rabbit_growth = wrap_system("rabbit_growth", ContinuousResourceSharer{Float64}(1, dotr))
rabbitfox_predation = wrap_system("rabbitfox_predation", ContinuousResourceSharer{Float64}(2, dotrf))
fox_decline = wrap_system("fox_decline", ContinuousResourceSharer{Float64}(1, dotf))
agent fox_decline with uuid 33083d47 of type GraphicalAgent 
   custom properties:
   model: 
   ports: ["1"]

Define the composition pattern

rf = @relation (rabbits,foxes) begin
    growth(rabbits)
    predation(rabbits,foxes)
    decline(foxes)
end
Catlab.Programs.RelationalPrograms.UntypedUnnamedRelationDiagram{Symbol, Symbol} {Box:3, Port:4, OuterPort:2, Junction:2, Name:0, VarName:0}
Box name
1 growth
2 predation
3 decline
Port box junction
1 1 1
2 2 1
3 2 2
4 3 2
OuterPort outer_junction
1 1
2 2
Junction variable
1 rabbits
2 foxes

Compose

rabbitfox_system = ⊕(rabbit_growth, rabbitfox_predation, fox_decline, diagram=rf, name="rabbitfox_system")
agent rabbitfox_system with uuid c220b6c7 of type GraphicalAgent 
   custom properties:
   model: 
   ports: ["rabbits", "foxes"]
   inner agents: 
    agent fox_decline with uuid 33083d47 of type GraphicalAgent 
       custom properties:
       model: 
       ports: ["1"]
    agent rabbitfox_predation with uuid 2103ddc4 of type GraphicalAgent 
       custom properties:
       model: 
       ports: ["1", "2"]
    agent rabbit_growth with uuid 6d744754 of type GraphicalAgent 
       custom properties:
       model: 
       ports: ["1"]

Solve and plot

u0 = [10.0, 100.0]
params = LVector(α=.3, β=0.015, γ=0.015, δ=0.7)
tspan = (0.0, 100.0)
(0.0, 100.0)
import DifferentialEquations
prob = DiffEqAgent(rabbitfox_system, u0, tspan, params)
agent rabbitfox_system with uuid d80247f3 of type DiffEqAgent 
   custom properties:
   integrator: 
t: 0.0
u: 2-element Vector{Float64}:
  10.0
 100.0
   inner agents: 
    agent fox_decline with uuid 33083d47 of type GraphicalAgent 
       custom properties:
       model: 
       ports: ["1"]
    agent rabbitfox_predation with uuid 2103ddc4 of type GraphicalAgent 
       custom properties:
       model: 
       ports: ["1", "2"]
    agent rabbit_growth with uuid 6d744754 of type GraphicalAgent 
       custom properties:
       model: 
       ports: ["1"]
sol = simulate(prob)
agent rabbitfox_system with uuid d80247f3 of type DiffEqAgent 
   custom properties:
   integrator: 
t: 100.0
u: 2-element Vector{Float64}:
 119.83184713731032
   0.5146458055479697
   inner agents: 
    agent fox_decline with uuid 33083d47 of type GraphicalAgent 
       custom properties:
       model: 
       ports: ["1"]
    agent rabbitfox_predation with uuid 2103ddc4 of type GraphicalAgent 
       custom properties:
       model: 
       ports: ["1", "2"]
    agent rabbit_growth with uuid 6d744754 of type GraphicalAgent 
       custom properties:
       model: 
       ports: ["1"]
draw(sol; label=["rabbits" "foxes"])

Directed Composition

using AlgebraicDynamics, AlgebraicDynamics.DWDDynam
using Catlab.WiringDiagrams, Catlab.Programs
using LabelledArrays
using Plots
using AlgebraicAgents, DifferentialEquations

Define the primitive systems

dotr(u, x, p, t) = [p.α*u[1] - p.β*u[1]*x[1]]
dotf(u, x, p, t) = [p.γ*u[1]*x[1] - p.δ*u[1]]

rabbit = wrap_system("rabbit", ContinuousMachine{Float64}(1,1,1, dotr, (u, p, t) -> u))
fox    = wrap_system("fox", ContinuousMachine{Float64}(1,1,1, dotf, (u, p, t) -> u))
agent fox with uuid 97712690 of type GraphicalAgent 
   custom properties:
   model: 
   ports: ["1"]

Define the composition pattern

rabbitfox_pattern = WiringDiagram([], [:rabbits, :foxes])
rabbit_box = add_box!(rabbitfox_pattern, Box(:rabbit, [:pop], [:pop]))
fox_box = add_box!(rabbitfox_pattern, Box(:fox, [:pop], [:pop]))

add_wires!(rabbitfox_pattern, Pair[
    (rabbit_box, 1) => (fox_box, 1),
    (fox_box, 1)    => (rabbit_box, 1),
    (rabbit_box, 1) => (output_id(rabbitfox_pattern), 1),
    (fox_box, 1)    => (output_id(rabbitfox_pattern), 2)
])

Compose

rabbitfox_system = ⊕(rabbit, fox; diagram=rabbitfox_pattern, name="rabbitfox_system")
agent rabbitfox_system with uuid 58711456 of type GraphicalAgent 
   custom properties:
   model: 
   ports: ["rabbits", "foxes"]
   inner agents: 
    agent rabbit with uuid 57c8365d of type GraphicalAgent 
       custom properties:
       model: 
       ports: ["1"]
    agent fox with uuid 97712690 of type GraphicalAgent 
       custom properties:
       model: 
       ports: ["1"]

Solve and plot

u0 = [10.0, 100.0]
params = LVector(α=.3, β=0.015, γ=0.015, δ=0.7)
tspan = (0.0, 100.0)
(0.0, 100.0)
# convert the system to a problem
prob = DiffEqAgent(rabbitfox_system, u0, tspan, params)
agent rabbitfox_system with uuid 3394ffda of type DiffEqAgent 
   custom properties:
   integrator: 
t: 0.0
u: 2-element Vector{Float64}:
  10.0
 100.0
   inner agents: 
    agent rabbit with uuid 57c8365d of type GraphicalAgent 
       custom properties:
       model: 
       ports: ["1"]
    agent fox with uuid 97712690 of type GraphicalAgent 
       custom properties:
       model: 
       ports: ["1"]
# solve the problem
simulate(prob)
agent rabbitfox_system with uuid 3394ffda of type DiffEqAgent 
   custom properties:
   integrator: 
t: 100.0
u: 2-element Vector{Float64}:
 119.83184713730492
   0.5146458055478338
   inner agents: 
    agent rabbit with uuid 57c8365d of type GraphicalAgent 
       custom properties:
       model: 
       ports: ["1"]
    agent fox with uuid 97712690 of type GraphicalAgent 
       custom properties:
       model: 
       ports: ["1"]
# plot
draw(prob; label=["rabbits" "foxes"])

Open CPG

using AlgebraicDynamics.CPortGraphDynam
using AlgebraicDynamics.CPortGraphDynam: barbell

Define the composition pattern

rabbitfox_pattern = barbell(1)

rabbitfox_system = ⊕(rabbit, fox; diagram=rabbitfox_pattern, name="rabbitfox_system")
agent rabbitfox_system with uuid 1e39893c of type GraphicalAgent 
   custom properties:
   model: 
   ports: String[]
   inner agents: 
    agent rabbit with uuid 57c8365d of type GraphicalAgent 
       custom properties:
       model: 
       ports: ["1"]
    agent fox with uuid 97712690 of type GraphicalAgent 
       custom properties:
       model: 
       ports: ["1"]

Solve and plot

u0 = [10.0, 100.0]
params = LVector(α=.3, β=0.015, γ=0.015, δ=0.7)
tspan = (0.0, 100.0)
(0.0, 100.0)
# convert the system to a problem
prob = DiffEqAgent(rabbitfox_system, u0, tspan, params)
agent rabbitfox_system with uuid 52f5f50d of type DiffEqAgent 
   custom properties:
   integrator: 
t: 0.0
u: 2-element Vector{Float64}:
  10.0
 100.0
   inner agents: 
    agent rabbit with uuid 57c8365d of type GraphicalAgent 
       custom properties:
       model: 
       ports: ["1"]
    agent fox with uuid 97712690 of type GraphicalAgent 
       custom properties:
       model: 
       ports: ["1"]
# solve the problem
simulate(prob)
agent rabbitfox_system with uuid 52f5f50d of type DiffEqAgent 
   custom properties:
   integrator: 
t: 100.0
u: 2-element Vector{Float64}:
 119.83184713730492
   0.5146458055478338
   inner agents: 
    agent rabbit with uuid 57c8365d of type GraphicalAgent 
       custom properties:
       model: 
       ports: ["1"]
    agent fox with uuid 97712690 of type GraphicalAgent 
       custom properties:
       model: 
       ports: ["1"]
# plot
draw(prob; label=["rabbits" "foxes"])