Augmenting Model Workflows

We can apply our model augmentation framework to models that are compositions of component models.

  1. How does the epidemic size depend on the probability of recovering?
  2. $SIR \mid y\approx ax+b$
  3. What if the disease is fatal?
  4. What if the population is Growing?
  5. Is the relationship linear?
In [89]:
samples = 100
nsteps = 25
finalcounts = Any[]
Out[89]:
0-element Array{Any,1}
In [92]:
m
Out[92]:
ExpStateModel(
  states=:([:S, :I, :R]),
  agents=Expr[:(a = sm.agents), :(a = fill(:S, n))],
  transitions=Expr[:(T = Dict(:S => (x...->begin
                      #= none:120 =#
                      if rand(Float64) < stateload(x[1], :I)
                          :I
                      else
                          :S
                      end
                  end), :I => (x...->begin
                      #= none:121 =#
                      if rand(Float64) < ρ
                          :I
                      else
                          :R
                      end
                  end), :R => (x...->begin
                      #= none:122 =#
                      if rand(Float64) < μ
                          :R
                      else
                          :S
                      end
                  end)))]
)
In [93]:
magents = m
println("\nRunning basic model")
AgentModels = eval(m.expr)
for i in 1:samples
    println(("======= . Simulation $i  ========"))
    newsam, counts, params = AgentModels.main(nsteps)
    push!(finalcounts, (model=:basic, counts=counts, params=params))
