Skip to content

Commit d6a0824

Browse files
refactor: revert cache for akima as it is always needed
1 parent d76d1e3 commit d6a0824

File tree

5 files changed

+80
-85
lines changed

5 files changed

+80
-85
lines changed

src/derivatives.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,17 +106,17 @@ end
106106

107107
function _derivative(A::AkimaInterpolation{<:AbstractVector}, t::Number, iguess)
108108
idx = get_idx(A, t, iguess; idx_shift = -1, side = :first)
109-
j = min(idx, length(A.p.c)) # for smooth derivative at A.t[end]
109+
j = min(idx, length(A.c)) # for smooth derivative at A.t[end]
110110
wj = t - A.t[idx]
111-
@evalpoly wj A.p.b[idx] 2A.p.c[j] 3A.p.d[j]
111+
@evalpoly wj A.b[idx] 2A.c[j] 3A.d[j]
112112
end
113113

114114
function _derivative(A::AkimaInterpolation{<:AbstractArray}, t::Number, iguess)
115115
idx = get_idx(A, t, iguess; idx_shift = -1, side = :first)
116-
j = min(idx, length(A.p.c)) # for smooth derivative at A.t[end]
116+
j = min(idx, length(A.c)) # for smooth derivative at A.t[end]
117117
wj = t - A.t[idx]
118118
ax = axes(A.u)[1:(end - 1)]
119-
@. @evalpoly wj A.p.b[ax..., idx] 2A.p.c[ax..., j] 3A.p.d[ax..., j]
119+
@. @evalpoly wj A.b[ax..., idx] 2A.c[ax..., j] 3A.d[ax..., j]
120120
end
121121

122122
function _derivative(A::ConstantInterpolation, t::Number, iguess)

src/integrals.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ function _integral(A::AkimaInterpolation{<:AbstractVector{<:Number}},
9090
idx::Number,
9191
t::Number)
9292
t1 = A.t[idx]
93-
A.u[idx] * (t - t1) + A.p.b[idx] * ((t - t1)^2 / 2) + A.p.c[idx] * ((t - t1)^3 / 3) +
94-
A.p.d[idx] * ((t - t1)^4 / 4)
93+
A.u[idx] * (t - t1) + A.b[idx] * ((t - t1)^2 / 2) + A.c[idx] * ((t - t1)^3 / 3) +
94+
A.d[idx] * ((t - t1)^4 / 4)
9595
end
9696

9797
_integral(A::LagrangeInterpolation, idx::Number, t::Number) = throw(IntegralNotFoundError())

src/interpolation_caches.jl

Lines changed: 72 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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} <:
200204
end
201205

202206
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}}
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] = 2m[3] - m[4]
217+
m[1] = 2m[2] - m[3]
218+
m[end - 1] = 2m[end - 2] - m[end - 3]
219+
m[end] = 2m[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] .= 2m[ax..., 3] .- m[ax..., 4]
248+
m[ax..., 1] .= 2m[ax..., 2] .- m[3]
249+
m[ax..., end - 1] .= 2m[ax..., end - 2] - m[ax..., end - 3]
250+
m[ax..., end] .= 2m[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)
211273
end
212274

