Raster
Spatial information can be added to the simulation in the form of one or more n-dimensional rasters.
Vahana.add_raster!
— Functionadd_raster!(sim, name::Symbol, dims::NTuple{N, Int}, agent_constructor)
Adds a n-dimensional grid to sim
, with the dimensions dims
.
For each cell a new node/agent is added to the graph. To create the agent, the agent_constructor
function is called, with the cell position in form of an CartesianIndex
as argument.
The symbol name
is an identifier for the created raster, as it is allowed to add multiple rasters to sim
.
The types of the agents created by the agent_constructor
must be already registered via register_agenttype!
.
Returns a vector with the IDs of the created agents.
Can be only called before finish_init!
.
See also calc_raster
connect_raster_neighbors!
and move_to!
.
Those rasters are implemented as part of the graph structure, with each cell represented as a node, so the cell types must be registered like the types of agents via register_agenttype!
.
To create edges between the cells, or between the cells and agents of other types via the following two helper functions.
Vahana.connect_raster_neighbors!
— Functionconnect_raster_neighbors!(sim, name::Symbol, edge_constructor; [distance::Int, metric:: Symbol, periodic::Bool])
All cells that are at most distance
from each other (using the metric metric
) are connected with edges, where the edges are created with the edge_constructor
.
The edge_constructor
must be a function with one argument with type Tuple{CartesianIndex, CartesianIndex}. The first CartesianIndex is the position of the source node, and the second CartesianIndex the position of the target node.
Valid metrics are :chebyshev, :euclidean and :manhatten.
The keyword periodic determines whether all dimensions are cyclic (e.g., in the two-dimensional case, the raster is a torus).
The default values of the optional keyword arguments are 1 for distance
, :chebyshev for metric
and true for periodic
. which is equivalent to a Moore neighborhood. The :manhatten metric can be used to connect cells in the von Neumann neighborhood.
The agent types of agents created by the agent_constructor
must be already registered via register_agenttype!
.
See also add_raster!
Vahana.move_to!
— Functionmove_to!(sim, name::Symbol, id::AgentID, pos, edge_from_raster, edge_to_raster; [distance = 0, metric = :chebyshev, periodic = true])
Creates up to two edges of type between the agent with ID id
and the cell from the raster name
at the position pos
.
pos
must be of type CartesianIndex or a Dims{N}.
edge_from_raster
is the edge that will be added with the cell as source node and the agent as target node. edge_from_raster
can be nothing
, in this case no edge will be added with the agent as target node.
edge_to_raster
is the edge that will be added with the agent as source node and the cell as target node. edge_to_raster
can be nothing
, in this case no edge will be added with the agent as source node.
Using the keyword arguments, it is possible to add additional edges to the surroundings of the cell at position pos
in the same raster, i.e. to all cells at distance distance
under metric metric
, where valid metrics are :chebyshev, :euclidean and :manhatten. And the keyword
periodic` determines whether all dimensions are cyclic.
See also add_raster!
and connect_raster_neighbors!
The id of a cell for a given position can be archived via cellid
Vahana.cellid
— Functioncellid(sim, name::Symbol, pos)
Returns the ID of the agent (node) from the raster name
at the position pos
. pos
must be of type CartesianIndex or a Dims{N}.
See also add_raster!
, move_to!
, add_edge!
and agentstate
cellid id or position of a random cell can be drawn via:
Vahana.random_pos
— Functionrandom_pos(sim, raster::Symbol, weights::Matrix)
Return a CartesianIndex with random position coordinates, weighted by a probability matrix weights
.
The likelihood of selecting a particular cell/index is proportional to its corresponding value in the weights
matrix.
See also random_pos(sim, raster)
and random_cell
random_pos(sim, raster::Symbol)
Return a CartesianIndex with random position coordinates.
The returned index is sampled from the rasters indizies where each index has the same probability.
See also random_pos(sim, raster, weights)
and random_cell
Vahana.random_cell
— Functionrandom_cell(sim, raster::Symbol)
Return a random cell id of the raster raster
from the simulation sim
.
random_cell(sim, raster::Symbol, weights::Array)
Return a random cell id of the raster raster
from the simulation sim
. The likelihood of selecting a particular cell is proportional to its corresponding value in the weights
matrix.
See also random_cell(sim, raster)
and random_pos
Such a raster is only a collection of nodes in the graph incl. an Vahana internal mapping from the cartesian coordinates to the cell IDs. Beside this mapping, cells are also just agents, but there are some Vahana functions that utilize the internal cartesian coordinates to create a n-dimensional representation of the state space.
Vahana.calc_raster
— Functioncalc_raster(sim, raster::Symbol, f, f_returns::DataType, accessible::Vector{DataType})
Calculate values for the raster raster
by applying f
to each cell ID of the cells constructed by the add_raster!
function.
f_returns
must be the type returned by the function f. There must be an implementation of the zero function for this type, and zero(returntype) | f(id) must be equal to f(id).
accessible
is a vector of Agent and/or Edge types. This vector must list all types that are accessed directly (e.g. via agentstate
or indirectly (e.g. via neighborstates
in the transition function.
If the results of calc_raster
depend only on the state of the cells (as in the following example) and all cells have the same type, calc_rasterstate
can be used as concise alternatives.
Returns a n-dimensional array (with the same dimensions as raster
) with those values.
Example:
The following code from a "Game of Life" implementation generates a boolean matrix indicating which cells are alive (and therefore maps the internal graph structure to the usual representation of a cellular automaton):
calc_raster(sim, :raster, id -> agentstate(sim, id, Cell).active, Bool, [ Cell ])
Can be only called after finish_init!
.
See also add_raster!
and calc_rasterstate
Vahana.calc_rasterstate
— Functioncalc_rasterstate(sim, raster::Symbol, f, f_returns::DataType = Nothing, ::Type{T} = Nothing)
Combined calc_raster with agentstate for the cells of the raster.
Calculate values for the raster raster
by applying f
to the state of each cell.
f_returns
must be the type returned by the function f. There must be an implementation of the zero function for this type, and zero(returntype) + f(state) must be equal to f(state). In the event that all cells in the raster returns the same DataType
, f_returns
can be set to Nothing
, in which case f_returns
is automatically derived.
T
can be set to Nothing
, this decreases the performance, but is necessary in the unusual case that a raster contains different types of agents (in this case agentstate_flexible
is used instead of agentstate
).
Returns a n-dimensional array (with the same dimensions as raster
) with those values.
Example:
Instead of
calc_raster(sim, :raster, id -> agentstate(sim, id, Cell).active, Bool, [ Cell ])
it also possible to just write
calc_rasterstate(sim, :raster, c -> c.active, Bool, Cell)
Can be only called after finish_init!
.
See also add_raster!
, calc_rasterstate
and rastervalues
Vahana.rastervalues
— Functionrastervalues(sim, raster::Symbol, fieldname::Symbol)
Creates a matrix with the same dims as the raster raster
with the values of the field fieldnames
. All cells of the raster must have the same type, and also a zeros
function must exist for the type of fieldnames
.
Example:
Instead of
calc_rasterstate(sim, :raster, c -> c.active, Bool, Cell)
it also possible to just write
rastervalues(sim, :raster, :active)
Can be only called after finish_init!
.
See also add_raster!
and calc_rasterstate