Commit ce88d252 authored by Victor's avatar Victor
Browse files

update with tuple fixes

parent fcb3d958
Pipeline #93088 failed with stage
in 18 minutes and 2 seconds
...@@ -24,28 +24,38 @@ import Base:eltype ...@@ -24,28 +24,38 @@ import Base:eltype
eltype(a::Agent{A,R,T,U,V}) where {A,R,T,U,V} = T eltype(a::Agent{A,R,T,U,V}) where {A,R,T,U,V} = T
# infers position type and zeros # infers position type and zeros
function initpos(s::S) where {S<:AbstractSpacesTuple} function _initpos(s::S) where {S<:AbstractSpacesTuple}
Eltype = eltype.(s) T = collect(eltype.(s))
Dims = ndims.(s) TT = collect(T)
pos = [] _nd = ndims.(s)
for i in 1:length(Eltype) for (i,n) in enumerate(_nd)
if Dims[i] > 1 if n > 1
push!(pos,ones(Eltype[i],Dims[i])) TT[i] = Vector{TT[i]}
end
end
pos = Union{TT...}[]
for i in 1:length(TT)
if _nd[i] > 1
push!(pos,ones(T[i],_nd[i]))
else else
pos = push!(pos,one(Eltype[i])) pos = push!(pos,one(T[i]))
end end
end end
_Type = eltype.(pos) Tuple{T...},pos
Tuple{_Type...},pos
end end
# default initialiser # default initialiser
""" """
$(SIGNATURES) $(SIGNATURES)
Initialises agent with 0 values everywhere Initialises agent with 0 values everywhere
""" # args
function Agent(s::S;ancestors=false,rates=false) where {S <: AbstractSpacesTuple} - `s` is the underlying space
T,pos = initpos(s) - `ancestors=true` when agents fitness needs to be updated at each time step.
This is needed for the Gillepsie algorithm, but not for CFM algorithm
- `ancestors=true` when one wants to store ancestors traits.
"""
function Agent(s::S;ancestors=false,rates=true) where {S <: AbstractSpacesTuple}
T,pos = _initpos(s)
t = 0. t = 0.
U = Float64 U = Float64
d = rates ? Float64(.0) : nothing d = rates ? Float64(.0) : nothing
...@@ -54,59 +64,66 @@ function Agent(s::S;ancestors=false,rates=false) where {S <: AbstractSpacesTupl ...@@ -54,59 +64,66 @@ function Agent(s::S;ancestors=false,rates=false) where {S <: AbstractSpacesTupl
Agent{Ancestors{ancestors},Rates{rates},T,U,V}([pos],[t],d,b) Agent{Ancestors{ancestors},Rates{rates},T,U,V}([pos],[t],d,b)
end end
# here pos is provided # here pos t should be provided
""" # this allows to initilise agents from any time steps knowing ancestors traits
$(SIGNATURES) function Agent(s::S,pos_t::Vector,t::Vector{U};ancestors=false,rates=true) where {S <: AbstractSpacesTuple, U <: AbstractFloat}
Initialises agent with `pos` provided
"""
function Agent(s::S, pos::P;ancestors=false,rates=false) where {P<:Vector,S <: AbstractSpacesTuple}
T = eltype.(s) T = eltype.(s)
for (i,p) in enumerate(pos) TT = collect(T) # we need an array to convert thereafter position
if eltype(p) !== T[i] _nd = ndims.(s)
try for (i,n) in enumerate(_nd)
p = convert.(T[i],p) if n > 1
catch e TT[i] = Vector{T[i]}
throw(ArgumentError("Position provided does not match with underlying space"))
end
end end
end end
t = 0. length(pos_t) == length(t) ? nothing : ArgumentError("length of `pos` should match length of `t`")
U = Float64 # we convert all
d = rates ? Float64(.0) : nothing pos2_t = Vector{Union{TT...}}[]
b = d for pos in pos_t
V = rates ? Float64 : Nothing pos2 = Union{TT...}[]
Agent{Ancestors{ancestors},Rates{rates},Tuple{T...},U,V}([pos],[t],d,b) for (i,p) in enumerate(pos)
end
# TODO : to be modified
function Agent(s::S,pos::Vector,t::Vector{U};ancestors=false,rates=false) where {S <: AbstractSpacesTuple,U}
T = eltype.(s)
for (i,p) in enumerate(pos[1])
if typeof(p) !== T[i]
try try
p = convert(T[i],p) push!(pos2,convert(TT[i],p))
catch e catch e
throw(ArgumentError("Position provided does not match with underlying space")) throw(ArgumentError("Position provided does not match with underlying space"))
end end
end end
push!(pos2_t,pos2)
end end
# U = Float64
d = rates ? Float64(.0) : nothing d = rates ? Float64(.0) : nothing
b = d b = d
V = rates ? Float64 : Nothing V = rates ? Float64 : Nothing
Agent{Ancestors{ancestors},Rates{rates},Tuple{T...},U,V}(pos,t,d,b) Agent{Ancestors{ancestors},Rates{rates},Tuple{T...},U,V}(pos2_t,t,d,b)
end end
"""
Agent(s, pos;ancestors=false,rates=true)
Initialises agent with initial position `pos` provided
# args
- `s` is the underlying space
- `ancestors=true` when agents fitness needs to be updated at each time step.
This is needed for the Gillepsie algorithm, but not for CFM algorithm
- `ancestors=true` when one wants to store ancestors traits.
"""
Agent(s, pos; ancestors=false, rates=true) = Agent(s, [pos], [0.],ancestors=ancestors, rates=rates)
import Base:copy,show import Base:copy,show
Base.copy(a::A) where {A<:AbstractAgent} = A(copy(a.x_history),copy(a.t_history),copy(a.d),copy(a.b)) Base.copy(a::A) where {A<:AbstractAgent} = A(copy(a.x_history),copy(a.t_history),copy(a.d),copy(a.b))
# this function only copies the trait history and time (x,t), and set birth and death rates to 0. # this function only copies the trait history and time (x,t), and set birth and death rates to 0.
copyxt(a::Agent{A,R,T,U,V}) where {A,R,T,U,V<:Number} = Agent{A,R,T,U,V}(copy(a.x_history),copy(a.t_history),zero(V),zero(V)) copyxt(a::Agent{A,R,T,U,V}) where {A,R,T,U,V<:Number} = Agent{A,R,T,U,V}(copy(a.x_history),copy(a.t_history),zero(V),zero(V))
copyxt(a::Agent{A,R,T,U,Nothing}) where {A,R,T,U} = Agent{A,R,T,U,Nothing}(copy(a.x_history),copy(a.t_history),nothing,nothing) copyxt(a::Agent{A,R,T,U,Nothing}) where {A,R,T,U} = Agent{A,R,T,U,Nothing}(copy(a.x_history),copy(a.t_history),nothing,nothing)
# this has to be overloaded for Base.copy(a::Agent) to work properly # this has to be overloaded for Base.copy(a::Agent) to work properly
Base.copy(m::Missing) = missing Base.copy(m::Missing) = missing
Base.copy(n::Nothing) = nothing Base.copy(n::Nothing) = nothing
function Base.show(io::IO, a::Agent{A,R,T,U,V}) where {A,R,T,U,V} function Base.show(io::IO, a::Agent{A,R,T,U,V}) where {A,R,T,U,V}
println(io, "Agent with indices of type", T) println(io, "Agent with indices of type ", T)
end end
Base.summary(A::AbstractAgent) = string(TYPE_COLOR,nameof(typeof(a)),NO_COLOR," with uType ",TYPE_COLOR,eltype(a.x_history)) Base.summary(A::AbstractAgent) = string(TYPE_COLOR,nameof(typeof(a)),NO_COLOR," with uType ",TYPE_COLOR,eltype(a.x_history))
...@@ -179,12 +196,16 @@ function _get_xinc(a::AbstractAgent,s::AbstractSpacesTuple,p::Dict,t::Number) ...@@ -179,12 +196,16 @@ function _get_xinc(a::AbstractAgent,s::AbstractSpacesTuple,p::Dict,t::Number)
@unpack D,mu = p @unpack D,mu = p
_x = deepcopy(get_x(a)) _x = deepcopy(get_x(a))
for (i,ss) in enumerate(s) for (i,ss) in enumerate(s)
E = eltype(mu[i])
S = eltype(ss)
if length(mu[i]) > 1 if length(mu[i]) > 1
mut = rand(eltype(mu[i]),ndims(ss)) .< mu[i] mut = (rand(E,ndims(ss)) .< mu[i]) .|> S
_x[i] .+= mut .* get_inc(_x[i],D[i],ss,t) _x[i] .+= mut .* get_inc(_x[i],D[i],ss,t)
else else
mut = rand(eltype(mu[i])) < mu[i] mut = rand(E) < mu[i]
_x[i] += mut * get_inc(_x[i],D[i],ss,t) if mut
_x[i] += get_inc(_x[i],D[i],ss,t)
end
end end
end end
_x _x
......
...@@ -93,13 +93,13 @@ function get_inc(x,D,s::ContinuousSegment{T}) where {T} ...@@ -93,13 +93,13 @@ function get_inc(x,D,s::ContinuousSegment{T}) where {T}
end end
function get_inc(x,D,s::DiscreteSegment{T}) where {T} function get_inc(x,D,s::DiscreteSegment{T}) where {T}
inc = D * randn() inc = D * randn(Float32)
return round(T,_reflect1D(x,inc,s)) return round(T,_reflect1D(x,inc,s))
end end
# normal dispersal kernel that gets truncated # normal dispersal kernel that gets truncated
function get_inc(x,D::Number,s::GraphSpace{T}) where {T} function get_inc(x,D::Number,s::GraphSpace{T}) where {T}
niter = round(Int,abs(D*randn())) + 1 niter = round(T,abs(D*randn(Float32))) + 1
# here we add +1 since randomwalk(s.g,x,niter) returns x # here we add +1 since randomwalk(s.g,x,niter) returns x
if niter > 0 if niter > 0
return last(randomwalk(s.g,x,niter)) - x return last(randomwalk(s.g,x,niter)) - x
......
...@@ -73,8 +73,8 @@ w4 = World(a4,myspace4,p4) ...@@ -73,8 +73,8 @@ w4 = World(a4,myspace4,p4)
@test abs(β) < Inf @test abs(β) < Inf
end end
@testset "Isolation by history - hamming distance" begin @testset "Isolation by history - hamming distance" begin
a1 = Agent((DiscreteSegment(1,10),),[(1,),(2,),(3,)],[0,1,4],ancestors=true) a1 = Agent((DiscreteSegment(1,10),),[1,2,3],[0.,1.,4.],ancestors=true)
a2 = Agent((DiscreteSegment(1,10),),[(1,),(10,),(3,),(10,)],[0,3,4,5],ancestors=true) a2 = Agent((DiscreteSegment(1,10),),[1,10,3,10],[0.,3.,4.,5.],ancestors=true)
@test get_dist_hist(a1,a2,(x,y)->y!=x,1) 3.0 @test get_dist_hist(a1,a2,(x,y)->y!=x,1) 3.0
end end
end end
......
...@@ -12,8 +12,8 @@ sigma_a = .7; ...@@ -12,8 +12,8 @@ sigma_a = .7;
K0 = 1000; K0 = 1000;
b(X,t) = gaussian(X[1],0.,sigma_K) b(X,t) = gaussian(X[1],0.,sigma_K)
d(X,Y,t) = gaussian(X[1],Y[1],sigma_a)/K0 d(X,Y,t) = gaussian(X[1],Y[1],sigma_a)/K0
D = (1e-2,) D = [1e-2]
mu = [.1] mu = [1.]
NMax = 10000 NMax = 10000
tend = 1.5 tend = 1.5
p = Dict{String,Any}();@pack! p = D,mu,NMax p = Dict{String,Any}();@pack! p = D,mu,NMax
...@@ -25,6 +25,6 @@ w0 = World(myagents,myspace,p,0.) ...@@ -25,6 +25,6 @@ w0 = World(myagents,myspace,p,0.)
@testset "Hamming distances" begin @testset "Hamming distances" begin
@test typeof(get_xhist_mat(agents(w0))[1] )<: Array @test typeof(get_xhist_mat(agents(w0))[1] )<: Array
@test get_pairwise_average_isolation(w0) >0 @test get_pairwise_average_isolation(w0) > 0
@test get_local_pairwise_average_isolation(w0) > 0 @test get_local_pairwise_average_isolation(w0) > 0
end end
...@@ -63,7 +63,7 @@ end ...@@ -63,7 +63,7 @@ end
a4 = Agent(myspace2,[1,1.,[1.,1]],rates=true) a4 = Agent(myspace2,[1,1.,[1.,1]],rates=true)
a5 = Agent(myspace2,ancestors=true) a5 = Agent(myspace2,ancestors=true)
# increment test # increment test
p_myspace = Dict("D"=>[1e-10,1e-10,1e-10],"mu" =>[1,1,1] ) p_myspace = Dict("D"=>Union{Float64,Float16}[1e-10,1e-10,Float16(1e-10)],"mu" =>Union{Float64,Float16}[1.,1.,Float16(1)] )
p_myspace2 = Dict("D"=>[1,1,[1,1]],"mu" =>[1,1,[1,1]]) p_myspace2 = Dict("D"=>[1,1,[1,1]],"mu" =>[1,1,[1,1]])
# basic test # basic test
...@@ -75,7 +75,7 @@ end ...@@ -75,7 +75,7 @@ end
old_a1 = deepcopy(a1) old_a1 = deepcopy(a1)
@test prod((get_x(old_a1) . get_x(increment_x!(a1,myspace,p_myspace,0.)))) @test prod((get_x(old_a1) . get_x(increment_x!(a1,myspace,p_myspace,0.))))
@test !prod((get_x(old_a1) .== get_x(increment_x!(a1,myspace,p_myspace,0.)))) # @test !prod((get_x(old_a1) .== get_x(increment_x!(a1,myspace,p_myspace,0.))))
@test nancestors(increment_x!(a2,myspace,p_myspace,2.)) > 1 @test nancestors(increment_x!(a2,myspace,p_myspace,2.)) > 1
@test !isnothing(increment_x!(a4,myspace2,p_myspace2,2.)) @test !isnothing(increment_x!(a4,myspace2,p_myspace2,2.))
@test !isnothing(increment_x!(a5,myspace2,p_myspace2,2.)) @test !isnothing(increment_x!(a5,myspace2,p_myspace2,2.))
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment