MCPcopy Create free account
hub / github.com/arguiot/TheoremJS / findRoots

Method findRoots

__test__/theorem.js:614–676  ·  view source on GitHub ↗
(f)

Source from the content-addressed store, hash-verified

612 }
613 }
614 findRoots(f) {
615 let exp = [];
616 if (f.type == "polynomial") {
617 switch (f.values.length - 1) {
618 case 1: {
619 exp.push(`${new BigNumber(f.values[1]).isNegative() ? '' : '-'}${f.values[1]} / ${f.values[0]}`)
620 break;
621 }
622 case 2: {
623 const delta = new BigNumber(f.values[1]).pow(2).minus(new BigNumber(4).times(f.values[0]).times(f.values[2])).toNumber()
624 if (delta > 0) {
625 exp.push(`(${new BigNumber(f.values[1]).isNegative() ? '' : '-'}${new BigNumber(f.values[1]).abs()} + Math.sqrt(${delta})) / ${new BigNumber(f.values[0]).times(2)}`)
626 exp.push(`(${new BigNumber(f.values[1]).isNegative() ? '' : '-'}${new BigNumber(f.values[1]).abs()} - Math.sqrt(${delta})) / ${new BigNumber(f.values[0]).times(2)}`)
627 }
628 break;
629 }
630 case 3: {
631 let a = new BigNumber(f.values[0]).toNumber()
632 let b = new BigNumber(f.values[1]).toNumber()
633 let c = new BigNumber(f.values[2]).toNumber()
634 let d = new BigNumber(f.values[3]).toNumber()
635
636 // Convert to depressed cubic t^3+pt+q = 0 (subst x = t - b/3a)
637 var p = (3 * a * c - b * b) / (3 * a * a);
638 var q = (2 * b * b * b - 9 * a * b * c + 27 * a * a * d) / (27 * a * a * a);
639 var roots;
640
641 if (Math.abs(p) < 1e-8) { // p = 0 -> t^3 = -q -> t = -q^1/3
642 roots = [Math.cbrt(-q)];
643 } else if (Math.abs(q) < 1e-8) { // q = 0 -> t^3 + pt = 0 -> t(t^2+p)=0
644 roots = [0].concat(p < 0 ? [Math.sqrt(-p), -Math.sqrt(-p)] : []);
645 } else {
646 var D = q * q / 4 + p * p * p / 27;
647
648 var u; // no-redeclare
649 if (Math.abs(D) < 1e-8) { // D = 0 -> two roots
650 roots = [-1.5 * q / p, 3 * q / p];
651 } else if (D > 0) { // Only one real root
652 u = Math.cbrt(-q / 2 - Math.sqrt(D));
653 roots = [u - p / (3 * u)];
654 } else { // D < 0, three roots, but needs to use complex numbers/trigonometric solution
655 u = 2 * Math.sqrt(-p / 3);
656 var t = Math.acos(3 * q / p / u) / 3; // D < 0 implies p < 0 and acos argument in [-1..1]
657 var k = 2 * Math.PI / 3;
658 roots = [u * Math.cos(t), u * Math.cos(t - k), u * Math.cos(t - 2 * k)];
659 }
660 }
661
662 // Convert back from depressed cubic
663 for (var i = 0; i < roots.length; i++)
664 roots[i] -= b / (3 * a);
665 exp = roots;
666 break;
667 }
668 default: {
669 exp = [this.numeralSolve(f, 0)[0]]
670 }
671 }

Callers 1

test.jsFile · 0.80

Calls 8

numeralSolveMethod · 0.95
minusMethod · 0.80
timesMethod · 0.80
sqrtMethod · 0.80
acosMethod · 0.80
cosMethod · 0.80
powMethod · 0.45
absMethod · 0.45

Tested by

no test coverage detected