(
xPow: Expression,
ePow: Expression
)
| 87 | * |
| 88 | * To change the cost function used by the engine, set the |
| 89 | * `ce.costFunction` property of the engine or pass a custom cost function |
| 90 | * to the `simplify` function. |
| 91 | * |
| 92 | */ |
| 93 | /** |
| 94 | * Price a `Power(base, exp)`. Extracted so the alias heads that canonicalize |
| 95 | * to a Power (`Square`, `Exp`) price identically to the canonical form — the |
| 96 | * cost function must not depend on which representation it is handed. |
| 97 | * |
| 98 | * The base is mostly ignored so that `2q^2` beats `2qq`, except when the base |
| 99 | * is a `Negate` (so `(-x)^n` is not cheaper than `-x^n`) or a `Multiply` (so |
| 100 | * `(ab)^n` is not artificially cheaper than the distributed `a^n b^n`). |
| 101 | */ |
| 102 | function powerCost(base: Expression, exp: Expression): number { |
| 103 | const expCost = costFunction(exp); |
| 104 | // Count a negated base too. This used to be a flat `expCost + 4`, which |
| 105 | // discarded everything under the sign — the same defect as the removed |
| 106 | // `Negate(Power(...))` shortcut, just on the other side. Once `Power` began |
| 107 | // counting its base it became load-bearing: `(-sin x)^2` scored 5 against |
| 108 | // `sin(x)^2` at 12, so the gate REJECTED the rewrite and left the negation |
| 109 | // in place. A symbol base hid it (`(-x)^2 -> x^2` still worked). |
| 110 | if (base.operator === 'Negate') return expCost + costFunction(base); |
| 111 | if (isFunction(base, 'Multiply')) { |
no test coverage detected