end
Running basic model
======= . Simulation 1  ========
WARNING: replacing module AgentModels.
newsam.agents = Symbol[:S, :S, :R, :S, :R, :R, :S, :R, :S, :I, :S, :S, :R, :S, :I, :S, :I, :I, :S, :S]
======= . Simulation 2  ========
newsam.agents = Symbol[:I, :I, :S, :I, :S, :R, :I, :R, :I, :R, :R, :S, :I, :I, :I, :R, :S, :I, :I, :R]
======= . Simulation 3  ========
newsam.agents = Symbol[:R, :R, :R, :S, :S, :I, :S, :R, :S, :R, :I, :R, :R, :S, :R, :R, :S, :S, :R, :S]
======= . Simulation 4  ========
newsam.agents = Symbol[:R, :S, :S, :S, :S, :S, :S, :S, :S, :S, :S, :S, :S, :I, :R, :S, :S, :S, :I, :S]
======= . Simulation 5  ========
newsam.agents = Symbol[:I, :I, :S, :I, :I, :I, :R, :I, :I, :S, :I, :I, :S, :R, :I, :I, :R, :S, :I, :I]
======= . Simulation 6  ========
newsam.agents = Symbol[:I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I]
======= . Simulation 7  ========
newsam.agents = Symbol[:S, :S, :S, :I, :S, :R, :S, :S, :S, :S, :S, :S, :S, :S, :I, :S, :R, :S, :S, :R]
======= . Simulation 8  ========
newsam.agents = Symbol[:R, :S, :S, :S, :I, :R, :S, :I, :I, :S, :I, :S, :R, :S, :I, :R, :S, :S, :R, :S]
======= . Simulation 9  ========
newsam.agents = Symbol[:I, :I, :S, :R, :I, :R, :R, :I, :I, :I, :I, :R, :I, :R, :R, :I, :I, :I, :S, :I]
======= . Simulation 10  ========
newsam.agents = Symbol[:I, :R, :S, :S, :S, :S, :S, :S, :R, :S, :S, :S, :S, :S, :S, :S, :I, :I, :S, :S]
======= . Simulation 11  ========
newsam.agents = Symbol[:R, :R, :S, :S, :S, :S, :I, :S, :S, :R, :S, :S, :R, :R, :I, :S, :S, :S, :S, :R]
======= . Simulation 12  ========
newsam.agents = Symbol[:S, :S, :S, :S, :R, :I, :S, :S, :S, :S, :S, :R, :S, :S, :I, :I, :S, :R, :I, :S]
======= . Simulation 13  ========
newsam.agents = Symbol[:S, :S, :S, :S, :S, :I, :S, :S, :R, :R, :S, :R, :R, :R, :S, :S, :R, :S, :S, :R]
======= . Simulation 14  ========
newsam.agents = Symbol[:I, :S, :S, :I, :S, :R, :I, :I, :R, :S, :R, :S, :S, :S, :I, :I, :S, :S, :S, :S]
======= . Simulation 15  ========
newsam.agents = Symbol[:I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I]
======= . Simulation 16  ========
newsam.agents = Symbol[:I, :I, :S, :S, :S, :S, :I, :S, :S, :I, :S, :S, :S, :I, :I, :I, :S, :S, :I, :S]
======= . Simulation 17  ========
newsam.agents = Symbol[:S, :R, :S, :S, :S, :R, :S, :S, :I, :R, :R, :I, :S, :S, :R, :S, :I, :S, :S, :R]
======= . Simulation 18  ========
newsam.agents = Symbol[:S, :S, :S, :S, :S, :S, :S, :S, :S, :S, :S, :S, :R, :R, :S, :R, :R, :S, :I, :S]
======= . Simulation 19  ========
newsam.agents = Symbol[:I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I]
======= . Simulation 20  ========
newsam.agents = Symbol[:I, :S, :S, :S, :S, :I, :S, :I, :S, :I, :S, :S, :R, :R, :S, :R, :S, :I, :S, :S]
======= . Simulation 21  ========
newsam.agents = Symbol[:R, :I, :R, :S, :S, :S, :S, :R, :S, :I, :S, :S, :S, :S, :R, :R, :S, :S, :S, :R]
======= . Simulation 22  ========
newsam.agents = Symbol[:I, :S, :R, :S, :S, :S, :S, :R, :S, :R, :R, :S, :S, :S, :S, :I, :S, :R, :S, :R]
======= . Simulation 23  ========
newsam.agents = Symbol[:R, :S, :S, :R, :S, :S, :R, :S, :I, :R, :S, :S, :S, :S, :S, :R, :R, :S, :S, :S]
======= . Simulation 24  ========
newsam.agents = Symbol[:I, :S, :S, :S, :I, :I, :S, :I, :I, :I, :R, :I, :S, :S, :R, :I, :R, :I, :R, :S]
======= . Simulation 25  ========
newsam.agents = Symbol[:I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I]
======= . Simulation 26  ========
newsam.agents = Symbol[:S, :I, :S, :S, :S, :S, :S, :S, :S, :R, :R, :I, :S, :S, :S, :S, :S, :S, :R, :I]
======= . Simulation 27  ========
newsam.agents = Symbol[:R, :S, :I, :R, :R, :S, :I, :I, :S, :R, :S, :I, :S, :I, :I, :I, :I, :I, :S, :R]
======= . Simulation 28  ========
newsam.agents = Symbol[:S, :I, :S, :R, :R, :S, :I, :S, :R, :I, :S, :I, :S, :R, :R, :S, :S, :R, :R, :I]
======= . Simulation 29  ========
newsam.agents = Symbol[:R, :S, :S, :S, :S, :S, :R, :R, :S, :S, :S, :R, :R, :S, :S, :R, :I, :S, :S, :R]
======= . Simulation 30  ========
newsam.agents = Symbol[:S, :S, :S, :S, :S, :R, :S, :I, :S, :S, :S, :I, :I, :R, :S, :S, :S, :S, :S, :S]
======= . Simulation 31  ========
newsam.agents = Symbol[:R, :S, :S, :S, :I, :R, :S, :S, :S, :S, :I, :I, :S, :S, :R, :R, :S, :S, :S, :S]
======= . Simulation 32  ========
newsam.agents = Symbol[:S, :S, :S, :R, :S, :S, :S, :S, :S, :S, :S, :S, :R, :I, :S, :R, :S, :S, :S, :I]
======= . Simulation 33  ========
newsam.agents = Symbol[:I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I]
======= . Simulation 34  ========
newsam.agents = Symbol[:S, :S, :S, :S, :S, :S, :R, :S, :I, :I, :S, :I, :S, :I, :I, :S, :I, :S, :R, :R]
======= . Simulation 35  ========
newsam.agents = Symbol[:S, :R, :S, :R, :I, :I, :R, :S, :I, :S, :S, :S, :R, :S, :R, :S, :R, :S, :S, :S]
======= . Simulation 36  ========
newsam.agents = Symbol[:R, :R, :S, :S, :S, :S, :S, :R, :R, :R, :S, :R, :S, :S, :S, :S, :S, :I, :R, :S]
======= . Simulation 37  ========
newsam.agents = Symbol[:S, :I, :S, :I, :S, :S, :R, :S, :S, :I, :R, :I, :S, :S, :S, :S, :I, :S, :R, :R]
======= . Simulation 38  ========
newsam.agents = Symbol[:I, :I, :S, :I, :I, :S, :S, :I, :I, :R, :I, :I, :I, :S, :R, :I, :I, :S, :R, :I]
======= . Simulation 39  ========
newsam.agents = Symbol[:S, :S, :S, :S, :S, :S, :S, :S, :R, :S, :S, :S, :S, :S, :S, :S, :S, :S, :S, :S]
======= . Simulation 40  ========
newsam.agents = Symbol[:R, :I, :I, :I, :R, :R, :R, :S, :R, :R, :S, :I, :S, :R, :S, :I, :R, :R, :R, :I]
======= . Simulation 41  ========
newsam.agents = Symbol[:S, :R, :R, :S, :S, :S, :S, :S, :I, :R, :S, :S, :S, :S, :I, :S, :S, :S, :S, :I]
======= . Simulation 42  ========
newsam.agents = Symbol[:I, :S, :I, :I, :I, :I, :S, :S, :I, :I, :S, :I, :I, :I, :I, :R, :I, :I, :S, :I]
======= . Simulation 43  ========
newsam.agents = Symbol[:S, :S, :I, :I, :I, :S, :R, :I, :I, :S, :S, :R, :S, :R, :I, :I, :R, :R, :S, :R]
======= . Simulation 44  ========
newsam.agents = Symbol[:S, :R, :R, :I, :I, :S, :I, :R, :I, :S, :I, :I, :R, :I, :R, :S, :I, :I, :I, :I]
======= . Simulation 45  ========
newsam.agents = Symbol[:R, :S, :S, :S, :S, :S, :S, :S, :R, :S, :S, :S, :I, :S, :S, :S, :R, :I, :S, :S]
======= . Simulation 46  ========
newsam.agents = Symbol[:S, :S, :S, :S, :S, :R, :S, :S, :R, :I, :R, :I, :S, :S, :R, :S, :S, :S, :I, :S]
======= . Simulation 47  ========
newsam.agents = Symbol[:S, :I, :S, :R, :I, :R, :S, :R, :I, :I, :I, :R, :R, :S, :S, :R, :I, :R, :R, :S]
======= . Simulation 48  ========
newsam.agents = Symbol[:I, :S, :R, :I, :S, :S, :I, :R, :I, :I, :I, :I, :R, :S, :I, :S, :I, :S, :I, :S]
======= . Simulation 49  ========
newsam.agents = Symbol[:S, :I, :R, :I, :R, :I, :R, :I, :R, :I, :I, :S, :I, :I, :I, :I, :R, :I, :I, :R]
======= . Simulation 50  ========
newsam.agents = Symbol[:R, :S, :S, :I, :S, :I, :I, :I, :I, :R, :S, :S, :I, :R, :I, :S, :I, :R, :I, :I]
======= . Simulation 51  ========
newsam.agents = Symbol[:S, :S, :I, :S, :S, :I, :S, :I, :S, :S, :R, :S, :I, :I, :R, :I, :S, :I, :S, :I]
======= . Simulation 52  ========
newsam.agents = Symbol[:R, :I, :S, :S, :I, :S, :S, :S, :S, :S, :R, :S, :R, :S, :I, :S, :I, :S, :S, :I]
======= . Simulation 53  ========
newsam.agents = Symbol[:R, :R, :I, :I, :S, :S, :I, :I, :I, :R, :I, :S, :R, :I, :R, :S, :I, :I, :R, :I]
======= . Simulation 54  ========
newsam.agents = Symbol[:S, :S, :S, :S, :S, :S, :S, :R, :S, :R, :S, :R, :S, :S, :S, :S, :S, :I, :S, :R]
======= . Simulation 55  ========
newsam.agents = Symbol[:S, :S, :S, :S, :S, :S, :S, :S, :S, :S, :S, :S, :R, :S, :S, :S, :S, :R, :S, :S]
======= . Simulation 56  ========
newsam.agents = Symbol[:I, :R, :R, :R, :S, :R, :R, :R, :S, :S, :S, :R, :I, :S, :S, :S, :S, :I, :S, :S]
======= . Simulation 57  ========
newsam.agents = Symbol[:I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I]
======= . Simulation 58  ========
newsam.agents = Symbol[:S, :S, :S, :S, :I, :S, :S, :I, :S, :S, :R, :S, :I, :I, :R, :S, :S, :S, :I, :I]
======= . Simulation 59  ========
newsam.agents = Symbol[:I, :S, :R, :S, :I, :S, :S, :R, :R, :R, :S, :S, :S, :S, :S, :S, :S, :S, :R, :S]
======= . Simulation 60  ========
newsam.agents = Symbol[:S, :S, :R, :S, :S, :S, :R, :R, :I, :R, :R, :R, :S, :S, :S, :S, :S, :S, :I, :R]
======= . Simulation 61  ========
newsam.agents = Symbol[:I, :S, :I, :R, :I, :R, :I, :S, :I, :I, :I, :I, :R, :S, :I, :I, :I, :I, :I, :I]
======= . Simulation 62  ========
newsam.agents = Symbol[:I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I]
======= . Simulation 63  ========
newsam.agents = Symbol[:I, :I, :I, :I, :I, :I, :I, :R, :S, :I, :I, :I, :R, :S, :R, :I, :I, :I, :R, :I]
======= . Simulation 64  ========
newsam.agents = Symbol[:S, :S, :I, :R, :R, :S, :I, :S, :S, :R, :R, :R, :I, :S, :I, :I, :R, :S, :R, :R]
======= . Simulation 65  ========
newsam.agents = Symbol[:I, :R, :R, :R, :R, :S, :R, :R, :S, :S, :S, :I, :R, :I, :S, :S, :S, :S, :I, :I]
======= . Simulation 66  ========
newsam.agents = Symbol[:I, :I, :I, :R, :I, :I, :I, :I, :S, :I, :I, :I, :R, :I, :I, :I, :I, :I, :S, :R]
======= . Simulation 67  ========
newsam.agents = Symbol[:S, :S, :S, :S, :S, :R, :S, :S, :R, :S, :S, :S, :R, :S, :S, :R, :S, :R, :S, :R]
======= . Simulation 68  ========
newsam.agents = Symbol[:S, :I, :S, :I, :S, :S, :I, :I, :R, :S, :R, :S, :R, :I, :S, :S, :I, :I, :I, :S]
======= . Simulation 69  ========
newsam.agents = Symbol[:I, :I, :R, :R, :I, :I, :R, :I, :I, :S, :I, :I, :R, :I, :I, :S, :S, :S, :I, :R]
======= . Simulation 70  ========
newsam.agents = Symbol[:R, :I, :S, :R, :R, :I, :R, :I, :R, :S, :S, :S, :S, :I, :S, :I, :R, :S, :I, :I]
======= . Simulation 71  ========
newsam.agents = Symbol[:I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I]
======= . Simulation 72  ========
newsam.agents = Symbol[:S, :I, :S, :R, :R, :S, :S, :R, :S, :R, :S, :I, :S, :R, :S, :R, :S, :R, :S, :S]
======= . Simulation 73  ========
newsam.agents = Symbol[:R, :S, :S, :R, :I, :I, :I, :R, :I, :S, :I, :S, :R, :I, :S, :S, :I, :S, :I, :I]
======= . Simulation 74  ========
newsam.agents = Symbol[:R, :S, :S, :S, :S, :S, :S, :R, :S, :S, :S, :R, :S, :S, :R, :S, :S, :S, :S, :S]
======= . Simulation 75  ========
newsam.agents = Symbol[:I, :I, :I, :S, :I, :I, :I, :I, :R, :S, :I, :R, :I, :I, :I, :I, :I, :R, :S, :R]
======= . Simulation 76  ========
newsam.agents = Symbol[:I, :R, :I, :I, :I, :S, :I, :R, :I, :R, :S, :I, :I, :S, :S, :S, :I, :I, :I, :R]
======= . Simulation 77  ========
newsam.agents = Symbol[:I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I]
======= . Simulation 78  ========
newsam.agents = Symbol[:R, :R, :S, :R, :I, :S, :R, :R, :I, :I, :S, :I, :R, :S, :R, :S, :R, :R, :I, :R]
======= . Simulation 79  ========
newsam.agents = Symbol[:I, :I, :R, :R, :R, :I, :S, :S, :S, :I, :S, :I, :S, :S, :S, :I, :I, :I, :S, :S]
======= . Simulation 80  ========
newsam.agents = Symbol[:I, :R, :S, :I, :S, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I, :I]
======= . Simulation 81  ========
newsam.agents = Symbol[:I, :I, :I, :I, :R, :R, :R, :S, :I, :R, :R, :R, :S, :S, :I, :R, :I, :S, :I, :R]
======= . Simulation 82  ========
newsam.agents = Symbol[:I, :I, :I, :S, :R, :S, :S, :I, :I, :S, :S, :S, :I, :I, :I, :R, :R, :R, :I, :S]
======= . Simulation 83  ========
newsam.agents = Symbol[:S, :S, :S, :R, :S, :S, :I, :S, :R, :S, :S, :R, :S, :S, :S, :S, :S, :S, :R, :S]
======= . Simulation 84  ========
newsam.agents = Symbol[:I, :I, :I, :S, :I, :I, :I, :I, :I, :I, :I, :I, :R, :I, :I, :S, :I, :I, :I, :R]
======= . Simulation 85  ========
newsam.agents = Symbol[:S, :I, :I, :S, :S, :R, :I, :R, :I, :R, :I, :I, :I, :I, :I, :I, :R, :I, :R, :S]
======= . Simulation 86  ========
newsam.agents = Symbol[:S, :S, :S, :S, :S, :I, :S, :I, :R, :R, :R, :S, :S, :S, :S, :S, :R, :S, :S, :S]
======= . Simulation 87  ========
newsam.agents = Symbol[:I, :R, :R, :S, :I, :R, :S, :S, :S, :I, :R, :I, :I, :I, :R, :R, :I, :I, :I, :I]
======= . Simulation 88  ========
newsam.agents = Symbol[:I, :I, :I, :S, :S, :I, :I, :S, :I, :I, :S, :I, :S, :I, :R, :S, :S, :I, :I, :I]
======= . Simulation 89  ========
newsam.agents = Symbol[:I, :I, :I, :R, :S, :R, :I, :I, :R, :R, :I, :I, :I, :I, :I, :R, :S, :S, :R, :R]
======= . Simulation 90  ========
newsam.agents = Symbol[:R, :S, :I, :S, :R, :R, :I, :I, :S, :S, :S, :S, :I, :R, :S, :I, :S, :S, :R, :I]
======= . Simulation 91  ========
newsam.agents = Symbol[:S, :S, :R, :S, :S, :S, :S, :S, :S, :S, :S, :S, :S, :S, :S, :S, :S, :S, :S, :I]
======= . Simulation 92  ========
newsam.agents = Symbol[:S, :S, :S, :S, :S, :I, :S, :S, :S, :S, :S, :S, :S, :S, :S, :S, :S, :I, :S, :S]
======= . Simulation 93  ========
newsam.agents = Symbol[:S, :S, :R, :S, :R, :R, :R, :R, :S, :R, :S, :S, :S, :S, :R, :R, :S, :R, :S, :R]
======= . Simulation 94  ========
newsam.agents = Symbol[:R, :S, :S, :R, :I, :S, :S, :S, :R, :R, :S, :S, :S, :R, :I, :S, :S, :I, :R, :R]
======= . Simulation 95  ========
newsam.agents = Symbol[:S, :I, :R, :S, :I, :S, :R, :S, :R, :S, :S, :R, :S, :S, :S, :I, :R, :S, :R, :I]
======= . Simulation 96  ========
newsam.agents = Symbol[:R, :S, :I, :S, :S, :I, :S, :S, :I, :R, :I, :R, :I, :I, :I, :S, :S, :S, :R, :R]
======= . Simulation 97  ========
newsam.agents = Symbol[:I, :I, :I, :R, :I, :I, :I, :I, :I, :I, :I, :I, :R, :S, :I, :S, :R, :I, :I, :R]
======= . Simulation 98  ========
newsam.agents = Symbol[:R, :R, :S, :S, :I, :S, :R, :R, :I, :R, :S, :R, :I, :S, :I, :R, :I, :R, :I, :R]
======= . Simulation 99  ========
newsam.agents = Symbol[:S, :S, :S, :I, :S, :S, :R, :R, :S, :S, :R, :S, :S, :R, :S, :R, :R, :S, :S, :I]
======= . Simulation 100  ========
newsam.agents = Symbol[:R, :S, :S, :R, :R, :R, :S, :R, :R, :S, :S, :S, :R, :R, :S, :S, :S, :R, :S, :S]
In [97]:
function connector(finalcounts)
    n = length(finalcounts)
    Data = zeros(n,length(finalcounts[1].counts))
    for i in 1:n
        c = finalcounts[i].counts
        Data[i, : ] = map(last, c)
    end
    X = Data[:, 1]
    Y = Data[:, 2]
    return X,Y
