Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New model with agent_step! and model_step! #889

Merged
merged 34 commits into from
Oct 5, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
6edb7d6
new model with agent_step! and model_step! inside
Tortar Sep 25, 2023
3663c87
fix
Tortar Sep 26, 2023
b171537
apply suggestions
Tortar Sep 26, 2023
7e19fad
more stuff
Tortar Sep 26, 2023
859add9
warnings
Tortar Sep 26, 2023
26fd68d
docstrings
Tortar Sep 26, 2023
7b5ba86
partial tests
Tortar Sep 27, 2023
37c5fe8
more tests
Tortar Sep 27, 2023
a0e3f6a
tests
Tortar Sep 28, 2023
8785fdf
almost ready
Tortar Sep 28, 2023
2aa6e65
fix
Tortar Sep 28, 2023
0e19cfe
improvements
Tortar Sep 28, 2023
86e3461
remove documenter compat
Datseris Sep 28, 2023
e0a273d
re-write enumerated list
Datseris Sep 29, 2023
678078c
remove mentioning of random device
Datseris Sep 29, 2023
5f25c83
write new step rule sections 3.1 and 3.2
Datseris Sep 29, 2023
9af7011
adjust docstrings to concrete implementation
Datseris Sep 30, 2023
288e48e
finish model evolution rules section
Datseris Sep 30, 2023
56d684e
finish section 4
Datseris Sep 30, 2023
bff452c
remove `agents_First` and correct teh step.jl file
Datseris Sep 30, 2023
05bf93c
fix add_agent docstring
Datseris Sep 30, 2023
080e850
update schelling
Datseris Sep 30, 2023
65346fd
add schedule for schedulers
Tortar Sep 30, 2023
0138484
Update schedulers.jl
Tortar Sep 30, 2023
3e1b8d4
Update schedulers.jl
Tortar Sep 30, 2023
3656057
Update docs/src/tutorial.md
Datseris Oct 1, 2023
59ce193
Update schedulers.jl
Tortar Oct 1, 2023
7dc5757
scheduling with schedule
Tortar Oct 1, 2023
57bd13d
simplify
Tortar Oct 1, 2023
97993b2
simplify schedule
Tortar Oct 1, 2023
05a57d7
fix tests
Tortar Oct 1, 2023
df206ec
fix model access
Tortar Oct 1, 2023
63b5f0d
Update tutorial.md
Tortar Oct 5, 2023
a95f61d
update changelog
Datseris Oct 5, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/simulations/collect.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ should_we_collect(s, model, when::Bool) = when
should_we_collect(s, model, when) = when(model, s)

"""
run!(model, agent_step! [, model_step!], n::Integer; kwargs...) → agent_df, model_df
run!(model, agent_step!, model_step!, n::Function; kwargs...) → agent_df, model_df
run!(model, n::Integer; kwargs...) → agent_df, model_df
run!(model, f::Function; kwargs...) → agent_df, model_df

Run the model (step it with the input arguments propagated into [`step!`](@ref)) and collect
data specified by the keywords, explained one by one below. Return the data as
Expand Down Expand Up @@ -160,8 +160,8 @@ function run!(model, n;
end

"""
offline_run!(model, agent_step! [, model_step!], n::Integer; kwargs...)
offline_run!(model, agent_step!, model_step!, n::Function; kwargs...)
offline_run!(model, n::Integer; kwargs...)
offline_run!(model, f::Function; kwargs...)

Do the same as [`run`](@ref), but instead of collecting the whole run into an in-memory
dataframe, write the output to a file after collecting data `writing_interval` times and
Expand Down
7 changes: 4 additions & 3 deletions src/simulations/ensemblerun.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ export ensemblerun!
Vector_or_Tuple = Union{AbstractArray,Tuple}

"""
ensemblerun!(models::Vector, agent_step!, model_step!, n; kwargs...)
ensemblerun!(models::Vector, n; kwargs...)
Perform an ensemble simulation of [`run!`](@ref) for all `model ∈ models`.
Each `model` should be a (different) instance of an [`AgentBasedModel`](@ref) but probably
initialized with a different random seed or different initial agent distribution.
All models obey the same rules `agent_step!, model_step!` and are evolved for `n`.
All models obey the same rules `agent_step!, model_step!` contained in the model
and are evolved for `n`.
Tortar marked this conversation as resolved.
Show resolved Hide resolved

Similarly to [`run!`](@ref) this function will collect data. It will furthermore
add one additional column to the dataframe called `:ensemble`, which has an integer
Expand Down Expand Up @@ -44,7 +45,7 @@ function ensemblerun!(
end

"""
ensemblerun!(generator, agent_step!, model_step!, n; kwargs...)
ensemblerun!(generator, n; kwargs...)
Generate many `ABM`s and propagate them into `ensemblerun!(models, ...)` using
the provided `generator` which is a one-argument function whose input is a seed.

Expand Down
11 changes: 5 additions & 6 deletions src/simulations/paramscan.jl
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,8 @@ The following keywords modify the `paramscan` function:
- `showprogress::Bool = false` whether a progressbar will be displayed to indicate % runs finished.

