UNPKG

commons-math-interpolation

Version:

A partial port of the Apache Commons Math Interpolation package, including Akima cubic spline interpolation and LOESS/LOWESS local regression.

53 lines 1.97 kB
import { checkStrictlyIncreasing, trimPoly, evaluatePolySegment } from "./Utils.js"; export function createCubicSplineInterpolator(xVals, yVals) { const segmentCoeffs = computeCubicPolyCoefficients(xVals, yVals); const xValsCopy = Float64Array.from(xVals); return (x) => evaluatePolySegment(xValsCopy, segmentCoeffs, x); } export function computeCubicPolyCoefficients(xVals, yVals) { if (xVals.length != yVals.length) { throw new Error("Dimension mismatch."); } if (xVals.length < 3) { throw new Error("Number of points is too small."); } checkStrictlyIncreasing(xVals); const n = xVals.length - 1; const h = new Float64Array(n); for (let i = 0; i < n; i++) { h[i] = xVals[i + 1] - xVals[i]; } const mu = new Float64Array(n); const z = new Float64Array(n + 1); mu[0] = 0; z[0] = 0; for (let i = 1; i < n; i++) { const g = 2 * (xVals[i + 1] - xVals[i - 1]) - h[i - 1] * mu[i - 1]; mu[i] = h[i] / g; z[i] = (3 * (yVals[i + 1] * h[i - 1] - yVals[i] * (xVals[i + 1] - xVals[i - 1]) + yVals[i - 1] * h[i]) / (h[i - 1] * h[i]) - h[i - 1] * z[i - 1]) / g; } const b = new Float64Array(n); const c = new Float64Array(n + 1); const d = new Float64Array(n); z[n] = 0; c[n] = 0; for (let i = n - 1; i >= 0; i--) { const dx = h[i]; const dy = yVals[i + 1] - yVals[i]; c[i] = z[i] - mu[i] * c[i + 1]; b[i] = dy / dx - dx * (c[i + 1] + 2 * c[i]) / 3; d[i] = (c[i + 1] - c[i]) / (3 * dx); } const segmentCoeffs = new Array(n); for (let i = 0; i < n; i++) { const coeffs = new Float64Array(4); coeffs[0] = yVals[i]; coeffs[1] = b[i]; coeffs[2] = c[i]; coeffs[3] = d[i]; segmentCoeffs[i] = trimPoly(coeffs); } return segmentCoeffs; } //# sourceMappingURL=Cubic.js.map