@@ -173,24 +173,28 @@ Extrapolation extends the last cubic polynomial on each side.
173
173
for a test based on the normalized standard deviation of the difference with respect
174
174
to the straight line (see [`looks_linear`](@ref)). Defaults to 1e-2.
175
175
"""
176
- struct AkimaInterpolation{uType, tType, IType, pType , T, N} < :
176
+ struct AkimaInterpolation{uType, tType, IType, bType, cType, dType , T, N} < :
177
177
AbstractInterpolation{T, N}
178
178
u:: uType
179
179
t:: tType
180
180
I:: IType
181
- p:: pType
181
+ b:: bType
182
+ c:: cType
183
+ d:: dType
182
184
extrapolate:: Bool
183
185
iguesser:: Guesser{tType}
184
186
cache_parameters:: Bool
185
187
linear_lookup:: Bool
186
188
function AkimaInterpolation (
187
- u, t, I, p , extrapolate, cache_parameters, assume_linear_t)
189
+ u, t, I, b, c, d , extrapolate, cache_parameters, assume_linear_t)
188
190
linear_lookup = seems_linear (assume_linear_t, t)
189
191
N = get_output_dim (u)
190
- new {typeof(u), typeof(t), typeof(I), typeof(p ), eltype(u), N} (u,
192
+ new {typeof(u), typeof(t), typeof(I), typeof(b), typeof(c), typeof(d ), eltype(u), N} (u,
191
193
t,
192
194
I,
193
- p,
195
+ b,
196
+ c,
197
+ d,
194
198
extrapolate,
195
199
Guesser (t),
196
200
cache_parameters,
@@ -200,14 +204,72 @@ struct AkimaInterpolation{uType, tType, IType, pType, T, N} <:
200
204
end
201
205
202
206
function AkimaInterpolation (
203
- u, t; extrapolate = false , cache_parameters = false , assume_linear_t = 1e-2 )
207
+ u:: uType , t; extrapolate = false , cache_parameters = false ,
208
+ assume_linear_t = 1e-2 ) where {uType < :
209
+ AbstractVector{<: Number }}
204
210
u, t = munge_data (u, t)
205
211
linear_lookup = seems_linear (assume_linear_t, t)
206
- p = AkimaParameterCache (u, t)
212
+ n = length (t)
213
+ dt = diff (t)
214
+ m = Array {eltype(u)} (undef, n + 3 )
215
+ m[3 : (end - 2 )] = diff (u) ./ dt
216
+ m[2 ] = 2 m[3 ] - m[4 ]
217
+ m[1 ] = 2 m[2 ] - m[3 ]
218
+ m[end - 1 ] = 2 m[end - 2 ] - m[end - 3 ]
219
+ m[end ] = 2 m[end - 1 ] - m[end - 2 ]
220
+ b = 0.5 .* (m[4 : end ] .+ m[1 : (end - 3 )])
221
+ dm = abs .(diff (m))
222
+ f1 = dm[3 : (n + 2 )]
223
+ f2 = dm[1 : n]
224
+ f12 = f1 + f2
225
+ ind = findall (f12 .> 1e-9 * maximum (f12))
226
+ b[ind] = (f1[ind] .* m[ind .+ 1 ] .+
227
+ f2[ind] .* m[ind .+ 2 ]) ./ f12[ind]
228
+ c = (3.0 .* m[3 : (end - 2 )] .- 2.0 .* b[1 : (end - 1 )] .- b[2 : end ]) ./ dt
229
+ d = (b[1 : (end - 1 )] .+ b[2 : end ] .- 2.0 .* m[3 : (end - 2 )]) ./ dt .^ 2
207
230
A = AkimaInterpolation (
208
- u, t, nothing , p , extrapolate, cache_parameters, linear_lookup)
231
+ u, t, nothing , b, c, d , extrapolate, cache_parameters, linear_lookup)
209
232
I = cumulative_integral (A, cache_parameters)
210
- AkimaInterpolation (u, t, I, p, extrapolate, cache_parameters, linear_lookup)
233
+ AkimaInterpolation (u, t, I, b, c, d, extrapolate, cache_parameters, linear_lookup)
234
+ end
235
+
236
+ function AkimaInterpolation (
237
+ u:: uType , t; extrapolate = false , cache_parameters = false ,
238
+ assume_linear_t = 1e-2 ) where {uType < :
239
+ AbstractArray}
240
+ n = length (t)
241
+ dt = diff (t)
242
+ ax = axes (u)[1 : (end - 1 )]
243
+ su = size (u)
244
+ m = zeros (eltype (u), su[1 : (end - 1 )]. .. , n + 3 )
245
+ m[ax... , 3 : (end - 2 )] .= mapslices (
246
+ x -> x ./ dt, diff (u, dims = length (su)); dims = length (su))
247
+ m[ax... , 2 ] .= 2 m[ax... , 3 ] .- m[ax... , 4 ]
248
+ m[ax... , 1 ] .= 2 m[ax... , 2 ] .- m[3 ]
249
+ m[ax... , end - 1 ] .= 2 m[ax... , end - 2 ] - m[ax... , end - 3 ]
250
+ m[ax... , end ] .= 2 m[ax... , end - 1 ] .- m[ax... , end - 2 ]
251
+ b = 0.5 .* (m[ax... , 4 : end ] .+ m[ax... , 1 : (end - 3 )])
252
+ dm = abs .(diff (m, dims = length (su)))
253
+ f1 = dm[ax... , 3 : (n + 2 )]
254
+ f2 = dm[ax... , 1 : n]
255
+ f12 = f1 .+ f2
256
+ ind = findall (f12 .> 1e-9 * maximum (f12))
257
+ indi = map (i -> i. I, ind)
258
+ b[ind] .= (f1[ind] .*
259
+ m[CartesianIndex .(map (i -> (i[1 : (end - 1 )]. .. , i[end ] + 1 ), indi))] .+
260
+ f2[ind] .*
261
+ m[CartesianIndex .(map (i -> (i[1 : (end - 1 )]. .. , i[end ] + 2 ), indi))]) ./
262
+ f12[ind]
263
+ c = mapslices (x -> x ./ dt,
264
+ (3.0 .* m[ax... , 3 : (end - 2 )] .- 2.0 .* b[ax... , 1 : (end - 1 )] .- b[ax... , 2 : end ]);
265
+ dims = length (su))
266
+ d = mapslices (x -> x ./ dt .^ 2 ,
267
+ (b[ax... , 1 : (end - 1 )] .+ b[ax... , 2 : end ] .- 2.0 .* m[ax... , 3 : (end - 2 )]);
268
+ dims = length (su))
269
+ A = AkimaInterpolation (
270
+ u, t, nothing , b, c, d, extrapolate, cache_parameters, linear_lookup)
271
+ I = cumulative_integral (A, cache_parameters)
272
+ AkimaInterpolation (u, t, I, b, c, d, extrapolate, cache_parameters, linear_lookup)
211
273
end
212
274
213
275
"""
367
429
368
430
function QuadraticSpline (
369
431
u:: uType , t; extrapolate = false , cache_parameters = false ,
370
- assume_linear_t = 1e-2 ) where {uType < :
371
- AbstractArray}
432
+ assume_linear_t = 1e-2 ) where {uType <: AbstractArray }
372
433
u, t = munge_data (u, t)
373
434
linear_lookup = seems_linear (assume_linear_t, t)
374
435
s = length (t)
0 commit comments