All other keywords are propagated into [`run!`](@ref).
Furthermore, `agent_step!, model_step!, n` are also keywords here, that are given
to [`run!`](@ref) as arguments. Naturally, stepping functions and the
number of time steps (`agent_step!`, `model_step!`, and `n`) and at least one
of `adata, mdata` are mandatory.
Furthermore, `n` is also a keyword here, that is given to [`run!`](@ref) as argument.
Naturally, the number of time steps `n` and at least one of `adata, mdata` are mandatory.
The `adata, mdata` lists shouldn't contain the parameters that are already in
the `parameters` dictionary to avoid duplication.

Expand Down Expand Up @@ -74,7 +72,7 @@ parameters = Dict(
:griddims => (20, 20), # not Vector = not expanded
)

adf, _ = paramscan(parameters, initialize; adata, agent_step!, n = 3)
adf, _ = paramscan(parameters, initialize; adata, n = 3)
```
"""
function paramscan(
Expand All @@ -92,7 +90,8 @@ function paramscan(
agent_step! = agent_step_field(model)
model_step! = model_step_field(model)
else
@warn "some warning"
@warn "Passing agent_step! and model_step! to paramscan is deprecated.
These functions should be already presented inside the model instance."
end
if include_constants
output_params = collect(keys(parameters))
Expand Down
26 changes: 6 additions & 20 deletions src/simulations/step.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,21 @@ using CommonSolve: step!
export step!, dummystep

"""
step!(model::ABM, agent_step!, n::Int = 1)
step!(model::ABM, agent_step!, model_step!, n::Int = 1, agents_first::Bool = true)
step!(model::ABM, n::Int = 1, agents_first::Bool = true)

Update agents `n` steps according to the stepping function `agent_step!`.
Agents will be activated as specified by the `abmscheduler(model)`.
`model_step!` is triggered _after_ every scheduled agent has acted, unless
the argument `agents_first` is `false` (which then first calls `model_step!` and then
activates the agents).
The `model_step!` function passed to the model is triggered _after_ every
scheduled agent has acted, unless the argument `agents_first` is `false`
(which then first calls `model_step!` and then activates the agents).

`step!` ignores scheduled IDs that do not exist within the model, allowing
you to safely remove agents dynamically.

step!(model, agent_step!, model_step!, n::Function, agents_first::Bool = true)
step!(model, f::Function, agents_first::Bool = true)

In this version `n` is a function.
Then `step!` runs the model until `n(model, s)` returns `true`, where `s` is the
In this version, `step!` runs the model until `f(model, s)` returns `true`, where `s` is the
current amount of steps taken, starting from 0.
For this method of `step!`, `model_step!` must be provided always (use [`dummystep`](@ref)
if you have no model stepping dynamics).

See also [Advanced stepping](@ref) for stepping complex models where `agent_step!` might
not be convenient.
Expand All @@ -41,17 +37,7 @@ function CommonSolve.step!(model::ABM, n::Int = 1, agents_first::Bool = true)
end
end

"""
dummystep(model)

Use instead of `model_step!` in [`step!`](@ref) if no function is useful to be defined.
"""
dummystep(model) = nothing
"""
dummystep(agent, model)

Use instead of `agent_step!` in [`step!`](@ref) if no function is useful to be defined.
"""
dummystep(agent, model) = nothing

until(s, n::Int, model) = s < n
Expand Down
12 changes: 5 additions & 7 deletions src/visualizations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,9 @@ The stand-alone function `abmplot` also takes two optional `NamedTuple`s named `
# Interactivity

## Evolution related
* `agent_step!, model_step! = Agents.dummystep`: Stepping functions to pass to
[`ABMObservable`](@ref) which itself passes to `Agents.step!`.
* `add_controls::Bool`: If `true`, `abmplot` switches to "interactive application" mode.
This is by default `true` if either `agent_step!` or `model_step!` keywords are provided.
These stepping functions are used to evolve the model interactively using `Agents.step!`.
This is by default `true` if the model contains either `agent_step!` or `model_step!`.
The model evolves interactively using `Agents.step!`.
The application has the following interactive elements:
1. "step": advances the simulation once for `spu` steps.
1. "run": starts/stops the continuous evolution of the model.
Expand Down Expand Up @@ -111,13 +109,13 @@ export abmplot, abmplot!


"""
ABMObservable(model; agent_step!, model_step!, adata, mdata, when) → abmobs
ABMObservable(model; adata, mdata, when) → abmobs

`abmobs` contains all information necessary to step an agent based model interactively.
It is also returned by [`abmplot`](@ref).

Calling `Agents.step!(abmobs, n)` will step the model for `n` using the provided
`agent_step!, model_step!, n` as in [`Agents.step!`](@ref).
`agent_step!, model_step!` cotained in the model as in [`Agents.step!`](@ref).

The fields `abmobs.model, abmobs.adf, abmobs.mdf` are _observables_ that contain
the [`AgentBasedModel`](@ref), and the agent and model dataframes with collected data.
Expand Down Expand Up @@ -174,7 +172,7 @@ function abmexploration end
export abmexploration

"""
abmvideo(file, model, agent_step! [, model_step!]; kwargs...)
abmvideo(file, model; kwargs...)

This function exports the animated time evolution of an agent based model into a video
saved at given path `file`, by recording the behavior of the interactive version of
Expand Down
Loading