@cortex-js/compute-engine 0.53.1 → 0.54.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (226) hide show
  1. package/dist/compute-engine.esm.js +979 -288
  2. package/dist/compute-engine.min.esm.js +70 -70
  3. package/dist/compute-engine.min.umd.cjs +72 -72
  4. package/dist/compute-engine.umd.cjs +979 -288
  5. package/dist/math-json.esm.js +2 -2
  6. package/dist/math-json.min.esm.js +2 -2
  7. package/dist/math-json.min.umd.cjs +2 -2
  8. package/dist/math-json.umd.cjs +2 -2
  9. package/dist/types/common/ansi-codes.d.ts +1 -1
  10. package/dist/types/common/configuration-change.d.ts +1 -1
  11. package/dist/types/common/fuzzy-string-match.d.ts +1 -1
  12. package/dist/types/common/grapheme-splitter.d.ts +1 -1
  13. package/dist/types/common/interruptible.d.ts +1 -1
  14. package/dist/types/common/one-of.d.ts +1 -1
  15. package/dist/types/common/signals.d.ts +1 -1
  16. package/dist/types/common/type/ast-nodes.d.ts +1 -1
  17. package/dist/types/common/type/boxed-type.d.ts +1 -1
  18. package/dist/types/common/type/lexer.d.ts +1 -1
  19. package/dist/types/common/type/parse.d.ts +1 -1
  20. package/dist/types/common/type/parser.d.ts +1 -1
  21. package/dist/types/common/type/primitive.d.ts +1 -1
  22. package/dist/types/common/type/reduce.d.ts +1 -1
  23. package/dist/types/common/type/serialize.d.ts +1 -1
  24. package/dist/types/common/type/subtype.d.ts +1 -1
  25. package/dist/types/common/type/type-builder.d.ts +1 -1
  26. package/dist/types/common/type/types.d.ts +1 -1
  27. package/dist/types/common/type/utils.d.ts +1 -1
  28. package/dist/types/common/utils.d.ts +1 -1
  29. package/dist/types/compute-engine/assume.d.ts +1 -1
  30. package/dist/types/compute-engine/boxed-expression/abstract-boxed-expression.d.ts +14 -3
  31. package/dist/types/compute-engine/boxed-expression/apply.d.ts +1 -1
  32. package/dist/types/compute-engine/boxed-expression/arithmetic-add.d.ts +1 -1
  33. package/dist/types/compute-engine/boxed-expression/arithmetic-mul-div.d.ts +1 -1
  34. package/dist/types/compute-engine/boxed-expression/arithmetic-power.d.ts +1 -1
  35. package/dist/types/compute-engine/boxed-expression/ascii-math.d.ts +1 -1
  36. package/dist/types/compute-engine/boxed-expression/box.d.ts +1 -1
  37. package/dist/types/compute-engine/boxed-expression/boxed-dictionary.d.ts +1 -1
  38. package/dist/types/compute-engine/boxed-expression/boxed-function.d.ts +3 -3
  39. package/dist/types/compute-engine/boxed-expression/boxed-number.d.ts +3 -3
  40. package/dist/types/compute-engine/boxed-expression/boxed-operator-definition.d.ts +1 -1
  41. package/dist/types/compute-engine/boxed-expression/boxed-patterns.d.ts +1 -1
  42. package/dist/types/compute-engine/boxed-expression/boxed-string.d.ts +1 -1
  43. package/dist/types/compute-engine/boxed-expression/boxed-symbol.d.ts +3 -3
  44. package/dist/types/compute-engine/boxed-expression/boxed-tensor.d.ts +1 -1
  45. package/dist/types/compute-engine/boxed-expression/boxed-value-definition.d.ts +1 -1
  46. package/dist/types/compute-engine/boxed-expression/cache.d.ts +1 -1
  47. package/dist/types/compute-engine/boxed-expression/canonical-utils.d.ts +1 -1
  48. package/dist/types/compute-engine/boxed-expression/canonical.d.ts +1 -1
  49. package/dist/types/compute-engine/boxed-expression/compare.d.ts +1 -1
  50. package/dist/types/compute-engine/boxed-expression/constants.d.ts +1 -1
  51. package/dist/types/compute-engine/boxed-expression/expand.d.ts +1 -1
  52. package/dist/types/compute-engine/boxed-expression/expression-map.d.ts +1 -1
  53. package/dist/types/compute-engine/boxed-expression/factor.d.ts +37 -4
  54. package/dist/types/compute-engine/boxed-expression/flatten.d.ts +1 -1
  55. package/dist/types/compute-engine/boxed-expression/hold.d.ts +1 -1
  56. package/dist/types/compute-engine/boxed-expression/inequality-bounds.d.ts +1 -1
  57. package/dist/types/compute-engine/boxed-expression/init-lazy-refs.d.ts +1 -1
  58. package/dist/types/compute-engine/boxed-expression/invisible-operator.d.ts +1 -1
  59. package/dist/types/compute-engine/boxed-expression/match.d.ts +2 -2
  60. package/dist/types/compute-engine/boxed-expression/negate.d.ts +1 -1
  61. package/dist/types/compute-engine/boxed-expression/numerics.d.ts +1 -1
  62. package/dist/types/compute-engine/boxed-expression/order.d.ts +1 -1
  63. package/dist/types/compute-engine/boxed-expression/pattern-utils.d.ts +1 -1
  64. package/dist/types/compute-engine/boxed-expression/polynomial-degree.d.ts +1 -1
  65. package/dist/types/compute-engine/boxed-expression/polynomials.d.ts +1 -1
  66. package/dist/types/compute-engine/boxed-expression/predicates.d.ts +1 -1
  67. package/dist/types/compute-engine/boxed-expression/rules.d.ts +1 -1
  68. package/dist/types/compute-engine/boxed-expression/serialize.d.ts +1 -1
  69. package/dist/types/compute-engine/boxed-expression/sgn.d.ts +1 -1
  70. package/dist/types/compute-engine/boxed-expression/simplify.d.ts +1 -1
  71. package/dist/types/compute-engine/boxed-expression/solve-linear-system.d.ts +1 -1
  72. package/dist/types/compute-engine/boxed-expression/solve.d.ts +1 -1
  73. package/dist/types/compute-engine/boxed-expression/stochastic-equal.d.ts +1 -1
  74. package/dist/types/compute-engine/boxed-expression/trigonometry.d.ts +1 -1
  75. package/dist/types/compute-engine/boxed-expression/type-guards.d.ts +1 -1
  76. package/dist/types/compute-engine/boxed-expression/utils.d.ts +1 -1
  77. package/dist/types/compute-engine/boxed-expression/validate.d.ts +1 -1
  78. package/dist/types/compute-engine/collection-utils.d.ts +1 -1
  79. package/dist/types/compute-engine/compilation/base-compiler.d.ts +1 -1
  80. package/dist/types/compute-engine/compilation/compile-expression.d.ts +1 -1
  81. package/dist/types/compute-engine/compilation/glsl-target.d.ts +1 -1
  82. package/dist/types/compute-engine/compilation/gpu-target.d.ts +1 -1
  83. package/dist/types/compute-engine/compilation/interval-javascript-target.d.ts +1 -1
  84. package/dist/types/compute-engine/compilation/javascript-target.d.ts +1 -1
  85. package/dist/types/compute-engine/compilation/python-target.d.ts +1 -1
  86. package/dist/types/compute-engine/compilation/types.d.ts +1 -1
  87. package/dist/types/compute-engine/compilation/wgsl-target.d.ts +1 -1
  88. package/dist/types/compute-engine/cost-function.d.ts +1 -1
  89. package/dist/types/compute-engine/engine-assumptions.d.ts +1 -1
  90. package/dist/types/compute-engine/engine-cache.d.ts +1 -1
  91. package/dist/types/compute-engine/engine-common-symbols.d.ts +1 -1
  92. package/dist/types/compute-engine/engine-compilation-targets.d.ts +1 -1
  93. package/dist/types/compute-engine/engine-configuration-lifecycle.d.ts +1 -1
  94. package/dist/types/compute-engine/engine-declarations.d.ts +1 -1
  95. package/dist/types/compute-engine/engine-expression-entrypoints.d.ts +1 -1
  96. package/dist/types/compute-engine/engine-extension-contracts.d.ts +1 -1
  97. package/dist/types/compute-engine/engine-latex-dictionary-state.d.ts +1 -1
  98. package/dist/types/compute-engine/engine-library-bootstrap.d.ts +1 -1
  99. package/dist/types/compute-engine/engine-numeric-configuration.d.ts +1 -1
  100. package/dist/types/compute-engine/engine-parse-entrypoint.d.ts +1 -1
  101. package/dist/types/compute-engine/engine-runtime-state.d.ts +1 -1
  102. package/dist/types/compute-engine/engine-scope.d.ts +1 -1
  103. package/dist/types/compute-engine/engine-sequences.d.ts +1 -1
  104. package/dist/types/compute-engine/engine-simplification-rules.d.ts +1 -1
  105. package/dist/types/compute-engine/engine-startup-coordinator.d.ts +1 -1
  106. package/dist/types/compute-engine/engine-type-resolver.d.ts +1 -1
  107. package/dist/types/compute-engine/engine-validation-entrypoints.d.ts +1 -1
  108. package/dist/types/compute-engine/free-functions.d.ts +1 -1
  109. package/dist/types/compute-engine/function-utils.d.ts +1 -1
  110. package/dist/types/compute-engine/global-types.d.ts +1 -1
  111. package/dist/types/compute-engine/index.d.ts +1 -1
  112. package/dist/types/compute-engine/interval/arithmetic.d.ts +1 -1
  113. package/dist/types/compute-engine/interval/comparison.d.ts +1 -1
  114. package/dist/types/compute-engine/interval/elementary.d.ts +1 -1
  115. package/dist/types/compute-engine/interval/index.d.ts +1 -1
  116. package/dist/types/compute-engine/interval/trigonometric.d.ts +1 -1
  117. package/dist/types/compute-engine/interval/types.d.ts +1 -1
  118. package/dist/types/compute-engine/interval/util.d.ts +1 -1
  119. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-algebra.d.ts +1 -1
  120. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-arithmetic.d.ts +1 -1
  121. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-calculus.d.ts +1 -1
  122. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-complex.d.ts +1 -1
  123. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-core.d.ts +1 -1
  124. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-linear-algebra.d.ts +1 -1
  125. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-logic.d.ts +1 -1
  126. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-other.d.ts +1 -1
  127. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-relational-operators.d.ts +1 -1
  128. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-sets.d.ts +1 -1
  129. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-statistics.d.ts +1 -1
  130. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-symbols.d.ts +1 -1
  131. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-trigonometry.d.ts +1 -1
  132. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-units.d.ts +1 -1
  133. package/dist/types/compute-engine/latex-syntax/dictionary/definitions.d.ts +1 -1
  134. package/dist/types/compute-engine/latex-syntax/dictionary/indexed-types.d.ts +1 -1
  135. package/dist/types/compute-engine/latex-syntax/parse-number.d.ts +1 -1
  136. package/dist/types/compute-engine/latex-syntax/parse-symbol.d.ts +1 -1
  137. package/dist/types/compute-engine/latex-syntax/parse.d.ts +1 -1
  138. package/dist/types/compute-engine/latex-syntax/serialize-dms.d.ts +1 -1
  139. package/dist/types/compute-engine/latex-syntax/serialize-number.d.ts +1 -1
  140. package/dist/types/compute-engine/latex-syntax/serializer-style.d.ts +1 -1
  141. package/dist/types/compute-engine/latex-syntax/serializer.d.ts +1 -1
  142. package/dist/types/compute-engine/latex-syntax/tokenizer.d.ts +1 -1
  143. package/dist/types/compute-engine/latex-syntax/types.d.ts +1 -1
  144. package/dist/types/compute-engine/latex-syntax/utils.d.ts +1 -1
  145. package/dist/types/compute-engine/library/arithmetic.d.ts +1 -1
  146. package/dist/types/compute-engine/library/calculus.d.ts +1 -1
  147. package/dist/types/compute-engine/library/collections.d.ts +1 -1
  148. package/dist/types/compute-engine/library/colors.d.ts +1 -1
  149. package/dist/types/compute-engine/library/combinatorics.d.ts +1 -1
  150. package/dist/types/compute-engine/library/complex.d.ts +1 -1
  151. package/dist/types/compute-engine/library/control-structures.d.ts +1 -1
  152. package/dist/types/compute-engine/library/core.d.ts +1 -1
  153. package/dist/types/compute-engine/library/fractals.d.ts +1 -1
  154. package/dist/types/compute-engine/library/library.d.ts +1 -1
  155. package/dist/types/compute-engine/library/linear-algebra.d.ts +1 -1
  156. package/dist/types/compute-engine/library/logic-analysis.d.ts +1 -1
  157. package/dist/types/compute-engine/library/logic.d.ts +1 -1
  158. package/dist/types/compute-engine/library/number-theory.d.ts +1 -1
  159. package/dist/types/compute-engine/library/polynomials.d.ts +1 -1
  160. package/dist/types/compute-engine/library/quantity-arithmetic.d.ts +1 -1
  161. package/dist/types/compute-engine/library/random-expression.d.ts +1 -1
  162. package/dist/types/compute-engine/library/relational-operator.d.ts +1 -1
  163. package/dist/types/compute-engine/library/sets.d.ts +1 -1
  164. package/dist/types/compute-engine/library/statistics.d.ts +1 -1
  165. package/dist/types/compute-engine/library/trigonometry.d.ts +1 -1
  166. package/dist/types/compute-engine/library/type-handlers.d.ts +1 -1
  167. package/dist/types/compute-engine/library/unit-data.d.ts +1 -1
  168. package/dist/types/compute-engine/library/units.d.ts +1 -1
  169. package/dist/types/compute-engine/library/utils.d.ts +1 -1
  170. package/dist/types/compute-engine/numeric-value/big-numeric-value.d.ts +1 -1
  171. package/dist/types/compute-engine/numeric-value/exact-numeric-value.d.ts +1 -1
  172. package/dist/types/compute-engine/numeric-value/machine-numeric-value.d.ts +1 -1
  173. package/dist/types/compute-engine/numeric-value/types.d.ts +1 -1
  174. package/dist/types/compute-engine/numerics/bigint.d.ts +1 -1
  175. package/dist/types/compute-engine/numerics/expression.d.ts +1 -1
  176. package/dist/types/compute-engine/numerics/interval.d.ts +1 -1
  177. package/dist/types/compute-engine/numerics/monte-carlo.d.ts +1 -1
  178. package/dist/types/compute-engine/numerics/numeric-bigint.d.ts +1 -1
  179. package/dist/types/compute-engine/numerics/numeric-bignum.d.ts +1 -1
  180. package/dist/types/compute-engine/numerics/numeric-complex.d.ts +1 -1
  181. package/dist/types/compute-engine/numerics/numeric.d.ts +1 -1
  182. package/dist/types/compute-engine/numerics/primes.d.ts +1 -1
  183. package/dist/types/compute-engine/numerics/rationals.d.ts +1 -1
  184. package/dist/types/compute-engine/numerics/richardson.d.ts +1 -1
  185. package/dist/types/compute-engine/numerics/special-functions.d.ts +1 -1
  186. package/dist/types/compute-engine/numerics/statistics.d.ts +1 -1
  187. package/dist/types/compute-engine/numerics/strings.d.ts +1 -1
  188. package/dist/types/compute-engine/numerics/types.d.ts +1 -1
  189. package/dist/types/compute-engine/numerics/unit-data.d.ts +1 -1
  190. package/dist/types/compute-engine/oeis.d.ts +1 -1
  191. package/dist/types/compute-engine/sequence.d.ts +1 -1
  192. package/dist/types/compute-engine/symbolic/antiderivative.d.ts +1 -1
  193. package/dist/types/compute-engine/symbolic/derivative.d.ts +1 -1
  194. package/dist/types/compute-engine/symbolic/distribute.d.ts +1 -1
  195. package/dist/types/compute-engine/symbolic/fu-cost.d.ts +1 -1
  196. package/dist/types/compute-engine/symbolic/fu-transforms.d.ts +1 -1
  197. package/dist/types/compute-engine/symbolic/fu.d.ts +1 -1
  198. package/dist/types/compute-engine/symbolic/logic-utils.d.ts +1 -1
  199. package/dist/types/compute-engine/symbolic/simplify-abs.d.ts +1 -1
  200. package/dist/types/compute-engine/symbolic/simplify-divide.d.ts +1 -1
  201. package/dist/types/compute-engine/symbolic/simplify-factorial.d.ts +1 -1
  202. package/dist/types/compute-engine/symbolic/simplify-hyperbolic.d.ts +1 -1
  203. package/dist/types/compute-engine/symbolic/simplify-infinity.d.ts +1 -1
  204. package/dist/types/compute-engine/symbolic/simplify-log.d.ts +1 -1
  205. package/dist/types/compute-engine/symbolic/simplify-logic.d.ts +1 -1
  206. package/dist/types/compute-engine/symbolic/simplify-power.d.ts +1 -1
  207. package/dist/types/compute-engine/symbolic/simplify-product.d.ts +1 -1
  208. package/dist/types/compute-engine/symbolic/simplify-rules.d.ts +1 -1
  209. package/dist/types/compute-engine/symbolic/simplify-sum.d.ts +1 -1
  210. package/dist/types/compute-engine/symbolic/simplify-trig.d.ts +1 -1
  211. package/dist/types/compute-engine/tensor/tensor-fields.d.ts +1 -1
  212. package/dist/types/compute-engine/tensor/tensors.d.ts +1 -1
  213. package/dist/types/compute-engine/types-definitions.d.ts +1 -1
  214. package/dist/types/compute-engine/types-engine.d.ts +1 -1
  215. package/dist/types/compute-engine/types-evaluation.d.ts +1 -1
  216. package/dist/types/compute-engine/types-expression.d.ts +61 -2
  217. package/dist/types/compute-engine/types-kernel-evaluation.d.ts +1 -1
  218. package/dist/types/compute-engine/types-kernel-serialization.d.ts +12 -1
  219. package/dist/types/compute-engine/types-serialization.d.ts +1 -1
  220. package/dist/types/compute-engine/types.d.ts +1 -1
  221. package/dist/types/compute-engine.d.ts +1 -1
  222. package/dist/types/math-json/symbols.d.ts +1 -1
  223. package/dist/types/math-json/types.d.ts +1 -1
  224. package/dist/types/math-json/utils.d.ts +1 -1
  225. package/dist/types/math-json.d.ts +2 -2
  226. package/package.json +3 -3
