MCPcopy Create free account
hub / github.com/cortex-js/compute-engine / factorPolynomial

Function factorPolynomial

src/compute-engine/boxed-expression/factor.ts:559–619  ·  view source on GitHub ↗
(
  expr: Expression,
  variable?: string
)

Source from the content-addressed store, hash-verified

557 * IMPORTANT: Does not call .simplify() to avoid infinite recursion.
558 */
559function extractContent(expr: Expression, variable: string): Expression | null {
560 const ce = expr.engine;
561 const coeffs = getPolynomialCoefficients(expr, variable);
562 if (!coeffs) return null;
563
564 // Extract integer values from all coefficients
565 const intCoeffs: number[] = [];
566 for (const c of coeffs) {
567 const n = asSmallInteger(c);
568 if (n === null) return null;
569 intCoeffs.push(n);
570 }
571
572 // Compute GCD of all non-zero coefficients
573 const gcd = (a: number, b: number): number => {
574 a = Math.abs(a);
575 b = Math.abs(b);
576 while (b) {
577 [a, b] = [b, a % b];
578 }
579 return a;
580 };
581
582 let content = 0;
583 for (const c of intCoeffs) {
584 if (c !== 0) content = gcd(content, c);
585 }
586
587 if (content <= 1) return null;
588
589 // If the leading coefficient is negative, extract a negative content so
590 // the primitive part leads with a positive coefficient:
591 // -2x - 4 → -2(x + 2), not 2(-x - 2)
592 // (the top slot can be 0 if leading terms canceled during expansion, so
593 // scan back to the last non-zero coefficient)
594 let i = intCoeffs.length - 1;
595 while (i >= 0 && intCoeffs[i] === 0) i -= 1;
596 if (i >= 0 && intCoeffs[i] < 0) content = -content;
597
598 // Divide all coefficients by the content to get the primitive part
599 const primitiveCoeffs = coeffs.map((c) => {
600 const n = asSmallInteger(c)!;
601 return ce.number(n / content);
602 });
603
604 // Reconstruct the primitive polynomial
605 const primitive = fromCoefficients(primitiveCoeffs, variable);
606
607 // Recursively factor the primitive part
608 const factoredPrimitive = factorPolynomial(primitive, variable);
609
610 // Build the product `content · primitive` with ce.function rather than
611 // `.mul()`. The arithmetic `.mul()` distributes a numeric factor over a
612 // bare sum — e.g. `3 · (2x + 3)` collapses back to `6x + 9`, undoing the
613 // content extraction for a primitive that doesn't factor further (such as
614 // a linear polynomial). Canonical `Multiply` does not distribute, so the
615 // factored form is preserved. `|content|` is always ≥ 2 here (we returned
616 // null for content ≤ 1 before applying the sign), so the coefficient-±1

Callers 8

factor.test.tsFile · 0.90
polynomials.tsFile · 0.90
extractContentFunction · 0.85
refactorProductFactorsFunction · 0.85
extractMonomialContentFunction · 0.85
partialFractionFunction · 0.85

Calls 9

isFunctionFunction · 0.90
refactorProductFactorsFunction · 0.85
extractContentFunction · 0.85
extractMonomialContentFunction · 0.85
factorPerfectSquareFunction · 0.85
factorQuadraticFunction · 0.85
factorByRationalRootsFunction · 0.85
factorFunction · 0.70

Tested by

no test coverage detected