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"])