Skip to content

Commit 1e1c615

Browse files
refactor: add missing derivatives
1 parent ef3eb39 commit 1e1c615

1 file changed

Lines changed: 57 additions & 9 deletions

File tree

src/derivatives.jl

Lines changed: 57 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,10 @@ function _derivative(A::LagrangeInterpolation{<:AbstractVector}, t::Number)
6262
der
6363
end
6464

65-
function _derivative(A::LagrangeInterpolation{<:AbstractMatrix}, t::Number)
65+
function _derivative(A::LagrangeInterpolation{<:AbstractArray}, t::Number)
6666
((t < A.t[1] || t > A.t[end]) && !A.extrapolate) && throw(ExtrapolationError())
67-
der = zero(A.u[:, 1])
67+
ax = axes(A.u)[1:(end - 1)]
68+
der = zero(A.u[ax..., 1])
6869
for j in eachindex(A.t)
6970
tmp = zero(A.t[1])
7071
if isnan(A.bcache[j])
@@ -91,23 +92,31 @@ function _derivative(A::LagrangeInterpolation{<:AbstractMatrix}, t::Number)
9192
tmp += k
9293
end
9394
end
94-
der += A.u[:, j] * tmp
95+
der += A.u[ax..., j] * tmp
9596
end
9697
der
9798
end
9899

99100
function _derivative(A::LagrangeInterpolation{<:AbstractVector}, t::Number, idx)
100101
_derivative(A, t)
101102
end
102-
function _derivative(A::LagrangeInterpolation{<:AbstractMatrix}, t::Number, idx)
103+
function _derivative(A::LagrangeInterpolation{<:AbstractArray}, t::Number, idx)
103104
_derivative(A, t)
104105
end
105106

106107
function _derivative(A::AkimaInterpolation{<:AbstractVector}, t::Number, iguess)
107108
idx = get_idx(A, t, iguess; idx_shift = -1, side = :first)
108-
j = min(idx, length(A.c)) # for smooth derivative at A.t[end]
109+
j = min(idx, length(A.p.c)) # for smooth derivative at A.t[end]
109110
wj = t - A.t[idx]
110-
@evalpoly wj A.b[idx] 2A.c[j] 3A.d[j]
111+
@evalpoly wj A.p.b[idx] 2A.p.c[j] 3A.p.d[j]
112+
end
113+
114+
function _derivative(A::AkimaInterpolation{<:AbstractArray}, t::Number, iguess)
115+
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]
117+
wj = t - A.t[idx]
118+
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]
111120
end
112121

113122
function _derivative(A::ConstantInterpolation, t::Number, iguess)
@@ -119,13 +128,15 @@ function _derivative(A::ConstantInterpolation{<:AbstractVector}, t::Number, igue
119128
return isempty(searchsorted(A.t, t)) ? zero(A.u[1]) : eltype(A.u)(NaN)
120129
end
121130

122-
function _derivative(A::ConstantInterpolation{<:AbstractMatrix}, t::Number, iguess)
131+
function _derivative(A::ConstantInterpolation{<:AbstractArray}, t::Number, iguess)
123132
((t < A.t[1] || t > A.t[end]) && !A.extrapolate) && throw(ExtrapolationError())
124-
return isempty(searchsorted(A.t, t)) ? zero(A.u[:, 1]) : eltype(A.u)(NaN) .* A.u[:, 1]
133+
ax = axes(A.u)[1:(end - 1)]
134+
return isempty(searchsorted(A.t, t)) ? zero(A.u[ax..., 1]) :
135+
eltype(A.u)(NaN) .* A.u[ax..., 1]
125136
end
126137

127138
# QuadraticSpline Interpolation
128-
function _derivative(A::QuadraticSpline{<:AbstractVector}, t::Number, iguess)
139+
function _derivative(A::QuadraticSpline, t::Number, iguess)
129140
idx = get_idx(A, t, iguess; lb = 2, ub_shift = 0, side = :first)
130141
σ = get_parameters(A, idx - 1)
131142
A.z[idx - 1] + 2σ * (t - A.t[idx - 1])
@@ -143,6 +154,18 @@ function _derivative(A::CubicSpline{<:AbstractVector}, t::Number, iguess)
143154
dI + dC + dD
144155
end
145156

157+
function _derivative(A::CubicSpline{<:AbstractArray}, t::Number, iguess)
158+
idx = get_idx(A, t, iguess)
159+
Δt₁ = t - A.t[idx]
160+
Δt₂ = A.t[idx + 1] - t
161+
ax = axes(A.u)[1:(end - 1)]
162+
dI = (-A.z[ax..., idx] * Δt₂^2 + A.z[ax..., idx + 1] * Δt₁^2) / (2A.h[idx + 1])
163+
c₁, c₂ = get_parameters(A, idx)
164+
dC = c₁
165+
dD = -c₂
166+
dI + dC + dD
167+
end
168+
146169
function _derivative(A::BSplineInterpolation{<:AbstractVector{<:Number}}, t::Number, iguess)
147170
# change t into param [0 1]
148171
t < A.t[1] && return zero(A.u[1])
@@ -197,6 +220,18 @@ function _derivative(
197220
out
198221
end
199222

223+
function _derivative(
224+
A::CubicHermiteSpline{<:AbstractArray}, t::Number, iguess)
225+
idx = get_idx(A, t, iguess)
226+
Δt₀ = t - A.t[idx]
227+
Δt₁ = t - A.t[idx + 1]
228+
ax = axes(A.u)[1:(end - 1)]
229+
out = A.du[ax..., idx]
230+
c₁, c₂ = get_parameters(A, idx)
231+
out .+= Δt₀ .* (Δt₀ .* c₂ .+ 2(c₁ .+ Δt₁ .* c₂))
232+
out
233+
end
234+
200235
# Quintic Hermite Spline
201236
function _derivative(
202237
A::QuinticHermiteSpline{<:AbstractVector{<:Number}}, t::Number, iguess)
@@ -209,3 +244,16 @@ function _derivative(
209244
(3c₁ + (3Δt₁ + Δt₀) * c₂ + (3Δt₁^2 + Δt₀ * 2Δt₁) * c₃)
210245
out
211246
end
247+
248+
function _derivative(
249+
A::QuinticHermiteSpline{<:AbstractArray}, t::Number, iguess)
250+
idx = get_idx(A, t, iguess)
251+
Δt₀ = t - A.t[idx]
252+
Δt₁ = t - A.t[idx + 1]
253+
ax = axes(A.u)[1:(end - 1)]
254+
out = A.du[ax..., idx] + A.ddu[ax..., idx] * Δt₀
255+
c₁, c₂, c₃ = get_parameters(A, idx)
256+
out .+= Δt₀^2 .*
257+
(3c₁ .+ (3Δt₁ .+ Δt₀) .* c₂ + (3Δt₁^2 .+ Δt₀ .* 2Δt₁) .* c₃)
258+
out
259+
end

0 commit comments

Comments
 (0)