@@ -107,15 +107,15 @@ end
107107Monotonic interpolation up to third order represented by type, knots and
108108coefficients.
109109"""
110- struct MonotonicInterpolation{T, TCoeffs , TEl, TInterpolationType<: MonotonicInterpolationType ,
110+ struct MonotonicInterpolation{T, TCoeffs1, TCoeffs2, TCoeffs3 , TEl, TInterpolationType<: MonotonicInterpolationType ,
111111 TKnots<: AbstractVector{<:Number} , TACoeff <: AbstractArray{TEl,1} } <: AbstractInterpolation{T,1,DimSpec{TInterpolationType}}
112112
113113 it:: TInterpolationType
114114 knots:: TKnots
115115 A:: TACoeff # constant parts of piecewise polynomials
116- m:: Vector{TCoeffs } # coefficients of linear parts of piecewise polynomials
117- c:: Vector{TCoeffs } # coefficients of quadratic parts of piecewise polynomials
118- d:: Vector{TCoeffs } # coefficients of cubic parts of piecewise polynomials
116+ m:: Vector{TCoeffs1 } # coefficients of linear parts of piecewise polynomials
117+ c:: Vector{TCoeffs2 } # coefficients of quadratic parts of piecewise polynomials
118+ d:: Vector{TCoeffs3 } # coefficients of cubic parts of piecewise polynomials
119119end
120120
121121function Base.:(== )(o1:: MonotonicInterpolation , o2:: MonotonicInterpolation )
@@ -134,10 +134,10 @@ itpflag(A::MonotonicInterpolation) = A.it
134134coefficients (A:: MonotonicInterpolation ) = A. A
135135
136136function MonotonicInterpolation (:: Type{TWeights} , it:: TInterpolationType , knots:: TKnots , A:: AbstractArray{TEl,1} ,
137- m:: Vector{TCoeffs } , c:: Vector{TCoeffs } , d:: Vector{TCoeffs } ) where {TWeights, TCoeffs , TEl, TInterpolationType<: MonotonicInterpolationType , TKnots<: AbstractVector{<:Number} }
137+ m:: Vector{TCoeffs1 } , c:: Vector{TCoeffs2 } , d:: Vector{TCoeffs3 } ) where {TWeights, TCoeffs1, TCoeffs2, TCoeffs3 , TEl, TInterpolationType<: MonotonicInterpolationType , TKnots<: AbstractVector{<:Number} }
138138
139139 isconcretetype (TInterpolationType) || error (" The spline type must be a leaf type (was $TInterpolationType )" )
140- isconcretetype (TCoeffs ) || warn (" For performance reasons, consider using an array of a concrete type (eltype(A) == $(eltype (A)) )" )
140+ isconcretetype (tcoef (A) ) || warn (" For performance reasons, consider using an array of a concrete type (eltype(A) == $(eltype (A)) )" )
141141
142142 check_monotonic (knots, A)
143143
@@ -148,22 +148,23 @@ function MonotonicInterpolation(::Type{TWeights}, it::TInterpolationType, knots:
148148 T = typeof (cZero * first (A))
149149 end
150150
151- MonotonicInterpolation {T, TCoeffs , TEl, TInterpolationType, TKnots, typeof(A)} (it, knots, A, m, c, d)
151+ MonotonicInterpolation {T, TCoeffs1, TCoeffs2, TCoeffs3 , TEl, TInterpolationType, TKnots, typeof(A)} (it, knots, A, m, c, d)
152152end
153153
154- function interpolate (:: Type{TWeights} , :: Type{TCoeffs } , knots:: TKnots ,
155- A:: AbstractArray{TEl,1} , it:: TInterpolationType ) where {TWeights,TCoeffs ,TEl,TKnots<: AbstractVector{<:Number} ,TInterpolationType<: MonotonicInterpolationType }
154+ function interpolate (:: Type{TWeights} , :: Type{TCoeffs1} , :: Type{TCoeffs2} , :: Type{TCoeffs3 } , knots:: TKnots ,
155+ A:: AbstractArray{TEl,1} , it:: TInterpolationType ) where {TWeights,TCoeffs1,TCoeffs2,TCoeffs3 ,TEl,TKnots<: AbstractVector{<:Number} ,TInterpolationType<: MonotonicInterpolationType }
156156
157157 check_monotonic (knots, A)
158158
159159 # first we need to determine tangents (m)
160160 n = length (knots)
161- m, Δ = calcTangents (TCoeffs , knots, A, it)
162- c = Vector {TCoeffs } (undef, n- 1 )
163- d = Vector {TCoeffs } (undef, n- 1 )
161+ m, Δ = calcTangents (TCoeffs1 , knots, A, it)
162+ c = Vector {TCoeffs2 } (undef, n- 1 )
163+ d = Vector {TCoeffs3 } (undef, n- 1 )
164164 for k ∈ 1 : n- 1
165165 if TInterpolationType == LinearMonotonicInterpolation
166- c[k] = d[k] = zero (TCoeffs)
166+ c[k] = zero (TCoeffs2)
167+ d[k] = zero (TCoeffs3)
167168 else
168169 xdiff = knots[k+ 1 ] - knots[k]
169170 c[k] = (3 * Δ[k] - 2 * m[k] - m[k+ 1 ]) / xdiff
177178function interpolate (knots:: AbstractVector{<:Number} , A:: AbstractArray{TEl,1} ,
178179 it:: TInterpolationType ) where {TEl,TInterpolationType<: MonotonicInterpolationType }
179180
180- interpolate (tweight (A), tcoef (A), knots, A, it)
181+ interpolate (tweight (A),typeof (oneunit (eltype (A)) / oneunit (eltype (knots))),
182+ typeof (oneunit (eltype (A)) / oneunit (eltype (knots))^ 2 ),
183+ typeof (oneunit (eltype (A)) / oneunit (eltype (knots))^ 3 ),knots,A,it)
181184end
182185
183186function (itp:: MonotonicInterpolation )(x:: Number )
@@ -282,6 +285,7 @@ function calcTangents(::Type{TCoeffs}, x::AbstractVector{<:Number},
282285 n = length (x)
283286 Δ = Vector {TCoeffs} (undef, n- 1 )
284287 m = Vector {TCoeffs} (undef, n)
288+ buff = Vector {typeof(first(Δ)^2)} (undef, n)
285289 for k in 1 : n- 1
286290 Δk = (y[k+ 1 ] - y[k]) / (x[k+ 1 ] - x[k])
287291 Δ[k] = Δk
@@ -290,10 +294,10 @@ function calcTangents(::Type{TCoeffs}, x::AbstractVector{<:Number},
290294 else
291295 # If any consecutive secant lines change sign (i.e. curve changes direction), initialize the tangent to zero.
292296 # This is needed to make the interpolation monotonic. Otherwise set tangent to the average of the secants.
293- if Δk <= zero (Δk)
297+ if Δ[k - 1 ] * Δk <= zero (Δk^ 2 )
294298 m[k] = zero (TCoeffs)
295299 else
296- m[k] = Δ[k - 1 ] * (Δ[k- 1 ] + Δk) / 2.0
300+ m[k] = (Δ[k- 1 ] + Δk) / 2.0
297301 end
298302 end
299303 end
@@ -317,8 +321,8 @@ function calcTangents(::Type{TCoeffs}, x::AbstractVector{<:Number},
317321 end
318322 α = m[k] / Δk
319323 β = m[k+ 1 ] / Δk
320- τ = 3.0 / sqrt (α^ 2 + β^ 2 )
321- if τ < 1.0 # if we're outside the circle with radius 3 then move onto the circle
324+ τ = 3.0 * oneunit (α) / sqrt (α^ 2 + β^ 2 )
325+ if τ < 1.0 # if we're outside the circle with radius 3 then move onto the circle
322326 m[k] = τ * α * Δk
323327 m[k+ 1 ] = τ * β * Δk
324328 end
@@ -341,7 +345,7 @@ function calcTangents(::Type{TCoeffs}, x::AbstractVector{<:Number},
341345 Δ[k] = Δk
342346 if k == 1 # left endpoint
343347 m[k] = Δk
344- elseif Δ[k- 1 ] * Δk <= zero (TCoeffs )
348+ elseif Δ[k- 1 ] * Δk <= zero (Δk ^ 2 )
345349 m[k] = zero (TCoeffs)
346350 else
347351 α = (1.0 + (x[k+ 1 ] - x[k]) / (x[k+ 1 ] - x[k- 1 ])) / 3.0
0 commit comments