monomial decomposition: u = Σ coeff·x^deg, coefficients x-free. * Returns null when u is not a polynomial in x.
(u: Expression, x: string)
| 288 | let m = 0; |
| 289 | for (const t of ops) { |
| 290 | const d = polyDegreeX(t, x); |
| 291 | if (d < 0) return -1; |
| 292 | m = Math.max(m, d); |
| 293 | } |
| 294 | return m; |
| 295 | } |
| 296 | case 'Multiply': { |
| 297 | let s = 0; |
| 298 | for (const t of ops) { |
| 299 | const d = polyDegreeX(t, x); |
| 300 | if (d < 0) return -1; |
| 301 | s += d; |
| 302 | } |
| 303 | return s; |
| 304 | } |
| 305 | case 'Negate': |
| 306 | return polyDegreeX(ops[0], x); |
| 307 | case 'Subtract': { |
| 308 | const d0 = polyDegreeX(ops[0], x); |
| 309 | const d1 = polyDegreeX(ops[1], x); |
| 310 | return d0 < 0 || d1 < 0 ? -1 : Math.max(d0, d1); |
| 311 | } |
| 312 | case 'Power': { |
| 313 | const e = realNum(ops[1]); |
| 314 | if (e === null || !Number.isInteger(e) || e < 0) return -1; |
| 315 | const d = polyDegreeX(ops[0], x); |
| 316 | return d < 0 ? -1 : d * e; |
| 317 | } |
| 318 | case 'Divide': |
| 319 | return ops[1].has(x) ? -1 : polyDegreeX(ops[0], x); |
| 320 | } |
| 321 | return -1; |
| 322 | } |
| 323 | |
| 324 | /** monomial decomposition: u = Σ coeff·x^deg, coefficients x-free. |
| 325 | * Returns null when u is not a polynomial in x. */ |
| 326 | function monomialsX(u: Expression, x: string): [Expression, number][] | null { |
| 327 | const ce = u.engine; |
| 328 | if (!u.has(x)) return [[u, 0]]; |
| 329 | if (u.symbol === x) return [[ce.One, 1]]; |
| 330 | const ops = u.ops; |
| 331 | if (!ops) return null; |
| 332 | switch (u.operator) { |
| 333 | case 'Add': { |
| 334 | const out: [Expression, number][] = []; |
| 335 | for (const t of ops) { |
| 336 | const m = monomialsX(t, x); |
| 337 | if (m === null) return null; |
| 338 | out.push(...m); |
| 339 | } |
| 340 | return out; |
| 341 | } |
| 342 | case 'Negate': { |
| 343 | const m = monomialsX(ops[0], x); |
| 344 | return m === null ? null : m.map(([c, d]) => [c.neg(), d]); |
| 345 | } |
| 346 | case 'Subtract': { |
| 347 | const m0 = monomialsX(ops[0], x); |