end
Out[97]:
connector (generic function with 2 methods)
In [98]:
X,Y = connector(finalcounts)
collect(zip(X,Y))[1:5]
Out[98]:
5-element Array{Tuple{Float64,Float64},1}:
 (11.0, 4.0)
 (4.0, 10.0)
 (8.0, 2.0) 
 (16.0, 2.0)
 (4.0, 13.0)
In [99]:
fit, result = Regression.main(connector(finalcounts)...)
result
Out[99]:
(β = [7.19], r = 58.54391514068734, n = 100)

Model Workflows

  • Pipelines connect models in sequence like a bash script.
  • $input \mid m_1 \mid c_1 \mid m_2 \mid c_2 \mid \dots \mid m_n > output$
In [105]:
m = model(Lsq, deepcopy(expr))
mstats = deepcopy(m)
P = Pipelines.Pipeline(deepcopy.([magents, mstats]),
    [(m, args...) -> begin 
            Random.seed!(42)
            results = Any[]
            Mod = eval(m.expr)
            for i in 1:samples
                r = Base.invokelatest(Mod.main, args...)
                push!(results, (model=:basic, counts=r[2], params=r[3]))
                #push!(results, r)
            end
            return [results]
                end,
        (m, results...) -> begin
            data = connector(results...)
            Mod = eval(m.expr)
            Base.invokelatest(Mod.main, data...) end
        ],
        Any[(10)]
        )
