UNPKG

theorem.js

Version:

A Math library for computation in JavaScript

64 lines (59 loc) 2.9 kB
findRoots(f) { let exp = []; if (f.type == "polynomial") { switch (f.values.length - 1) { case 1: { exp.push(`${new BigNumber(f.values[1]).isNegative() ? '' : '-'}${f.values[1]} / ${f.values[0]}`) break; } case 2: { const delta = new BigNumber(f.values[1]).pow(2).minus(new BigNumber(4).times(f.values[0]).times(f.values[2])).toNumber() if (delta > 0) { exp.push(`(${new BigNumber(f.values[1]).isNegative() ? '' : '-'}${new BigNumber(f.values[1]).abs()} + Math.sqrt(${delta})) / ${new BigNumber(f.values[0]).times(2)}`) exp.push(`(${new BigNumber(f.values[1]).isNegative() ? '' : '-'}${new BigNumber(f.values[1]).abs()} - Math.sqrt(${delta})) / ${new BigNumber(f.values[0]).times(2)}`) } break; } case 3: { let a = new BigNumber(f.values[0]).toNumber() let b = new BigNumber(f.values[1]).toNumber() let c = new BigNumber(f.values[2]).toNumber() let d = new BigNumber(f.values[3]).toNumber() // Convert to depressed cubic t^3+pt+q = 0 (subst x = t - b/3a) var p = (3 * a * c - b * b) / (3 * a * a); var q = (2 * b * b * b - 9 * a * b * c + 27 * a * a * d) / (27 * a * a * a); var roots; if (Math.abs(p) < 1e-8) { // p = 0 -> t^3 = -q -> t = -q^1/3 roots = [Math.cbrt(-q)]; } else if (Math.abs(q) < 1e-8) { // q = 0 -> t^3 + pt = 0 -> t(t^2+p)=0 roots = [0].concat(p < 0 ? [Math.sqrt(-p), -Math.sqrt(-p)] : []); } else { var D = q * q / 4 + p * p * p / 27; var u; // no-redeclare if (Math.abs(D) < 1e-8) { // D = 0 -> two roots roots = [-1.5 * q / p, 3 * q / p]; } else if (D > 0) { // Only one real root u = Math.cbrt(-q / 2 - Math.sqrt(D)); roots = [u - p / (3 * u)]; } else { // D < 0, three roots, but needs to use complex numbers/trigonometric solution u = 2 * Math.sqrt(-p / 3); var t = Math.acos(3 * q / p / u) / 3; // D < 0 implies p < 0 and acos argument in [-1..1] var k = 2 * Math.PI / 3; roots = [u * Math.cos(t), u * Math.cos(t - k), u * Math.cos(t - 2 * k)]; } } // Convert back from depressed cubic for (var i = 0; i < roots.length; i++) roots[i] -= b / (3 * a); exp = roots; break; } default: { exp = [this.numeralSolve(f, 0)[0]] } } } else { exp = [this.numeralSolve(f, 0)[0]] } return exp }