UNPKG

frame.akima

Version:

A package for Akima interpolation

89 lines (88 loc) 2.49 kB
/** * Evaluates the polynomial of the segment corresponding to the specified x value. * @param xVals * @param segmentCoeffs * @param x * @returns */ export function evaluatePolySegment(xVals, segmentCoeffs, x) { let i = binarySearch(xVals, x); if (i < 0) { i = -i - 2; } i = Math.max(0, Math.min(i, segmentCoeffs.length - 1)); return evaluatePoly(segmentCoeffs[i], x - xVals[i]); } /** * Corresponds to java.util.Arrays.binarySearch(). * The insertion point is defined as the point at which the key would be inserted into the array: the index of the first element greater than * the key, or a.length if all elements in the array are less than the specified key. * @param a * @param key * @returns the index of the search key, if it is contained in the array. Otherwise it returns -(insertionPoint + 1) */ export function binarySearch(a, key) { let low = 0; let high = a.length - 1; while (low <= high) { const mid = (low + high) >>> 1; // tslint:disable-line:no-bitwise const midVal = a[mid]; if (midVal < key) { low = mid + 1; } else if (midVal > key) { high = mid - 1; } else if (midVal === key) { return mid; } else { // values might be NaN throw new Error('Invalid number encountered in binary search.'); } } return -(low + 1); // key not found } /** * Evaluates the value of a polynomial. * @param c contains the polynomial coefficients in ascending order. * @param x * @returns */ export function evaluatePoly(c, x) { const n = c.length; if (n === 0) { return 0; } let v = c[n - 1]; for (let i = n - 2; i >= 0; i--) { v = x * v + c[i]; } return v; } /** * Checks that a number sequence is strictly increasing and all values are finite. * @param a */ export function checkStrictlyIncreasing(a) { for (let i = 0; i < a.length; i++) { if (!Number.isFinite(a[i])) { throw new Error('Non-finite number detected.'); } if (i > 0 && a[i] <= a[i - 1]) { throw new Error('Number sequence is not strictly increasing.'); } } } /** * Trims top order polynomial coefficients which are zero. * @param c * @returns */ export function trimPoly(c) { let n = c.length; while (n > 1 && c[n - 1] === 0) { n--; } return n === c.length ? c : c.subarray(0, n); }