Skip to content

Commit 4d60ba7

Browse files
Merge pull request #20 from ScottPJones/spj/node
Additional renaming, use node(s) instead of daughter(s), fix REQUIRE & README.md
2 parents cdfa7d2 + 8f0c5b5 commit 4d60ba7

10 files changed

+299
-287
lines changed

README.md

Lines changed: 57 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -27,23 +27,23 @@ cells contain proteins whose concentrations are modeled as simply a vector
2727
of numbers (it can be anything linearly indexable).
2828

2929
```julia
30-
immutable Cell{B} <: AbstractMultiScaleArrayLeaf{B}
31-
x::Vector{B}
30+
struct Cell{B} <: AbstractMultiScaleArrayLeaf{B}
31+
values::Vector{B}
3232
end
33-
immutable Population{T<:AbstractMultiScaleArray,B<:Number} <: AbstractMultiScaleArray{B}
34-
x::Vector{T}
35-
y::Vector{B}
36-
end_idxs::Vector{Int}
33+
struct Population{T<:AbstractMultiScaleArray,B<:Number} <: AbstractMultiScaleArray{B}
34+
nodes::Vector{T}
35+
values::Vector{B}
36+
end_idxs::Vector{Int}
3737
end
38-
immutable Tissue{T<:AbstractMultiScaleArray,B<:Number} <: AbstractMultiScaleArray{B}
39-
x::Vector{T}
40-
y::Vector{B}
41-
end_idxs::Vector{Int}
38+
struct Tissue{T<:AbstractMultiScaleArray,B<:Number} <: AbstractMultiScaleArray{B}
39+
nodes::Vector{T}
40+
values::Vector{B}
41+
end_idxs::Vector{Int}
4242
end
43-
immutable Embryo{T<:AbstractMultiScaleArray,B<:Number} <: AbstractMultiScaleArrayHead{B}
44-
x::Vector{T}
45-
y::Vector{B}
46-
end_idxs::Vector{Int}
43+
struct Embryo{T<:AbstractMultiScaleArray,B<:Number} <: AbstractMultiScaleArrayHead{B}
44+
nodes::Vector{T}
45+
values::Vector{B}
46+
end_idxs::Vector{Int}
4747
end
4848
```
4949

@@ -55,22 +55,22 @@ version is the following:
5555
Let's build a version of this. Using the constructors we can directly construct leaf types:
5656

5757
```julia
58-
cell1 = Cell([1.0;2.0;3.0])
59-
cell2 = Cell([4.0;5])
58+
cell1 = Cell([1.0; 2.0; 3.0])
59+
cell2 = Cell([4.0; 5.0])
6060
```
6161

6262
and build types higher up in the hierarchy by using the `constuct` method. The method
63-
is `construct(T::AbstractMultiScaleArray,x,y)`, though if `y` is not given it's
63+
is `construct(T::AbstractMultiScaleArray, nodes, values)`, though if `values` is not given it's
6464
taken to be empty.
6565

6666
```julia
67-
population = construct(Population,deepcopy([cell1,cell2])) # Make a Population from cells
68-
cell3 = Cell([3.0;2.0;5.0])
69-
cell4 = Cell([4.0;6])
70-
population2 = construct(Population,deepcopy([cell3,cell4]))
71-
tissue1 = construct(Tissue,deepcopy([population,population2])) # Make a Tissue from Populations
72-
tissue2 = construct(Tissue,deepcopy([population2,population]))
73-
embryo = construct(Embryo,deepcopy([tissue1,tissue2])) # Make an embryo from Tissues
67+
population = construct(Population, deepcopy([cell1, cell2])) # Make a Population from cells
68+
cell3 = Cell([3.0; 2.0; 5.0])
69+
cell4 = Cell([4.0; 6.0])
70+
population2 = construct(Population, deepcopy([cell3, cell4]))
71+
tissue1 = construct(Tissue, deepcopy([population, population2])) # Make a Tissue from Populations
72+
tissue2 = construct(Tissue, deepcopy([population2, population]))
73+
embryo = construct(Embryo, deepcopy([tissue1, tissue2])) # Make an embryo from Tissues
7474
```
7575

7676
The head node then acts as the king. It is designed to have functionality which
@@ -108,8 +108,8 @@ level. Using `level_iter_idx`, we can have its changes update some other head no
108108
`d_embryo` via:
109109

110110
```julia
111-
for (cell,y,z) in LevelIterIdx(embryo,2)
112-
f(t,cell,@view d_embryo[y:z])
111+
for (cell, y, z) in LevelIterIdx(embryo, 2)
112+
f(t, cell, @view d_embryo[y:z])
113113
end
114114
```
115115

