AlgebraicJulia / Structured-Epidemic-Modeling

Results and software for our paper on structured epidemic modeling
BSD 2-Clause "Simplified" License
12 stars 5 forks source link

Problem wiring a simple SEIR model #7

Open sdwfrost opened 1 year ago

sdwfrost commented 1 year ago

For some reason, the following code for an SEIR model wires E to R, rather than I to R. Can anyone spot where I'm going wrong?

using AlgebraicPetri,AlgebraicPetri.TypedPetri
using Catlab, Catlab.CategoricalAlgebra, Catlab.Programs
using Catlab.WiringDiagrams, Catlab.Graphics
using AlgebraicDynamics.UWDDynam

epi_transitions = LabelledPetriNet(
  [:Pop],
  :infection=>((:Pop, :Pop)=>(:Pop, :Pop)),
  :progression=>(:Pop=>:Pop),
  :recovery=>(:Pop=>:Pop)
)

seir_uwd = @relation () where (S::Pop, E::Pop, I::Pop, R::Pop) begin
    infection(S, I, E, I)
    progression(E, I)
    recovery(I, R)
end
seir_acst = oapply_typed(epi_transitions, seir_uwd, [:β, :δ, :γ])
seir_lpn = dom(seir_acst)
Graph(seir_lpn)
jpfairbanks commented 1 year ago

It looks like you specified it right. I'm digging in now.

jpfairbanks commented 1 year ago

I do not know why this fixed it, but this code makes the correct answer.

using AlgebraicPetri,AlgebraicPetri.TypedPetri
using Catlab, Catlab.CategoricalAlgebra, Catlab.Programs
using Catlab.WiringDiagrams, Catlab.Graphics
using AlgebraicDynamics.UWDDynam
using Catlab.Graphics.Graphviz

epi_transitions = LabelledPetriNet(
  [:Pop],
  :infection=>((:Pop, :Pop)=>(:Pop, :Pop)),
  :progression=>(:Pop=>:Pop),
  :recovery=>(:Pop=>:Pop)
)

seir_uwd = @relation () where (S::Pop, I::Pop, E::Pop, R::Pop) begin
    infection(S, I, E, I)
    progression(E, I)
    recovery(I, R)
end
to_graphviz(seir_uwd, box_labels=:name, junction_labels=:variable)
seir_acst = oapply_typed(epi_transitions, seir_uwd, [:β, :δ, :γ])
seir_lpn = dom(seir_acst)
Graph(seir_lpn)

The change was to reorder the arguments in the UWD.

seir_uwd = @relation () where **(S::Pop, I::Pop, E::Pop, R::Pop)** begin
    infection(S, I, E, I)
    progression(E, I)
    recovery(I, R)
end

The fact that this fixed it, makes me suspicious that there is a deeper bug.

sdwfrost commented 1 year ago

Your fix lists the symbols in the order they appear in the rules. This sounds like a bug/undocumented feature!

epatters commented 1 year ago

Yeah, this looks like a bug. It shouldn't matter how you order the outer ports in the UWD.

sdwfrost commented 1 year ago

I was trying to look into this further, but the following code for drawing the UWD doesn't display labels - is this a config thing on my side?

using Catlab, Catlab.CategoricalAlgebra, Catlab.Programs
using Catlab.WiringDiagrams, Catlab.Graphics

seir_uwd = @relation (S, I, E, R)  begin
    infection(S, I, E, I)
    progression(E, I)
    recovery(I, R)
end
to_graphviz(seir_uwd)
epatters commented 1 year ago

You want

to_graphviz(seir_uwd, box_labels=:name)

or

to_graphviz(seir_uwd, box_labels=:name, junction_labels=:variable)

depending on whether you also want junction labels.

sdwfrost commented 1 year ago

Thanks @epatters! The UWD displays correctly (I wired to R), so it's this bit of the code where things get rewired:

seir_acst = oapply_typed(epi_transitions, seir_uwd, [:β, :δ, :γ])
seir_lpn = dom(seir_acst)
Graph(seir_lpn)