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

Function onBranchCut

src/compute-engine/function-properties/index.ts:197–233  ·  view source on GitHub ↗
(
  ce: IComputeEngine,
  operator: string,
  arg: Expression
)

Source from the content-addressed store, hash-verified

195}
196
197/**
198 * Eligibility gate for **real-only** simplification rewrites (policy D4).
199 *
200 * Rewrites that are valid only on the reals — `√(x²) → |x|`, `|x²| → x²`,
201 * `|x|² → x²`, `ln(x^{2k}) → 2k·ln|x|` — must not fire when the operand was
202 * *declared* (or provably inferred) a complex or imaginary type. Although
203 * `complex ⊇ real`, an explicit `complex`/`imaginary` declaration signals a
204 * *general* complex value, so these rewrites bail on it (e.g.
205 * `z: complex ⇒ √(z²)` stays `√(z²)`, not `|z|`, since `√(i²) = i ≠ 1`).
206 *
207 * *Unconstrained* symbols (type `unknown`) — and composite expressions of them
208 * (`x·y`, `x+1`, which the engine types `number`) — keep the
209 * documented generic-real convention and remain eligible.
210 *
211 * Detection is by **type**, not by `isExtendedReal`. That predicate is
212 * three-valued for functions as well as symbols, so a composite expression of
213 * unconstrained symbols answers `undefined` rather than `true`: `x·y` and
214 * `ln(x)` both type `number`, which is not below the extended real line.
215 * Gating on it would therefore need a decision about the
216 * `undefined` case, and treating `undefined` as "bail" would drop the
217 * generic-real convention on `ln(x)+ln(y) → ln(xy)` and friends. A type that
218 * matches `complex` but not `real` is a two-valued test that reliably
219 * identifies declared/inferred complex operands, which is what D4 targets.
220 *
221 * @returns `false` (bail) when `x`'s type admits genuinely non-real complex
222 * values — that is, `complex` or `imaginary`; `true` otherwise.
223 */
224export function isEligibleRealRewrite(x: Expression): boolean {
225 return !isNonRealNumber(x.type.type);
226}
227
228// Operators that carry at least one Poles record — a cheap gate so the numeric
229// evaluator only does membership work for functions that can have poles.
230const POLE_OPERATORS: ReadonlySet<string> = new Set(
231 Object.keys(DATA.operators).filter((op) =>
232 DATA.operators[op].some((r) => r.property === 'Poles')
233 )
234);
235
236function isOnPoleSet(

Callers 3

simplifyLogCoreFunction · 0.90
lnMethod · 0.90

Calls 5

getFunctionPropertiesFunction · 0.85
hasMethod · 0.65
valueOfMethod · 0.65
evaluateMethod · 0.65
functionMethod · 0.65

Tested by

no test coverage detected