ABMEv_Space.jl 4.65 KB
Newer Older
Victor's avatar
Victor committed
1

Victor's avatar
Victor committed
2
3
4
5

abstract type IsFinite{T} end

#ife stands for is finite
Victor's avatar
Victor committed
6
7
"""
$(TYPEDEF)
Victor's avatar
Victor committed
8
9
`Dim` is the dimension of the space,
`T` is the element type,
Victor's avatar
Victor committed
10
11
`I` to indicate finiteness
"""
Victor's avatar
Victor committed
12
13
abstract type AbstractSpace{Dim,T,I} end
AbstractSpacesTuple = Tuple{Vararg{AbstractSpace}}
14
import Base:ndims,isfinite,eltype
Victor's avatar
Victor committed
15
Base.ndims(x::AbstractSpace{Dim,T,I}) where {Dim,T,I} = Dim
Victor's avatar
Victor committed
16
Base.isfinite(x::AbstractSpace{Dim,T,IsFinite{t}}) where {Dim,T,t} = t #not sure we need this
17
Base.eltype(::AbstractSpace{Dim,T,I}) where {Dim,T,I} = Dim > 1 ? Vector{T} : T
18
19
Base.ndims(ss::AbstractSpacesTuple) = length(ss)
Base.eltype(ss::AbstractSpacesTuple) where {Dim,T,I} = Tuple{eltype.(ss)...}
Victor's avatar
Victor committed
20
21
22

SpaceType=Union{Nothing, AbstractSpace} # not sure what is this used for

Victor's avatar
Victor committed
23
24
25
# Static spaces
abstract type AbstractStatSpace{Dim,T,I} <: AbstractSpace{Dim,T,I} end

26
27
28
"""
$(TYPEDEF)
"""
Victor's avatar
Victor committed
29
struct GraphSpace{T} <: AbstractStatSpace{1,T,IsFinite{true}}
Victor's avatar
Victor committed
30
31
32
    g::AbstractGraph{T}
end

Victor's avatar
Victor committed
33
abstract type AbstractSegment{T<:Number}  <: AbstractStatSpace{1,T,IsFinite{true}} end
34
35
36
37

"""
$(TYPEDEF)
"""
38
struct ContinuousSegment{T<:AbstractFloat} <:  AbstractSegment{T}
Victor's avatar
Victor committed
39
40
41
42
    s::T
    e::T
end

43
44
45
"""
$(TYPEDEF)
"""
46
struct DiscreteSegment{T<:Integer} <: AbstractSegment{T}
Victor's avatar
Victor committed
47
48
49
    s::T
    e::T
end
Victor's avatar
Victor committed
50

51
52
"""
$(TYPEDEF)
Victor's avatar
Victor committed
53
A real space with dimension N and type T
54
"""
Victor's avatar
Victor committed
55
56
57
58
59
60
struct RealSpace{N,T} <: AbstractStatSpace{N,T,IsFinite{false}} end
"""
$(TYPEDEF)
A natural space with dimension N and type T
"""
struct NaturalSpace{N,T} <: AbstractStatSpace{N,T,IsFinite{false}} end
Victor's avatar
Victor committed
61

Victor's avatar
Victor committed
62
## Increments - specialised function
Victor's avatar
Victor committed
63
# TODO: find a way to put a type on D in get_inc
64

Victor's avatar
Victor committed
65
66
67
68
69
70
71
72
"""
$(SIGNATURES)
Returns increment corresponding to space `s`
"""
get_inc(x,D,s::AbstractStatSpace,t) = get_inc(x,D,s) # this is defined to skip representation of t for following specialised methods
get_inc(x,D,s::AbstractSpace{Dim,T,I}) where {Dim,T,I<:IsFinite{false}} = get_inc(D,s) # This is defined to skip representation of x for spaces which do not use reflections.

function get_inc(D,s::AbstractSpace{Dim,T,I}) where {Dim,T<:AbstractFloat,I<:IsFinite{false}}
Victor's avatar
Victor committed
73
    if Dim > 1
74
        return D .* randn(T,Dim)
Victor's avatar
Victor committed
75
    else
76
        return D * randn(T)
Victor's avatar
Victor committed
77
    end
Victor's avatar
Victor committed
78
end
79

