@@ -18,13 +18,14 @@ mutable struct IndependentlyLinearizedSolutionChunks{T, S}
18
18
u_offsets:: Vector{Int}
19
19
t_offset:: Int
20
20
21
- function IndependentlyLinearizedSolutionChunks {T, S} (num_us:: Int , num_derivatives:: Int = 0 ,
21
+ function IndependentlyLinearizedSolutionChunks {T, S} (
22
+ num_us:: Int , num_derivatives:: Int = 0 ,
22
23
chunk_size:: Int = 100 ) where {T, S}
23
24
return new ([Vector {T} (undef, chunk_size)],
24
- [[Matrix {S} (undef, num_derivatives+ 1 , chunk_size)] for _ in 1 : num_us],
25
+ [[Matrix {S} (undef, num_derivatives + 1 , chunk_size)] for _ in 1 : num_us],
25
26
[BitMatrix (undef, num_us, chunk_size)],
26
27
[1 for _ in 1 : num_us],
27
- 1 ,
28
+ 1
28
29
)
29
30
end
30
31
end
@@ -69,7 +70,7 @@ function get_chunks(ilsc::IndependentlyLinearizedSolutionChunks{T, S}) where {T,
69
70
# Check if we need to allocate any new `u` chunks (but only for those with `u_mask`)
70
71
for (u_idx, u_chunks) in enumerate (ilsc. u_chunks)
71
72
if ilsc. u_offsets[u_idx] > chunksize
72
- push! (u_chunks, Matrix {S} (undef, num_derivatives (ilsc)+ 1 , chunksize))
73
+ push! (u_chunks, Matrix {S} (undef, num_derivatives (ilsc) + 1 , chunksize))
73
74
ilsc. u_offsets[u_idx] = 1
74
75
end
75
76
end
@@ -78,7 +79,7 @@ function get_chunks(ilsc::IndependentlyLinearizedSolutionChunks{T, S}) where {T,
78
79
return (
79
80
ilsc. t_chunks[end ],
80
81
ilsc. time_masks[end ],
81
- [u_chunks[end ] for u_chunks in ilsc. u_chunks],
82
+ [u_chunks[end ] for u_chunks in ilsc. u_chunks]
82
83
)
83
84
end
84
85
@@ -91,24 +92,25 @@ function get_prev_t(ilsc::IndependentlyLinearizedSolutionChunks)
91
92
return - Inf
92
93
end
93
94
# Otherwise, return the last element of the previous chunk
94
- return ilsc. t_chunks[end - 1 ][end ]
95
+ return ilsc. t_chunks[end - 1 ][end ]
95
96
end
96
97
# Otherwise return the previous element of the current chunk
97
- return ilsc. t_chunks[end ][ilsc. t_offset- 1 ]
98
+ return ilsc. t_chunks[end ][ilsc. t_offset - 1 ]
98
99
end
99
100
100
- function get_prev_u (ilsc:: IndependentlyLinearizedSolutionChunks{T,S} , u_out:: Vector{S} ) where {T,S}
101
+ function get_prev_u (
102
+ ilsc:: IndependentlyLinearizedSolutionChunks{T, S} , u_out:: Vector{S} ) where {T, S}
101
103
for u_idx in 1 : length (ilsc. u_offsets)
102
104
if ilsc. u_offsets[u_idx] == 1
103
105
if length (ilsc. u_chunks[u_idx]) == 1
104
106
# If we have never stored anything for this `u`, just return `0.0`
105
107
u_out[u_idx] = S (0 )
106
108
end
107
109
# Otherwise, get the last element of the previous chunk
108
- u_out[u_idx] = ilsc. u_chunks[u_idx][end - 1 ][end ]
110
+ u_out[u_idx] = ilsc. u_chunks[u_idx][end - 1 ][end ]
109
111
else
110
112
# Otherwise, return the previous element of the current chunk
111
- u_out[u_idx] = ilsc. u_chunks[u_idx][end ][ilsc. u_offsets[u_idx]- 1 ]
113
+ u_out[u_idx] = ilsc. u_chunks[u_idx][end ][ilsc. u_offsets[u_idx] - 1 ]
112
114
end
113
115
end
114
116
return u_out
@@ -122,9 +124,9 @@ but only the values identified by the given `u_mask`. The `us` matrix
122
124
should be of the size `(num_us(ilsc), num_derivatives(ilsc))`.
123
125
"""
124
126
function store! (ilsc:: IndependentlyLinearizedSolutionChunks{T, S} ,
125
- t:: T ,
126
- u:: AbstractMatrix{S} ,
127
- u_mask:: BitVector ) where {T, S}
127
+ t:: T ,
128
+ u:: AbstractMatrix{S} ,
129
+ u_mask:: BitVector ) where {T, S}
128
130
# If `t` has been stored before, drop it.
129
131
# We don't store duplicate timepoints, even though the solver sometimes does.
130
132
if get_prev_t (ilsc) == t
@@ -148,8 +150,6 @@ function store!(ilsc::IndependentlyLinearizedSolutionChunks{T, S},
148
150
ilsc. t_offset += 1
149
151
end
150
152
151
-
152
-
153
153
"""
154
154
IndependentlyLinearizedSolution
155
155
@@ -171,35 +171,39 @@ mutable struct IndependentlyLinearizedSolution{T, S}
171
171
172
172
# Bitmatrix denoting which time indices are used for which us.
173
173
time_mask:: BitMatrix
174
-
174
+
175
175
# Temporary object used during construction, will be set to `nothing` at the end.
176
- ilsc:: Union{Nothing,IndependentlyLinearizedSolutionChunks{T,S}}
176
+ ilsc:: Union{Nothing, IndependentlyLinearizedSolutionChunks{T, S}}
177
177
end
178
178
# Helper function to create an ILS wrapped around an in-progress ILSC
179
- function IndependentlyLinearizedSolution (ilsc:: IndependentlyLinearizedSolutionChunks{T,S} ) where {T,S}
179
+ function IndependentlyLinearizedSolution (ilsc:: IndependentlyLinearizedSolutionChunks {
180
+ T, S}) where {T, S}
180
181
ils = IndependentlyLinearizedSolution (
181
182
T[],
182
183
Matrix{S}[],
183
- BitMatrix (undef, 0 ,0 ),
184
- ilsc,
184
+ BitMatrix (undef, 0 , 0 ),
185
+ ilsc
185
186
)
186
187
return ils
187
188
end
188
189
# Automatically create an ILS wrapped around an ILSC from a `prob`
189
- function IndependentlyLinearizedSolution (prob:: SciMLBase.AbstractDEProblem , num_derivatives = 0 )
190
+ function IndependentlyLinearizedSolution (
191
+ prob:: SciMLBase.AbstractDEProblem , num_derivatives = 0 )
190
192
T = eltype (prob. tspan)
191
193
U = isnothing (prob. u0) ? Float64 : eltype (prob. u0)
192
194
N = isnothing (prob. u0) ? 0 : length (prob. u0)
193
- chunks = IndependentlyLinearizedSolutionChunks {T,U} (N, num_derivatives)
195
+ chunks = IndependentlyLinearizedSolutionChunks {T, U} (N, num_derivatives)
194
196
return IndependentlyLinearizedSolution (chunks)
195
197
end
196
198
197
- num_derivatives (ils:: IndependentlyLinearizedSolution ) = ! isempty (ils. us) ? size (first (ils. us), 1 ) : 0
199
+ function num_derivatives (ils:: IndependentlyLinearizedSolution )
200
+ ! isempty (ils. us) ? size (first (ils. us), 1 ) : 0
201
+ end
198
202
num_us (ils:: IndependentlyLinearizedSolution ) = length (ils. us)
199
203
Base. size (ils:: IndependentlyLinearizedSolution ) = size (ils. time_mask)
200
204
Base. length (ils:: IndependentlyLinearizedSolution ) = length (ils. ts)
201
205
202
- function finish! (ils:: IndependentlyLinearizedSolution{T, S} , return_code) where {T,S}
206
+ function finish! (ils:: IndependentlyLinearizedSolution{T, S} , return_code) where {T, S}
203
207
function trim_chunk (chunks:: Vector , offset)
204
208
chunks = [chunk for chunk in chunks]
205
209
if eltype (chunks) <: AbstractVector
@@ -225,7 +229,7 @@ function finish!(ils::IndependentlyLinearizedSolution{T, S}, return_code) where
225
229
ts = vcat (trim_chunk (ilsc. t_chunks, ilsc. t_offset)... )
226
230
time_mask = hcat (trim_chunk (ilsc. time_masks, ilsc. t_offset)... )
227
231
us = [hcat (trim_chunk (ilsc. u_chunks[u_idx], ilsc. u_offsets[u_idx])... )
228
- for u_idx in 1 : length (ilsc. u_chunks)]
232
+ for u_idx in 1 : length (ilsc. u_chunks)]
229
233
end
230
234
231
235
# Sanity-check lengths
317
321
function Base. seek (ils:: IndependentlyLinearizedSolution , t_idx = 1 )
318
322
return [ILSStateCursor (ils, u_idx, t_idx) for u_idx in 1 : length (ils. us)]
319
323
end
320
- function iteration_state (ils:: IndependentlyLinearizedSolution{T, S} , t_idx= 1 ) where {T, S}
324
+ function iteration_state (ils:: IndependentlyLinearizedSolution{T, S} , t_idx = 1 ) where {T, S}
321
325
# Nice little hack so we don't have to allocate `u` over and over again
322
326
u = zeros (S, (num_us (ils), num_derivatives (ils)))
323
327
cursors = seek (ils, t_idx)
@@ -334,7 +338,7 @@ function Base.iterate(ils::IndependentlyLinearizedSolution{T, S},
334
338
for deriv_idx in 0 : (size (u, 2 ) - 1 )
335
339
for u_idx in 1 : size (u, 1 )
336
340
cursors[u_idx] = seek_forward (ils, cursors[u_idx], t)
337
- u[u_idx, deriv_idx+ 1 ] = interpolate (ils, cursors[u_idx], t, deriv_idx)
341
+ u[u_idx, deriv_idx + 1 ] = interpolate (ils, cursors[u_idx], t, deriv_idx)
338
342
end
339
343
end
340
344
347
351
Batch-sample `ils` at the given timepoints for the given derivative level, storing into `out`.
348
352
"""
349
353
function sample! (out:: Matrix{S} ,
350
- ils:: IndependentlyLinearizedSolution{T, S} ,
351
- ts:: AbstractVector{T} ,
352
- deriv_idx:: Int = 0 ) where {T, S}
354
+ ils:: IndependentlyLinearizedSolution{T, S} ,
355
+ ts:: AbstractVector{T} ,
356
+ deriv_idx:: Int = 0 ) where {T, S}
353
357
sampled_size = (length (ts), length (ils. us))
354
358
if size (out) != sampled_size
355
359
throw (ArgumentError (" Output size ($(size (out)) ) != sampled size ($(sampled_size) )" ))
@@ -366,8 +370,8 @@ function sample!(out::Matrix{S},
366
370
return out
367
371
end
368
372
function sample (ils:: IndependentlyLinearizedSolution{T, S} ,
369
- ts:: AbstractVector{T} ,
370
- deriv_idx:: Int = 0 ) where {T, S}
373
+ ts:: AbstractVector{T} ,
374
+ deriv_idx:: Int = 0 ) where {T, S}
371
375
out = Matrix {S} (undef, length (ts), length (ils. us))
372
376
return sample! (out, ils, ts, deriv_idx)
373
377
end
0 commit comments