split u = scale·x^m·rest where scale and m are x-free and rest is the * single non-monomial x-dependent factor (null when u has no such shape)
( u: Expression, x: string )
| 2030 | b: s.mul(t.b).evaluate(), |
| 2031 | c: s.mul(t.c).evaluate(), |
| 2032 | n: t.n, |
| 2033 | }); |
| 2034 | switch (u.operator) { |
| 2035 | case 'Power': { |
| 2036 | // w^2 with w a binomial (a ≠ 0) → (a + b·x^n)² trinomial |
| 2037 | if (realNum(ops[1]) !== 2) return null; |
| 2038 | const p = binomialPartsX(ops[0], x); |
| 2039 | if (p === null || p.a.isSame(0) || zeroQ(p.a)) return null; |
| 2040 | return { |
| 2041 | a: p.a.pow(2).evaluate(), |
| 2042 | b: p.a.mul(p.b).mul(2).evaluate(), |
| 2043 | c: p.b.pow(2).evaluate(), |
| 2044 | n: p.n, |
| 2045 | }; |
| 2046 | } |
| 2047 | case 'Negate': { |
| 2048 | const t = trinomialPartsX(ops[0], x); |
| 2049 | return t === null ? null : scaleTri(ce.NegativeOne, t); |
| 2050 | } |
| 2051 | case 'Divide': { |
| 2052 | if (ops[1].has(x)) return null; |
| 2053 | const t = trinomialPartsX(ops[0], x); |
| 2054 | return t === null ? null : scaleTri(ce.One.div(ops[1]), t); |
| 2055 | } |
| 2056 | case 'Multiply': { |
| 2057 | let scale = ce.One; |
| 2058 | const dep: Expression[] = []; |
| 2059 | for (const f of ops) { |
no test coverage detected