@@ -27,23 +27,23 @@ cells contain proteins whose concentrations are modeled as simply a vector
27
27
of numbers (it can be anything linearly indexable).
28
28
29
29
``` julia
30
- immutable Cell{B} <: AbstractMultiScaleArrayLeaf{B}
31
- x :: Vector{B}
30
+ struct Cell{B} <: AbstractMultiScaleArrayLeaf{B}
31
+ values :: Vector{B}
32
32
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}
37
37
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}
42
42
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}
47
47
end
48
48
```
49
49
@@ -55,22 +55,22 @@ version is the following:
55
55
Let's build a version of this. Using the constructors we can directly construct leaf types:
56
56
57
57
``` 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 ])
60
60
```
61
61
62
62
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
64
64
taken to be empty.
65
65
66
66
``` 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
74
74
```
75
75
76
76
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
108
108
` d_embryo ` via:
109
109
110
110
``` 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])
113
113
end
114
114
```
115
115
@@ -123,9 +123,9 @@ passed to the event handling. MultiScaleArrays includes behavior for changing th
123
123
structure. For example:
124
124
125
125
``` 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
129
129
```
130
130
131
131
Combined with event handling, this allows for dynamic structures to be derived from
@@ -153,38 +153,38 @@ techniques for each new model.
153
153
154
154
The required interface is as follows. Leaf types must extend AbstractMultiScaleArrayLeaf, the
155
155
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}` .
157
157
Each type above then contains three fields:
158
158
159
- - ` x ::Vector{T}`
160
- - ` y ::Vector{B}`
159
+ - ` nodes ::Vector{T}`
160
+ - ` values ::Vector{B}`
161
161
- `end_idxs::Vector{Int}``
162
162
163
163
` B ` is the ` BottomType ` , which has to be the same as the eltype for the array
164
164
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 ` ).
167
167
You can add and use extra fields as you please, and even make the types immutable.
168
168
169
169
## The MultiScaleModel API
170
170
171
171
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 `
174
174
are its "intrinsic values". There is an indexing scheme on ` ln ` , where:
175
175
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 `
177
177
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.
180
180
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.
183
183
184
184
In addition, iterators are provided to make it easy to iterate through levels.
185
185
For ` h ` being the head node, ` level_iter(h,n) ` iterates through all level objects
186
186
` 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
188
188
the values it holds in the linear indexing.
189
189
190
190
### Extensions
@@ -194,50 +194,50 @@ extended as one pleases. For example, we can change the definition of the cell
194
194
to have:
195
195
196
196
``` 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
200
200
end
201
201
```
202
202
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
204
204
give it a cell type. This information is part of the call, so
205
205
206
206
``` 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])
209
209
end
210
210
```
211
211
212
212
can allow one to check the ` cell.celltype ` in ` f ` an apply a different ODE depending
213
213
on the cell type. You can add fields however you want, so you can use them
214
214
to name cells and track lineages.
215
215
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
217
217
of 3 values:
218
218
219
219
``` 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 ])
221
221
```
222
222
223
- We can selectively apply some function on these ` y ` values via:
223
+ We can selectively apply some function on these ` values ` via:
224
224
225
225
``` 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])
228
228
end
229
229
```
230
230
231
- and mutatate ` tis.y ` in ` f ` . For example, we could have
231
+ and mutate ` tis.values ` in ` f ` . For example, we could have
232
232
233
233
``` julia
234
- function f (t,tissue:: Tissue ,du)
235
- du .+ = randn (3 )
234
+ function f (t, tissue:: Tissue , du)
235
+ du .+ = randn (3 )
236
236
end
237
237
```
238
238
239
239
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
241
241
adding Brownian motion.
242
242
243
243
Of course, you can keep going and kind of do whatever you want. The power is yours!
0 commit comments