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

Update EventQueueABM to multi-agent + make plotting and run model agnostic #1001

Merged
merged 75 commits into from
Mar 15, 2024
Merged
Show file tree
Hide file tree
Changes from 67 commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
bcd582d
mention ABM API
Datseris Mar 10, 2024
87fb44d
separate step files
Datseris Mar 10, 2024
dc79b63
useful comment for Ref
Datseris Mar 10, 2024
c7c3fa7
change decleration: `types` to `kinds` for multiagent
Datseris Mar 10, 2024
304ff10
minor docstring improvements
Datseris Mar 10, 2024
3fcffbc
finish rewriting docstring
Datseris Mar 10, 2024
0c905ce
rename everything; add comments to main function
Datseris Mar 10, 2024
c6ee18c
finish all code in event queue abm
Datseris Mar 10, 2024
5c7f9a3
add another todo for type stability
Datseris Mar 10, 2024
694a25a
[WIP] making example runnable... not yet!
Datseris Mar 10, 2024
6f631fb
fix one bug, another one remains :(
Datseris Mar 10, 2024
e0a70f8
finally model is buildable!!!
Datseris Mar 11, 2024
efc8085
improve replicate! to allow custom `pos`
Datseris Mar 11, 2024
b514dd2
document and export allkinds
Datseris Mar 11, 2024
51e94c2
finish RPS example
Datseris Mar 11, 2024
17aeafa
better wording in the example
Datseris Mar 11, 2024
7379017
deprecate `spf` in favor of `dt` in `abmvideo`
Datseris Mar 11, 2024
5ec12a8
remove stepping functions from ABMObservable
Datseris Mar 11, 2024
f7520ee
don't enforce model time to be an integer
Datseris Mar 11, 2024
24d0dfe
simplify the unreasonably overcomplicated step!(ABMObservable)
Datseris Mar 11, 2024
bc8f68f
remove agent step completely from ABM plot
Datseris Mar 11, 2024
a067c6c
F*CK yeah `abmplot` works with the freaking RPS!!!!
Datseris Mar 11, 2024
d35cf5d
remove abmstep from `add_controls!` they are literaly used nowhere
Datseris Mar 11, 2024
64dbbf1
make add_controls true if params is not empty
Datseris Mar 11, 2024
3b0ebee
the whole visualizations example works with the updated plotting code
Datseris Mar 11, 2024
0be1154
change "spu" to "dt" and update defaults to per model
Datseris Mar 11, 2024
cac62a4
rename step to time in abmvideo
Datseris Mar 11, 2024
8cac47c
abmvideo fully works with EvenQueue
Datseris Mar 11, 2024
f20026a
rephrase the whole handling of time in step!/run!
Datseris Mar 11, 2024
8a0aa01
introduce `discretetimeabm` function
Datseris Mar 11, 2024
832b299
re-write the `run!` function to be model agnostic
Datseris Mar 11, 2024
70cfce3
`run!` code works, but doesn't give correct results
Datseris Mar 11, 2024
0133082
Merge remote-tracking branch 'origin/main' into annv6
Datseris Mar 13, 2024
4433a0b
correct `run!` logic!
Datseris Mar 13, 2024
0909ec6
add init keyword to `4run!`
Datseris Mar 13, 2024
fc16ea8
simplify code logic now that init works
Datseris Mar 13, 2024
4fabc28
add orthogonality and run! statements in changelog
Datseris Mar 13, 2024
1a01613
rename `:step` to `:time` in run
Datseris Mar 13, 2024
6806dde
also change name in headers
Datseris Mar 13, 2024
d76ea8e
data colletion works perfectly for RPS
Datseris Mar 13, 2024
51a1fbd
incorporate new run logic into abmexploration (still test: interaction)
Datseris Mar 13, 2024
2ddb031
remove data collection logic from `interaction.jl`: it is done in ABMObs
Datseris Mar 13, 2024
709ad3c
fix problem of duplicate collection at time 0
Datseris Mar 13, 2024
8030ed1
reorganize RPS example
Datseris Mar 13, 2024
fcb1886
remove missleading comment
Datseris Mar 13, 2024
8bda92d
update offline_run! to new run! format
Datseris Mar 13, 2024
24bed2f
Merge branch 'main' into annv6
Tortar Mar 14, 2024
13d4386
better default `dt` in explortaon
Datseris Mar 14, 2024
4234fc2
better wording for collect
Datseris Mar 14, 2024
0cde4cf
Merge remote-tracking branch 'origin/main' into annv6
Datseris Mar 14, 2024
22fd1f6
show video in RPS via HTML
Datseris Mar 14, 2024
700e707
remove unecessary `replicaet` signature
Datseris Mar 14, 2024
5125234
fix all model access tests
Datseris Mar 14, 2024
9d4184e
only 6 datacollection failures remain
Datseris Mar 14, 2024
787937a
fix visualization data correction pausing when pressing reset
Datseris Mar 15, 2024
6b0e06d
also collect data on reset
Datseris Mar 15, 2024
be112ed
tests fail in: High-level API for Collections:
Datseris Mar 15, 2024
d9eaf53
fix the time year modulo data collection errors (more remain)
Datseris Mar 15, 2024
b3b3346
remove useless `writing_interval` keyword
Datseris Mar 15, 2024
5e5c3a3
fully fix offline run and its tests!
Datseris Mar 15, 2024
1d4e29b
fix all the tests!!! (fingers crossed?)
Datseris Mar 15, 2024
529d70a
hell yeah, all green!
Datseris Mar 15, 2024
737cce9
improve changelog
Datseris Mar 15, 2024
071ecc9
fixes
Tortar Mar 15, 2024
1df7ac2
Update collect.jl
Tortar Mar 15, 2024
3d397f6
Rename step_eventque.jl to step_eventqueue.jl
Tortar Mar 15, 2024
a85cb2b
Update Agents.jl
Tortar Mar 15, 2024
57e803c
fix
Tortar Mar 15, 2024
f3f25ae
correct isnothing comparison
Datseris Mar 15, 2024
fceed91
remove dev version of Agents commands
Tortar Mar 15, 2024
7a6da9c
Update Project.toml
Tortar Mar 15, 2024
4633757
Update Project.toml
Tortar Mar 15, 2024
0f9ee5a
Update Project.toml
Tortar Mar 15, 2024
d44b588
Update Project.toml
Tortar Mar 15, 2024
cd5de5d
Update Project.toml
Tortar Mar 15, 2024
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ agents_visualizations.md
celllistmap.mp4
test/adata.arrow
test/mdata.arrow
*.csv
*.arrow
30 changes: 19 additions & 11 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,38 @@
# v6 - New Major release!

## Major and/or BREAKING
## Potentially BREAKING changes

_We tried to deprecate every major change, resulting in practically no breakage from v5 to v6. However, in version v6.2 we will remove all deprecations (and hence un-updated code will break)_

- The `step` column in collected dataframes has been renamed to `time` in `run!`.
- The `@agent` macro has been rewritten to support fields with default and const values. It has a new usage syntax now that parallelizes more Julia's native `struct` declaration. The old macro version still works but it's deprecated. Since now the macro supports these features, using `@agent` is the only supported way to create agent types for Agents.jl.
- Manually setting or altering the ids of agents is no longer allowed. The agent id is now considered a read-only field, and is set internally by Agents.jl to enable hidden optimizations in the future. Due to this, the `nextid` function is no longer public API. As a consequence, new constructor of agents which accept the model as first argument have been created with the agent macro e.g. `A(model, pos)`, so that to handle the id assignment automatically.
- Manually setting or altering the ids of agents is no longer allowed. The agent id is now considered a read-only field, and is set internally by Agents.jl to enable hidden optimizations in the future. Due to this, the `nextid` function is no longer public API. As a consequence, new constructor of agents which accept the model as first argument have been created with the agent macro e.g. `A(model, pos; kwargs...)`, so that to handle the id assignment automatically.
- We anyways recommend using exclusively the API function `add_agent!` to create new model agents. This means you never have to care about the id!
- Agent types in `ContinuousSpace` now use `SVector` for their `pos` and `vel` fields rather than `NTuple`. `NTuple` usage in `ContinuousSpace` is officially deprecated, but backward compatibility is *mostly* maintained. Known breakages include the comparison of agent position and/or velocity with user-defined tuples, e.g., doing `agent.pos == (0.5, 0.5)`. This will always be `false` in v6 as `agent.pos` is an `SVector`. The rest of the functionality should all work without problems, such as moving agents to tuple-based positions etc.
- The `:step` column name of the dataframes resulting from `run!` has been renamed to `:time`, to accommodate for the fact that now both discrete time and continuous time models are possible in Agents.jl.

## New features

- `AgentBasedModel` defines an API that new model types may extend.
This opens the door for making new types of models as well as better integration
of other agent based modelling frameworks with Agents.jl.
- Every aspect of Agents.jl is orthogonal to `AgentBasedModel`: movement and neighbor searching in any space, data collection, visualizations, etc., are independent of the specific type of `AgentBasedModel` and work out of the box with any model.
- Logic of when to collect data in `run!` has been improved to accommodate both discrete and continuous time models. This is reflected in the new options for the keyword `when`.
- A new keyword `init` is now available for `run!` to data collect from the model before evolving it. Whether data were collected at time 0 or not was not really obvious in the original version of `run!` due to the ambiguity of the previous handling of `when`.
- A new `@multiagent` macro allows to run multi-agent simulations much more efficiently. It has
two version: In `:opt_speed` the created agents are optimized such as there is virtually
no performance difference between having 1 agent type at the cost of each agent occupying
more memory that in the `Union` case. In `:opt_memory` each agent is optimized to occupy practically
no performance difference between having 1 agent type at the cost of each agent occupying
more memory that in the `Union` case. In `:opt_memory` each agent is optimized to occupy practically
the same memory as the `Union` case, however this comes at a cost of performance versus having 1 type.
- A new experimental model type `EventQueueABM` has been implemented. It operates in continuous time through
- A new experimental model type `EventQueueABM` has been implemented. It operates in continuous time through
the scheduling of events at arbitrary time points, in contrast with the discrete time nature of a `StandardABM`.
- Both the visualization and the model abstract interface have been refactored to improve the user
experience to conform to the Agents.jl API when creating a new model type and its visualizations.
- Grid and continuous spaces support boundaries with mixed periodicity, specified by tuples with a `Bool` value for each dimension, e.g. `GridSpace((5,5); periodic=(true,false))` is periodic along the first dimension but not along the second.
- `Arrow` backend in `offline_run! is now supported` also for Windows users.
- The model time/step is tracked automatically, accessible through `abmtime(model)`.
- `Arrow` backend in `offline_run!` is now supported also for Windows users.
- The model time is now tracked automatically, accessible through `abmtime(model)`. This is part of the new `AgentBasedModel` API.
- Two new functions `random_id_in_position` and `random_agent_in_position` can be used to select a random id/agent in a position in discrete spaces (even with filtering).
- A new function `swap_agents` can be used to swap an agents couple in a discrete space.
- New function `hasid`
- A new function `swap_agents` can be used to swap the positions of a pair of agents, which works even in spaces which allow 1 agent per position.
- New function `hasid` to check if a model has an agent with a given id.

## Performance Improvements

Expand All @@ -36,7 +43,7 @@ _We tried to deprecate every major change, resulting in practically no breakage

## Deprecations

- The way the evolution rule (`agent_step!, model_step!`) is handled has changed. Now, the stepping functions must be given to the agent based model during construction of the model instead of given to `step!, run!, abmplot, ...`. This change is important and allows us to:
- The way the evolution rule (`agent_step!, model_step!`) is handled has changed. Now, the stepping functions must be given to the agent based model during construction of the model instead of given to `step!, run!, abmplot, ...`. This change is important and allows us to:
- Have Agents.jl have the same mental model as DifferentialEquations.jl, DynamicalSystems.jl, and other dynamical modelling packages, where the evolution rules are part of the central simulation struct.
- Allows us to develop new types of models that may have rules that are defined differently, without being based on e.g., two particular functions.
- Allows us to develop (in the future) a new model type that is optimized for multi-agent simulations.
Expand All @@ -47,6 +54,7 @@ _We tried to deprecate every major change, resulting in practically no breakage
- `add_agent_pos!` has been deprecated in favor of the more descriptive `add_agent_own_pos!`.
- `schedule(model, scheduler)` is deprecated. Use `scheduler(model)` together with `hasid(model)`.
- Deprecations that were in place in v5 (see section `# v5` of this CHANGELOG) have been removed.
- Keyword `spf` is deprecated in favor of `dt` in `abmvideo`.

# v5.17

Expand Down
2 changes: 1 addition & 1 deletion docs/src/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ EventQueueABM
AbstractAgent
@multiagent
kindof
allkinds
```

### Minimal agent types
Expand Down Expand Up @@ -380,4 +381,3 @@ translate_polygon
scale_polygon
rotate_polygon
```

1 change: 0 additions & 1 deletion docs/src/tutorial.jl
Original file line number Diff line number Diff line change
Expand Up @@ -665,7 +665,6 @@ adf[end-10:end, :] # display only the last few rows
# entry of the tuple is the data to collect, and the second how to
# aggregate it over agents.


using Statistics: mean
schelling = initialize();
adata = [(:mood, sum), (x, mean)]
Expand Down
54 changes: 32 additions & 22 deletions examples/agents_visualizations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# The animation at the start of the page is created using the code of this page, see below.

# The docs are built using versions:
using Pkg
import Pkg
Pkg.status(["Agents", "CairoMakie"];
mode = PKGMODE_MANIFEST, io=stdout
)
Expand All @@ -34,30 +34,34 @@ using Agents, CairoMakie
try
using Pkg
Pkg.develop(url="https://github.com/JuliaDynamics/AgentsExampleZoo.jl.git")
using AgentsExampleZoo
catch
Pkg.develop(path=joinpath(DEPOT_PATH[1],"dev","AgentsExampleZoo"))
using AgentsExampleZoo
end
using AgentsExampleZoo

model = AgentsExampleZoo.daisyworld(; solar_luminosity = 1.0, solar_change = 0.0,
scenario = :change)
model = AgentsExampleZoo.daisyworld(;
solar_luminosity = 1.0, solar_change = 0.0, scenario = :change
)
model

# Now, to plot daisyworld we provide a function for the color
# for the agents that depend on the agent properties, and
# a size and marker style that are constants,
daisycolor(a) = a.breed # agent color
agent_size = 20 # agent size
agent_marker = '✿' # agent marker
daisycolor(a) = a.breed
agent_size = 20
agent_marker = '✿'
agentsplotkwargs = (strokewidth = 1.0,) # add stroke around each agent
fig, ax, abmobs = abmplot(model; agent_color = daisycolor, agent_size, agent_marker, agentsplotkwargs)
fig
fig, ax, abmobs = abmplot(model;
agent_color = daisycolor, agent_size, agent_marker, agentsplotkwargs
)
fig # returning the figure displays it

# !!! note "Supported keyword arguments"
# We do not check internally, if the keyword arguments passed to `abmplot` are
# supported. Please make sure that there are no typos and that the used kwargs are
# We do not check internally, if the keyword arguments passed to `abmplot` are
# supported. Please make sure that there are no typos and that the used kwargs are
# supported by the [`abmplot`](@ref) function. Otherwise they will be ignored.
# This is an unfortunate consequence of how Makie.jl recipes work, and we believe
# that in the future this problem will be addressed in Makie.jl.

# Besides agents, we can also plot spatial properties as a heatmap.
# Here we plot the temperature of the planet by providing the name
Expand All @@ -73,20 +77,24 @@ plotkwargs = (;
fig, ax, abmobs = abmplot(model; plotkwargs...)
fig


# ```@docs
# ```@docs; canonical = false
# abmplot
# ```

# ## Interactive ABM Applications

# Continuing from the Daisyworld plots above, we can turn them into interactive
# applications straightforwardly, simply by providing the stepping functions
# as illustrated in the documentation of [`abmplot`](@ref).
# applications straightforwardly, simply by setting the keyword `add_controls = true`
# as discussed in the documentation of [`abmplot`](@ref).
# Note that [`GLMakie`](https://makie.juliaplots.org/v0.15/documentation/backends_and_output/)
# should be used instead of `CairoMakie` when wanting to use the interactive
# aspects of the plots.
fig, ax, abmobs = abmplot(model; plotkwargs...)
# aspects of the plots!

# ```julia
# using GLMakie
# ```

fig, ax, abmobs = abmplot(model; add_controls = true, plotkwargs...)
fig

# One could click the run button and see the model evolve.
Expand All @@ -100,6 +108,7 @@ fig

# One can furthermore collect data while the model evolves and visualize them using the
# convenience function [`abmexploration`](@ref)

using Statistics: mean
black(a) = a.breed == :black
white(a) = a.breed == :white
Expand All @@ -118,14 +127,15 @@ nothing #hide
# </video>
# ```

# ```@docs
# ```@docs; canonical = false
# abmexploration
# ```

# ## ABM Videos
# ```@docs
# ```@docs; canonical = false
# abmvideo
# ```

# E.g., continuing from above,
model = AgentsExampleZoo.daisyworld()
abmvideo("daisyworld.mp4", model; title = "Daisy World", frames = 150, plotkwargs...)
Expand Down Expand Up @@ -153,7 +163,7 @@ abmvideo("daisyworld.mp4", model; title = "Daisy World", frames = 150, plotkwarg
# ![RabbitFoxHawk inspection example](https://github.com/JuliaDynamics/JuliaDynamics/tree/master/videos/agents/RabbitFoxHawk_inspection.png)

# The tooltip can be customized by extending `Agents.agent2string`.
# ```@docs
# ```@docs; canonical = false
# Agents.agent2string
# ```

Expand All @@ -165,7 +175,7 @@ abmvideo("daisyworld.mp4", model; title = "Daisy World", frames = 150, plotkwarg
# The same steps are necessary when we want to create custom plots that compose
# animations of the model space and other aspects.

# ```@docs
# ```@docs; canonical = false
# ABMObservable
# ```
# To do custom animations you need to have a good idea of how Makie's animation system works.
Expand Down
Loading
Loading