JuliaDynamics / Agents.jl

Agent-based modeling framework in Julia
https://juliadynamics.github.io/Agents.jl/stable/
MIT License
731 stars 118 forks source link

Different number of model steps in InteractiveDynamics.abm_video vs run! #478

Closed rmcsqrd closed 3 years ago

rmcsqrd commented 3 years ago

Describe the bug In a model that I am building I have one global parameter num_steps. Sometimes I just run a model and record data without producing an output mp4 to avoid incurring that overhead. When I run the model using run!() I pass in num_steps as the number of times to step!() the model.

Other times when I call InteractiveDynamics.abm_video(), I pass in frames=num_steps. I believe that abm_video steps the model one less time than run!(). The relevant parts of the code are below which I interpret to make my MWE.

Agents.jl/src/simulations/step.jl:

function _run!()
...
    s = 0
    while until(s, n, model)
        if should_we_collect(s, model, when)
            collect_agent_data!(df_agent, model, adata, s; obtainer)
        end
        if should_we_collect(s, model, when_model)
            collect_model_data!(df_model, model, mdata, s; obtainer)
        end
        step!(model, agent_step!, model_step!, 1, agents_first)
        s += 1
    end
...

InteractiveDynamics.jl/src/agents/plots_videos.jl:

function abm_video()
...
    record(fig, file; framerate) do io
        for j in 1:frames-1
            recordframe!(io)
            Agents.step!(abmstepper, model, agent_step!, model_step!, spf)
            s[] += spf; s[] = s[]
        end
...

Minimal Working Example Assuming that num_steps is constant and passed in to both functions such that n=num_steps and frames=num_steps respectively:

num_steps = 100

# run!() equivalent
until(s, n::Int, model) = s < n
s = 0
while until(s, num_steps, nothing)
    s+=1
end
display(s)  # 100

# abm_video equivalent
x = 0
frames = num_steps
for j in 1:frames-1
    x+=1
end
display(x)  # 99

Basically every time I increment s and x step!() would be called. My expected behavior would be that abm_video and run! would call step!() the same number of times. I am not sure if there is something that requires the upper bound of the for loop to be frames-1 but removing the -1 would be my proposed fix. Thanks.

Agents.jl version

[46ada45e] Agents v4.1.3 /Users/riomcmahon/Programming/Agents.jl#FMP [ec714cd0] InteractiveDynamics v0.13.5

Datseris commented 3 years ago

Yes that's normal since the functions do different things. run! will step the model n times. The video will record n frames including the starting state of the model as a frame and thus will step the model n-1 times.