@@ -79,7 +79,7 @@ function node_densities(cell_positions::AbstractVector{T}; smooth_boundary=true)
79
79
end
80
80
81
81
"""
82
- get_knots(sol, num_knots = 500; indices = eachindex(sol), stat=maximum)
82
+ get_knots(sol, num_knots = 500; indices = eachindex(sol), stat=maximum, parallel=false )
83
83
84
84
Computes knots for each time, covering the extremum of the cell positions across all
85
85
cell simulations. You can restrict the simultaions to consider using the `indices`.
@@ -88,7 +88,7 @@ to the vector of extrema at each time. For example, if `stat=maximum` then, at e
88
88
the knots range between the smallest position observed and the maximum position
89
89
observed across each simulation at that time.
90
90
"""
91
- function get_knots (sol:: EnsembleSolution , num_knots= 500 ; indices= eachindex (sol), stat= (minimum, maximum))
91
+ function get_knots (sol:: EnsembleSolution , num_knots= 500 ; indices= eachindex (sol), stat= (minimum, maximum), parallel = false )
92
92
if stat isa Function
93
93
stat = (stat, stat)
94
94
end
@@ -98,15 +98,27 @@ function get_knots(sol::EnsembleSolution, num_knots=500; indices=eachindex(sol),
98
98
knots = Vector {LinRange{Float64,Int}} (undef, length (first (sol)))
99
99
end
100
100
times = first (sol). t
101
- Base. Threads. @threads for i in eachindex (times)
102
- local a, b
103
- a = zeros (length (indices))
104
- b = zeros (length (indices))
105
- for (ℓ, j) in enumerate (indices)
106
- a[ℓ] = sol[j]. u[i][begin ]
107
- b[ℓ] = sol[j]. u[i][end ]
101
+ if parallel
102
+ Base. Threads. @threads for i in eachindex (times)
103
+ local a, b
104
+ a = zeros (length (indices))
105
+ b = zeros (length (indices))
106
+ for (ℓ, j) in enumerate (indices)
107
+ a[ℓ] = sol[j]. u[i][begin ]
108
+ b[ℓ] = sol[j]. u[i][end ]
109
+ end
110
+ knots[i] = LinRange (stat[1 ](a), stat[2 ](b), num_knots)
111
+ end
112
+ else
113
+ for i in eachindex (times)
114
+ a = zeros (length (indices))
115
+ b = zeros (length (indices))
116
+ for (ℓ, j) in enumerate (indices)
117
+ a[ℓ] = sol[j]. u[i][begin ]
118
+ b[ℓ] = sol[j]. u[i][end ]
119
+ end
120
+ knots[i] = LinRange (stat[1 ](a), stat[2 ](b), num_knots)
108
121
end
109
- knots[i] = LinRange (stat[1 ](a), stat[2 ](b), num_knots)
110
122
end
111
123
return knots
112
124
end
@@ -137,7 +149,8 @@ negative values are set to zero.
137
149
- `indices = eachindex(sol)`: The indices of the cell simulations to consider.
138
150
- `num_knots::Int = 500`: The number of knots to use for the spline interpolation.
139
151
- `stat = (minimum, maximum)`: How to summarise the knots for `get_knots`.
140
- - `knots::Vector{Vector{Float64}} = get_knots(sol, num_knots; indices, stat)`: The knots to use for the spline interpolation.
152
+ - `parallel = false`: Whether to use multithreading for the loops.
153
+ - `knots::Vector{Vector{Float64}} = get_knots(sol, num_knots; indices, stat, parallel)`: The knots to use for the spline interpolation.
141
154
- `alpha::Float64 = 0.05`: The significance level for the confidence intervals.
142
155
- `interp_fnc = (u, t) -> LinearInterpolation{true}(u, t)`: The function to use for constructing the interpolant.
143
156
- `smooth_boundary::Bool = true`: Whether to use the smooth boundary node densities.
@@ -155,44 +168,81 @@ function node_densities(sol::EnsembleSolution;
155
168
indices= eachindex (sol),
156
169
num_knots= 500 ,
157
170
stat= (minimum, maximum),
171
+ parallel= false ,
158
172
knots= get_knots (sol, num_knots; indices, stat),
159
173
alpha= 0.05 ,
160
174
interp_fnc= (u, t) -> LinearInterpolation {true} (u, t),
161
175
smooth_boundary= true ,
162
176
extrapolate= false )
163
177
q = Vector {Vector{Vector{Float64}}} (undef, length (indices))
164
178
r = Vector {Vector{Vector{Float64}}} (undef, length (indices))
165
- Base. Threads. @threads for i in eachindex (indices)
166
- q[i] = node_densities .(sol[indices[i]]. u; smooth_boundary)
167
- r[i] = sol[indices[i]]. u
179
+ if parallel
180
+ Base. Threads. @threads for i in eachindex (indices)
181
+ q[i] = node_densities .(sol[indices[i]]. u; smooth_boundary)
182
+ r[i] = sol[indices[i]]. u
183
+ end
184
+ else
185
+ for i in eachindex (indices)
186
+ q[i] = node_densities .(sol[indices[i]]. u; smooth_boundary)
187
+ r[i] = sol[indices[i]]. u
188
+ end
168
189
end
169
190
nt = length (first (sol))
170
191
nsims = length (indices)
171
192
q_splines = zeros (num_knots, nt, nsims)
172
193
q_means = [zeros (num_knots) for _ in 1 : nt]
173
194
q_lowers = [zeros (num_knots) for _ in 1 : nt]
174
195
q_uppers = [zeros (num_knots) for _ in 1 : nt]
175
- Base. Threads. @threads for k in 1 : nsims
176
- for j in 1 : nt
177
- densities = q[k][j]
178
- cell_positions = r[k][j]
179
- interp = interp_fnc (densities, cell_positions)
180
- for i in eachindex (knots[j])
181
- if ! extrapolate && knots[j][i] > r[k][j][end ]
182
- q_splines[i, j, k] = 0.0
183
- else
184
- q_splines[i, j, k] = max (0.0 , interp (knots[j][i]))
196
+ if parallel
197
+ Base. Threads. @threads for k in 1 : nsims
198
+ for j in 1 : nt
199
+ densities = q[k][j]
200
+ cell_positions = r[k][j]
201
+ interp = interp_fnc (densities, cell_positions)
202
+ for i in eachindex (knots[j])
203
+ if ! extrapolate && knots[j][i] > r[k][j][end ]
204
+ q_splines[i, j, k] = 0.0
205
+ else
206
+ q_splines[i, j, k] = max (0.0 , interp (knots[j][i]))
207
+ end
208
+ end
209
+ end
210
+ end
211
+ else
212
+ for k in 1 : nsims
213
+ for j in 1 : nt
214
+ densities = q[k][j]
215
+ cell_positions = r[k][j]
216
+ interp = interp_fnc (densities, cell_positions)
217
+ for i in eachindex (knots[j])
218
+ if ! extrapolate && knots[j][i] > r[k][j][end ]
219
+ q_splines[i, j, k] = 0.0
220
+ else
221
+ q_splines[i, j, k] = max (0.0 , interp (knots[j][i]))
222
+ end
185
223
end
186
224
end
187
225
end
188
226
end
189
- Base. Threads. @threads for j in 1 : nt
190
- knot_range = knots[j]
191
- for i in eachindex (knot_range)
192
- q_values = @views q_splines[i, j, :]
193
- q_means[j][i] = mean (q_values)
194
- q_lowers[j][i] = quantile (q_values, alpha / 2 )
195
- q_uppers[j][i] = quantile (q_values, 1 - alpha / 2 )
227
+ if parallel
228
+ Base. Threads. @threads for j in 1 : nt
229
+ knot_range = knots[j]
230
+ for i in eachindex (knot_range)
231
+ q_values = @views q_splines[i, j, :]
232
+ q_means[j][i] = mean (q_values)
233
+ q_lowers[j][i] = quantile (q_values, alpha / 2 )
234
+ q_uppers[j][i] = quantile (q_values, 1 - alpha / 2 )
235
+ end
236
+ end
237
+ else
238
+ for j in 1 : nt
239
+ knot_range = knots[j]
240
+ for i in eachindex (knot_range)
241
+ q_values = @views q_splines[i, j, :]
242
+ q_means[j][i] = mean (q_values)
243
+ q_lowers[j][i] = quantile (q_values, alpha / 2 )
244
+ q_uppers[j][i] = quantile (q_values, 1 - alpha / 2 )
245
+ end
196
246
end
197
247
end
198
248
return (q= q, r= r, means= q_means, lowers= q_lowers, uppers= q_uppers, knots= knots)
0 commit comments