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

Function simplifyLogCore

src/compute-engine/symbolic/simplify-log.ts:40–905  ·  view source on GitHub ↗
(x: Expression)

Source from the content-addressed store, hash-verified

38 *
39 * They are matched by exact label, NOT by an `e^(ln(` prefix: sibling rules in
40 * this file label themselves `e^(ln(x) * y) -> x^y` and
41 * `e^(ln(x) / y) -> x^(1/y)`, which such a prefix would silently exempt too.
42 * Neither needs the exemption (both reduce cost on their own), and a
43 * `transform` tag is an unconditional gate bypass, so it should never be
44 * handed out by accident.
45 *
46 * The `combine ln/log terms`, `c^...` and `log base 0 or 1` steps remain
47 * untagged.
48 */
49const EXP_OF_LOG_SUM_LABELS = new Set([
50 'e^(ln(x) + y) -> x * e^y',
51 'e^(log_c(x) + y) -> x^{1/ln(c)} * e^y',
52]);
53
54export function simplifyLog(x: Expression): RuleStep | undefined {
55 const r = simplifyLogCore(x);
56 if (r === undefined) return r;
57 const b = r.because;
58 if (
59 b === 'ln' ||
60 b?.startsWith('ln(') ||
61 b?.startsWith('log_') ||
62 (b !== undefined && EXP_OF_LOG_SUM_LABELS.has(b))
63 )
64 return { ...r, purpose: 'transform' };
65 return r;
66}
67
68function simplifyLogCore(x: Expression): RuleStep | undefined {
69 const op = x.operator;
70 const ce = x.engine;
71
72 if (!isFunction(x)) return undefined;
73
74 // Handle Ln
75 if (op === 'Ln') {
76 const arg = x.op1;
77 if (!arg) return undefined;
78
79 // ln(0) -> -inf (matches `evaluate()`/`BoxedNumber.ln()`, and Mathematica's
80 // `Log[0] == -Infinity`). This branch is currently shadowed by the
81 // unconditional "Ln, Log (basic evaluation)" rule in simplify-rules.ts,
82 // which calls `.ln()` and already reduces `Ln(0)` before this one runs —
83 // but keep this in sync with `evaluate()` in case that ordering changes.
84 if (arg.isSame(0)) {
85 return { value: ce.NegativeInfinity, because: 'ln(0) -> -inf' };
86 }
87
88 // ln(+inf) -> +inf
89 if (arg.isInfinity === true && arg.isPositive === true) {
90 return { value: ce.PositiveInfinity, because: 'ln(+inf) -> +inf' };
91 }
92
93 // ln(p/q) -> ln(p) - ln(q) for positive rational p/q (not integer)
94 if (
95 arg.operator === 'Rational' &&
96 arg.isRational === true &&
97 arg.isInteger === false

Callers 1

simplifyLogFunction · 0.85

Calls 15

isFunctionFunction · 0.90
isEligibleRealRewriteFunction · 0.90
onBranchCutFunction · 0.90
symFunction · 0.90
toBigintFunction · 0.90
isSameMethod · 0.65
negMethod · 0.65
_fnMethod · 0.65
numberMethod · 0.65
subMethod · 0.65
mulMethod · 0.65
addMethod · 0.65

Tested by

no test coverage detected