@@ -1,4 +1,4 @@
1
- /** Compute Engine 0.53.1 */
1
+ /** Compute Engine 0.54.1 */
2
2
 
3
3
  // node_modules/complex-esm/dist/src/complex.js
4
4
  var cosh = Math.cosh || function(x) {
@@ -12290,6 +12290,18 @@ var _expandForIs;
12290
12290
  function _setExpandForIs(fn) {
12291
12291
  _expandForIs = fn;
12292
12292
  }
12293
+ var _getPolynomialCoefficients;
12294
+ function _setGetPolynomialCoefficients(fn) {
12295
+ _getPolynomialCoefficients = fn;
12296
+ }
12297
+ var _getPolynomialDegree;
12298
+ function _setGetPolynomialDegree(fn) {
12299
+ _getPolynomialDegree = fn;
12300
+ }
12301
+ var _findUnivariateRoots;
12302
+ function _setFindUnivariateRoots(fn) {
12303
+ _findUnivariateRoots = fn;
12304
+ }
12293
12305
  var EXPANDABLE_OPS = ["Multiply", "Power", "Negate", "Divide"];
12294
12306
  function _couldBenefitFromExpand(a, b) {
12295
12307
  if (a.has(EXPANDABLE_OPS)) return true;
@@ -12605,6 +12617,34 @@ var _BoxedExpression = class __BoxedExpression {
12605
12617
  factors() {
12606
12618
  return [this];
12607
12619
  }
12620
+ polynomialCoefficients(variable) {
12621
+ let vars;
12622
+ if (variable === void 0) {
12623
+ const unknowns = this.unknowns;
12624
+ if (unknowns.length !== 1) return void 0;
12625
+ vars = [unknowns[0]];
12626
+ } else if (typeof variable === "string") {
12627
+ vars = [variable];
12628
+ } else {
12629
+ if (variable.length === 0) return void 0;
12630
+ vars = variable;
12631
+ }
12632
+ for (const v of vars) {
12633
+ if (_getPolynomialDegree(this, v) < 0) return void 0;
12634
+ }
12635
+ const coeffs = _getPolynomialCoefficients(this, vars[0]);
12636
+ if (coeffs === null) return void 0;
12637
+ return coeffs.reverse();
12638
+ }
12639
+ polynomialRoots(variable) {
12640
+ if (variable === void 0) {
12641
+ const unknowns = this.unknowns;
12642
+ if (unknowns.length !== 1) return void 0;
12643
+ variable = unknowns[0];
12644
+ }
12645
+ if (_getPolynomialDegree(this, variable) < 0) return void 0;
12646
+ return _findUnivariateRoots(this, variable);
12647
+ }
12608
12648
  is(other, tolerance) {
12609
12649
  if (this.isSame(other)) return true;
12610
12650
  if (_expandForIs && _couldBenefitFromExpand(this, other)) {
@@ -16064,10 +16104,14 @@ function isSqrt(expr) {
16064
16104
  return expr.operator === "Sqrt" || expr.operator === "Power" && expr.op2.im === 0 && expr.op2.re === 0.5 || expr.operator === "Root" && expr.op2.im === 0 && expr.op2.re === 2;
16065
16105
  }
16066
16106
  function asRadical(expr) {
16067
- if (isSqrt(expr) && isFunction2(expr)) return asRational(expr.op1) ?? null;
16107
+ if (isSqrt(expr) && isFunction2(expr)) {
16108
+ const r = asRational(expr.op1);
16109
+ if (r === void 0 || r[0] < 0 || r[1] < 0) return null;
16110
+ return r;
16111
+ }
16068
16112
  if (isFunction2(expr, "Divide") && expr.op1.isSame(1) && isSqrt(expr.op2)) {
16069
16113
  const n = expr.op2.re;
16070
- if (!Number.isInteger(n)) return null;
16114
+ if (!Number.isInteger(n) || n <= 0) return null;
16071
16115
  return [1, n];
16072
16116
  }
16073
16117
  return null;
@@ -23948,7 +23992,9 @@ var ARITHMETIC_LIBRARY = [
23948
23992
  if (n === null) return void 0;
23949
23993
  const ce = x.engine;
23950
23994
  if (bignumPreferred(ce))
23951
- return ce.number(run(factorial23(ce, ce.bignum(n)), ce._timeRemaining));
23995
+ return ce.number(
23996
+ run(factorial23(ce, ce.bignum(n)), ce._timeRemaining)
23997
+ );
23952
23998
  return ce.number(factorial22(n));
23953
23999
  }
23954
24000
  },
@@ -26349,6 +26395,268 @@ function expandAll(expr) {
26349
26395
  return expand2(result);
26350
26396
  }
26351
26397
 
26398
+ // src/compute-engine/boxed-expression/polynomials.ts
26399
+ function polynomialDegree(expr, variable) {
26400
+ if (isNumber(expr)) return 0;
26401
+ if (isSymbol2(expr)) {
26402
+ if (expr.symbol === variable) return 1;
26403
+ return 0;
26404
+ }
26405
+ if (!isFunction2(expr)) {
26406
+ if (expr.has(variable)) return -1;
26407
+ return 0;
26408
+ }
26409
+ const op = expr.operator;
26410
+ if (op === "Negate") return polynomialDegree(expr.op1, variable);
26411
+ if (op === "Add" || op === "Subtract") {
26412
+ let maxDeg = 0;
26413
+ for (const arg of expr.ops) {
26414
+ const deg = polynomialDegree(arg, variable);
26415
+ if (deg < 0) return -1;
26416
+ maxDeg = Math.max(maxDeg, deg);
26417
+ }
26418
+ return maxDeg;
26419
+ }
26420
+ if (op === "Multiply") {
26421
+ let totalDeg = 0;
26422
+ for (const arg of expr.ops) {
26423
+ const deg = polynomialDegree(arg, variable);
26424
+ if (deg < 0) return -1;
26425
+ totalDeg += deg;
26426
+ }
26427
+ return totalDeg;
26428
+ }
26429
+ if (op === "Power") {
26430
+ const baseDeg = polynomialDegree(expr.op1, variable);
26431
+ if (baseDeg < 0) return -1;
26432
+ if (baseDeg === 0) {
26433
+ if (expr.op2.has(variable)) return -1;
26434
+ return 0;
26435
+ }
26436
+ const exp3 = asSmallInteger(expr.op2);
26437
+ if (exp3 === null || exp3 < 0) return -1;
26438
+ return baseDeg * exp3;
26439
+ }
26440
+ if (expr.has(variable)) return -1;
26441
+ return 0;
26442
+ }
26443
+ function getPolynomialCoefficients(expr, variable) {
26444
+ const ce = expr.engine;
26445
+ const degree = polynomialDegree(expr, variable);
26446
+ if (degree < 0) return null;
26447
+ const coeffs = new Array(degree + 1).fill(ce.Zero);
26448
+ const expanded = expand2(expr);
26449
+ const addCoefficient = (coef, deg) => {
26450
+ if (deg > degree) return false;
26451
+ coeffs[deg] = coeffs[deg].add(coef);
26452
+ return true;
26453
+ };
26454
+ const processTerm = (term) => {
26455
+ const termDeg = polynomialDegree(term, variable);
26456
+ if (termDeg < 0) return false;
26457
+ if (termDeg === 0) {
26458
+ return addCoefficient(term, 0);
26459
+ }
26460
+ if (isSymbol2(term, variable)) {
26461
+ return addCoefficient(ce.One, 1);
26462
+ }
26463
+ if (isFunction2(term, "Negate")) {
26464
+ const innerDeg = polynomialDegree(term.op1, variable);
26465
+ if (innerDeg === 0) {
26466
+ return addCoefficient(term, 0);
26467
+ }
26468
+ const innerCoeffs = getPolynomialCoefficients(term.op1, variable);
26469
+ if (!innerCoeffs) return false;
26470
+ for (let i = 0; i < innerCoeffs.length; i++) {
26471
+ if (!innerCoeffs[i].isSame(0)) {
26472
+ addCoefficient(innerCoeffs[i].neg(), i);
26473
+ }
26474
+ }
26475
+ return true;
26476
+ }
26477
+ if (isFunction2(term, "Power")) {
26478
+ if (isSymbol2(term.op1, variable)) {
26479
+ const exp3 = asSmallInteger(term.op2);
26480
+ if (exp3 !== null && exp3 >= 0) {
26481
+ return addCoefficient(ce.One, exp3);
26482
+ }
26483
+ }
26484
+ if (!term.op1.has(variable)) {
26485
+ return addCoefficient(term, 0);
26486
+ }
26487
+ return false;
26488
+ }
26489
+ if (isFunction2(term, "Multiply")) {
26490
+ const factors = term.ops;
26491
+ let coef = ce.One;
26492
+ let varDeg = 0;
26493
+ for (const factor3 of factors) {
26494
+ if (!factor3.has(variable)) {
26495
+ coef = coef.mul(factor3);
26496
+ } else if (isSymbol2(factor3, variable)) {
26497
+ varDeg += 1;
26498
+ } else if (isFunction2(factor3, "Power") && isSymbol2(factor3.op1, variable)) {
26499
+ const exp3 = asSmallInteger(factor3.op2);
26500
+ if (exp3 !== null && exp3 >= 0) {
26501
+ varDeg += exp3;
26502
+ } else {
26503
+ return false;
26504
+ }
26505
+ } else {
26506
+ return false;
26507
+ }
26508
+ }
26509
+ return addCoefficient(coef, varDeg);
26510
+ }
26511
+ return false;
26512
+ };
26513
+ if (isFunction2(expanded, "Add")) {
26514
+ for (const term of expanded.ops) {
26515
+ if (!processTerm(term)) return null;
26516
+ }
26517
+ } else {
26518
+ if (!processTerm(expanded)) return null;
26519
+ }
26520
+ return coeffs;
26521
+ }
26522
+ function fromCoefficients(coeffs, variable) {
26523
+ if (coeffs.length === 0) return coeffs[0]?.engine.Zero ?? null;
26524
+ const ce = coeffs[0].engine;
26525
+ const x = ce.symbol(variable);
26526
+ const terms = [];
26527
+ for (let i = 0; i < coeffs.length; i++) {
26528
+ const coef = coeffs[i];
26529
+ if (coef.isSame(0)) continue;
26530
+ if (i === 0) {
26531
+ terms.push(coef);
26532
+ } else if (i === 1) {
26533
+ if (coef.isSame(1)) {
26534
+ terms.push(x);
26535
+ } else if (coef.isSame(-1)) {
26536
+ terms.push(x.neg());
26537
+ } else {
26538
+ terms.push(coef.mul(x));
26539
+ }
26540
+ } else {
26541
+ const xPow = ce.box(["Power", variable, i]);
26542
+ if (coef.isSame(1)) {
26543
+ terms.push(xPow);
26544
+ } else if (coef.isSame(-1)) {
26545
+ terms.push(xPow.neg());
26546
+ } else {
26547
+ terms.push(coef.mul(xPow));
26548
+ }
26549
+ }
26550
+ }
26551
+ if (terms.length === 0) return ce.Zero;
26552
+ if (terms.length === 1) return terms[0];
26553
+ return add3(...terms);
26554
+ }
26555
+ function polynomialDivide(dividend, divisor, variable) {
26556
+ const ce = dividend.engine;
26557
+ const dividendCoeffs = getPolynomialCoefficients(dividend, variable);
26558
+ const divisorCoeffs = getPolynomialCoefficients(divisor, variable);
26559
+ if (!dividendCoeffs || !divisorCoeffs) return null;
26560
+ if (divisorCoeffs.every((c) => c.isSame(0))) return null;
26561
+ const actualDegree = (coeffs) => {
26562
+ for (let i = coeffs.length - 1; i >= 0; i--) {
26563
+ if (!coeffs[i].isSame(0)) return i;
26564
+ }
26565
+ return -1;
26566
+ };
26567
+ const dividendDeg = actualDegree(dividendCoeffs);
26568
+ const divisorDeg = actualDegree(divisorCoeffs);
26569
+ if (divisorDeg < 0) return null;
26570
+ if (dividendDeg < 0) {
26571
+ return [ce.Zero, ce.Zero];
26572
+ }
26573
+ if (dividendDeg < divisorDeg) {
26574
+ return [ce.Zero, dividend];
26575
+ }
26576
+ const remainder2 = dividendCoeffs.map((c) => c);
26577
+ const quotientCoeffs = new Array(
26578
+ dividendDeg - divisorDeg + 1
26579
+ ).fill(ce.Zero);
26580
+ const leadingDivisor = divisorCoeffs[divisorDeg];
26581
+ for (let i = dividendDeg; i >= divisorDeg; i--) {
26582
+ if (remainder2[i].isSame(0)) continue;
26583
+ const quotientCoef = remainder2[i].div(leadingDivisor);
26584
+ quotientCoeffs[i - divisorDeg] = quotientCoef;
26585
+ for (let j = 0; j <= divisorDeg; j++) {
26586
+ const product = quotientCoef.mul(divisorCoeffs[j]);
26587
+ remainder2[i - divisorDeg + j] = remainder2[i - divisorDeg + j].sub(product);
26588
+ }
26589
+ }
26590
+ const quotient = fromCoefficients(quotientCoeffs, variable);
26591
+ const remainderPoly = fromCoefficients(remainder2, variable);
26592
+ return [quotient, remainderPoly];
26593
+ }
26594
+ function polynomialGCD(a, b, variable) {
26595
+ const ce = a.engine;
26596
+ const degA = polynomialDegree(a, variable);
26597
+ const degB = polynomialDegree(b, variable);
26598
+ if (degA < 0 || degB < 0) return ce.One;
26599
+ const aCoeffs = getPolynomialCoefficients(a, variable);
26600
+ const bCoeffs = getPolynomialCoefficients(b, variable);
26601
+ if (!aCoeffs || aCoeffs.every((c) => c.isSame(0))) {
26602
+ return makeMonic(b, variable);
26603
+ }
26604
+ if (!bCoeffs || bCoeffs.every((c) => c.isSame(0))) {
26605
+ return makeMonic(a, variable);
26606
+ }
26607
+ let p = a;
26608
+ let q = b;
26609
+ while (true) {
26610
+ const qCoeffs = getPolynomialCoefficients(q, variable);
26611
+ if (!qCoeffs || qCoeffs.every((c) => c.isSame(0))) {
26612
+ break;
26613
+ }
26614
+ const divResult = polynomialDivide(p, q, variable);
26615
+ if (!divResult) {
26616
+ return ce.One;
26617
+ }
26618
+ const [, remainder2] = divResult;
26619
+ p = q;
26620
+ q = remainder2;
26621
+ }
26622
+ return makeMonic(p, variable);
26623
+ }
26624
+ function makeMonic(poly, variable) {
26625
+ const coeffs = getPolynomialCoefficients(poly, variable);
26626
+ if (!coeffs) return poly;
26627
+ let leadingCoef = null;
26628
+ for (let i = coeffs.length - 1; i >= 0; i--) {
26629
+ if (!coeffs[i].isSame(0)) {
26630
+ leadingCoef = coeffs[i];
26631
+ break;
26632
+ }
26633
+ }
26634
+ if (!leadingCoef || leadingCoef.isSame(1)) return poly;
26635
+ const monicCoeffs = coeffs.map((c) => c.div(leadingCoef));
26636
+ return fromCoefficients(monicCoeffs, variable);
26637
+ }
26638
+ function cancelCommonFactors(expr, variable) {
26639
+ if (!isFunction2(expr, "Divide")) return expr;
26640
+ const numerator = expr.op1;
26641
+ const denominator = expr.op2;
26642
+ const numDeg = polynomialDegree(numerator, variable);
26643
+ const denDeg = polynomialDegree(denominator, variable);
26644
+ if (numDeg < 0 || denDeg < 0) return expr;
26645
+ const gcd7 = polynomialGCD(numerator, denominator, variable);
26646
+ const gcdDeg = polynomialDegree(gcd7, variable);
26647
+ if (gcdDeg <= 0) return expr;
26648
+ const numDivResult = polynomialDivide(numerator, gcd7, variable);
26649
+ const denDivResult = polynomialDivide(denominator, gcd7, variable);
26650
+ if (!numDivResult || !denDivResult) return expr;
26651
+ const [newNumerator] = numDivResult;
26652
+ const [newDenominator] = denDivResult;
26653
+ const denCoeffs = getPolynomialCoefficients(newDenominator, variable);
26654
+ if (denCoeffs && denCoeffs.length === 1 && denCoeffs[0].isSame(1)) {
26655
+ return newNumerator;
26656
+ }
26657
+ return newNumerator.div(newDenominator);
26658
+ }
26659
+
26352
26660
  // src/compute-engine/boxed-expression/solve.ts
26353
26661
  function numericApproximation(value) {
26354
26662
  if (typeof value === "number") return value;
@@ -27172,6 +27480,13 @@ function findUnivariateRoots(expr, x) {
27172
27480
  )
27173
27481
  );
27174
27482
  }
27483
+ if (result.length === 0) {
27484
+ const deg = polynomialDegree(originalExpr, x);
27485
+ if (deg >= 3) {
27486
+ const rationalRoots = findRationalRoots(originalExpr, x, ce);
27487
+ if (rationalRoots.length > 0) result = rationalRoots;
27488
+ }
27489
+ }
27175
27490
  } finally {
27176
27491
  ce.popScope();
27177
27492
  }
@@ -27310,267 +27625,49 @@ function filterRootsByType(ce, x, roots) {
27310
27625
  return true;
27311
27626
  });
27312
27627
  }
27313
-
27314
- // src/compute-engine/boxed-expression/polynomials.ts
27315
- function polynomialDegree(expr, variable) {
27316
- if (isNumber(expr)) return 0;
27317
- if (isSymbol2(expr)) {
27318
- if (expr.symbol === variable) return 1;
27319
- return 0;
27320
- }
27321
- if (!isFunction2(expr)) {
27322
- if (expr.has(variable)) return -1;
27323
- return 0;
27324
- }
27325
- const op = expr.operator;
27326
- if (op === "Negate") return polynomialDegree(expr.op1, variable);
27327
- if (op === "Add" || op === "Subtract") {
27328
- let maxDeg = 0;
27329
- for (const arg of expr.ops) {
27330
- const deg = polynomialDegree(arg, variable);
27331
- if (deg < 0) return -1;
27332
- maxDeg = Math.max(maxDeg, deg);
27333
- }
27334
- return maxDeg;
27335
- }
27336
- if (op === "Multiply") {
27337
- let totalDeg = 0;
27338
- for (const arg of expr.ops) {
27339
- const deg = polynomialDegree(arg, variable);
27340
- if (deg < 0) return -1;
27341
- totalDeg += deg;
27342
- }
27343
- return totalDeg;
27344
- }
27345
- if (op === "Power") {
27346
- const baseDeg = polynomialDegree(expr.op1, variable);
27347
- if (baseDeg < 0) return -1;
27348
- if (baseDeg === 0) {
27349
- if (expr.op2.has(variable)) return -1;
27350
- return 0;
27351
- }
27352
- const exp3 = asSmallInteger(expr.op2);
27353
- if (exp3 === null || exp3 < 0) return -1;
27354
- return baseDeg * exp3;
27355
- }
27356
- if (expr.has(variable)) return -1;
27357
- return 0;
27358
- }
27359
- function getPolynomialCoefficients(expr, variable) {
27360
- const ce = expr.engine;
27361
- const degree = polynomialDegree(expr, variable);
27362
- if (degree < 0) return null;
27363
- const coeffs = new Array(degree + 1).fill(ce.Zero);
27364
- const expanded = expand2(expr);
27365
- const addCoefficient = (coef, deg) => {
27366
- if (deg > degree) return false;
27367
- coeffs[deg] = coeffs[deg].add(coef);
27368
- return true;
27369
- };
27370
- const processTerm = (term) => {
27371
- const termDeg = polynomialDegree(term, variable);
27372
- if (termDeg < 0) return false;
27373
- if (termDeg === 0) {
27374
- return addCoefficient(term, 0);
27375
- }
27376
- if (isSymbol2(term, variable)) {
27377
- return addCoefficient(ce.One, 1);
27378
- }
27379
- if (isFunction2(term, "Negate")) {
27380
- const innerDeg = polynomialDegree(term.op1, variable);
27381
- if (innerDeg === 0) {
27382
- return addCoefficient(term, 0);
27383
- }
27384
- const innerCoeffs = getPolynomialCoefficients(term.op1, variable);
27385
- if (!innerCoeffs) return false;
27386
- for (let i = 0; i < innerCoeffs.length; i++) {
27387
- if (!innerCoeffs[i].isSame(0)) {
27388
- addCoefficient(innerCoeffs[i].neg(), i);
27389
- }
27390
- }
27391
- return true;
27392
- }
27393
- if (isFunction2(term, "Power")) {
27394
- if (isSymbol2(term.op1, variable)) {
27395
- const exp3 = asSmallInteger(term.op2);
27396
- if (exp3 !== null && exp3 >= 0) {
27397
- return addCoefficient(ce.One, exp3);
27398
- }
27399
- }
27400
- if (!term.op1.has(variable)) {
27401
- return addCoefficient(term, 0);
27402
- }
27403
- return false;
27404
- }
27405
- if (isFunction2(term, "Multiply")) {
27406
- const factors = term.ops;
27407
- let coef = ce.One;
27408
- let varDeg = 0;
27409
- for (const factor3 of factors) {
27410
- if (!factor3.has(variable)) {
27411
- coef = coef.mul(factor3);
27412
- } else if (isSymbol2(factor3, variable)) {
27413
- varDeg += 1;
27414
- } else if (isFunction2(factor3, "Power") && isSymbol2(factor3.op1, variable)) {
27415
- const exp3 = asSmallInteger(factor3.op2);
27416
- if (exp3 !== null && exp3 >= 0) {
27417
- varDeg += exp3;
27418
- } else {
27419
- return false;
27420
- }
27421
- } else {
27422
- return false;
27423
- }
27628
+ function findRationalRoots(expr, variable, ce) {
27629
+ const coeffs = getPolynomialCoefficients(expr, variable);
27630
+ if (!coeffs) return [];
27631
+ const degree = coeffs.length - 1;
27632
+ if (degree < 1) return [];
27633
+ const constantInt = asSmallInteger(coeffs[0]);
27634
+ const leadingInt = asSmallInteger(coeffs[degree]);
27635
+ if (leadingInt === null || constantInt === null) return [];
27636
+ if (leadingInt === 0 || constantInt === 0) return [];
27637
+ const divisors = (n) => {
27638
+ n = Math.abs(n);
27639
+ const result = [];
27640
+ for (let i = 1; i * i <= n; i++) {
27641
+ if (n % i === 0) {
27642
+ result.push(i);
27643
+ if (i !== n / i) result.push(n / i);
27424
27644
  }
27425
- return addCoefficient(coef, varDeg);
27426
27645
  }
27427
- return false;
27646
+ return result;
27428
27647
  };
27429
- if (isFunction2(expanded, "Add")) {
27430
- for (const term of expanded.ops) {
27431
- if (!processTerm(term)) return null;
27432
- }
27433
- } else {
27434
- if (!processTerm(expanded)) return null;
27435
- }
27436
- return coeffs;
27437
- }
27438
- function fromCoefficients(coeffs, variable) {
27439
- if (coeffs.length === 0) return coeffs[0]?.engine.Zero ?? null;
27440
- const ce = coeffs[0].engine;
27441
- const x = ce.symbol(variable);
27442
- const terms = [];
27443
- for (let i = 0; i < coeffs.length; i++) {
27444
- const coef = coeffs[i];
27445
- if (coef.isSame(0)) continue;
27446
- if (i === 0) {
27447
- terms.push(coef);
27448
- } else if (i === 1) {
27449
- if (coef.isSame(1)) {
27450
- terms.push(x);
27451
- } else if (coef.isSame(-1)) {
27452
- terms.push(x.neg());
27453
- } else {
27454
- terms.push(coef.mul(x));
27455
- }
27456
- } else {
27457
- const xPow = ce.box(["Power", variable, i]);
27458
- if (coef.isSame(1)) {
27459
- terms.push(xPow);
27460
- } else if (coef.isSame(-1)) {
27461
- terms.push(xPow.neg());
27462
- } else {
27463
- terms.push(coef.mul(xPow));
27648
+ const pDivisors = divisors(constantInt);
27649
+ const qDivisors = divisors(leadingInt);
27650
+ const candidates = [];
27651
+ const seen = /* @__PURE__ */ new Set();
27652
+ for (const p of pDivisors) {
27653
+ for (const q of qDivisors) {
27654
+ for (const sign3 of [1, -1]) {
27655
+ const val = sign3 * p / q;
27656
+ if (!seen.has(val)) {
27657
+ seen.add(val);
27658
+ candidates.push(val);
27659
+ }
27464
27660
  }
27465
27661
  }
27466
27662
  }
27467
- if (terms.length === 0) return ce.Zero;
27468
- if (terms.length === 1) return terms[0];
27469
- return add3(...terms);
27470
- }
27471
- function polynomialDivide(dividend, divisor, variable) {
27472
- const ce = dividend.engine;
27473
- const dividendCoeffs = getPolynomialCoefficients(dividend, variable);
27474
- const divisorCoeffs = getPolynomialCoefficients(divisor, variable);
27475
- if (!dividendCoeffs || !divisorCoeffs) return null;
27476
- if (divisorCoeffs.every((c) => c.isSame(0))) return null;
27477
- const actualDegree = (coeffs) => {
27478
- for (let i = coeffs.length - 1; i >= 0; i--) {
27479
- if (!coeffs[i].isSame(0)) return i;
27480
- }
27481
- return -1;
27482
- };
27483
- const dividendDeg = actualDegree(dividendCoeffs);
27484
- const divisorDeg = actualDegree(divisorCoeffs);
27485
- if (divisorDeg < 0) return null;
27486
- if (dividendDeg < 0) {
27487
- return [ce.Zero, ce.Zero];
27488
- }
27489
- if (dividendDeg < divisorDeg) {
27490
- return [ce.Zero, dividend];
27491
- }
27492
- const remainder2 = dividendCoeffs.map((c) => c);
27493
- const quotientCoeffs = new Array(
27494
- dividendDeg - divisorDeg + 1
27495
- ).fill(ce.Zero);
27496
- const leadingDivisor = divisorCoeffs[divisorDeg];
27497
- for (let i = dividendDeg; i >= divisorDeg; i--) {
27498
- if (remainder2[i].isSame(0)) continue;
27499
- const quotientCoef = remainder2[i].div(leadingDivisor);
27500
- quotientCoeffs[i - divisorDeg] = quotientCoef;
27501
- for (let j = 0; j <= divisorDeg; j++) {
27502
- const product = quotientCoef.mul(divisorCoeffs[j]);
27503
- remainder2[i - divisorDeg + j] = remainder2[i - divisorDeg + j].sub(product);
27504
- }
27505
- }
27506
- const quotient = fromCoefficients(quotientCoeffs, variable);
27507
- const remainderPoly = fromCoefficients(remainder2, variable);
27508
- return [quotient, remainderPoly];
27509
- }
27510
- function polynomialGCD(a, b, variable) {
27511
- const ce = a.engine;
27512
- const degA = polynomialDegree(a, variable);
27513
- const degB = polynomialDegree(b, variable);
27514
- if (degA < 0 || degB < 0) return ce.One;
27515
- const aCoeffs = getPolynomialCoefficients(a, variable);
27516
- const bCoeffs = getPolynomialCoefficients(b, variable);
27517
- if (!aCoeffs || aCoeffs.every((c) => c.isSame(0))) {
27518
- return makeMonic(b, variable);
27519
- }
27520
- if (!bCoeffs || bCoeffs.every((c) => c.isSame(0))) {
27521
- return makeMonic(a, variable);
27522
- }
27523
- let p = a;
27524
- let q = b;
27525
- while (true) {
27526
- const qCoeffs = getPolynomialCoefficients(q, variable);
27527
- if (!qCoeffs || qCoeffs.every((c) => c.isSame(0))) {
27528
- break;
27529
- }
27530
- const divResult = polynomialDivide(p, q, variable);
27531
- if (!divResult) {
27532
- return ce.One;
27533
- }
27534
- const [, remainder2] = divResult;
27535
- p = q;
27536
- q = remainder2;
27537
- }
27538
- return makeMonic(p, variable);
27539
- }
27540
- function makeMonic(poly, variable) {
27541
- const coeffs = getPolynomialCoefficients(poly, variable);
27542
- if (!coeffs) return poly;
27543
- let leadingCoef = null;
27544
- for (let i = coeffs.length - 1; i >= 0; i--) {
27545
- if (!coeffs[i].isSame(0)) {
27546
- leadingCoef = coeffs[i];
27547
- break;
27548
- }
27549
- }
27550
- if (!leadingCoef || leadingCoef.isSame(1)) return poly;
27551
- const monicCoeffs = coeffs.map((c) => c.div(leadingCoef));
27552
- return fromCoefficients(monicCoeffs, variable);
27553
- }
27554
- function cancelCommonFactors(expr, variable) {
27555
- if (!isFunction2(expr, "Divide")) return expr;
27556
- const numerator = expr.op1;
27557
- const denominator = expr.op2;
27558
- const numDeg = polynomialDegree(numerator, variable);
27559
- const denDeg = polynomialDegree(denominator, variable);
27560
- if (numDeg < 0 || denDeg < 0) return expr;
27561
- const gcd6 = polynomialGCD(numerator, denominator, variable);
27562
- const gcdDeg = polynomialDegree(gcd6, variable);
27563
- if (gcdDeg <= 0) return expr;
27564
- const numDivResult = polynomialDivide(numerator, gcd6, variable);
27565
- const denDivResult = polynomialDivide(denominator, gcd6, variable);
27566
- if (!numDivResult || !denDivResult) return expr;
27567
- const [newNumerator] = numDivResult;
27568
- const [newDenominator] = denDivResult;
27569
- const denCoeffs = getPolynomialCoefficients(newDenominator, variable);
27570
- if (denCoeffs && denCoeffs.length === 1 && denCoeffs[0].isSame(1)) {
27571
- return newNumerator;
27663
+ if (candidates.length > 100) return [];
27664
+ const roots = [];
27665
+ for (const candidate of candidates) {
27666
+ const root2 = ce.number(candidate);
27667
+ const value = expr.subs({ [variable]: root2 }).N();
27668
+ if (value.isSame(0)) roots.push(root2);
27572
27669
  }
27573
- return newNumerator.div(newDenominator);
27670
+ return roots;
27574
27671
  }
27575
27672
 
27576
27673
  // src/compute-engine/symbolic/antiderivative.ts
@@ -38214,7 +38311,107 @@ function factorQuadratic(expr, variable) {
38214
38311
  return ce.box(["Multiply", a.json, factor1.json, factor22.json]);
38215
38312
  }
38216
38313
  }
38314
+ function factorByRationalRoots(expr, variable) {
38315
+ const ce = expr.engine;
38316
+ const coeffs = getPolynomialCoefficients(expr, variable);
38317
+ if (!coeffs) return null;
38318
+ const degree = coeffs.length - 1;
38319
+ if (degree < 2) return null;
38320
+ const leadingInt = asSmallInteger(coeffs[degree]);
38321
+ const constantInt = asSmallInteger(coeffs[0]);
38322
+ if (leadingInt === null || constantInt === null) return null;
38323
+ if (leadingInt === 0 || constantInt === 0) return null;
38324
+ const divisors = (n) => {
38325
+ n = Math.abs(n);
38326
+ const result = [];
38327
+ for (let i = 1; i * i <= n; i++) {
38328
+ if (n % i === 0) {
38329
+ result.push(i);
38330
+ if (i !== n / i) result.push(n / i);
38331
+ }
38332
+ }
38333
+ return result;
38334
+ };
38335
+ const pDivisors = divisors(constantInt);
38336
+ const qDivisors = divisors(leadingInt);
38337
+ const candidates = [];
38338
+ const seen = /* @__PURE__ */ new Set();
38339
+ for (const p of pDivisors) {
38340
+ for (const q of qDivisors) {
38341
+ const pos = p / q;
38342
+ const neg2 = -p / q;
38343
+ if (!seen.has(pos)) {
38344
+ seen.add(pos);
38345
+ candidates.push([p, q]);
38346
+ }
38347
+ if (!seen.has(neg2)) {
38348
+ seen.add(neg2);
38349
+ candidates.push([-p, q]);
38350
+ }
38351
+ }
38352
+ }
38353
+ if (candidates.length > 100) return null;
38354
+ const x = ce.symbol(variable);
38355
+ const factors = [];
38356
+ let remaining = expr;
38357
+ for (const [p, q] of candidates) {
38358
+ const remDeg2 = polynomialDegree(remaining, variable);
38359
+ if (remDeg2 <= 0) break;
38360
+ const root2 = q === 1 ? ce.number(p) : ce.number(p).div(ce.number(q));
38361
+ const value = remaining.subs({ [variable]: root2 }).N();
38362
+ if (!value.isSame(0)) continue;
38363
+ const linearFactor = q === 1 ? x.sub(ce.number(p)) : ce.number(q).mul(x).sub(ce.number(p));
38364
+ const divResult = polynomialDivide(remaining, linearFactor, variable);
38365
+ if (!divResult) continue;
38366
+ factors.push(linearFactor);
38367
+ remaining = divResult[0];
38368
+ }
38369
+ if (factors.length === 0) return null;
38370
+ const remDeg = polynomialDegree(remaining, variable);
38371
+ if (remDeg === 2) {
38372
+ const quadFactored = factorQuadratic(remaining, variable);
38373
+ if (quadFactored !== null) remaining = quadFactored;
38374
+ }
38375
+ factors.push(remaining);
38376
+ if (factors.length === 1) return factors[0];
38377
+ return ce.box(["Multiply", ...factors.map((f) => f.json)]);
38378
+ }
38379
+ function extractContent(expr, variable) {
38380
+ const ce = expr.engine;
38381
+ const coeffs = getPolynomialCoefficients(expr, variable);
38382
+ if (!coeffs) return null;
38383
+ const intCoeffs = [];
38384
+ for (const c of coeffs) {
38385
+ const n = asSmallInteger(c);
38386
+ if (n === null) return null;
38387
+ intCoeffs.push(n);
38388
+ }
38389
+ const gcd7 = (a, b) => {
38390
+ a = Math.abs(a);
38391
+ b = Math.abs(b);
38392
+ while (b) {
38393
+ [a, b] = [b, a % b];
38394
+ }
38395
+ return a;
38396
+ };
38397
+ let content = 0;
38398
+ for (const c of intCoeffs) {
38399
+ if (c !== 0) content = gcd7(content, c);
38400
+ }
38401
+ if (content <= 1) return null;
38402
+ const primitiveCoeffs = coeffs.map((c) => {
38403
+ const n = asSmallInteger(c);
38404
+ return ce.number(n / content);
38405
+ });
38406
+ const primitive = fromCoefficients(primitiveCoeffs, variable);
38407
+ const factoredPrimitive = factorPolynomial(primitive, variable);
38408
+ return ce.number(content).mul(factoredPrimitive);
38409
+ }
38217
38410
  function factorPolynomial(expr, variable) {
38411
+ if (variable !== void 0) {
38412
+ const contentFactored = extractContent(expr, variable);
38413
+ if (contentFactored !== null) return contentFactored;
38414
+ }
38218
38415
  const perfectSquare = factorPerfectSquare(expr);
38219
38416
  if (perfectSquare !== null) return perfectSquare;
38220
38417
  const diffSquares = factorDifferenceOfSquares(expr);
@@ -38222,6 +38419,8 @@ function factorPolynomial(expr, variable) {
38222
38419
  if (variable !== void 0) {
38223
38420
  const quadratic = factorQuadratic(expr, variable);
38224
38421
  if (quadratic !== null) return quadratic;
38422
+ const rationalRoot = factorByRationalRoots(expr, variable);
38423
+ if (rationalRoot !== null) return rationalRoot;
38225
38424
  }
38226
38425
  return factor(expr);
38227
38426
  }
@@ -38267,6 +38466,257 @@ function factor(expr) {
38267
38466
  }
38268
38467
  return Product.from(together(expr)).asExpression();
38269
38468
  }
38469
+ function collectFactors(expr, variable) {
38470
+ const rawFactors = [];
38471
+ collectFactorsRaw(expr, variable, rawFactors);
38472
+ const merged = [];
38473
+ for (const f of rawFactors) {
38474
+ let found = false;
38475
+ for (const m of merged) {
38476
+ if (m.factor.isSame(f.factor)) {
38477
+ m.multiplicity += f.multiplicity;
38478
+ found = true;
38479
+ break;
38480
+ }
38481
+ }
38482
+ if (!found) merged.push({ ...f });
38483
+ }
38484
+ return merged;
38485
+ }
38486
+ function collectFactorsRaw(expr, variable, result) {
38487
+ if (isFunction2(expr, "Multiply")) {
38488
+ for (const op of expr.ops) {
38489
+ collectFactorsRaw(op, variable, result);
38490
+ }
38491
+ return;
38492
+ }
38493
+ if (isFunction2(expr, "Power")) {
38494
+ const base = expr.op1;
38495
+ const exp3 = asSmallInteger(expr.op2);
38496
+ if (exp3 !== null && exp3 > 0 && base.has(variable)) {
38497
+ const deg3 = polynomialDegree(base, variable);
38498
+ result.push({ factor: base, multiplicity: exp3, degree: deg3 });
38499
+ return;
38500
+ }
38501
+ if (!expr.has(variable)) return;
38502
+ const deg2 = polynomialDegree(expr, variable);
38503
+ result.push({ factor: expr, multiplicity: 1, degree: deg2 });
38504
+ return;
38505
+ }
38506
+ if (!expr.has(variable)) return;
38507
+ if (isNumber(expr)) return;
38508
+ const deg = polynomialDegree(expr, variable);
38509
+ result.push({ factor: expr, multiplicity: 1, degree: deg });
38510
+ }
38511
+ function solveLinearSystem(matrix, numVars) {
38512
+ const rows = matrix.length;
38513
+ const cols = numVars + 1;
38514
+ const m = matrix.map((row) => [...row]);
38515
+ const pivotRow = new Array(numVars).fill(-1);
38516
+ let currentRow = 0;
38517
+ for (let col = 0; col < numVars && currentRow < rows; col++) {
38518
+ let maxVal = 0;
38519
+ let maxRow = -1;
38520
+ for (let row = currentRow; row < rows; row++) {
38521
+ const absVal = Math.abs(m[row][col]);
38522
+ if (absVal > maxVal) {
38523
+ maxVal = absVal;
38524
+ maxRow = row;
38525
+ }
38526
+ }
38527
+ if (maxVal === 0) continue;
38528
+ if (maxRow !== currentRow) {
38529
+ [m[currentRow], m[maxRow]] = [m[maxRow], m[currentRow]];
38530
+ }
38531
+ pivotRow[col] = currentRow;
38532
+ for (let row = 0; row < rows; row++) {
38533
+ if (row === currentRow) continue;
38534
+ if (m[row][col] === 0) continue;
38535
+ const factor3 = m[row][col];
38536
+ const pivotVal = m[currentRow][col];
38537
+ for (let j = 0; j < cols; j++) {
38538
+ m[row][j] = m[row][j] * pivotVal - factor3 * m[currentRow][j];
38539
+ }
38540
+ }
38541
+ currentRow++;
38542
+ }
38543
+ const solution = new Array(numVars);
38544
+ for (let col = 0; col < numVars; col++) {
38545
+ const pr = pivotRow[col];
38546
+ if (pr === -1) {
38547
+ solution[col] = [0, 1];
38548
+ continue;
38549
+ }
38550
+ const num = m[pr][cols - 1];
38551
+ const den = m[pr][col];
38552
+ if (den === 0) return null;
38553
+ const g = gcd4(Math.abs(num), Math.abs(den));
38554
+ const sign3 = den < 0 ? -1 : 1;
38555
+ solution[col] = [sign3 * num / g, sign3 * den / g];
38556
+ }
38557
+ return solution;
38558
+ }
38559
+ function gcd4(a, b) {
38560
+ a = Math.abs(a);
38561
+ b = Math.abs(b);
38562
+ while (b) {
38563
+ [a, b] = [b, a % b];
38564
+ }
38565
+ return a || 1;
38566
+ }
38567
+ function partialFraction(expr, variable) {
38568
+ const ce = expr.engine;
38569
+ if (!isFunction2(expr, "Divide")) return expr;
38570
+ const numer = expr.op1;
38571
+ const denom = expr.op2;
38572
+ const numerDeg = polynomialDegree(numer, variable);
38573
+ const denomDeg = polynomialDegree(denom, variable);
38574
+ if (numerDeg < 0 || denomDeg < 0) return expr;
38575
+ if (denomDeg === 0) return expr;
38576
+ let quotient = null;
38577
+ let remainder2;
38578
+ if (numerDeg >= denomDeg) {
38579
+ const divResult = polynomialDivide(numer, denom, variable);
38580
+ if (!divResult) return expr;
38581
+ quotient = divResult[0];
38582
+ remainder2 = divResult[1];
38583
+ const remCoeffs2 = getPolynomialCoefficients(remainder2, variable);
38584
+ if (remCoeffs2 && remCoeffs2.every((c) => c.isSame(0))) {
38585
+ return quotient;
38586
+ }
38587
+ } else {
38588
+ remainder2 = numer;
38589
+ }
38590
+ const factoredDenom = factorPolynomial(denom, variable);
38591
+ const factors = collectFactors(factoredDenom, variable);
38592
+ if (factors.length === 0) return expr;
38593
+ if (factors.length === 1 && factors[0].multiplicity === 1) {
38594
+ if (quotient) return quotient.add(remainder2.div(denom));
38595
+ return expr;
38596
+ }
38597
+ for (const f of factors) {
38598
+ if (f.degree > 2 || f.degree < 0) return expr;
38599
+ }
38600
+ let totalFactorDeg = 0;
38601
+ for (const f of factors) {
38602
+ totalFactorDeg += f.degree * f.multiplicity;
38603
+ }
38604
+ if (totalFactorDeg !== denomDeg) return expr;
38605
+ const templateTerms = [];
38606
+ let unknownCount = 0;
38607
+ for (const f of factors) {
38608
+ for (let k = 1; k <= f.multiplicity; k++) {
38609
+ if (f.degree === 1) {
38610
+ templateTerms.push({
38611
+ isLinear: true,
38612
+ factor: f.factor,
38613
+ power: k,
38614
+ unknownIndex: unknownCount
38615
+ });
38616
+ unknownCount++;
38617
+ } else {
38618
+ templateTerms.push({
38619
+ isLinear: false,
38620
+ factor: f.factor,
38621
+ power: k,
38622
+ unknownIndex: unknownCount
38623
+ });
38624
+ unknownCount += 2;
38625
+ }
38626
+ }
38627
+ }
38628
+ if (unknownCount !== denomDeg) return expr;
38629
+ const expandedDenom = expand2(denom);
38630
+ const denomCoeffs = getPolynomialCoefficients(expandedDenom, variable);
38631
+ if (!denomCoeffs) return expr;
38632
+ const expandedRemainder = expand2(remainder2);
38633
+ const remCoeffs = getPolynomialCoefficients(expandedRemainder, variable);
38634
+ if (!remCoeffs) return expr;
38635
+ const systemRows = denomDeg;
38636
+ const augMatrix = [];
38637
+ for (let i = 0; i < systemRows; i++) {
38638
+ augMatrix.push(new Array(unknownCount + 1).fill(0));
38639
+ }
38640
+ for (let i = 0; i < systemRows; i++) {
38641
+ const coeff = i < remCoeffs.length ? asSmallInteger(remCoeffs[i]) : 0;
38642
+ if (coeff === null) return expr;
38643
+ augMatrix[i][unknownCount] = coeff;
38644
+ }
38645
+ for (const t of templateTerms) {
38646
+ let termDenom;
38647
+ if (t.power === 1) {
38648
+ termDenom = t.factor;
38649
+ } else {
38650
+ termDenom = ce.box(["Power", t.factor.json, t.power]);
38651
+ }
38652
+ const cofactorResult = polynomialDivide(expandedDenom, termDenom, variable);
38653
+ if (!cofactorResult) return expr;
38654
+ const cofactor = cofactorResult[0];
38655
+ const cofRem = cofactorResult[1];
38656
+ const cofRemCoeffs = getPolynomialCoefficients(cofRem, variable);
38657
+ if (!cofRemCoeffs || !cofRemCoeffs.every((c) => c.isSame(0))) return expr;
38658
+ const expandedCofactor = expand2(cofactor);
38659
+ const cofCoeffs = getPolynomialCoefficients(expandedCofactor, variable);
38660
+ if (!cofCoeffs) return expr;
38661
+ const intCofCoeffs = [];
38662
+ for (let i = 0; i < systemRows; i++) {
38663
+ const c = i < cofCoeffs.length ? asSmallInteger(cofCoeffs[i]) : 0;
38664
+ if (c === null) return expr;
38665
+ intCofCoeffs.push(c);
38666
+ }
38667
+ if (t.isLinear) {
38668
+ for (let i = 0; i < systemRows; i++) {
38669
+ augMatrix[i][t.unknownIndex] += intCofCoeffs[i];
38670
+ }
38671
+ } else {
38672
+ const aIdx = t.unknownIndex;
38673
+ const bIdx = t.unknownIndex + 1;
38674
+ for (let i = 0; i < systemRows; i++) {
38675
+ augMatrix[i][bIdx] += intCofCoeffs[i];
38676
+ if (i > 0) {
38677
+ augMatrix[i][aIdx] += intCofCoeffs[i - 1];
38678
+ }
38679
+ }
38680
+ }
38681
+ }
38682
+ const solution = solveLinearSystem(augMatrix, unknownCount);
38683
+ if (!solution) return expr;
38684
+ const x = ce.symbol(variable);
38685
+ const partialTerms = [];
38686
+ if (quotient) partialTerms.push(quotient);
38687
+ for (const t of templateTerms) {
38688
+ let termDenom;
38689
+ if (t.power === 1) {
38690
+ termDenom = t.factor;
38691
+ } else {
38692
+ termDenom = ce.box(["Power", t.factor.json, t.power]);
38693
+ }
38694
+ let termNumer;
38695
+ if (t.isLinear) {
38696
+ const [num, den] = solution[t.unknownIndex];
38697
+ if (num === 0) continue;
38698
+ termNumer = den === 1 ? ce.number(num) : ce.number(num).div(ce.number(den));
38699
+ } else {
38700
+ const [aNum, aDen] = solution[t.unknownIndex];
38701
+ const [bNum, bDen] = solution[t.unknownIndex + 1];
38702
+ if (aNum === 0 && bNum === 0) continue;
38703
+ const terms = [];
38704
+ if (aNum !== 0) {
38705
+ const aCoeff = aDen === 1 ? ce.number(aNum) : ce.number(aNum).div(ce.number(aDen));
38706
+ terms.push(aCoeff.mul(x));
38707
+ }
38708
+ if (bNum !== 0) {
38709
+ const bCoeff = bDen === 1 ? ce.number(bNum) : ce.number(bNum).div(ce.number(bDen));
38710
+ terms.push(bCoeff);
38711
+ }
38712
+ termNumer = terms.length === 1 ? terms[0] : add3(...terms);
38713
+ }
38714
+ partialTerms.push(termNumer.div(termDenom));
38715
+ }
38716
+ if (partialTerms.length === 0) return ce.Zero;
38717
+ if (partialTerms.length === 1) return partialTerms[0];
38718
+ return add3(...partialTerms);
38719
+ }
38270
38720
 
38271
38721
  // src/compute-engine/symbolic/distribute.ts
38272
38722
  function distribute2(lhs, rhs, g, f) {
@@ -38341,7 +38791,7 @@ var POLYNOMIALS_LIBRARY = [
38341
38791
  }
38342
38792
  },
38343
38793
  CoefficientList: {
38344
- description: "Return the list of coefficients of a polynomial, from lowest to highest degree. Example: CoefficientList(x\xB3 + 2x + 1, x) \u2192 [1, 2, 0, 1]",
38794
+ description: "Return the list of coefficients of a polynomial, from highest to lowest degree. Example: CoefficientList(x\xB3 + 2x + 1, x) \u2192 [1, 0, 2, 1]",
38345
38795
  lazy: true,
38346
38796
  signature: "(value, symbol) -> list<value>",
38347
38797
  evaluate: ([poly, varExpr]) => {
@@ -38350,7 +38800,7 @@ var POLYNOMIALS_LIBRARY = [
38350
38800
  if (!variable) return void 0;
38351
38801
  const coeffs = getPolynomialCoefficients(poly.canonical, variable);
38352
38802
  if (!coeffs) return void 0;
38353
- return poly.engine.box(["List", ...coeffs]);
38803
+ return poly.engine.box(["List", ...coeffs.reverse()]);
38354
38804
  }
38355
38805
  },
38356
38806
  PolynomialQuotient: {
@@ -38406,6 +38856,85 @@ var POLYNOMIALS_LIBRARY = [
38406
38856
  if (!variable) return void 0;
38407
38857
  return cancelCommonFactors(expr.canonical, variable);
38408
38858
  }
38859
+ },
38860
+ PartialFraction: {
38861
+ description: "Decompose a rational expression into partial fractions. Example: PartialFraction(1/((x+1)(x+2)), x) \u2192 1/(x+1) - 1/(x+2)",
38862
+ lazy: true,
38863
+ signature: "(value, symbol) -> value",
38864
+ evaluate: ([expr, varExpr]) => {
38865
+ if (!expr || !varExpr) return void 0;
38866
+ const variable = sym(varExpr.canonical);
38867
+ if (!variable) return void 0;
38868
+ return partialFraction(expr.canonical, variable);
38869
+ }
38870
+ },
38871
+ Apart: {
38872
+ description: "Alias for PartialFraction. Decompose a rational expression into partial fractions.",
38873
+ lazy: true,
38874
+ signature: "(value, symbol) -> value",
38875
+ evaluate: ([expr, varExpr]) => {
38876
+ if (!expr || !varExpr) return void 0;
38877
+ const variable = sym(varExpr.canonical);
38878
+ if (!variable) return void 0;
38879
+ return partialFraction(expr.canonical, variable);
38880
+ }
38881
+ },
38882
+ PolynomialRoots: {
38883
+ description: "Return the roots of a polynomial expression. Example: PolynomialRoots(x\xB2 - 5x + 6, x) \u2192 {2, 3}",
38884
+ lazy: true,
38885
+ signature: "(value, symbol) -> set<value>",
38886
+ evaluate: ([poly, varExpr]) => {
38887
+ if (!poly || !varExpr) return void 0;
38888
+ const variable = sym(varExpr.canonical);
38889
+ if (!variable) return void 0;
38890
+ const roots = poly.canonical.polynomialRoots(variable);
38891
+ if (!roots || roots.length === 0) return void 0;
38892
+ return poly.engine.box(["Set", ...roots.map((r) => r.json)]);
38893
+ }
38894
+ },
38895
+ Discriminant: {
38896
+ description: "Return the discriminant of a polynomial. Example: Discriminant(x\xB2 - 5x + 6, x) \u2192 1",
38897
+ lazy: true,
38898
+ signature: "(value, symbol) -> value",
38899
+ evaluate: ([poly, varExpr]) => {
38900
+ if (!poly || !varExpr) return void 0;
38901
+ const variable = sym(varExpr.canonical);
38902
+ if (!variable) return void 0;
38903
+ const coeffsAsc = getPolynomialCoefficients(poly.canonical, variable);
38904
+ if (!coeffsAsc) return void 0;
38905
+ const coeffs = [...coeffsAsc].reverse();
38906
+ const degree = coeffs.length - 1;
38907
+ const ce = poly.engine;
38908
+ if (degree === 2) {
38909
+ const [a, b, c] = coeffs;
38910
+ return b.mul(b).sub(ce.number(4).mul(a).mul(c));
38911
+ }
38912
+ if (degree === 3) {
38913
+ const [a, b, c, d] = coeffs;
38914
+ return b.mul(b).mul(c).mul(c).sub(ce.number(4).mul(a).mul(c).mul(c).mul(c)).sub(ce.number(4).mul(b).mul(b).mul(b).mul(d)).add(ce.number(18).mul(a).mul(b).mul(c).mul(d)).sub(ce.number(27).mul(a).mul(a).mul(d).mul(d));
38915
+ }
38916
+ if (degree === 4) {
38917
+ const [a, b, c, d, e] = coeffs;
38918
+ return ce.number(256).mul(a).mul(a).mul(a).mul(e).mul(e).mul(e).sub(ce.number(192).mul(a).mul(a).mul(b).mul(d).mul(e).mul(e)).sub(ce.number(128).mul(a).mul(a).mul(c).mul(c).mul(e).mul(e)).add(ce.number(144).mul(a).mul(a).mul(c).mul(d).mul(d).mul(e)).sub(ce.number(27).mul(a).mul(a).mul(d).mul(d).mul(d).mul(d)).add(ce.number(144).mul(a).mul(b).mul(b).mul(c).mul(e).mul(e)).sub(ce.number(6).mul(a).mul(b).mul(b).mul(d).mul(d).mul(e)).sub(ce.number(80).mul(a).mul(b).mul(c).mul(c).mul(d).mul(e)).add(ce.number(18).mul(a).mul(b).mul(c).mul(d).mul(d).mul(d)).add(ce.number(16).mul(a).mul(c).mul(c).mul(c).mul(c).mul(e)).sub(ce.number(4).mul(a).mul(c).mul(c).mul(c).mul(d).mul(d)).sub(ce.number(27).mul(b).mul(b).mul(b).mul(b).mul(e).mul(e)).add(ce.number(18).mul(b).mul(b).mul(b).mul(c).mul(d).mul(e)).sub(ce.number(4).mul(b).mul(b).mul(b).mul(d).mul(d).mul(d)).sub(ce.number(4).mul(b).mul(b).mul(c).mul(c).mul(c).mul(e)).add(b.mul(b).mul(c).mul(c).mul(d).mul(d));
38919
+ }
38920
+ return void 0;
38921
+ }
38922
+ },
38923
+ Polynomial: {
38924
+ description: "Construct a polynomial from a list of coefficients (highest to lowest degree) and a variable. Example: Polynomial([1, 0, 2, 1], x) \u2192 x\xB3 + 2x + 1",
38925
+ lazy: true,
38926
+ signature: "(list<value>, symbol) -> value",
38927
+ evaluate: ([coeffList, varExpr]) => {
38928
+ if (!coeffList || !varExpr) return void 0;
38929
+ const variable = sym(varExpr.canonical);
38930
+ if (!variable) return void 0;
38931
+ const canonical2 = coeffList.canonical;
38932
+ if (!isFunction2(canonical2, "List")) return void 0;
38933
+ const coeffs = canonical2.ops;
38934
+ if (coeffs.length === 0) return void 0;
38935
+ const ascending = [...coeffs].reverse();
38936
+ return fromCoefficients(ascending, variable);
38937
+ }
38409
38938
  }
38410
38939
  }
38411
38940
  ];
@@ -46404,7 +46933,7 @@ function isLinearInVariables(expr, variables) {
46404
46933
  };
46405
46934
  return checkTerm(expr);
46406
46935
  }
46407
- function solveLinearSystem(equations, variables) {
46936
+ function solveLinearSystem2(equations, variables) {
46408
46937
  if (equations.length === 0 || variables.length === 0) return null;
46409
46938
  const ce = equations[0].engine;
46410
46939
  const n = variables.length;
@@ -47389,6 +47918,15 @@ function matchOnce(expr, pattern, substitution, options) {
47389
47918
  } else if (operator2 === expr.operator) {
47390
47919
  const matchPerms = options.matchPermutations ?? true;
47391
47920
  result = pattern.operatorDefinition.commutative && matchPerms ? matchPermutation(expr, pattern, substitution, options) : matchArguments(expr, pattern.ops, substitution, options);
47921
+ if (result === null && options.matchMissingTerms && isFunction2(expr) && isFunction2(pattern) && expr.nops < pattern.nops) {
47922
+ result = matchWithMissingTerms(
47923
+ expr,
47924
+ pattern,
47925
+ substitution,
47926
+ options,
47927
+ ce
47928
+ );
47929
+ }
47392
47930
  }
47393
47931
  if (result === null && useVariations) {
47394
47932
  if (!acceptVariants) return null;
@@ -47686,8 +48224,8 @@ function matchCommutativeWithAnchors(expr, pattern, substitution, options) {
47686
48224
  const minCapture = 1;
47687
48225
  const maxCapture2 = remaining.length - countMinNeeded(restWildcards);
47688
48226
  for (let count = maxCapture2; count >= minCapture; count--) {
47689
- const combinations = getCombinations(remaining.length, count);
47690
- for (const indices of combinations) {
48227
+ const combinations2 = getCombinations(remaining.length, count);
48228
+ for (const indices of combinations2) {
47691
48229
  const captured = indices.map((i) => remaining[i]);
47692
48230
  const capturedExpr = wrapCaptured(captured);
47693
48231
  const newSub = captureWildcard(wcName, capturedExpr, sub3);
@@ -47716,8 +48254,8 @@ function matchCommutativeWithAnchors(expr, pattern, substitution, options) {
47716
48254
  if (result !== null) return result;
47717
48255
  }
47718
48256
  } else {
47719
- const combinations = getCombinations(remaining.length, count);
47720
- for (const indices of combinations) {
48257
+ const combinations2 = getCombinations(remaining.length, count);
48258
+ for (const indices of combinations2) {
47721
48259
  const captured = indices.map((i) => remaining[i]);
47722
48260
  const capturedExpr = wrapCaptured(captured);
47723
48261
  const newSub = captureWildcard(wcName, capturedExpr, sub3);
@@ -47891,17 +48429,140 @@ function matchArguments(expr, patterns, substitution, options) {
47891
48429
  }
47892
48430
  }
47893
48431
  }
48432
+ function matchWithMissingTerms(expr, pattern, substitution, options, ce) {
48433
+ if (!isFunction2(expr) || !isFunction2(pattern)) return null;
48434
+ const operator2 = expr.operator;
48435
+ const identity = operator2 === "Add" ? ce.Zero : operator2 === "Multiply" ? ce.One : null;
48436
+ if (!identity) return null;
48437
+ const patOps = pattern.ops;
48438
+ const missing = patOps.length - expr.nops;
48439
+ if (missing <= 0) return null;
48440
+ const combos = combinations(patOps.length, missing);
48441
+ combos.sort((a, b) => {
48442
+ const scoreA = a.reduce((s, i) => s + patternComplexity(patOps[i]), 0);
48443
+ const scoreB = b.reduce((s, i) => s + patternComplexity(patOps[i]), 0);
48444
+ return scoreA - scoreB;
48445
+ });
48446
+ for (const identityIndices of combos) {
48447
+ const activePatOps = patOps.filter((_, i) => !identityIndices.includes(i));
48448
+ const identityPatOps = identityIndices.map((i) => patOps[i]);
48449
+ const subPattern = ce.function(operator2, activePatOps, { form: "raw" });
48450
+ let sub3 = matchPermutation(expr, subPattern, substitution, options);
48451
+ if (sub3 === null) continue;
48452
+ let failed = false;
48453
+ for (const patOp of identityPatOps) {
48454
+ const result = matchIdentityTerm(patOp, identity, sub3, options, ce);
48455
+ if (result === null) {
48456
+ failed = true;
48457
+ break;
48458
+ }
48459
+ sub3 = result;
48460
+ }
48461
+ if (!failed) return sub3;
48462
+ }
48463
+ return null;
48464
+ }
48465
+ function matchIdentityTerm(patOp, identity, sub3, options, ce) {
48466
+ const result = matchOnce(identity, patOp, sub3, options);
48467
+ if (result !== null) return result;
48468
+ if (identity.isSame(0) && isFunction2(patOp, "Multiply")) {
48469
+ for (const op of patOp.ops) {
48470
+ const wn = wildcardName(op);
48471
+ if (wn && !(wn in sub3)) {
48472
+ return captureWildcard(wn, identity, sub3);
48473
+ }
48474
+ }
48475
+ }
48476
+ if (identity.isSame(1) && isFunction2(patOp, "Power")) {
48477
+ const expOp = patOp.ops[1];
48478
+ if (expOp) {
48479
+ const wn = wildcardName(expOp);
48480
+ if (wn && !(wn in sub3)) {
48481
+ return captureWildcard(wn, ce.Zero, sub3);
48482
+ }
48483
+ }
48484
+ }
48485
+ return null;
48486
+ }
48487
+ function patternComplexity(expr) {
48488
+ if (isWildcard(expr)) return 0;
48489
+ if (isNumber(expr) || isSymbol2(expr) || isString(expr)) return 1;
48490
+ if (isFunction2(expr))
48491
+ return 1 + expr.ops.reduce((s, op) => s + patternComplexity(op), 0);
48492
+ return 1;
48493
+ }
48494
+ function combinations(n, k) {
48495
+ const result = [];
48496
+ const combo = [];
48497
+ function backtrack(start) {
48498
+ if (combo.length === k) {
48499
+ result.push([...combo]);
48500
+ return;
48501
+ }
48502
+ for (let i = start; i < n; i++) {
48503
+ combo.push(i);
48504
+ backtrack(i + 1);
48505
+ combo.pop();
48506
+ }
48507
+ }
48508
+ backtrack(0);
48509
+ return result;
48510
+ }
47894
48511
  function match(subject, pattern, options) {
47895
- pattern = pattern.structural;
47896
- const useVariations = options?.useVariations ?? false;
48512
+ const ce = subject.engine;
48513
+ let autoWildcard = false;
48514
+ let boxedPattern;
48515
+ if (typeof pattern === "string") {
48516
+ autoWildcard = true;
48517
+ boxedPattern = ce.parse(pattern).map(
48518
+ (x) => isSymbol2(x) && x.symbol.length === 1 ? ce.symbol("_" + x.symbol) : x,
48519
+ { canonical: false }
48520
+ );
48521
+ } else if ("engine" in pattern) {
48522
+ boxedPattern = pattern;
48523
+ } else {
48524
+ boxedPattern = ce.box(pattern);
48525
+ }
48526
+ boxedPattern = boxedPattern.structural;
48527
+ const useVariations = options?.useVariations ?? autoWildcard;
47897
48528
  const opts = {
47898
48529
  recursive: options?.recursive ?? false,
47899
48530
  useVariations,
47900
48531
  acceptVariants: useVariations,
47901
- matchPermutations: options?.matchPermutations ?? true
48532
+ matchPermutations: options?.matchPermutations ?? true,
48533
+ matchMissingTerms: options?.matchMissingTerms ?? autoWildcard
47902
48534
  };
47903
- const substitution = options?.substitution ?? {};
47904
- return matchOnce(subject.structural, pattern.structural, substitution, opts);
48535
+ let substitution = options?.substitution ?? {};
48536
+ if (autoWildcard && Object.keys(substitution).length > 0) {
48537
+ const prefixed = {};
48538
+ for (const [k, v] of Object.entries(substitution)) {
48539
+ if (k.startsWith("_")) {
48540
+ prefixed[k] = v;
48541
+ } else {
48542
+ if (!(`_${k}` in substitution)) prefixed[`_${k}`] = v;
48543
+ prefixed[k] = v;
48544
+ }
48545
+ }
48546
+ substitution = prefixed;
48547
+ }
48548
+ const result = matchOnce(
48549
+ subject.structural,
48550
+ boxedPattern.structural,
48551
+ substitution,
48552
+ opts
48553
+ );
48554
+ if (!result) return null;
48555
+ if (autoWildcard) {
48556
+ const clean = {};
48557
+ for (const [k, v] of Object.entries(result)) {
48558
+ if (!k.startsWith("_")) continue;
48559
+ const name = k.slice(1);
48560
+ if (isSymbol2(v) && v.symbol === name) continue;
48561
+ clean[name] = v;
48562
+ }
48563
+ return clean;
48564
+ }
48565
+ return result;
47905
48566
  }
47906
48567
 
47907
48568
  // src/compute-engine/boxed-expression/sgn.ts
@@ -48757,7 +49418,7 @@ var BoxedFunction = class extends _BoxedExpression {
48757
49418
  };
48758
49419
  function solveSystem(ce, equations, varNames) {
48759
49420
  if (equations && equations.every((eq2) => eq2.operator === "Equal")) {
48760
- const linearResult = solveLinearSystem([...equations], varNames);
49421
+ const linearResult = solveLinearSystem2([...equations], varNames);
48761
49422
  if (linearResult && filterSolutionByTypes(ce, varNames, linearResult))
48762
49423
  return linearResult;
48763
49424
  const polyResult = solvePolynomialSystem([...equations], varNames);
@@ -48787,7 +49448,7 @@ function solveSystem(ce, equations, varNames) {
48787
49448
  (eq2) => inequalityOps.includes(eq2.operator ?? "")
48788
49449
  );
48789
49450
  if (equalities.length > 0 && inequalities.length > 0 && equalities.length + inequalities.length === equations.length) {
48790
- const linearResult = solveLinearSystem([...equalities], varNames);
49451
+ const linearResult = solveLinearSystem2([...equalities], varNames);
48791
49452
  if (linearResult) {
48792
49453
  if (satisfiesInequalities(linearResult, inequalities))
48793
49454
  return filterSolutionByTypes(ce, varNames, linearResult) ? linearResult : null;
@@ -50428,11 +51089,7 @@ var BaseCompiler = class _BaseCompiler {
50428
51089
  if (h === "Function") {
50429
51090
  const fnFn = target.functions?.(h);
50430
51091
  if (typeof fnFn === "function")
50431
- return fnFn(
50432
- args,
50433
- (expr) => _BaseCompiler.compile(expr, target),
50434
- target
50435
- );
51092
+ return fnFn(args, (expr) => _BaseCompiler.compile(expr, target), target);
50436
51093
  const params = args.slice(1).map((x) => isSymbol2(x) ? x.symbol : "_");
50437
51094
  return `((${params.join(", ")}) => ${_BaseCompiler.compile(
50438
51095
  args[0].canonical,
@@ -50561,7 +51218,10 @@ var BaseCompiler = class _BaseCompiler {
50561
51218
  };
50562
51219
  const result = args.filter((a) => !isSymbol2(a, "Nothing")).map((arg) => {
50563
51220
  if (isFunction2(arg, "Declare") && isSymbol2(arg.ops[0]) && target.declare) {
50564
- return target.declare(arg.ops[0].symbol, typeHints[arg.ops[0].symbol]);
51221
+ return target.declare(
51222
+ arg.ops[0].symbol,
51223
+ typeHints[arg.ops[0].symbol]
51224
+ );
50565
51225
  }
50566
51226
  return _BaseCompiler.compile(arg, localTarget);
50567
51227
  }).filter((s) => s !== "");
@@ -51052,6 +51712,9 @@ _setExpandForIs(expand2);
51052
51712
  _setSerializeJson(serializeJson);
51053
51713
  _setProduct(Product);
51054
51714
  _setCompile(compile);
51715
+ _setGetPolynomialCoefficients(getPolynomialCoefficients);
51716
+ _setGetPolynomialDegree(polynomialDegree);
51717
+ _setFindUnivariateRoots(findUnivariateRoots);
51055
51718
 
51056
51719
  // src/compute-engine/symbolic/simplify-logic.ts
51057
51720
  function simplifyLogicFunction(x) {
@@ -53990,6 +54653,27 @@ var SIMPLIFY_RULES = [
53990
54653
  if (result.isSame(x)) return void 0;
53991
54654
  return { value: result, because: "cancel common polynomial factors" };
53992
54655
  },
54656
+ //
54657
+ // Auto partial fraction decomposition for Divide with factored denominator
54658
+ // e.g., 1/((x+1)(x+2)) → 1/(x+1) - 1/(x+2)
54659
+ // Only triggers when denominator is already in factored form (Multiply or Power)
54660
+ //
54661
+ // IMPORTANT: partialFraction must not call .simplify() on its result
54662
+ //
54663
+ (x) => {
54664
+ if (!isFunction2(x, "Divide")) return void 0;
54665
+ const denom = x.op2;
54666
+ const denomOp = denom.operator;
54667
+ if (denomOp !== "Multiply" && denomOp !== "Power") return void 0;
54668
+ const unknowns = x.unknowns;
54669
+ if (unknowns.length !== 1) return void 0;
54670
+ const variable = unknowns[0];
54671
+ const result = partialFraction(x, variable);
54672
+ if (result.isSame(x)) return void 0;
54673
+ const ce = x.engine;
54674
+ if (ce.costFunction(result) >= ce.costFunction(x)) return void 0;
54675
+ return { value: result, because: "partial fraction decomposition" };
54676
+ },
53993
54677
  // Quick a/a -> 1 check for identical numerator/denominator
53994
54678
  // Must run before expand to avoid decomposing the fraction first
53995
54679
  (x) => {
@@ -57754,7 +58438,8 @@ var GPU_FUNCTIONS = {
57754
58438
  return `_gpu_fresnelS(${compile3(x)})`;
57755
58439
  },
57756
58440
  BesselJ: ([n, x], compile3, target) => {
57757
- if (n === null || x === null) throw new Error("BesselJ: need two arguments");
58441
+ if (n === null || x === null)
58442
+ throw new Error("BesselJ: need two arguments");
57758
58443
  const intCast = target?.language === "wgsl" ? "i32" : "int";
57759
58444
  return `_gpu_besselJ(${intCast}(${compile3(n)}), ${compile3(x)})`;
57760
58445
  },
@@ -57856,8 +58541,7 @@ var GPU_FUNCTIONS = {
57856
58541
  throw new Error("Loop: expected Element(index, Range(lo, hi))");
57857
58542
  const indexExpr = indexing.ops[0];
57858
58543
  const rangeExpr = indexing.ops[1];
57859
- if (!isSymbol2(indexExpr))
57860
- throw new Error("Loop: index must be a symbol");
58544
+ if (!isSymbol2(indexExpr)) throw new Error("Loop: index must be a symbol");
57861
58545
  if (!isFunction2(rangeExpr, "Range"))
57862
58546
  throw new Error("Loop: expected Range(lo, hi)");
57863
58547
  const index = indexExpr.symbol;
@@ -59109,7 +59793,9 @@ var WGSLTarget = class extends GPUShaderTarget {
59109
59793
  const params = parameters.map(([name, type2]) => `${name}: ${toWGSLType(type2)}`).join(", ");
59110
59794
  if (body.includes("\n")) {
59111
59795
  const indented = body.split("\n").map((l) => ` ${l}`).join("\n");
59112
- return `fn ${functionName}(${params}) -> ${toWGSLType(returnType)} {
59796
+ return `fn ${functionName}(${params}) -> ${toWGSLType(
59797
+ returnType
59798
+ )} {
59113
59799
  ${indented};
59114
59800
  }`;
59115
59801
  }
@@ -59757,7 +60443,7 @@ function binomial2(n, k) {
59757
60443
  ];
59758
60444
  return ok({ lo: Math.min(...vals), hi: Math.max(...vals) });
59759
60445
  }
59760
- function gcd4(a, b) {
60446
+ function gcd5(a, b) {
59761
60447
  const uA = unwrapOrPropagate(a);
59762
60448
  if (!Array.isArray(uA)) return uA;
59763
60449
  const uB = unwrapOrPropagate(b);
@@ -60409,7 +61095,7 @@ var IntervalArithmetic = {
60409
61095
  factorial: factorial5,
60410
61096
  factorial2: factorial24,
60411
61097
  binomial: binomial2,
60412
- gcd: gcd4,
61098
+ gcd: gcd5,
60413
61099
  lcm: lcm4,
60414
61100
  chop: chop4,
60415
61101
  erf: erf2,
@@ -64188,6 +64874,11 @@ var _Parser = class __Parser {
64188
64874
  if (this.atEnd) return lhs;
64189
64875
  console.assert(lhs !== null);
64190
64876
  const index = this.index;
64877
+ if (this.options.strict === false && typeof lhs === "string" && lhs.length === 1 && /^[a-zA-Z]$/.test(lhs) && /^[2-9]$/.test(this.peek)) {
64878
+ const digit = parseInt(this.peek);
64879
+ this.index++;
64880
+ return this.parseSupsub(["Power", lhs, digit]);
64881
+ }
64191
64882
  this.skipSpace();
64192
64883
  const superscripts = [];
64193
64884
  const subscripts = [];
@@ -66292,9 +66983,9 @@ function TR12i(expr) {
66292
66983
  return ce._fn("Tan", [tanCArg]).neg();
66293
66984
  }
66294
66985
  function lcm5(a, b) {
66295
- return Math.abs(a * b) / gcd5(a, b);
66986
+ return Math.abs(a * b) / gcd6(a, b);
66296
66987
  }
66297
- function gcd5(a, b) {
66988
+ function gcd6(a, b) {
66298
66989
  a = Math.abs(a);
66299
66990
  b = Math.abs(b);
66300
66991
  while (b) {
@@ -67980,10 +68671,10 @@ var ComputeEngine = class _ComputeEngine {
67980
68671
  _setComputeEngineClass(ComputeEngine);
67981
68672
 
67982
68673
  // src/compute-engine.ts
67983
- var version = "0.53.1";
68674
+ var version = "0.54.1";
67984
68675
  globalThis[/* @__PURE__ */ Symbol.for("io.cortexjs.compute-engine")] = {
67985
68676
  ComputeEngine: ComputeEngine.prototype.constructor,
67986
- version: "0.53.1"
68677
+ version: "0.54.1"
67987
68678
  };
67988
68679
  export {
67989
68680
  BaseCompiler,