Victor's avatar
Victor committed
80
function get_inc(D,s::AbstractSpace{Dim,T,I}) where {Dim,T<:Integer,I<:IsFinite{false}}
Victor's avatar
Victor committed
81
    if Dim > 1
82
        return round.(T,D .*randn(Float32,Dim))
Victor's avatar
Victor committed
83
84
85
86
87
    else
        return round(D * randn(Float32))
    end
end

88
#TODO: there is probably a better way of dealing with those two functions
Victor's avatar
Victor committed
89
function get_inc(x,D,s::ContinuousSegment{T}) where {T}
90
    inc = D * randn(T)
Victor's avatar
Victor committed
91
    return _reflect1D(x,inc,s)
Victor's avatar
Victor committed
92
93
94
end

function get_inc(x,D,s::DiscreteSegment{T}) where {T}
95
    inc = D * randn()
Victor's avatar
Victor committed
96
    return round(T,_reflect1D(x,inc,s))
Victor's avatar
Victor committed
97
98
end

99
# normal dispersal kernel that gets truncated
Victor's avatar
Victor committed
100
function get_inc(x,D,s::GraphSpace{T}) where {T}
101
102
    niter = round(Int,abs(D*randn())) + 1
    # here we add +1 since randomwalk(s.g,x,niter) returns x
Victor's avatar
Victor committed
103
104
105
106
107
    if niter > 0
        return last(randomwalk(s.g,x,niter)) - x
    else
        return 0
    end
Victor's avatar
Victor committed
108
end
109
110
111
112
# short range dispersal kernel, jump to neighbour node
function get_inc(x,D,s::GraphSpace{T}) where {T}
    return last(randomwalk(s.g,x,2)) - x
end
Victor's avatar
Victor committed
113

Victor's avatar
Victor committed
114
115
116
117
118
## Dynamic spaces
abstract type AbstractDynSpace{Dim,T<:Number} <: AbstractSpace{Dim,T,IsFinite{true}} end
"""
$(TYPEDEF)
A dynamic graph space.
Victor's avatar
Victor committed
119
120
121

# Example
`DynGraphSpace(g,f)`
Victor's avatar
Victor committed
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
Function `f(t)` takes as argument time, and returns the index of the graph to pick at time `t` from array `g`
"""
struct DynGraphSpace{T<:Number} <: AbstractDynSpace{1,T}
    g::Vector{AbstractGraph{T}}
    f #update function
end
# This is surely not elegant, but we have not found an other way to do it yet
function DynGraphSpace(g::Array{A},f) where A <: AbstractGraph
     DynGraphSpace{eltype(g[1])}(g,f)
 end

"""
$SIGNATURES
Returns the graph correseponding to `d::DynGraphSpace` at time `t`
"""
get_graph(d::DynGraphSpace,t) = d.g[d.f(t)]


140
141
142
## Increments - specialised functions for dynamic graphs
# normal dispersal kernel that gets truncated
function get_inc(x,D::Number,d::DynGraphSpace{T},t) where {T}
Victor's avatar
Victor committed
143
144
145
146
147
148
149
150
151
    niter = round(Int,abs(D*randn())) + 1
    # here we add +1 since randomwalk(s.g,x,niter) returns x
    if niter > 0
        return last(randomwalk(get_graph(d,t),x,niter)) - x
    else
        return 0
    end
end

152
153
154
155
156
# short range dispersal kernel, jump to neighbour node
function get_inc(x,D::Nothing,d::DynGraphSpace{T},t) where {T}
    return last(randomwalk(get_graph(d,t),x,2)) - x
end

Victor's avatar
Victor committed
157
"""
Victor's avatar
Victor committed
158
159
$(SIGNATURES)
Here we increment the trajectory of trait 1 such that it follows a reflected brownian motion (1D)
Victor's avatar
Victor committed
160
"""
Victor's avatar
Victor committed
161
162
function _reflect1D(x::Number,inc::Number,s::AbstractSegment)
    if x + inc < s.s
Victor's avatar
Victor committed
163
        inc = 2 * ( s.s - x ) - inc
Victor's avatar
Victor committed
164
    elseif  x + inc > s.e
Victor's avatar
Victor committed
165
        inc = 2 * ( s.e - x ) - inc
Victor's avatar
Victor committed
166
167
168
    else
        return inc
    end
Victor's avatar
Victor committed
169
    _reflect1D(x,inc,s)
Victor's avatar
Victor committed
170
end