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

More correct replicate! (and sample!) #832

Merged
merged 6 commits into from
Jul 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "Agents"
uuid = "46ada45e-f475-11e8-01d0-f70cc89e6671"
authors = ["George Datseris", "Tim DuBois", "Aayush Sabharwal", "Ali Vahdati", "Adriano Meligrana"]
version = "5.17.0"
version = "5.17.1"

[deps]
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
Expand Down
1 change: 1 addition & 0 deletions docs/src/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ OpenStreetMapSpace
```@docs
add_agent!
add_agent_pos!
replicate!
nextid
random_position
```
Expand Down
37 changes: 21 additions & 16 deletions src/simulations/sample.jl
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,14 @@ end
function add_newids!(model, org_ids, newids)
# `counter` counts the number of occurencies for each item, it comes from DataStructure.jl
count_newids = counter(newids)
n = nextid(model)
for id in org_ids
noccurances = count_newids[id]
agent = model[id]
if noccurances == 0
remove_agent!(agent, model)
else
for _ in 2:noccurances
newagent = deepcopy(agent)
newagent.id = n
add_agent_pos!(newagent, model)
n += 1
replicate!(agent, model)
end
end
end
Expand All @@ -59,9 +55,9 @@ end
"""
replicate!(agent, model; kwargs...)

Create a new agent at the same position of the given agent, copying the values
of its fields. With the `kwargs` it is possible to override the values by specifying
new ones for some fields.
Add a new agent to the `model` at the same position of the given agent, copying
the values of its fields. With the `kwargs` it is possible to override the values
by specifying new ones for some fields.
Return the new agent instance.

## Example
Expand All @@ -77,16 +73,25 @@ a = A(1, (2, 2), 0.5, 0.5)
b = replicate!(a, model; w = 0.8)
```
"""
function replicate!(agent, model; kwargs...)
newagent = deepcopy(agent)
for (key, value) in kwargs
setfield!(newagent, key, value)
end
newagent.id = nextid(model)
function replicate!(agent::A, model; kwargs...) where {A<:AbstractAgent}
args = new_args(agent::A, model; kwargs...)
newagent = A(nextid(model), args...)
add_agent_pos!(newagent, model)
return newagent
end

function Base.deepcopy(agent::A) where {A<:AbstractAgent}
return A((deepcopy(getfield(agent, name)) for name in fieldnames(A))...)
function new_args(agent::A, model; kwargs...) where {A<:AbstractAgent}
fields = fieldnames(A)
idx_id = findfirst(x -> x == :id, fields)
fields_no_id = tuple(fields[1:idx_id-1]..., fields[idx_id+1:end]...)
if isempty(kwargs)
new_args = (deepcopy(getfield(agent, x)) for x in fields_no_id)
else
kwargs_nt = NamedTuple(kwargs)
new_args = (choose_arg(x, kwargs_nt, agent) for x in fields_no_id)
end
end

function choose_arg(x, kwargs_nt, agent)
return deepcopy(getfield(hasproperty(kwargs_nt, x) ? kwargs_nt : agent, x))
end