@@ -173,24 +173,28 @@ Extrapolation extends the last cubic polynomial on each side.
173173 for a test based on the normalized standard deviation of the difference with respect
174174 to the straight line (see [`looks_linear`](@ref)). Defaults to 1e-2.
175175"""
176- struct AkimaInterpolation{uType, tType, IType, pType , T, N} < :
176+ struct AkimaInterpolation{uType, tType, IType, bType, cType, dType , T, N} < :
177177 AbstractInterpolation{T, N}
178178 u:: uType
179179 t:: tType
180180 I:: IType
181- p:: pType
181+ b:: bType
182+ c:: cType
183+ d:: dType
182184 extrapolate:: Bool
183185 iguesser:: Guesser{tType}
184186 cache_parameters:: Bool
185187 linear_lookup:: Bool
186188 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)
188190 linear_lookup = seems_linear (assume_linear_t, t)
189191 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,
191193 t,
192194 I,
193- p,
195+ b,
196+ c,
197+ d,
194198 extrapolate,
195199 Guesser (t),
196200 cache_parameters,
@@ -200,14 +204,72 @@ struct AkimaInterpolation{uType, tType, IType, pType, T, N} <:
200204end
201205
202206function 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 }}
204210 u, t = munge_data (u, t)
205211 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
207230 A = AkimaInterpolation (
208- u, t, nothing , p , extrapolate, cache_parameters, linear_lookup)
231+ u, t, nothing , b, c, d , extrapolate, cache_parameters, linear_lookup)
209232 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)
211273end
212274
213275"""
367429
368430function QuadraticSpline (
369431 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 }
372433 u, t = munge_data (u, t)
373434 linear_lookup = seems_linear (assume_linear_t, t)
374435 s = length (t)
0 commit comments