@@ -123,9 +123,9 @@ passed to the event handling. MultiScaleArrays includes behavior for changing th
123123
structure. For example:
124124

125125
```julia
126-
tissue3 = construct(Tissue,deepcopy([population;population2]))
127-
add_daughter!(embryo,tissue3) # Adds a new tissue to the embryo
128-
remove_daughter!(embryo,2,1) # Removes population 1 from tissue 2 of the embryo
126+
tissue3 = construct(Tissue, deepcopy([population; population2]))
127+
add_node!(embryo, tissue3) # Adds a new tissue to the embryo
128+
remove_node!(embryo, 2, 1) # Removes population 1 from tissue 2 of the embryo
129129
```
130130

131131
Combined with event handling, this allows for dynamic structures to be derived from
@@ -153,38 +153,38 @@ techniques for each new model.
153153

154154
The required interface is as follows. Leaf types must extend AbstractMultiScaleArrayLeaf, the
155155
highest level of the model or the head extends MultiScaleModelHead, and all
156-
intermediate types extend AbstractMultiScaleArray. The leaf has an array `x::Vector{B}`.
156+
intermediate types extend AbstractMultiScaleArray. The leaf has an array `values::Vector{B}`.
157157
Each type above then contains three fields:
158158

159-
- `x::Vector{T}`
160-
- `y::Vector{B}`
159+
- `nodes::Vector{T}`
160+
- `values::Vector{B}`
161161
- `end_idxs::Vector{Int}``
162162

163163
`B` is the `BottomType`, which has to be the same as the eltype for the array
164164
in the leaf types. `T` is another `AbstractMultiScaleArray`. Thus at each level,
165-
an` AbstractMultiScaleArray` contains some information of its own (`y`), the
166-
next level down in the heirarchy (`x`), and caching for indices (`end_idxs`).
165+
an` AbstractMultiScaleArray` contains some information of its own (`values`), the
166+
next level down in the heirarchy (`nodes`), and caching for indices (`end_idxs`).
167167
You can add and use extra fields as you please, and even make the types immutable.
168168

169169
## The MultiScaleModel API
170170

171171
The resulting type acts as an array. A leaf type `l` acts exactly as an array
172-
with `l[i]==l.x[i]`. Higher nodes also act as a linear array. If `ln` is level
173-
`n` in the heirarchy, then `ln.x` is the vector of level `n-1` objects, and `ln.y`
172+
with `l[i] == l.values[i]`. Higher nodes also act as a linear array. If `ln` is level
173+
`n` in the heirarchy, then `ln.nodes` is the vector of level `n-1` objects, and `ln.values`
174174
are its "intrinsic values". There is an indexing scheme on `ln`, where:
175175

176-
- `ln[i,j,k]` gets the `k`th `n-3` obejct in the `j`th `n-2` object in the `i`th level `n-1`
176+
- `ln[i,j,k]` gets the `k`th `n-3` object in the `j`th `n-2` object in the `i`th level `n-1`
177177
object. Of course, this recurses for the whole hierarchy.
178-
- `ln[i]` provides a linear index through all `.x` and `.y` values in every lower
179-
level and `ln.y` itself.
178+
- `ln[i]` provides a linear index through all `.nodes` and `.values` values in every lower
179+
level and `ln.values` itself.
180180

181-
Thus `typeof(ln) <: AbstarctArray{B,1}` where `B` is the eltype of its leaves and
182-
all `.y`'s.
181+
Thus `typeof(ln) <: AbstractVector{B}` where `B` is the eltype of its leaves and
182+
all `.values`'s.
183183

184184
In addition, iterators are provided to make it easy to iterate through levels.
185185
For `h` being the head node, `level_iter(h,n)` iterates through all level objects
186186
`n` levels down from the top, while `level_iter_idx(h,n)` is an enumeration
187-
`(x,y,z)` where `x` are the `n`th from the head objects, with `h[y:z]` being
187+
`(node,y,z)` where `node` are the `n`th from the head objects, with `h[y:z]` being
188188
the values it holds in the linear indexing.
189189

190190
### Extensions
@@ -194,50 +194,50 @@ extended as one pleases. For example, we can change the definition of the cell
194194
to have:
195195

196196
```julia
197-
immutable Cell{B} <: AbstractMultiScaleArrayLeaf{B}
198-
x::Vector{B}
199-
celltype::Symbol
197+
struct Cell{B} <: AbstractMultiScaleArrayLeaf{B}
198+
values::Vector{B}
199+
celltype::Symbol
200200
end
201201
```
202202

203-
Then we'd construct cells with `cell3 = Cell([3.0;2.0;5.0],:BCell)`, and can
203+
Then we'd construct cells with `cell3 = Cell([3.0; 2.0; 5.0], :BCell)`, and can
204204
give it a cell type. This information is part of the call, so
205205

206206
```julia
207-
for (cell,y,z) in level_iter_idx(embryo,2)
208-
f(t,cell,@view embryo[y:z])
207+
for (cell, y, z) in level_iter_idx(embryo, 2)
208+
f(t, cell, @view embryo[y:z])
209209
end
210210
```
211211

212212
can allow one to check the `cell.celltype` in `f` an apply a different ODE depending
213213
on the cell type. You can add fields however you want, so you can use them
214214
to name cells and track lineages.
215215

216-
Showing the use of `y`, you just pass it to the constructor. Let's pass it an array
216+
Showing the use of `values`, you just pass it to the constructor. Let's pass it an array
217217
of 3 values:
218218

219219
```julia
220-
tissue = construct(Tissue,deepcopy([population;population2]),[0.0;0.0;0.0])
220+
tissue = construct(Tissue, deepcopy([population; population2]), [0.0; 0.0; 0.0])
221221
```
222222

223-
We can selectively apply some function on these `y` values via:
223+
We can selectively apply some function on these `values` via:
224224

225225
```julia
226-
for (tissue,y,z) in level_iter_idx(embryo,1)
227-
f(t,tissue,@view embryo[y:z])
226+
for (tissue, y, z) in level_iter_idx(embryo, 1)
227+
f(t, tissue, @view embryo[y:z])
228228
end
229229
```
230230

231-
and mutatate `tis.y` in `f`. For example, we could have
231+
and mutate `tis.values` in `f`. For example, we could have
232232

233233
```julia
234-
function f(t,tissue::Tissue,du)
235-
du .+= randn(3)
234+
function f(t, tissue::Tissue, du)
235+
du .+= randn(3)
236236
end
237237
```
238238

239239
applies normal random numbers to the three values. We could use this to add to the
240-
model the fact that `tissue.y[1:3]` are the tissue's position, and `f` would then be
240+
model the fact that `tissue.values[1:3]` are the tissue's position, and `f` would then be
241241
adding Brownian motion.
242242

243243
Of course, you can keep going and kind of do whatever you want. The power is yours!

REQUIRE

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
julia 0.5
1+
julia 0.6
22
RecursiveArrayTools 0.8.0
33
DiffEqBase 0.11.0
4-
Compat 0.19.0
4+

src/MultiScaleArrays.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ export AbstractMultiScaleArray, AbstractMultiScaleArrayLeaf,
3434
export construct, recursivecopy!
3535

3636
# Addition Deletion
37-
export add_daughter!, remove_daughter!
37+
export add_node!, remove_node!
3838

3939
# Indexing
40-
export num_daughters, getindices
40+
export num_nodes, getindices
4141

4242
# Misc
4343
export LevelIterIdx, level_iter

src/addition_deletion.jl

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,55 @@
1-
function __add_daughter!(m::AbstractMultiScaleArray, nodes::AbstractMultiScaleArray)
2-
push!(m.end_idxs, m.end_idxs[end] + length(nodes) + length(m.values))
3-
push!(m.nodes, nodes)
1+
function __add_node!(m::AbstractMultiScaleArray, node::AbstractMultiScaleArray)
2+
push!(m.end_idxs, m.end_idxs[end] + length(node) + length(m.values))
3+
push!(m.nodes, node)
44
nothing
55
end
66

77
function __update_lengths(m::AbstractMultiScaleArray, beg, len)
8-
for j = beg:num_daughters(m)
8+
for j = beg:num_nodes(m)
99
m.end_idxs[j] += len
1010
end
1111
isempty(m.values) || (m.end_idxs[end] += len)
1212
nothing
1313
end
1414

15-
function __add_daughter!(m::AbstractMultiScaleArray, nodes::AbstractMultiScaleArray, i::Int)
16-
__add_daughter!(m.nodes[i], nodes)
17-
__update_lengths(m, i, length(nodes))
15+
function __add_node!(m::AbstractMultiScaleArray, node::AbstractMultiScaleArray, i::Int)
16+
__add_node!(m.nodes[i], node)
17+
__update_lengths(m, i, length(node))
1818
end
1919

20-
function __add_daughter!(m::AbstractMultiScaleArray, nodes::AbstractMultiScaleArray, i, I::Int...)
21-
__add_daughter!(m.nodes[i], nodes, I...)
22-
__update_lengths(m, i, length(nodes))
20+
function __add_node!(m::AbstractMultiScaleArray, node::AbstractMultiScaleArray, i, I::Int...)
21+
__add_node!(m.nodes[i], node, I...)
22+
__update_lengths(m, i, length(node))
2323
end
2424

25-
add_daughter!(m::AbstractMultiScaleArrayHead, nodes::AbstractMultiScaleArray) =
26-
__add_daughter!(m, nodes)
25+
add_node!(m::AbstractMultiScaleArrayHead, node::AbstractMultiScaleArray) =
26+
__add_node!(m, node)
2727

28-
add_daughter!(m::AbstractMultiScaleArrayHead, nodes::AbstractMultiScaleArray, i::Int) =
29-
__add_daughter!(m, nodes, i)
28+
add_node!(m::AbstractMultiScaleArrayHead, node::AbstractMultiScaleArray, i::Int) =
29+
__add_node!(m, node, i)
3030

31-
add_daughter!(m::AbstractMultiScaleArrayHead, nodes::AbstractMultiScaleArray, i, I::Int...) =
32-
__add_daughter!(m, nodes, i, I...)
31+
add_node!(m::AbstractMultiScaleArrayHead, node::AbstractMultiScaleArray, i, I::Int...) =
32+
__add_node!(m, node, i, I...)
3333

34-
function __remove_daughter!(m::AbstractMultiScaleArray, i::Int)
34+
function __remove_node!(m::AbstractMultiScaleArray, i::Int)
3535
del_length = length(m.nodes[i])
3636
deleteat!(m.nodes, i)
3737
deleteat!(m.end_idxs, i)
38-
for j = i:num_daughters(m)
38+
for j = i:num_nodes(m)
3939
m.end_idxs[j] -= del_length
4040
end
4141
isempty(m.values) || (m.end_idxs[end] -= del_length)
4242
del_length
4343
end
4444

45-
function __remove_daughter!(m::AbstractMultiScaleArrayLeaf, i::Int)
45+
function __remove_node!(m::AbstractMultiScaleArrayLeaf, i::Int)
4646
deleteat!(m.nodes, i)
4747
1
4848
end
4949

50-
function remove_daughter!(m::AbstractMultiScaleArrayHead, i, I::Int...)
51-
del_length = __remove_daughter!(m.nodes[i], I...)
52-
for j = i:num_daughters(m)
50+
function remove_node!(m::AbstractMultiScaleArrayHead, i, I::Int...)
51+
del_length = __remove_node!(m.nodes[i], I...)
52+
for j = i:num_nodes(m)
5353
m.end_idxs[j] -= del_length
5454
end
5555
isempty(m.values) || (m.end_idxs[end] -= del_length)
@@ -60,15 +60,15 @@ function remove_daughter!(m::AbstractMultiScaleArrayHead, i, I::Int...)
6060
nothing
6161
end
6262

63-
function __remove_daughter!(m::AbstractMultiScaleArray, i, I::Int...)
64-
del_length = __remove_daughter!(m.nodes[i], I...)
65-
for j = i:num_daughters(m)
63+
function __remove_node!(m::AbstractMultiScaleArray, i, I::Int...)
64+
del_length = __remove_node!(m.nodes[i], I...)
65+
for j = i:num_nodes(m)
6666
m.end_idxs[j] -= del_length
6767
end
6868
isempty(m.values) || (m.end_idxs[end] -= del_length)
6969
isempty(m.nodes[i]) && deleteat!(m.nodes, i)
7070
del_length
7171
end
7272

73-
remove_daughter!(m::AbstractMultiScaleArrayHead, i::Int) =
74-
(__remove_daughter!(m, i); nothing)
73+
remove_node!(m::AbstractMultiScaleArrayHead, i::Int) =
74+
(__remove_node!(m, i); nothing)

src/diffeq.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
function remove_daughter!(integrator::DEIntegrator, I...)
1+
function remove_node!(integrator::DEIntegrator, I...)
22
idxs = getindices(integrator.u, I...)
33
for c in user_cache(integrator)
4-
remove_daughter!(c, I...)
4+
remove_node!(c, I...)
55
end
66
deleteat_non_user_cache!(integrator, idxs)
77
end
88

9-
function add_daughter!(integrator::DEIntegrator, x, I...)
9+
function add_node!(integrator::DEIntegrator, x, I...)
1010
cur_len = length(integrator.u)
1111
add_len = length(x)
1212
for c in user_cache(integrator)
13-
add_daughter!(c, similar(x, eltype(c)), I...)
13+
add_node!(c, similar(x, eltype(c)), I...)
1414
end
1515
last_idx = length(integrator.u[I...].nodes)
1616
idxs = getindices(integrator.u, I..., last_idx)

0 commit comments

Comments
 (0)