Out[105]:
Main.Pipelines.Pipeline(AbstractModel[ExpStateModel(
  states=:([:S, :I, :R]),
  agents=Expr[:(a = sm.agents), :(a = fill(:S, n))],
  transitions=Expr[:(T = Dict(:S => (x...->begin
                      #= none:120 =#
                      if rand(Float64) < stateload(x[1], :I)
                          :I
                      else
                          :S
                      end
                  end), :I => (x...->begin
                      #= none:121 =#
                      if rand(Float64) < ρ
                          :I
                      else
                          :R
                      end
                  end), :R => (x...->begin
                      #= none:122 =#
                      if rand(Float64) < μ
                          :R
                      else
                          :S
                      end
                  end)))]
), Lsq(
  f=:f,
  coefficient=:β,
  p₀=:a₀
)], Function[##63#65(), ##64#66()], Any[10])
In [107]:
#Pipelines.run!(P)
r =  P.results[end][end]
Out[107]:
(β = [6.56], r = 54.851071092550235, n = 100)

Transforming the Pipeline

  • Define $\times$ so that $T_1\times T_2$ acts on a pipeline by creating $P(T_1(m_1),T_2(m_2), c_1,c_2)$.

  • The following diagram commutes

    A diagram showing how pipelining commutes with tranforming models

Adding the Dead State

We are going to add an additional state to the model to represent the infectious disease fatalities. The user must specify what that concept means in terms of the name for the new state and the behavior of that state. D is a terminal state for a finite automata.

Some utilities for manipulating functions at a higher level than expressions.

Population Growth

Another change we can make to our model is the introduction of population growth. Our model for population is that on each timestep, one new suceptible person will be added to the list of agents. We use the tick! function as an anchor point for this transformation.

Model Augmentation yields polynomial regression

Given transformations

  1. f(x) -> xf(x)
  2. f(x) -> f(x) + beta

we are able to generate all possible polynomial regression using composition of these transformations.

In [114]:
# Let's build an instance of the model object from the code snippet expr
m = model(Lsq, deepcopy(expr))
mstats = deepcopy(m)
@show m
poly(m)
m = Lsq(
  f=:f,
  coefficient=:β,
  p₀=:a₀
)
Out[114]:
:((.+)(β[1] .* x .^ 0))

Generating the Transformation Monoid

  1. $T_x,T_1$ are generators for our monoid of transformations $T = \langle T_x, T_1 \rangle$.
  2. $T_x$ multiplies by $x$
  3. $T_1$ adds a constant to our polynomial
  4. Any polynomial can be generated by these two operations cf. Horner's rule.
In [115]:
Tₓ = Pow(1)
T₁ = AddConst();

m′ = deepcopy(m)
Tₓ(m′)
T₁(m′)
@show poly(m)
Regression = eval(m′.expr)

@show poly(m′)
fit′, result′ = Regression.main(connector(finalcounts)...)
result′
poly(m) = :((.+)(β[1] .* x .^ 0))
poly(m′) = :(β[1] .* x .^ 1 .+ β[2] .* x .^ 0)
WARNING: replacing module Regression.
Out[115]:
(β = [-1.03625, 16.0396], r = 25.696754245956956, n = 100)
In [116]:
for i in 1:10
    Tₓ(m′)
#    Tₓ(m′)
    T₁(m′)
end

@show poly(m)
Regression = eval(m′.expr)

@show poly(m′)
fit′, result′ = Regression.main(connector(finalcounts)...)
result′
poly(m) = :((.+)(β[1] .* x .^ 0))
poly(m′) = :(.+(β[1] .* x .^ 11, β[2] .* x .^ 10, β[3] .* x .^ 9, β[4] .* x .^ 8, β[5] .* x .^ 7, β[6] .* x .^ 6, β[7] .* x .^ 5, β[8] .* x .^ 4, β[9] .* x .^ 3, β[10] .* x .^ 2, β[11] .* x .^ 1, β[12] .* x .^ 0))
WARNING: replacing module Regression.
Out[116]:
(β = [-9.47833e-9, 1.02527e-6, -4.83734e-5, 0.0013056, -0.0222097, 0.247207, -1.80843, 8.49992, -24.3001, 38.0006, -27.3597, 19.9997], r = 18.873040849080034, n = 100)
In [119]:
println("\nInitial Pipeline")
println("----------------")
P.steps[1].states, poly(P.steps[2])
Initial Pipeline
----------------
Out[119]:
(:([:S, :I, :R]), :((.+)(β[1] .* x .^ 0)))
In [120]:
println("\n\nApplying the first pair of transformations")
println(     "------------------------------------------")
(addstate! × one(Pow))(P)

Applying the first pair of transformations
------------------------------------------

The system states are Any[:(:S), :(:I), :(:R)]

Adding un estado de los muertos

The system states are Any[:(:S), :(:I), :(:R), :(:D)]

There is no resurrection in this model

Infected individuals recover or die in one step
m[:I] = :(x...->begin
          #= In[111]:13 =#
          #= In[111]:14 =#
          roll = rand()
          #= In[111]:15 =#
          if roll < ρ
              #= In[111]:16 =#
              return :R
          elseif #= In[111]:17 =# rand(Bool)
              #= In[111]:18 =#
              return :D
          else
              #= In[111]:20 =#
              return :I
          end
      end)
In [121]:
P.steps[1].states, poly(P.steps[2])
Out[121]:
(:([:S, :I, :R, :D]), :((.+)(β[1] .* x .^ 1)))
In [122]:
println("\n\nApplying the second pair of transformations")
println(    "-------------------------------------------")
(addgrowth! × T₁)(P)
(identity   × Tₓ)(P)
(identity   × T₁)(P)
(identity   × Tₓ)(P)
(identity   × Tₓ)(P)
(identity   × T₁)(P)

Applying the second pair of transformations
-------------------------------------------

Adding population growth to this model
stepr = :(function tick!(sm::StateModel)
      #= none:59 =#
      sm.loads = map((s->begin
                      #= none:59 =#
                      stateload(sm, s)
                  end), sm.states)
      #= none:60 =#
      return sm.loads
  end)
------------------------
stepr = :(function tick!(sm::StateModel)
      #= none:59 =#
      sm.loads = map((s->begin
                      #= none:59 =#
                      stateload(sm, s)
                  end), sm.states)
      #= none:60 =#
      return sm.loads
      push!(sm.agents, :S)
  end)
In [123]:
println("\n\nThe final model state")
println(     "---------------------")
println(filter(isexpr, findfunc(P.steps[1].expr, :tick!))[end])
P.steps[1].states, poly(P.steps[2])

The final model state
---------------------
function tick!(sm::StateModel)
    #= none:59 =#
    sm.loads = map((s->begin
                    #= none:59 =#
                    stateload(sm, s)
                end), sm.states)
    #= none:60 =#
    return sm.loads
    push!(sm.agents, :S)
end
Out[123]:
(:([:S, :I, :R, :D]), :(.+(β[1] .* x .^ 4, β[2] .* x .^ 3, β[3] .* x .^ 2, β[4] .* x .^ 0)))

Results

  • The pipeline produces a regression polynomial
  • This shows the nonlinear dependence of the model on the recovery rate $\rho$
In [129]:
p = scatter(first.(table), last.(table), label="obs")
plot!(first.(xŷ), last.(xŷ), label="fit")
xlabel!(p, "Probability of Recovery")
ylabel!(p, "Deaths")
println("β: ", P.results[end][2].β, "\n", string(poly(P.steps[2])))
p
β: [-65.4064, 142.05, -91.1202, 14.3129]
.+(β[1] .* x .^ 4, β[2] .* x .^ 3, β[3] .* x .^ 2, β[4] .* x .^ 0)
Out[129]:
0.00 0.25 0.50 0.75 1.00 0 5 10 15 20 Probability of Recovery Deaths obs fit