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

Function reduceBigOp

src/compute-engine/library/utils.ts:561–645  ·  view source on GitHub ↗
(
  body: Expression,
  indexes: ReadonlyArray<Expression>,
  fn: (acc: T, x: Expression) => T | null,
  initial: T
)

Source from the content-addressed store, hash-verified

559 */
560export function symbolicProductClosedForm(
561 body: Expression | undefined,
562 limits: Expression,
563 ce: ComputeEngine
564): Expression | undefined {
565 if (!body || !isFunction(limits, 'Limits')) return undefined;
566 const index = isSymbol(limits.op1) ? limits.op1.symbol : undefined;
567 const lower = limits.op2;
568 const upper = limits.op3;
569 if (!index || !lower || !upper) return undefined;
570
571 // Π_{k=1}^{n} k = n! (bare index, lower bound 1).
572 if (isSymbol(body) && body.symbol === index && lower.isSame(1))
573 return ce.function('Factorial', [upper]);
574
575 // Telescoping product: body = h(k+1)/h(k).
576 const { num, den } = asSingleFraction(body, ce);
577 if (new Set(num.unknowns).has(index) && new Set(den.unknowns).has(index)) {
578 // forward: den shifted by k→k+1 equals num ⇒ body = h(k+1)/h(k), h = den.
579 if (shiftIndex(den, index, ce).isSame(num))
580 return ce.function('Divide', [
581 num.subs({ [index]: upper }),
582 den.subs({ [index]: lower }),
583 ]);
584 // mirror: num shifted by k→k+1 equals den ⇒ body = h(k)/h(k+1), h = num.
585 if (shiftIndex(num, index, ce).isSame(den))
586 return ce.function('Divide', [
587 num.subs({ [index]: lower }),
588 den.subs({ [index]: upper }),
589 ]);
590 }
591
592 return undefined;
593}
594
595/**
596 * Reformat an evaluated closed form so a rational multiple of a symbolic factor
597 * reads as a fraction: `Multiply(Rational(p, q), R)` → `Divide(p·R, q)` (and
598 * `Divide(R, q)` when `p = 1`). Mirrors the readability intent of the
599 * telescoping `Subtract` above (`π²/6` instead of `(1/6)·π²`). Any other shape
600 * is returned unchanged.
601 */
602function asReadableFraction(z: Expression, ce: ComputeEngine): Expression {
603 if (!isFunction(z, 'Multiply')) return z;
604 let coeff: Expression | undefined;
605 const rest: Expression[] = [];
606 for (const op of z.ops) {
607 if (coeff === undefined && isNumber(op) && op.im === 0) coeff = op;
608 else rest.push(op);
609 }
610 if (coeff === undefined || rest.length === 0) return z;
611 const [num, den] = coeff.numeratorDenominator;
612 if (den.isSame(1)) return z;
613 const restExpr =
614 rest.length === 1
615 ? rest[0]
616 : ce.function('Multiply', rest, { form: 'structural' });
617 const numExpr = num.isSame(1)
618 ? restExpr

Callers 1

arithmetic.tsFile · 0.90

Calls 8

reduceCollectionFunction · 0.90
fnFunction · 0.85
normalizeIndexingSetsFunction · 0.85
evaluateMethod · 0.65
assignMethod · 0.65
nextMethod · 0.45

Tested by

no test coverage detected