213275
"""
@@ -367,8 +429,7 @@ end
367429

368430
function 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)

src/interpolation_methods.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,14 +121,14 @@ end
121121
function _interpolate(A::AkimaInterpolation{<:AbstractVector}, t::Number, iguess)
122122
idx = get_idx(A, t, iguess)
123123
wj = t - A.t[idx]
124-
@evalpoly wj A.u[idx] A.p.b[idx] A.p.c[idx] A.p.d[idx]
124+
@evalpoly wj A.u[idx] A.b[idx] A.c[idx] A.d[idx]
125125
end
126126

127127
function _interpolate(A::AkimaInterpolation{<:AbstractArray}, t::Number, iguess)
128128
idx = get_idx(A, t, iguess)
129129
wj = t - A.t[idx]
130130
ax = axes(A.u)[1:(end - 1)]
131-
@. @evalpoly wj A.u[ax..., idx] A.p.b[ax..., idx] A.p.c[ax..., idx] A.p.d[ax..., idx]
131+
@. @evalpoly wj A.u[ax..., idx] A.b[ax..., idx] A.c[ax..., idx] A.d[ax..., idx]
132132
end
133133

134134
# ConstantInterpolation Interpolation

src/parameter_caches.jl

Lines changed: 0 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -75,72 +75,6 @@ function quadratic_interpolation_parameters(u::AbstractArray{T, N}, t, idx) wher
7575
return l₀, l₁, l₂
7676
end
7777

78-
struct AkimaParameterCache{pType}
79-
b::pType
80-
c::pType
81-
d::pType
82-
end
83-
84-
function AkimaParameterCache(u, t)
85-
b, c, d = akima_interpolation_parameters(u, t)
86-
AkimaParameterCache(b, c, d)
87-
end
88-
89-
function akima_interpolation_parameters(u::AbstractVector, t)
90-
n = length(t)
91-
dt = diff(t)
92-
m = Array{eltype(u)}(undef, n + 3)
93-
m[3:(end - 2)] = diff(u) ./ dt
94-
m[2] = 2m[3] - m[4]
95-
m[1] = 2m[2] - m[3]
96-
m[end - 1] = 2m[end - 2] - m[end - 3]
97-
m[end] = 2m[end - 1] - m[end - 2]
98-
b = 0.5 .* (m[4:end] .+ m[1:(end - 3)])
99-
dm = abs.(diff(m))
100-
f1 = dm[3:(n + 2)]
101-
f2 = dm[1:n]
102-
f12 = f1 + f2
103-
ind = findall(f12 .> 1e-9 * maximum(f12))
104-
b[ind] = (f1[ind] .* m[ind .+ 1] .+
105-
f2[ind] .* m[ind .+ 2]) ./ f12[ind]
106-
c = (3.0 .* m[3:(end - 2)] .- 2.0 .* b[1:(end - 1)] .- b[2:end]) ./ dt
107-
d = (b[1:(end - 1)] .+ b[2:end] .- 2.0 .* m[3:(end - 2)]) ./ dt .^ 2
108-
return b, c, d
109-
end
110-
111-
function akima_interpolation_parameters(u::AbstractArray, t)
112-
n = length(t)
113-
dt = diff(t)
114-
ax = axes(u)[1:(end - 1)]
115-
su = size(u)
116-
m = zeros(eltype(u), su[1:(end - 1)]..., n + 3)
117-
m[ax..., 3:(end - 2)] .= mapslices(
118-
x -> x ./ dt, diff(u, dims = length(su)); dims = length(su))
119-
m[ax..., 2] .= 2m[ax..., 3] .- m[ax..., 4]
120-
m[ax..., 1] .= 2m[ax..., 2] .- m[3]
121-
m[ax..., end - 1] .= 2m[ax..., end - 2] - m[ax..., end - 3]
122-
m[ax..., end] .= 2m[ax..., end - 1] .- m[ax..., end - 2]
123-
b = 0.5 .* (m[ax..., 4:end] .+ m[ax..., 1:(end - 3)])
124-
dm = abs.(diff(m, dims = length(su)))
125-
f1 = dm[ax..., 3:(n + 2)]
126-
f2 = dm[ax..., 1:n]
127-
f12 = f1 .+ f2
128-
ind = findall(f12 .> 1e-9 * maximum(f12))
129-
indi = map(i -> i.I, ind)
130-
b[ind] .= (f1[ind] .*
131-
m[CartesianIndex.(map(i -> (i[1:(end - 1)]..., i[end] + 1), indi))] .+
132-
f2[ind] .*
133-
m[CartesianIndex.(map(i -> (i[1:(end - 1)]..., i[end] + 2), indi))]) ./
134-
f12[ind]
135-
c = mapslices(x -> x ./ dt,
136-
(3.0 .* m[ax..., 3:(end - 2)] .- 2.0 .* b[ax..., 1:(end - 1)] .- b[ax..., 2:end]);
137-
dims = length(su))
138-
d = mapslices(x -> x ./ dt .^ 2,
139-
(b[ax..., 1:(end - 1)] .+ b[ax..., 2:end] .- 2.0 .* m[ax..., 3:(end - 2)]);
140-
dims = length(su))
141-
return b, c, d
142-
end
143-
14478
struct QuadraticSplineParameterCache{pType}
14579
σ::pType
14680
end

0 commit comments

Comments
 (0)