( expr: Expression, fn: (x: number) => number | Complex, bigFn?: (x: BigDecimal) => BigDecimal | Complex | number, complexFn?: (x: Complex) => number | Complex )
| 88 | numericApproximation: boolean | undefined, |
| 89 | ...ops: ReadonlyArray<Expression | undefined | null> |
| 90 | ): boolean { |
| 91 | if (numericApproximation) return true; |
| 92 | return ops.some((op) => op != null && !isExactNumber(op)); |
| 93 | } |
| 94 | |
| 95 | /** |
| 96 | * True if a kernel result is `undefined` or a NaN number/Complex/BigDecimal — |
| 97 | * the signal that the value is "outside this kernel's implemented (real) |
| 98 | * domain", used to trigger a cascade to a complex-valued kernel. A boxed |
| 99 | * `Expression` result is never a domain signal and never cascades. |
| 100 | */ |
| 101 | function isNaNKernelResult(r: unknown): boolean { |
| 102 | if (r === undefined) return true; |
| 103 | if (typeof r === 'number') return Number.isNaN(r); |
| 104 | if (r instanceof Complex) return r.isNaN(); |
| 105 | if (r instanceof BigDecimal) return r.isNaN(); |
| 106 | return false; |
| 107 | } |
| 108 | |
| 109 | export function apply( |
| 110 | expr: Expression, |
| 111 | fn: (x: number) => number | Complex, |
| 112 | bigFn?: (x: BigDecimal) => BigDecimal | Complex | number, |
| 113 | complexFn?: (x: Complex) => number | Complex |
| 114 | ): Expression | undefined { |
| 115 | if (!isNumber(expr)) return undefined; |
| 116 | const ce = expr.engine; |
| 117 | |
| 118 | let result: number | Complex | BigDecimal | undefined = undefined; |
| 119 | if (expr.im !== 0) result = complexFn?.(ce.complex(expr.re, expr.im)); |
| 120 | else { |
no test coverage detected