@@ -70,7 +70,7 @@ function quadratic_spline_params(t::AbstractVector, sc::AbstractVector)
70
70
71
71
# Create linear system Ac = u, where:
72
72
# - A consists of basis function evaulations in t
73
- # - c are 1D control points
73
+ # - c are 1D control points
74
74
n = length (t)
75
75
dtype_sc = typeof (t[1 ] / t[1 ])
76
76
@@ -235,6 +235,19 @@ function du_PCHIP(u, t)
235
235
δ = diff (u) ./ h
236
236
s = sign .(δ)
237
237
238
+ # Special handling of the slope at the endpoints, see
239
+ # Cleve Moler, Numerical Computing with MATLAB, Chap 3.6 (file pchiptx.m, function pchipend())
240
+ function _edge_case (h₁, h₂, δ₁, δ₂)
241
+ d = ((2 * h₁ + h₂) * δ₁ - h₁ * δ₂) / (h₁ + h₂)
242
+ if sign (d) != sign (δ₁)
243
+ zero (eltype (δ))
244
+ elseif sign (δ₁) != sign (δ₂) && abs (d) > 3 * abs (δ₁)
245
+ 3 * δ₁
246
+ else
247
+ d
248
+ end
249
+ end
250
+
238
251
function _du (k)
239
252
sₖ₋₁, sₖ = if k == 1
240
253
s[1 ], s[2 ]
@@ -248,17 +261,22 @@ function du_PCHIP(u, t)
248
261
zero (eltype (δ))
249
262
elseif sₖ₋₁ == sₖ
250
263
if k == 1
251
- (( 2 * h[1 ] + h[2 ]) * δ[1 ] - h[ 1 ] * δ[ 2 ]) / (h[ 1 ] + h [2 ])
264
+ _edge_case ( h[1 ], h[2 ], δ[1 ], δ [2 ])
252
265
elseif k == lastindex (t)
253
- ((2 * h[end ] + h[end - 1 ]) * δ[end ] - h[end ] * δ[end - 1 ]) /
254
- (h[end ] + h[end - 1 ])
266
+ _edge_case (h[end ], h[end - 1 ], δ[end ], δ[end - 1 ])
255
267
else
256
268
w₁ = 2 h[k] + h[k - 1 ]
257
269
w₂ = h[k] + 2 h[k - 1 ]
258
270
(w₁ + w₂) / (w₁ / δ[k - 1 ] + w₂ / δ[k])
259
271
end
260
272
else
261
- zero (eltype (δ))
273
+ if k == 1
274
+ _edge_case (h[1 ], h[2 ], δ[1 ], δ[2 ])
275
+ elseif k == lastindex (t)
276
+ _edge_case (h[end ], h[end - 1 ], δ[end ], δ[end - 1 ])
277
+ else
278
+ zero (eltype (δ))
279
+ end
262
280
end
263
281
end
264
282
0 commit comments