UNPKG

@thi.ng/math

Version:

Assorted common math functions & utilities

93 lines (92 loc) 2.62 kB
import { EPS } from "./api.js"; import { safeDiv } from "./safe-div.js"; const derivative = (f, eps = EPS) => (x) => (f(x + eps) - f(x)) / eps; const solveLinear = (a, b) => safeDiv(-b, a); const solveQuadratic = (a, b, c, eps = 1e-9) => { const d = 2 * a; let r = b * b - 4 * a * c; return r < 0 ? [] : r < eps ? [-b / d] : (r = Math.sqrt(r), [(-b - r) / d, (-b + r) / d]); }; const solveCubic = (a, b, c, d, eps = 1e-9) => { const aa = a * a; const bb = b * b; const ba3 = b / (3 * a); const p = (3 * a * c - bb) / (3 * aa); const q = (2 * bb * b - 9 * a * b * c + 27 * aa * d) / (27 * aa * a); if (Math.abs(p) < eps) { return [Math.cbrt(-q) - ba3]; } else if (Math.abs(q) < eps) { return p < 0 ? [-Math.sqrt(-p) - ba3, -ba3, Math.sqrt(-p) - ba3] : [-ba3]; } else { const denom = q * q / 4 + p * p * p / 27; if (Math.abs(denom) < eps) { return [-1.5 * q / p - ba3, 3 * q / p - ba3]; } else if (denom > 0) { const u = Math.cbrt(-q / 2 - Math.sqrt(denom)); return [u - p / (3 * u) - ba3]; } else { const u = 2 * Math.sqrt(-p / 3), t = Math.acos(3 * q / p / u) / 3, k = 2 * Math.PI / 3; return [ u * Math.cos(t) - ba3, u * Math.cos(t - k) - ba3, u * Math.cos(t - 2 * k) - ba3 ]; } } }; const solveTridiagonal = (a, b, c, d) => { const n = d.length - 1; const tmp = new Array(n + 1); tmp[0] = c[0] / b[0]; d[0] = d[0] / b[0]; for (let i = 1; i <= n; i++) { const ai = a[i]; const bi = b[i]; const denom = 1 / (bi - ai * tmp[i - 1]); tmp[i] = c[i] * denom; d[i] = (d[i] - ai * d[i - 1]) * denom; } for (let i = n; i-- > 0; ) { d[i] -= tmp[i] * d[i + 1]; } return d; }; const gaussianElimination = (mat, degree) => { const n = mat.length - 1; const coeffs = [degree]; for (let i = 0; i < n; i++) { let max = i; const col = mat[i]; for (let j = i + 1; j < n; j++) { if (Math.abs(col[j]) > Math.abs(col[max])) max = j; } for (let k = i; k <= n; k++) { const col2 = mat[k]; const tmp = col2[i]; col2[i] = col2[max]; col2[max] = tmp; } for (let j = i + 1; j < n; j++) { for (let k = n; k >= i; k--) { mat[k][j] -= mat[k][i] * mat[i][j] / mat[i][i]; } } } for (let j = n; j-- > 0; ) { const d = mat[j][j]; let sum = 0; for (let k = j + 1; k < n; k++) { sum += mat[k][j] * coeffs[k]; } coeffs[j] = (mat[n][j] - sum) / d; } return coeffs; }; export { derivative, gaussianElimination, solveCubic, solveLinear, solveQuadratic, solveTridiagonal };