Skip to content

Commit 95c2ff2

Browse files
committed
Makes splineMonotone() actually monotone; re: #91
1 parent a846314 commit 95c2ff2

File tree

2 files changed

+35
-9
lines changed

2 files changed

+35
-9
lines changed

src/interpolate/splineBasis.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import identity from '../util/identity';
22

33
/*
4-
54
Basis spline
65
------------
76

src/interpolate/splineMonotone.js

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,46 @@
11
import identity from '../util/identity';
22

3-
const monotone = (v0, v1, v2, v3, h, t) => {
3+
/*
4+
Monotone spline
5+
---------------
6+
7+
Based on:
8+
9+
Steffen, M.
10+
"A simple method for monotonic interpolation in one dimension."
11+
in Astronomy and Astrophysics, Vol. 239, p. 443-450 (Nov. 1990),
12+
Provided by the SAO/NASA Astrophysics Data System.
13+
14+
https://ui.adsabs.harvard.edu/abs/1990A&A...239..443S
15+
16+
(Reference thanks to `d3/d3-shape`)
17+
*/
18+
19+
const sgn = Math.sign,
20+
min = Math.min,
21+
abs = Math.abs;
22+
23+
const monotone = (y_im1, y_i, y_ip1, y_ip2, h, t) => {
424
let h2 = h * h;
525
let t2 = t * t;
626
let t3 = t2 * t;
727

8-
let s20 = (v2 - v0) / (2 * h);
9-
let s31 = (v3 - v1) / (2 * h);
10-
let s21 = (v2 - v1) / h;
28+
let s_im1 = (y_i - y_im1) / h;
29+
let s_i = (y_ip1 - y_i) / h;
30+
let s_ip1 = (y_ip2 - y_ip1) / h;
31+
32+
let yp_i =
33+
(sgn(s_im1) + sgn(s_i)) *
34+
min(abs(s_im1), abs(s_i), 0.5 * abs((y_ip1 - y_im1) / (2 * h)));
35+
let yp_ip1 =
36+
(sgn(s_i) + sgn(s_ip1)) *
37+
min(abs(s_i), abs(s_ip1), 0.5 * abs((y_ip2 - y_i) / (2 * h)));
1138

1239
return (
13-
((s20 + s31 - 2 * s21) / h2) * t3 +
14-
((3 * s21 - 2 * s20 - s31) / h) * t2 +
15-
s20 * t +
16-
v1
40+
((yp_i + yp_ip1 - 2 * si) / h2) * t3 +
41+
((3 * si - 2 * yp_i - yp_ip1) / h) * t2 +
42+
yp_i * t +
43+
y_i
1744
);
1845
};
1946

0 commit comments

Comments
 (0)