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

Function factorQuadratic

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

Source from the content-addressed store, hash-verified

296}
297
298/**
299 * Detect if an expression is a difference of squares.
300 * Returns the factored form (a-b)(a+b) if successful, null otherwise.
301 *
302 * Pattern: a² - b² → (a-b)(a+b)
303 *
304 * IMPORTANT: Does not call .simplify() on the result to avoid infinite recursion.
305 */
306export function factorDifferenceOfSquares(expr: Expression): Expression | null {
307 const ce = expr.engine;
308
309 // Must be an Add expression with exactly 2 terms (one positive, one negative)
310 if (!isFunction(expr, 'Add')) return null;
311
312 const terms = expr.ops;
313 if (terms.length !== 2) return null;
314
315 // Try to extract square roots of both terms
316 // One should be positive, one negative
317 const results: Array<{
318 sqrt: Expression;
319 isNegative: boolean;
320 }> = [];
321
322 for (const term of terms) {
323 // Check if term is negative
324 let isNeg = isFunction(term, 'Negate');
325 let absTerm = isNeg && isFunction(term) ? term.op1 : term;
326
327 // Also handle negative numeric literals
328 if (!isNeg && isNumber(term) && term.isNegative === true) {
329 isNeg = true;
330 absTerm = term.neg(); // Get the absolute value
331 }
332
333 // Also handle negative terms from Multiply with negative coefficient
334 if (!isNeg && isFunction(term, 'Multiply')) {
335 const ops = term.ops;
336 // Check if first operand is negative number
337 if (isNumber(ops[0]) && ops[0].isNegative === true) {
338 isNeg = true;
339 // Create positive version by negating the coefficient
340 const newOps = [ops[0].neg(), ...ops.slice(1)];
341 absTerm = ce.expr(['Multiply', ...newOps.map((op) => op.json)]);
342 }
343 }
344
345 const sqrt = extractSquareRoot(absTerm);
346 if (sqrt === null) return null;
347
348 results.push({ sqrt, isNegative: isNeg });
349 }
350
351 // We need exactly one positive and one negative square
352 const posSquares = results.filter((r) => !r.isNegative);
353 const negSquares = results.filter((r) => r.isNegative);
354
355 if (posSquares.length !== 1 || negSquares.length !== 1) return null;

Callers 5

factor.test.tsFile · 0.90
factorByRationalRootsFunction · 0.85
factorPolynomialFunction · 0.85

Calls 15

polynomialDegreeFunction · 0.90
isNumberFunction · 0.90
hasNonTrivialRadicalFunction · 0.85
checkRadicalFunction · 0.85
isSameMethod · 0.65
subMethod · 0.65
powMethod · 0.65
mulMethod · 0.65
numberMethod · 0.65
sqrtMethod · 0.65
divMethod · 0.65

Tested by

no test coverage detected