@cortex-js/compute-engine 0.53.1 → 0.54.0

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 +1 -1
@@ -1,4 +1,4 @@
1
- /** Compute Engine 0.53.1 */
1
+ /** Compute Engine 0.54.0 */
2
2
  (function(global,factory){typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'],factory):(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ComputeEngine = {}));})(this, (function (exports) { 'use strict';
3
3
  var ComputeEngine = (() => {
4
4
  var __defProp = Object.defineProperty;
@@ -12351,6 +12351,18 @@ var ComputeEngine = (() => {
12351
12351
  function _setExpandForIs(fn) {
12352
12352
  _expandForIs = fn;
12353
12353
  }
12354
+ var _getPolynomialCoefficients;
12355
+ function _setGetPolynomialCoefficients(fn) {
12356
+ _getPolynomialCoefficients = fn;
12357
+ }
12358
+ var _getPolynomialDegree;
12359
+ function _setGetPolynomialDegree(fn) {
12360
+ _getPolynomialDegree = fn;
12361
+ }
12362
+ var _findUnivariateRoots;
12363
+ function _setFindUnivariateRoots(fn) {
12364
+ _findUnivariateRoots = fn;
12365
+ }
12354
12366
  var EXPANDABLE_OPS = ["Multiply", "Power", "Negate", "Divide"];
12355
12367
  function _couldBenefitFromExpand(a, b) {
12356
12368
  if (a.has(EXPANDABLE_OPS)) return true;
@@ -12666,6 +12678,34 @@ var ComputeEngine = (() => {
12666
12678
  factors() {
12667
12679
  return [this];
12668
12680
  }
12681
+ polynomialCoefficients(variable) {
12682
+ let vars;
12683
+ if (variable === void 0) {
12684
+ const unknowns = this.unknowns;
12685
+ if (unknowns.length !== 1) return void 0;
12686
+ vars = [unknowns[0]];
12687
+ } else if (typeof variable === "string") {
12688
+ vars = [variable];
12689
+ } else {
12690
+ if (variable.length === 0) return void 0;
12691
+ vars = variable;
12692
+ }
12693
+ for (const v of vars) {
12694
+ if (_getPolynomialDegree(this, v) < 0) return void 0;
12695
+ }
12696
+ const coeffs = _getPolynomialCoefficients(this, vars[0]);
12697
+ if (coeffs === null) return void 0;
12698
+ return coeffs.reverse();
12699
+ }
12700
+ polynomialRoots(variable) {
12701
+ if (variable === void 0) {
12702
+ const unknowns = this.unknowns;
12703
+ if (unknowns.length !== 1) return void 0;
12704
+ variable = unknowns[0];
12705
+ }
12706
+ if (_getPolynomialDegree(this, variable) < 0) return void 0;
12707
+ return _findUnivariateRoots(this, variable);
12708
+ }
12669
12709
  is(other, tolerance) {
12670
12710
  if (this.isSame(other)) return true;
12671
12711
  if (_expandForIs && _couldBenefitFromExpand(this, other)) {
@@ -16125,10 +16165,14 @@ ${lines.join("\n")}`;
16125
16165
  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;
16126
16166
  }
16127
16167
  function asRadical(expr) {
16128
- if (isSqrt(expr) && isFunction2(expr)) return asRational(expr.op1) ?? null;
16168
+ if (isSqrt(expr) && isFunction2(expr)) {
16169
+ const r = asRational(expr.op1);
16170
+ if (r === void 0 || r[0] < 0 || r[1] < 0) return null;
16171
+ return r;
16172
+ }
16129
16173
  if (isFunction2(expr, "Divide") && expr.op1.isSame(1) && isSqrt(expr.op2)) {
16130
16174
  const n = expr.op2.re;
16131
- if (!Number.isInteger(n)) return null;
16175
+ if (!Number.isInteger(n) || n <= 0) return null;
16132
16176
  return [1, n];
16133
16177
  }
16134
16178
  return null;
@@ -24009,7 +24053,9 @@ ${lines.join("\n")}`;
24009
24053
  if (n === null) return void 0;
24010
24054
  const ce = x.engine;
24011
24055
  if (bignumPreferred(ce))
24012
- return ce.number(run(factorial23(ce, ce.bignum(n)), ce._timeRemaining));
24056
+ return ce.number(
24057
+ run(factorial23(ce, ce.bignum(n)), ce._timeRemaining)
24058
+ );
24013
24059
  return ce.number(factorial22(n));
24014
24060
  }
24015
24061
  },
@@ -26410,6 +26456,268 @@ ${e.message}
26410
26456
  return expand2(result);
26411
26457
  }
26412
26458
 
26459
+ // src/compute-engine/boxed-expression/polynomials.ts
26460
+ function polynomialDegree(expr, variable) {
26461
+ if (isNumber(expr)) return 0;
26462
+ if (isSymbol2(expr)) {
26463
+ if (expr.symbol === variable) return 1;
26464
+ return 0;
26465
+ }
26466
+ if (!isFunction2(expr)) {
26467
+ if (expr.has(variable)) return -1;
26468
+ return 0;
26469
+ }
26470
+ const op = expr.operator;
26471
+ if (op === "Negate") return polynomialDegree(expr.op1, variable);
26472
+ if (op === "Add" || op === "Subtract") {
26473
+ let maxDeg = 0;
26474
+ for (const arg of expr.ops) {
26475
+ const deg = polynomialDegree(arg, variable);
26476
+ if (deg < 0) return -1;
26477
+ maxDeg = Math.max(maxDeg, deg);
26478
+ }
26479
+ return maxDeg;
26480
+ }
26481
+ if (op === "Multiply") {
26482
+ let totalDeg = 0;
26483
+ for (const arg of expr.ops) {
26484
+ const deg = polynomialDegree(arg, variable);
26485
+ if (deg < 0) return -1;
26486
+ totalDeg += deg;
26487
+ }
26488
+ return totalDeg;
26489
+ }
26490
+ if (op === "Power") {
26491
+ const baseDeg = polynomialDegree(expr.op1, variable);
26492
+ if (baseDeg < 0) return -1;
26493
+ if (baseDeg === 0) {
26494
+ if (expr.op2.has(variable)) return -1;
26495
+ return 0;
26496
+ }
26497
+ const exp3 = asSmallInteger(expr.op2);
26498
+ if (exp3 === null || exp3 < 0) return -1;
26499
+ return baseDeg * exp3;
26500
+ }
26501
+ if (expr.has(variable)) return -1;
26502
+ return 0;
26503
+ }
26504
+ function getPolynomialCoefficients(expr, variable) {
26505
+ const ce = expr.engine;
26506
+ const degree = polynomialDegree(expr, variable);
26507
+ if (degree < 0) return null;
26508
+ const coeffs = new Array(degree + 1).fill(ce.Zero);
26509
+ const expanded = expand2(expr);
26510
+ const addCoefficient = (coef, deg) => {
26511
+ if (deg > degree) return false;
26512
+ coeffs[deg] = coeffs[deg].add(coef);
26513
+ return true;
26514
+ };
26515
+ const processTerm = (term) => {
26516
+ const termDeg = polynomialDegree(term, variable);
26517
+ if (termDeg < 0) return false;
26518
+ if (termDeg === 0) {
26519
+ return addCoefficient(term, 0);
26520
+ }
26521
+ if (isSymbol2(term, variable)) {
26522
+ return addCoefficient(ce.One, 1);
26523
+ }
26524
+ if (isFunction2(term, "Negate")) {
26525
+ const innerDeg = polynomialDegree(term.op1, variable);
26526
+ if (innerDeg === 0) {
26527
+ return addCoefficient(term, 0);
26528
+ }
26529
+ const innerCoeffs = getPolynomialCoefficients(term.op1, variable);
26530
+ if (!innerCoeffs) return false;
26531
+ for (let i = 0; i < innerCoeffs.length; i++) {
26532
+ if (!innerCoeffs[i].isSame(0)) {
26533
+ addCoefficient(innerCoeffs[i].neg(), i);
26534
+ }
26535
+ }
26536
+ return true;
26537
+ }
26538
+ if (isFunction2(term, "Power")) {
26539
+ if (isSymbol2(term.op1, variable)) {
26540
+ const exp3 = asSmallInteger(term.op2);
26541
+ if (exp3 !== null && exp3 >= 0) {
26542
+ return addCoefficient(ce.One, exp3);
26543
+ }
26544
+ }
26545
+ if (!term.op1.has(variable)) {
26546
+ return addCoefficient(term, 0);
26547
+ }
26548
+ return false;
26549
+ }
26550
+ if (isFunction2(term, "Multiply")) {
26551
+ const factors = term.ops;
26552
+ let coef = ce.One;
26553
+ let varDeg = 0;
26554
+ for (const factor3 of factors) {
26555
+ if (!factor3.has(variable)) {
26556
+ coef = coef.mul(factor3);
26557
+ } else if (isSymbol2(factor3, variable)) {
26558
+ varDeg += 1;
26559
+ } else if (isFunction2(factor3, "Power") && isSymbol2(factor3.op1, variable)) {
26560
+ const exp3 = asSmallInteger(factor3.op2);
26561
+ if (exp3 !== null && exp3 >= 0) {
26562
+ varDeg += exp3;
26563
+ } else {
26564
+ return false;
26565
+ }
26566
+ } else {
26567
+ return false;
26568
+ }
26569
+ }
26570
+ return addCoefficient(coef, varDeg);
26571
+ }
26572
+ return false;
26573
+ };
26574
+ if (isFunction2(expanded, "Add")) {
26575
+ for (const term of expanded.ops) {
26576
+ if (!processTerm(term)) return null;
26577
+ }
26578
+ } else {
26579
+ if (!processTerm(expanded)) return null;
26580
+ }
26581
+ return coeffs;
26582
+ }
26583
+ function fromCoefficients(coeffs, variable) {
26584
+ if (coeffs.length === 0) return coeffs[0]?.engine.Zero ?? null;
26585
+ const ce = coeffs[0].engine;
26586
+ const x = ce.symbol(variable);
26587
+ const terms = [];
26588
+ for (let i = 0; i < coeffs.length; i++) {
26589
+ const coef = coeffs[i];
26590
+ if (coef.isSame(0)) continue;
26591
+ if (i === 0) {
26592
+ terms.push(coef);
26593
+ } else if (i === 1) {
26594
+ if (coef.isSame(1)) {
26595
+ terms.push(x);
26596
+ } else if (coef.isSame(-1)) {
26597
+ terms.push(x.neg());
26598
+ } else {
26599
+ terms.push(coef.mul(x));
26600
+ }
26601
+ } else {
26602
+ const xPow = ce.box(["Power", variable, i]);
26603
+ if (coef.isSame(1)) {
26604
+ terms.push(xPow);
26605
+ } else if (coef.isSame(-1)) {
26606
+ terms.push(xPow.neg());
26607
+ } else {
26608
+ terms.push(coef.mul(xPow));
26609
+ }
26610
+ }
26611
+ }
26612
+ if (terms.length === 0) return ce.Zero;
26613
+ if (terms.length === 1) return terms[0];
26614
+ return add3(...terms);
26615
+ }
26616
+ function polynomialDivide(dividend, divisor, variable) {
26617
+ const ce = dividend.engine;
26618
+ const dividendCoeffs = getPolynomialCoefficients(dividend, variable);
26619
+ const divisorCoeffs = getPolynomialCoefficients(divisor, variable);
26620
+ if (!dividendCoeffs || !divisorCoeffs) return null;
26621
+ if (divisorCoeffs.every((c) => c.isSame(0))) return null;
26622
+ const actualDegree = (coeffs) => {
26623
+ for (let i = coeffs.length - 1; i >= 0; i--) {
26624
+ if (!coeffs[i].isSame(0)) return i;
26625
+ }
26626
+ return -1;
26627
+ };
26628
+ const dividendDeg = actualDegree(dividendCoeffs);
26629
+ const divisorDeg = actualDegree(divisorCoeffs);
26630
+ if (divisorDeg < 0) return null;
26631
+ if (dividendDeg < 0) {
26632
+ return [ce.Zero, ce.Zero];
26633
+ }
26634
+ if (dividendDeg < divisorDeg) {
26635
+ return [ce.Zero, dividend];
26636
+ }
26637
+ const remainder2 = dividendCoeffs.map((c) => c);
26638
+ const quotientCoeffs = new Array(
26639
+ dividendDeg - divisorDeg + 1
26640
+ ).fill(ce.Zero);
26641
+ const leadingDivisor = divisorCoeffs[divisorDeg];
26642
+ for (let i = dividendDeg; i >= divisorDeg; i--) {
26643
+ if (remainder2[i].isSame(0)) continue;
26644
+ const quotientCoef = remainder2[i].div(leadingDivisor);
26645
+ quotientCoeffs[i - divisorDeg] = quotientCoef;
26646
+ for (let j = 0; j <= divisorDeg; j++) {
26647
+ const product = quotientCoef.mul(divisorCoeffs[j]);
26648
+ remainder2[i - divisorDeg + j] = remainder2[i - divisorDeg + j].sub(product);
26649
+ }
26650
+ }
26651
+ const quotient = fromCoefficients(quotientCoeffs, variable);
26652
+ const remainderPoly = fromCoefficients(remainder2, variable);
26653
+ return [quotient, remainderPoly];
26654
+ }
26655
+ function polynomialGCD(a, b, variable) {
26656
+ const ce = a.engine;
26657
+ const degA = polynomialDegree(a, variable);
26658
+ const degB = polynomialDegree(b, variable);
26659
+ if (degA < 0 || degB < 0) return ce.One;
26660
+ const aCoeffs = getPolynomialCoefficients(a, variable);
26661
+ const bCoeffs = getPolynomialCoefficients(b, variable);
26662
+ if (!aCoeffs || aCoeffs.every((c) => c.isSame(0))) {
26663
+ return makeMonic(b, variable);
26664
+ }
26665
+ if (!bCoeffs || bCoeffs.every((c) => c.isSame(0))) {
26666
+ return makeMonic(a, variable);
26667
+ }
26668
+ let p = a;
26669
+ let q = b;
26670
+ while (true) {
26671
+ const qCoeffs = getPolynomialCoefficients(q, variable);
26672
+ if (!qCoeffs || qCoeffs.every((c) => c.isSame(0))) {
26673
+ break;
26674
+ }
26675
+ const divResult = polynomialDivide(p, q, variable);
26676
+ if (!divResult) {
26677
+ return ce.One;
26678
+ }
26679
+ const [, remainder2] = divResult;
26680
+ p = q;
26681
+ q = remainder2;
26682
+ }
26683
+ return makeMonic(p, variable);
26684
+ }
26685
+ function makeMonic(poly, variable) {
26686
+ const coeffs = getPolynomialCoefficients(poly, variable);
26687
+ if (!coeffs) return poly;
26688
+ let leadingCoef = null;
26689
+ for (let i = coeffs.length - 1; i >= 0; i--) {
26690
+ if (!coeffs[i].isSame(0)) {
26691
+ leadingCoef = coeffs[i];
26692
+ break;
26693
+ }
26694
+ }
26695
+ if (!leadingCoef || leadingCoef.isSame(1)) return poly;
26696
+ const monicCoeffs = coeffs.map((c) => c.div(leadingCoef));
26697
+ return fromCoefficients(monicCoeffs, variable);
26698
+ }
26699
+ function cancelCommonFactors(expr, variable) {
26700
+ if (!isFunction2(expr, "Divide")) return expr;
26701
+ const numerator = expr.op1;
26702
+ const denominator = expr.op2;
26703
+ const numDeg = polynomialDegree(numerator, variable);
26704
+ const denDeg = polynomialDegree(denominator, variable);
26705
+ if (numDeg < 0 || denDeg < 0) return expr;
26706
+ const gcd7 = polynomialGCD(numerator, denominator, variable);
26707
+ const gcdDeg = polynomialDegree(gcd7, variable);
26708
+ if (gcdDeg <= 0) return expr;
26709
+ const numDivResult = polynomialDivide(numerator, gcd7, variable);
26710
+ const denDivResult = polynomialDivide(denominator, gcd7, variable);
26711
+ if (!numDivResult || !denDivResult) return expr;
26712
+ const [newNumerator] = numDivResult;
26713
+ const [newDenominator] = denDivResult;
26714
+ const denCoeffs = getPolynomialCoefficients(newDenominator, variable);
26715
+ if (denCoeffs && denCoeffs.length === 1 && denCoeffs[0].isSame(1)) {
26716
+ return newNumerator;
26717
+ }
26718
+ return newNumerator.div(newDenominator);
26719
+ }
26720
+
26413
26721
  // src/compute-engine/boxed-expression/solve.ts
26414
26722
  function numericApproximation(value) {
26415
26723
  if (typeof value === "number") return value;
@@ -27233,6 +27541,13 @@ ${e.message}
27233
27541
  )
27234
27542
  );
27235
27543
  }
27544
+ if (result.length === 0) {
27545
+ const deg = polynomialDegree(originalExpr, x);
27546
+ if (deg >= 3) {
27547
+ const rationalRoots = findRationalRoots(originalExpr, x, ce);
27548
+ if (rationalRoots.length > 0) result = rationalRoots;
27549
+ }
27550
+ }
27236
27551
  } finally {
27237
27552
  ce.popScope();
27238
27553
  }
@@ -27371,267 +27686,49 @@ ${e.message}
27371
27686
  return true;
27372
27687
  });
27373
27688
  }
27374
-
27375
- // src/compute-engine/boxed-expression/polynomials.ts
27376
- function polynomialDegree(expr, variable) {
27377
- if (isNumber(expr)) return 0;
27378
- if (isSymbol2(expr)) {
27379
- if (expr.symbol === variable) return 1;
27380
- return 0;
27381
- }
27382
- if (!isFunction2(expr)) {
27383
- if (expr.has(variable)) return -1;
27384
- return 0;
27385
- }
27386
- const op = expr.operator;
27387
- if (op === "Negate") return polynomialDegree(expr.op1, variable);
27388
- if (op === "Add" || op === "Subtract") {
27389
- let maxDeg = 0;
27390
- for (const arg of expr.ops) {
27391
- const deg = polynomialDegree(arg, variable);
27392
- if (deg < 0) return -1;
27393
- maxDeg = Math.max(maxDeg, deg);
27394
- }
27395
- return maxDeg;
27396
- }
27397
- if (op === "Multiply") {
27398
- let totalDeg = 0;
27399
- for (const arg of expr.ops) {
27400
- const deg = polynomialDegree(arg, variable);
27401
- if (deg < 0) return -1;
27402
- totalDeg += deg;
27403
- }
27404
- return totalDeg;
27405
- }
27406
- if (op === "Power") {
27407
- const baseDeg = polynomialDegree(expr.op1, variable);
27408
- if (baseDeg < 0) return -1;
27409
- if (baseDeg === 0) {
27410
- if (expr.op2.has(variable)) return -1;
27411
- return 0;
27412
- }
27413
- const exp3 = asSmallInteger(expr.op2);
27414
- if (exp3 === null || exp3 < 0) return -1;
27415
- return baseDeg * exp3;
27416
- }
27417
- if (expr.has(variable)) return -1;
27418
- return 0;
27419
- }
27420
- function getPolynomialCoefficients(expr, variable) {
27421
- const ce = expr.engine;
27422
- const degree = polynomialDegree(expr, variable);
27423
- if (degree < 0) return null;
27424
- const coeffs = new Array(degree + 1).fill(ce.Zero);
27425
- const expanded = expand2(expr);
27426
- const addCoefficient = (coef, deg) => {
27427
- if (deg > degree) return false;
27428
- coeffs[deg] = coeffs[deg].add(coef);
27429
- return true;
27430
- };
27431
- const processTerm = (term) => {
27432
- const termDeg = polynomialDegree(term, variable);
27433
- if (termDeg < 0) return false;
27434
- if (termDeg === 0) {
27435
- return addCoefficient(term, 0);
27436
- }
27437
- if (isSymbol2(term, variable)) {
27438
- return addCoefficient(ce.One, 1);
27439
- }
27440
- if (isFunction2(term, "Negate")) {
27441
- const innerDeg = polynomialDegree(term.op1, variable);
27442
- if (innerDeg === 0) {
27443
- return addCoefficient(term, 0);
27444
- }
27445
- const innerCoeffs = getPolynomialCoefficients(term.op1, variable);
27446
- if (!innerCoeffs) return false;
27447
- for (let i = 0; i < innerCoeffs.length; i++) {
27448
- if (!innerCoeffs[i].isSame(0)) {
27449
- addCoefficient(innerCoeffs[i].neg(), i);
27450
- }
27451
- }
27452
- return true;
27453
- }
27454
- if (isFunction2(term, "Power")) {
27455
- if (isSymbol2(term.op1, variable)) {
27456
- const exp3 = asSmallInteger(term.op2);
27457
- if (exp3 !== null && exp3 >= 0) {
27458
- return addCoefficient(ce.One, exp3);
27459
- }
27460
- }
27461
- if (!term.op1.has(variable)) {
27462
- return addCoefficient(term, 0);
27463
- }
27464
- return false;
27465
- }
27466
- if (isFunction2(term, "Multiply")) {
27467
- const factors = term.ops;
27468
- let coef = ce.One;
27469
- let varDeg = 0;
27470
- for (const factor3 of factors) {
27471
- if (!factor3.has(variable)) {
27472
- coef = coef.mul(factor3);
27473
- } else if (isSymbol2(factor3, variable)) {
27474
- varDeg += 1;
27475
- } else if (isFunction2(factor3, "Power") && isSymbol2(factor3.op1, variable)) {
27476
- const exp3 = asSmallInteger(factor3.op2);
27477
- if (exp3 !== null && exp3 >= 0) {
27478
- varDeg += exp3;
27479
- } else {
27480
- return false;
27481
- }
27482
- } else {
27483
- return false;
27484
- }
27689
+ function findRationalRoots(expr, variable, ce) {
27690
+ const coeffs = getPolynomialCoefficients(expr, variable);
27691
+ if (!coeffs) return [];
27692
+ const degree = coeffs.length - 1;
27693
+ if (degree < 1) return [];
27694
+ const constantInt = asSmallInteger(coeffs[0]);
27695
+ const leadingInt = asSmallInteger(coeffs[degree]);
27696
+ if (leadingInt === null || constantInt === null) return [];
27697
+ if (leadingInt === 0 || constantInt === 0) return [];
27698
+ const divisors = (n) => {
27699
+ n = Math.abs(n);
27700
+ const result = [];
27701
+ for (let i = 1; i * i <= n; i++) {
27702
+ if (n % i === 0) {
27703
+ result.push(i);
27704
+ if (i !== n / i) result.push(n / i);
27485
27705
  }
27486
- return addCoefficient(coef, varDeg);
27487
27706
  }
27488
- return false;
27707
+ return result;
27489
27708
  };
27490
- if (isFunction2(expanded, "Add")) {
27491
- for (const term of expanded.ops) {
27492
- if (!processTerm(term)) return null;
27493
- }
27494
- } else {
27495
- if (!processTerm(expanded)) return null;
27496
- }
27497
- return coeffs;
27498
- }
27499
- function fromCoefficients(coeffs, variable) {
27500
- if (coeffs.length === 0) return coeffs[0]?.engine.Zero ?? null;
27501
- const ce = coeffs[0].engine;
27502
- const x = ce.symbol(variable);
27503
- const terms = [];
27504
- for (let i = 0; i < coeffs.length; i++) {
27505
- const coef = coeffs[i];
27506
- if (coef.isSame(0)) continue;
27507
- if (i === 0) {
27508
- terms.push(coef);
27509
- } else if (i === 1) {
27510
- if (coef.isSame(1)) {
27511
- terms.push(x);
27512
- } else if (coef.isSame(-1)) {
27513
- terms.push(x.neg());
27514
- } else {
27515
- terms.push(coef.mul(x));
27516
- }
27517
- } else {
27518
- const xPow = ce.box(["Power", variable, i]);
27519
- if (coef.isSame(1)) {
27520
- terms.push(xPow);
27521
- } else if (coef.isSame(-1)) {
27522
- terms.push(xPow.neg());
27523
- } else {
27524
- terms.push(coef.mul(xPow));
27709
+ const pDivisors = divisors(constantInt);
27710
+ const qDivisors = divisors(leadingInt);
27711
+ const candidates = [];
27712
+ const seen = /* @__PURE__ */ new Set();
27713
+ for (const p of pDivisors) {
27714
+ for (const q of qDivisors) {
27715
+ for (const sign3 of [1, -1]) {
27716
+ const val = sign3 * p / q;
27717
+ if (!seen.has(val)) {
27718
+ seen.add(val);
27719
+ candidates.push(val);
27720
+ }
27525
27721
  }
27526
27722
  }
27527
27723
  }
27528
- if (terms.length === 0) return ce.Zero;
27529
- if (terms.length === 1) return terms[0];
27530
- return add3(...terms);
27531
- }
27532
- function polynomialDivide(dividend, divisor, variable) {
27533
- const ce = dividend.engine;
27534
- const dividendCoeffs = getPolynomialCoefficients(dividend, variable);
27535
- const divisorCoeffs = getPolynomialCoefficients(divisor, variable);
27536
- if (!dividendCoeffs || !divisorCoeffs) return null;
27537
- if (divisorCoeffs.every((c) => c.isSame(0))) return null;
27538
- const actualDegree = (coeffs) => {
27539
- for (let i = coeffs.length - 1; i >= 0; i--) {
27540
- if (!coeffs[i].isSame(0)) return i;
27541
- }
27542
- return -1;
27543
- };
27544
- const dividendDeg = actualDegree(dividendCoeffs);
27545
- const divisorDeg = actualDegree(divisorCoeffs);
27546
- if (divisorDeg < 0) return null;
27547
- if (dividendDeg < 0) {
27548
- return [ce.Zero, ce.Zero];
27549
- }
27550
- if (dividendDeg < divisorDeg) {
27551
- return [ce.Zero, dividend];
27552
- }
27553
- const remainder2 = dividendCoeffs.map((c) => c);
27554
- const quotientCoeffs = new Array(
27555
- dividendDeg - divisorDeg + 1
27556
- ).fill(ce.Zero);
27557
- const leadingDivisor = divisorCoeffs[divisorDeg];
27558
- for (let i = dividendDeg; i >= divisorDeg; i--) {
27559
- if (remainder2[i].isSame(0)) continue;
27560
- const quotientCoef = remainder2[i].div(leadingDivisor);
27561
- quotientCoeffs[i - divisorDeg] = quotientCoef;
27562
- for (let j = 0; j <= divisorDeg; j++) {
27563
- const product = quotientCoef.mul(divisorCoeffs[j]);
27564
- remainder2[i - divisorDeg + j] = remainder2[i - divisorDeg + j].sub(product);
27565
- }
27566
- }
27567
- const quotient = fromCoefficients(quotientCoeffs, variable);
27568
- const remainderPoly = fromCoefficients(remainder2, variable);
27569
- return [quotient, remainderPoly];
27570
- }
27571
- function polynomialGCD(a, b, variable) {
27572
- const ce = a.engine;
27573
- const degA = polynomialDegree(a, variable);
27574
- const degB = polynomialDegree(b, variable);
27575
- if (degA < 0 || degB < 0) return ce.One;
27576
- const aCoeffs = getPolynomialCoefficients(a, variable);
27577
- const bCoeffs = getPolynomialCoefficients(b, variable);
27578
- if (!aCoeffs || aCoeffs.every((c) => c.isSame(0))) {
27579
- return makeMonic(b, variable);
27580
- }
27581
- if (!bCoeffs || bCoeffs.every((c) => c.isSame(0))) {
27582
- return makeMonic(a, variable);
27583
- }
27584
- let p = a;
27585
- let q = b;
27586
- while (true) {
27587
- const qCoeffs = getPolynomialCoefficients(q, variable);
27588
- if (!qCoeffs || qCoeffs.every((c) => c.isSame(0))) {
27589
- break;
27590
- }
27591
- const divResult = polynomialDivide(p, q, variable);
27592
- if (!divResult) {
27593
- return ce.One;
27594
- }
27595
- const [, remainder2] = divResult;
27596
- p = q;
27597
- q = remainder2;
27598
- }
27599
- return makeMonic(p, variable);
27600
- }
27601
- function makeMonic(poly, variable) {
27602
- const coeffs = getPolynomialCoefficients(poly, variable);
27603
- if (!coeffs) return poly;
27604
- let leadingCoef = null;
27605
- for (let i = coeffs.length - 1; i >= 0; i--) {
27606
- if (!coeffs[i].isSame(0)) {
27607
- leadingCoef = coeffs[i];
27608
- break;
27609
- }
27610
- }
27611
- if (!leadingCoef || leadingCoef.isSame(1)) return poly;
27612
- const monicCoeffs = coeffs.map((c) => c.div(leadingCoef));
27613
- return fromCoefficients(monicCoeffs, variable);
27614
- }
27615
- function cancelCommonFactors(expr, variable) {
27616
- if (!isFunction2(expr, "Divide")) return expr;
27617
- const numerator = expr.op1;
27618
- const denominator = expr.op2;
27619
- const numDeg = polynomialDegree(numerator, variable);
27620
- const denDeg = polynomialDegree(denominator, variable);
27621
- if (numDeg < 0 || denDeg < 0) return expr;
27622
- const gcd6 = polynomialGCD(numerator, denominator, variable);
27623
- const gcdDeg = polynomialDegree(gcd6, variable);
27624
- if (gcdDeg <= 0) return expr;
27625
- const numDivResult = polynomialDivide(numerator, gcd6, variable);
27626
- const denDivResult = polynomialDivide(denominator, gcd6, variable);
27627
- if (!numDivResult || !denDivResult) return expr;
27628
- const [newNumerator] = numDivResult;
27629
- const [newDenominator] = denDivResult;
27630
- const denCoeffs = getPolynomialCoefficients(newDenominator, variable);
27631
- if (denCoeffs && denCoeffs.length === 1 && denCoeffs[0].isSame(1)) {
27632
- return newNumerator;
27724
+ if (candidates.length > 100) return [];
27725
+ const roots = [];
27726
+ for (const candidate of candidates) {
27727
+ const root2 = ce.number(candidate);
27728
+ const value = expr.subs({ [variable]: root2 }).N();
27729
+ if (value.isSame(0)) roots.push(root2);
27633
27730
  }
27634
- return newNumerator.div(newDenominator);
27731
+ return roots;
27635
27732
  }
27636
27733
 
27637
27734
  // src/compute-engine/symbolic/antiderivative.ts
@@ -38275,7 +38372,107 @@ ${e.message}
38275
38372
  return ce.box(["Multiply", a.json, factor1.json, factor22.json]);
38276
38373
  }
38277
38374
  }
38375
+ function factorByRationalRoots(expr, variable) {
38376
+ const ce = expr.engine;
38377
+ const coeffs = getPolynomialCoefficients(expr, variable);
38378
+ if (!coeffs) return null;
38379
+ const degree = coeffs.length - 1;
38380
+ if (degree < 2) return null;
38381
+ const leadingInt = asSmallInteger(coeffs[degree]);
38382
+ const constantInt = asSmallInteger(coeffs[0]);
38383
+ if (leadingInt === null || constantInt === null) return null;
38384
+ if (leadingInt === 0 || constantInt === 0) return null;
38385
+ const divisors = (n) => {
38386
+ n = Math.abs(n);
38387
+ const result = [];
38388
+ for (let i = 1; i * i <= n; i++) {
38389
+ if (n % i === 0) {
38390
+ result.push(i);
38391
+ if (i !== n / i) result.push(n / i);
38392
+ }
38393
+ }
38394
+ return result;
38395
+ };
38396
+ const pDivisors = divisors(constantInt);
38397
+ const qDivisors = divisors(leadingInt);
38398
+ const candidates = [];
38399
+ const seen = /* @__PURE__ */ new Set();
38400
+ for (const p of pDivisors) {
38401
+ for (const q of qDivisors) {
38402
+ const pos = p / q;
38403
+ const neg2 = -p / q;
38404
+ if (!seen.has(pos)) {
38405
+ seen.add(pos);
38406
+ candidates.push([p, q]);
38407
+ }
38408
+ if (!seen.has(neg2)) {
38409
+ seen.add(neg2);
38410
+ candidates.push([-p, q]);
38411
+ }
38412
+ }
38413
+ }
38414
+ if (candidates.length > 100) return null;
38415
+ const x = ce.symbol(variable);
38416
+ const factors = [];
38417
+ let remaining = expr;
38418
+ for (const [p, q] of candidates) {
38419
+ const remDeg2 = polynomialDegree(remaining, variable);
38420
+ if (remDeg2 <= 0) break;
38421
+ const root2 = q === 1 ? ce.number(p) : ce.number(p).div(ce.number(q));
38422
+ const value = remaining.subs({ [variable]: root2 }).N();
38423
+ if (!value.isSame(0)) continue;
38424
+ const linearFactor = q === 1 ? x.sub(ce.number(p)) : ce.number(q).mul(x).sub(ce.number(p));
38425
+ const divResult = polynomialDivide(remaining, linearFactor, variable);
38426
+ if (!divResult) continue;
38427
+ factors.push(linearFactor);
38428
+ remaining = divResult[0];
38429
+ }
38430
+ if (factors.length === 0) return null;
38431
+ const remDeg = polynomialDegree(remaining, variable);
38432
+ if (remDeg === 2) {
38433
+ const quadFactored = factorQuadratic(remaining, variable);
38434
+ if (quadFactored !== null) remaining = quadFactored;
38435
+ }
38436
+ factors.push(remaining);
38437
+ if (factors.length === 1) return factors[0];
38438
+ return ce.box(["Multiply", ...factors.map((f) => f.json)]);
38439
+ }
38440
+ function extractContent(expr, variable) {
38441
+ const ce = expr.engine;
38442
+ const coeffs = getPolynomialCoefficients(expr, variable);
38443
+ if (!coeffs) return null;
38444
+ const intCoeffs = [];
38445
+ for (const c of coeffs) {
38446
+ const n = asSmallInteger(c);
38447
+ if (n === null) return null;
38448
+ intCoeffs.push(n);
38449
+ }
38450
+ const gcd7 = (a, b) => {
38451
+ a = Math.abs(a);
38452
+ b = Math.abs(b);
38453
+ while (b) {
38454
+ [a, b] = [b, a % b];
38455
+ }
38456
+ return a;
38457
+ };
38458
+ let content = 0;
38459
+ for (const c of intCoeffs) {
38460
+ if (c !== 0) content = gcd7(content, c);
38461
+ }
38462
+ if (content <= 1) return null;
38463
+ const primitiveCoeffs = coeffs.map((c) => {
38464
+ const n = asSmallInteger(c);
38465
+ return ce.number(n / content);
38466
+ });
38467
+ const primitive = fromCoefficients(primitiveCoeffs, variable);
38468
+ const factoredPrimitive = factorPolynomial(primitive, variable);
38469
+ return ce.number(content).mul(factoredPrimitive);
38470
+ }
38278
38471
  function factorPolynomial(expr, variable) {
38472
+ if (variable !== void 0) {
38473
+ const contentFactored = extractContent(expr, variable);
38474
+ if (contentFactored !== null) return contentFactored;
38475
+ }
38279
38476
  const perfectSquare = factorPerfectSquare(expr);
38280
38477
  if (perfectSquare !== null) return perfectSquare;
38281
38478
  const diffSquares = factorDifferenceOfSquares(expr);
@@ -38283,6 +38480,8 @@ ${e.message}
38283
38480
  if (variable !== void 0) {
38284
38481
  const quadratic = factorQuadratic(expr, variable);
38285
38482
  if (quadratic !== null) return quadratic;
38483
+ const rationalRoot = factorByRationalRoots(expr, variable);
38484
+ if (rationalRoot !== null) return rationalRoot;
38286
38485
  }
38287
38486
  return factor(expr);
38288
38487
  }
@@ -38328,6 +38527,257 @@ ${e.message}
38328
38527
  }
38329
38528
  return Product.from(together(expr)).asExpression();
38330
38529
  }
38530
+ function collectFactors(expr, variable) {
38531
+ const rawFactors = [];
38532
+ collectFactorsRaw(expr, variable, rawFactors);
38533
+ const merged = [];
38534
+ for (const f of rawFactors) {
38535
+ let found = false;
38536
+ for (const m of merged) {
38537
+ if (m.factor.isSame(f.factor)) {
38538
+ m.multiplicity += f.multiplicity;
38539
+ found = true;
38540
+ break;
38541
+ }
38542
+ }
38543
+ if (!found) merged.push({ ...f });
38544
+ }
38545
+ return merged;
38546
+ }
38547
+ function collectFactorsRaw(expr, variable, result) {
38548
+ if (isFunction2(expr, "Multiply")) {
38549
+ for (const op of expr.ops) {
38550
+ collectFactorsRaw(op, variable, result);
38551
+ }
38552
+ return;
38553
+ }
38554
+ if (isFunction2(expr, "Power")) {
38555
+ const base = expr.op1;
38556
+ const exp3 = asSmallInteger(expr.op2);
38557
+ if (exp3 !== null && exp3 > 0 && base.has(variable)) {
38558
+ const deg3 = polynomialDegree(base, variable);
38559
+ result.push({ factor: base, multiplicity: exp3, degree: deg3 });
38560
+ return;
38561
+ }
38562
+ if (!expr.has(variable)) return;
38563
+ const deg2 = polynomialDegree(expr, variable);
38564
+ result.push({ factor: expr, multiplicity: 1, degree: deg2 });
38565
+ return;
38566
+ }
38567
+ if (!expr.has(variable)) return;
38568
+ if (isNumber(expr)) return;
38569
+ const deg = polynomialDegree(expr, variable);
38570
+ result.push({ factor: expr, multiplicity: 1, degree: deg });
38571
+ }
38572
+ function solveLinearSystem(matrix, numVars) {
38573
+ const rows = matrix.length;
38574
+ const cols = numVars + 1;
38575
+ const m = matrix.map((row) => [...row]);
38576
+ const pivotRow = new Array(numVars).fill(-1);
38577
+ let currentRow = 0;
38578
+ for (let col = 0; col < numVars && currentRow < rows; col++) {
38579
+ let maxVal = 0;
38580
+ let maxRow = -1;
38581
+ for (let row = currentRow; row < rows; row++) {
38582
+ const absVal = Math.abs(m[row][col]);
38583
+ if (absVal > maxVal) {
38584
+ maxVal = absVal;
38585
+ maxRow = row;
38586
+ }
38587
+ }
38588
+ if (maxVal === 0) continue;
38589
+ if (maxRow !== currentRow) {
38590
+ [m[currentRow], m[maxRow]] = [m[maxRow], m[currentRow]];
38591
+ }
38592
+ pivotRow[col] = currentRow;
38593
+ for (let row = 0; row < rows; row++) {
38594
+ if (row === currentRow) continue;
38595
+ if (m[row][col] === 0) continue;
38596
+ const factor3 = m[row][col];
38597
+ const pivotVal = m[currentRow][col];
38598
+ for (let j = 0; j < cols; j++) {
38599
+ m[row][j] = m[row][j] * pivotVal - factor3 * m[currentRow][j];
38600
+ }
38601
+ }
38602
+ currentRow++;
38603
+ }
38604
+ const solution = new Array(numVars);
38605
+ for (let col = 0; col < numVars; col++) {
38606
+ const pr = pivotRow[col];
38607
+ if (pr === -1) {
38608
+ solution[col] = [0, 1];
38609
+ continue;
38610
+ }
38611
+ const num = m[pr][cols - 1];
38612
+ const den = m[pr][col];
38613
+ if (den === 0) return null;
38614
+ const g = gcd4(Math.abs(num), Math.abs(den));
38615
+ const sign3 = den < 0 ? -1 : 1;
38616
+ solution[col] = [sign3 * num / g, sign3 * den / g];
38617
+ }
38618
+ return solution;
38619
+ }
38620
+ function gcd4(a, b) {
38621
+ a = Math.abs(a);
38622
+ b = Math.abs(b);
38623
+ while (b) {
38624
+ [a, b] = [b, a % b];
38625
+ }
38626
+ return a || 1;
38627
+ }
38628
+ function partialFraction(expr, variable) {
38629
+ const ce = expr.engine;
38630
+ if (!isFunction2(expr, "Divide")) return expr;
38631
+ const numer = expr.op1;
38632
+ const denom = expr.op2;
38633
+ const numerDeg = polynomialDegree(numer, variable);
38634
+ const denomDeg = polynomialDegree(denom, variable);
38635
+ if (numerDeg < 0 || denomDeg < 0) return expr;
38636
+ if (denomDeg === 0) return expr;
38637
+ let quotient = null;
38638
+ let remainder2;
38639
+ if (numerDeg >= denomDeg) {
38640
+ const divResult = polynomialDivide(numer, denom, variable);
38641
+ if (!divResult) return expr;
38642
+ quotient = divResult[0];
38643
+ remainder2 = divResult[1];
38644
+ const remCoeffs2 = getPolynomialCoefficients(remainder2, variable);
38645
+ if (remCoeffs2 && remCoeffs2.every((c) => c.isSame(0))) {
38646
+ return quotient;
38647
+ }
38648
+ } else {
38649
+ remainder2 = numer;
38650
+ }
38651
+ const factoredDenom = factorPolynomial(denom, variable);
38652
+ const factors = collectFactors(factoredDenom, variable);
38653
+ if (factors.length === 0) return expr;
38654
+ if (factors.length === 1 && factors[0].multiplicity === 1) {
38655
+ if (quotient) return quotient.add(remainder2.div(denom));
38656
+ return expr;
38657
+ }
38658
+ for (const f of factors) {
38659
+ if (f.degree > 2 || f.degree < 0) return expr;
38660
+ }
38661
+ let totalFactorDeg = 0;
38662
+ for (const f of factors) {
38663
+ totalFactorDeg += f.degree * f.multiplicity;
38664
+ }
38665
+ if (totalFactorDeg !== denomDeg) return expr;
38666
+ const templateTerms = [];
38667
+ let unknownCount = 0;
38668
+ for (const f of factors) {
38669
+ for (let k = 1; k <= f.multiplicity; k++) {
38670
+ if (f.degree === 1) {
38671
+ templateTerms.push({
38672
+ isLinear: true,
38673
+ factor: f.factor,
38674
+ power: k,
38675
+ unknownIndex: unknownCount
38676
+ });
38677
+ unknownCount++;
38678
+ } else {
38679
+ templateTerms.push({
38680
+ isLinear: false,
38681
+ factor: f.factor,
38682
+ power: k,
38683
+ unknownIndex: unknownCount
38684
+ });
38685
+ unknownCount += 2;
38686
+ }
38687
+ }
38688
+ }
38689
+ if (unknownCount !== denomDeg) return expr;
38690
+ const expandedDenom = expand2(denom);
38691
+ const denomCoeffs = getPolynomialCoefficients(expandedDenom, variable);
38692
+ if (!denomCoeffs) return expr;
38693
+ const expandedRemainder = expand2(remainder2);
38694
+ const remCoeffs = getPolynomialCoefficients(expandedRemainder, variable);
38695
+ if (!remCoeffs) return expr;
38696
+ const systemRows = denomDeg;
38697
+ const augMatrix = [];
38698
+ for (let i = 0; i < systemRows; i++) {
38699
+ augMatrix.push(new Array(unknownCount + 1).fill(0));
38700
+ }
38701
+ for (let i = 0; i < systemRows; i++) {
38702
+ const coeff = i < remCoeffs.length ? asSmallInteger(remCoeffs[i]) : 0;
38703
+ if (coeff === null) return expr;
38704
+ augMatrix[i][unknownCount] = coeff;
38705
+ }
38706
+ for (const t of templateTerms) {
38707
+ let termDenom;
38708
+ if (t.power === 1) {
38709
+ termDenom = t.factor;
38710
+ } else {
38711
+ termDenom = ce.box(["Power", t.factor.json, t.power]);
38712
+ }
38713
+ const cofactorResult = polynomialDivide(expandedDenom, termDenom, variable);
38714
+ if (!cofactorResult) return expr;
38715
+ const cofactor = cofactorResult[0];
38716
+ const cofRem = cofactorResult[1];
38717
+ const cofRemCoeffs = getPolynomialCoefficients(cofRem, variable);
38718
+ if (!cofRemCoeffs || !cofRemCoeffs.every((c) => c.isSame(0))) return expr;
38719
+ const expandedCofactor = expand2(cofactor);
38720
+ const cofCoeffs = getPolynomialCoefficients(expandedCofactor, variable);
38721
+ if (!cofCoeffs) return expr;
38722
+ const intCofCoeffs = [];
38723
+ for (let i = 0; i < systemRows; i++) {
38724
+ const c = i < cofCoeffs.length ? asSmallInteger(cofCoeffs[i]) : 0;
38725
+ if (c === null) return expr;
38726
+ intCofCoeffs.push(c);
38727
+ }
38728
+ if (t.isLinear) {
38729
+ for (let i = 0; i < systemRows; i++) {
38730
+ augMatrix[i][t.unknownIndex] += intCofCoeffs[i];
38731
+ }
38732
+ } else {
38733
+ const aIdx = t.unknownIndex;
38734
+ const bIdx = t.unknownIndex + 1;
38735
+ for (let i = 0; i < systemRows; i++) {
38736
+ augMatrix[i][bIdx] += intCofCoeffs[i];
38737
+ if (i > 0) {
38738
+ augMatrix[i][aIdx] += intCofCoeffs[i - 1];
38739
+ }
38740
+ }
38741
+ }
38742
+ }
38743
+ const solution = solveLinearSystem(augMatrix, unknownCount);
38744
+ if (!solution) return expr;
38745
+ const x = ce.symbol(variable);
38746
+ const partialTerms = [];
38747
+ if (quotient) partialTerms.push(quotient);
38748
+ for (const t of templateTerms) {
38749
+ let termDenom;
38750
+ if (t.power === 1) {
38751
+ termDenom = t.factor;
38752
+ } else {
38753
+ termDenom = ce.box(["Power", t.factor.json, t.power]);
38754
+ }
38755
+ let termNumer;
38756
+ if (t.isLinear) {
38757
+ const [num, den] = solution[t.unknownIndex];
38758
+ if (num === 0) continue;
38759
+ termNumer = den === 1 ? ce.number(num) : ce.number(num).div(ce.number(den));
38760
+ } else {
38761
+ const [aNum, aDen] = solution[t.unknownIndex];
38762
+ const [bNum, bDen] = solution[t.unknownIndex + 1];
38763
+ if (aNum === 0 && bNum === 0) continue;
38764
+ const terms = [];
38765
+ if (aNum !== 0) {
38766
+ const aCoeff = aDen === 1 ? ce.number(aNum) : ce.number(aNum).div(ce.number(aDen));
38767
+ terms.push(aCoeff.mul(x));
38768
+ }
38769
+ if (bNum !== 0) {
38770
+ const bCoeff = bDen === 1 ? ce.number(bNum) : ce.number(bNum).div(ce.number(bDen));
38771
+ terms.push(bCoeff);
38772
+ }
38773
+ termNumer = terms.length === 1 ? terms[0] : add3(...terms);
38774
+ }
38775
+ partialTerms.push(termNumer.div(termDenom));
38776
+ }
38777
+ if (partialTerms.length === 0) return ce.Zero;
38778
+ if (partialTerms.length === 1) return partialTerms[0];
38779
+ return add3(...partialTerms);
38780
+ }
38331
38781
 
38332
38782
  // src/compute-engine/symbolic/distribute.ts
38333
38783
  function distribute2(lhs, rhs, g, f) {
@@ -38402,7 +38852,7 @@ ${e.message}
38402
38852
  }
38403
38853
  },
38404
38854
  CoefficientList: {
38405
- 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]",
38855
+ 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]",
38406
38856
  lazy: true,
38407
38857
  signature: "(value, symbol) -> list<value>",
38408
38858
  evaluate: ([poly, varExpr]) => {
@@ -38411,7 +38861,7 @@ ${e.message}
38411
38861
  if (!variable) return void 0;
38412
38862
  const coeffs = getPolynomialCoefficients(poly.canonical, variable);
38413
38863
  if (!coeffs) return void 0;
38414
- return poly.engine.box(["List", ...coeffs]);
38864
+ return poly.engine.box(["List", ...coeffs.reverse()]);
38415
38865
  }
38416
38866
  },
38417
38867
  PolynomialQuotient: {
@@ -38467,6 +38917,85 @@ ${e.message}
38467
38917
  if (!variable) return void 0;
38468
38918
  return cancelCommonFactors(expr.canonical, variable);
38469
38919
  }
38920
+ },
38921
+ PartialFraction: {
38922
+ description: "Decompose a rational expression into partial fractions. Example: PartialFraction(1/((x+1)(x+2)), x) \u2192 1/(x+1) - 1/(x+2)",
38923
+ lazy: true,
38924
+ signature: "(value, symbol) -> value",
38925
+ evaluate: ([expr, varExpr]) => {
38926
+ if (!expr || !varExpr) return void 0;
38927
+ const variable = sym(varExpr.canonical);
38928
+ if (!variable) return void 0;
38929
+ return partialFraction(expr.canonical, variable);
38930
+ }
38931
+ },
38932
+ Apart: {
38933
+ description: "Alias for PartialFraction. Decompose a rational expression into partial fractions.",
38934
+ lazy: true,
38935
+ signature: "(value, symbol) -> value",
38936
+ evaluate: ([expr, varExpr]) => {
38937
+ if (!expr || !varExpr) return void 0;
38938
+ const variable = sym(varExpr.canonical);
38939
+ if (!variable) return void 0;
38940
+ return partialFraction(expr.canonical, variable);
38941
+ }
38942
+ },
38943
+ PolynomialRoots: {
38944
+ description: "Return the roots of a polynomial expression. Example: PolynomialRoots(x\xB2 - 5x + 6, x) \u2192 {2, 3}",
38945
+ lazy: true,
38946
+ signature: "(value, symbol) -> set<value>",
38947
+ evaluate: ([poly, varExpr]) => {
38948
+ if (!poly || !varExpr) return void 0;
38949
+ const variable = sym(varExpr.canonical);
38950
+ if (!variable) return void 0;
38951
+ const roots = poly.canonical.polynomialRoots(variable);
38952
+ if (!roots || roots.length === 0) return void 0;
38953
+ return poly.engine.box(["Set", ...roots.map((r) => r.json)]);
38954
+ }
38955
+ },
38956
+ Discriminant: {
38957
+ description: "Return the discriminant of a polynomial. Example: Discriminant(x\xB2 - 5x + 6, x) \u2192 1",
38958
+ lazy: true,
38959
+ signature: "(value, symbol) -> value",
38960
+ evaluate: ([poly, varExpr]) => {
38961
+ if (!poly || !varExpr) return void 0;
38962
+ const variable = sym(varExpr.canonical);
38963
+ if (!variable) return void 0;
38964
+ const coeffsAsc = getPolynomialCoefficients(poly.canonical, variable);
38965
+ if (!coeffsAsc) return void 0;
38966
+ const coeffs = [...coeffsAsc].reverse();
38967
+ const degree = coeffs.length - 1;
38968
+ const ce = poly.engine;
38969
+ if (degree === 2) {
38970
+ const [a, b, c] = coeffs;
38971
+ return b.mul(b).sub(ce.number(4).mul(a).mul(c));
38972
+ }
38973
+ if (degree === 3) {
38974
+ const [a, b, c, d] = coeffs;
38975
+ 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));
38976
+ }
38977
+ if (degree === 4) {
38978
+ const [a, b, c, d, e] = coeffs;
38979
+ 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));
38980
+ }
38981
+ return void 0;
38982
+ }
38983
+ },
38984
+ Polynomial: {
38985
+ 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",
38986
+ lazy: true,
38987
+ signature: "(list<value>, symbol) -> value",
38988
+ evaluate: ([coeffList, varExpr]) => {
38989
+ if (!coeffList || !varExpr) return void 0;
38990
+ const variable = sym(varExpr.canonical);
38991
+ if (!variable) return void 0;
38992
+ const canonical2 = coeffList.canonical;
38993
+ if (!isFunction2(canonical2, "List")) return void 0;
38994
+ const coeffs = canonical2.ops;
38995
+ if (coeffs.length === 0) return void 0;
38996
+ const ascending = [...coeffs].reverse();
38997
+ return fromCoefficients(ascending, variable);
38998
+ }
38470
38999
  }
38471
39000
  }
38472
39001
  ];
@@ -46465,7 +46994,7 @@ Error in definition of "${name}"`,
46465
46994
  };
46466
46995
  return checkTerm(expr);
46467
46996
  }
46468
- function solveLinearSystem(equations, variables) {
46997
+ function solveLinearSystem2(equations, variables) {
46469
46998
  if (equations.length === 0 || variables.length === 0) return null;
46470
46999
  const ce = equations[0].engine;
46471
47000
  const n = variables.length;
@@ -47450,6 +47979,15 @@ Error in definition of "${name}"`,
47450
47979
  } else if (operator2 === expr.operator) {
47451
47980
  const matchPerms = options.matchPermutations ?? true;
47452
47981
  result = pattern.operatorDefinition.commutative && matchPerms ? matchPermutation(expr, pattern, substitution, options) : matchArguments(expr, pattern.ops, substitution, options);
47982
+ if (result === null && options.matchMissingTerms && isFunction2(expr) && isFunction2(pattern) && expr.nops < pattern.nops) {
47983
+ result = matchWithMissingTerms(
47984
+ expr,
47985
+ pattern,
47986
+ substitution,
47987
+ options,
47988
+ ce
47989
+ );
47990
+ }
47453
47991
  }
47454
47992
  if (result === null && useVariations) {
47455
47993
  if (!acceptVariants) return null;
@@ -47747,8 +48285,8 @@ Error in definition of "${name}"`,
47747
48285
  const minCapture = 1;
47748
48286
  const maxCapture2 = remaining.length - countMinNeeded(restWildcards);
47749
48287
  for (let count = maxCapture2; count >= minCapture; count--) {
47750
- const combinations = getCombinations(remaining.length, count);
47751
- for (const indices of combinations) {
48288
+ const combinations2 = getCombinations(remaining.length, count);
48289
+ for (const indices of combinations2) {
47752
48290
  const captured = indices.map((i) => remaining[i]);
47753
48291
  const capturedExpr = wrapCaptured(captured);
47754
48292
  const newSub = captureWildcard(wcName, capturedExpr, sub3);
@@ -47777,8 +48315,8 @@ Error in definition of "${name}"`,
47777
48315
  if (result !== null) return result;
47778
48316
  }
47779
48317
  } else {
47780
- const combinations = getCombinations(remaining.length, count);
47781
- for (const indices of combinations) {
48318
+ const combinations2 = getCombinations(remaining.length, count);
48319
+ for (const indices of combinations2) {
47782
48320
  const captured = indices.map((i) => remaining[i]);
47783
48321
  const capturedExpr = wrapCaptured(captured);
47784
48322
  const newSub = captureWildcard(wcName, capturedExpr, sub3);
@@ -47952,17 +48490,140 @@ Error in definition of "${name}"`,
47952
48490
  }
47953
48491
  }
47954
48492
  }
48493
+ function matchWithMissingTerms(expr, pattern, substitution, options, ce) {
48494
+ if (!isFunction2(expr) || !isFunction2(pattern)) return null;
48495
+ const operator2 = expr.operator;
48496
+ const identity = operator2 === "Add" ? ce.Zero : operator2 === "Multiply" ? ce.One : null;
48497
+ if (!identity) return null;
48498
+ const patOps = pattern.ops;
48499
+ const missing = patOps.length - expr.nops;
48500
+ if (missing <= 0) return null;
48501
+ const combos = combinations(patOps.length, missing);
48502
+ combos.sort((a, b) => {
48503
+ const scoreA = a.reduce((s, i) => s + patternComplexity(patOps[i]), 0);
48504
+ const scoreB = b.reduce((s, i) => s + patternComplexity(patOps[i]), 0);
48505
+ return scoreA - scoreB;
48506
+ });
48507
+ for (const identityIndices of combos) {
48508
+ const activePatOps = patOps.filter((_, i) => !identityIndices.includes(i));
48509
+ const identityPatOps = identityIndices.map((i) => patOps[i]);
48510
+ const subPattern = ce.function(operator2, activePatOps, { form: "raw" });
48511
+ let sub3 = matchPermutation(expr, subPattern, substitution, options);
48512
+ if (sub3 === null) continue;
48513
+ let failed = false;
48514
+ for (const patOp of identityPatOps) {
48515
+ const result = matchIdentityTerm(patOp, identity, sub3, options, ce);
48516
+ if (result === null) {
48517
+ failed = true;
48518
+ break;
48519
+ }
48520
+ sub3 = result;
48521
+ }
48522
+ if (!failed) return sub3;
48523
+ }
48524
+ return null;
48525
+ }
48526
+ function matchIdentityTerm(patOp, identity, sub3, options, ce) {
48527
+ const result = matchOnce(identity, patOp, sub3, options);
48528
+ if (result !== null) return result;
48529
+ if (identity.isSame(0) && isFunction2(patOp, "Multiply")) {
48530
+ for (const op of patOp.ops) {
48531
+ const wn = wildcardName(op);
48532
+ if (wn && !(wn in sub3)) {
48533
+ return captureWildcard(wn, identity, sub3);
48534
+ }
48535
+ }
48536
+ }
48537
+ if (identity.isSame(1) && isFunction2(patOp, "Power")) {
48538
+ const expOp = patOp.ops[1];
48539
+ if (expOp) {
48540
+ const wn = wildcardName(expOp);
48541
+ if (wn && !(wn in sub3)) {
48542
+ return captureWildcard(wn, ce.Zero, sub3);
48543
+ }
48544
+ }
48545
+ }
48546
+ return null;
48547
+ }
48548
+ function patternComplexity(expr) {
48549
+ if (isWildcard(expr)) return 0;
48550
+ if (isNumber(expr) || isSymbol2(expr) || isString(expr)) return 1;
48551
+ if (isFunction2(expr))
48552
+ return 1 + expr.ops.reduce((s, op) => s + patternComplexity(op), 0);
48553
+ return 1;
48554
+ }
48555
+ function combinations(n, k) {
48556
+ const result = [];
48557
+ const combo = [];
48558
+ function backtrack(start) {
48559
+ if (combo.length === k) {
48560
+ result.push([...combo]);
48561
+ return;
48562
+ }
48563
+ for (let i = start; i < n; i++) {
48564
+ combo.push(i);
48565
+ backtrack(i + 1);
48566
+ combo.pop();
48567
+ }
48568
+ }
48569
+ backtrack(0);
48570
+ return result;
48571
+ }
47955
48572
  function match(subject, pattern, options) {
47956
- pattern = pattern.structural;
47957
- const useVariations = options?.useVariations ?? false;
48573
+ const ce = subject.engine;
48574
+ let autoWildcard = false;
48575
+ let boxedPattern;
48576
+ if (typeof pattern === "string") {
48577
+ autoWildcard = true;
48578
+ boxedPattern = ce.parse(pattern).map(
48579
+ (x) => isSymbol2(x) && x.symbol.length === 1 ? ce.symbol("_" + x.symbol) : x,
48580
+ { canonical: false }
48581
+ );
48582
+ } else if ("engine" in pattern) {
48583
+ boxedPattern = pattern;
48584
+ } else {
48585
+ boxedPattern = ce.box(pattern);
48586
+ }
48587
+ boxedPattern = boxedPattern.structural;
48588
+ const useVariations = options?.useVariations ?? autoWildcard;
47958
48589
  const opts = {
47959
48590
  recursive: options?.recursive ?? false,
47960
48591
  useVariations,
47961
48592
  acceptVariants: useVariations,
47962
- matchPermutations: options?.matchPermutations ?? true
48593
+ matchPermutations: options?.matchPermutations ?? true,
48594
+ matchMissingTerms: options?.matchMissingTerms ?? autoWildcard
47963
48595
  };
47964
- const substitution = options?.substitution ?? {};
47965
- return matchOnce(subject.structural, pattern.structural, substitution, opts);
48596
+ let substitution = options?.substitution ?? {};
48597
+ if (autoWildcard && Object.keys(substitution).length > 0) {
48598
+ const prefixed = {};
48599
+ for (const [k, v] of Object.entries(substitution)) {
48600
+ if (k.startsWith("_")) {
48601
+ prefixed[k] = v;
48602
+ } else {
48603
+ if (!(`_${k}` in substitution)) prefixed[`_${k}`] = v;
48604
+ prefixed[k] = v;
48605
+ }
48606
+ }
48607
+ substitution = prefixed;
48608
+ }
48609
+ const result = matchOnce(
48610
+ subject.structural,
48611
+ boxedPattern.structural,
48612
+ substitution,
48613
+ opts
48614
+ );
48615
+ if (!result) return null;
48616
+ if (autoWildcard) {
48617
+ const clean = {};
48618
+ for (const [k, v] of Object.entries(result)) {
48619
+ if (!k.startsWith("_")) continue;
48620
+ const name = k.slice(1);
48621
+ if (isSymbol2(v) && v.symbol === name) continue;
48622
+ clean[name] = v;
48623
+ }
48624
+ return clean;
48625
+ }
48626
+ return result;
47966
48627
  }
47967
48628
 
47968
48629
  // src/compute-engine/boxed-expression/sgn.ts
@@ -48818,7 +49479,7 @@ Error in definition of "${name}"`,
48818
49479
  };
48819
49480
  function solveSystem(ce, equations, varNames) {
48820
49481
  if (equations && equations.every((eq2) => eq2.operator === "Equal")) {
48821
- const linearResult = solveLinearSystem([...equations], varNames);
49482
+ const linearResult = solveLinearSystem2([...equations], varNames);
48822
49483
  if (linearResult && filterSolutionByTypes(ce, varNames, linearResult))
48823
49484
  return linearResult;
48824
49485
  const polyResult = solvePolynomialSystem([...equations], varNames);
@@ -48848,7 +49509,7 @@ Error in definition of "${name}"`,
48848
49509
  (eq2) => inequalityOps.includes(eq2.operator ?? "")
48849
49510
  );
48850
49511
  if (equalities.length > 0 && inequalities.length > 0 && equalities.length + inequalities.length === equations.length) {
48851
- const linearResult = solveLinearSystem([...equalities], varNames);
49512
+ const linearResult = solveLinearSystem2([...equalities], varNames);
48852
49513
  if (linearResult) {
48853
49514
  if (satisfiesInequalities(linearResult, inequalities))
48854
49515
  return filterSolutionByTypes(ce, varNames, linearResult) ? linearResult : null;
@@ -50489,11 +51150,7 @@ Error in definition of "${name}"`,
50489
51150
  if (h === "Function") {
50490
51151
  const fnFn = target.functions?.(h);
50491
51152
  if (typeof fnFn === "function")
50492
- return fnFn(
50493
- args,
50494
- (expr) => _BaseCompiler.compile(expr, target),
50495
- target
50496
- );
51153
+ return fnFn(args, (expr) => _BaseCompiler.compile(expr, target), target);
50497
51154
  const params = args.slice(1).map((x) => isSymbol2(x) ? x.symbol : "_");
50498
51155
  return `((${params.join(", ")}) => ${_BaseCompiler.compile(
50499
51156
  args[0].canonical,
@@ -50622,7 +51279,10 @@ Error in definition of "${name}"`,
50622
51279
  };
50623
51280
  const result = args.filter((a) => !isSymbol2(a, "Nothing")).map((arg) => {
50624
51281
  if (isFunction2(arg, "Declare") && isSymbol2(arg.ops[0]) && target.declare) {
50625
- return target.declare(arg.ops[0].symbol, typeHints[arg.ops[0].symbol]);
51282
+ return target.declare(
51283
+ arg.ops[0].symbol,
51284
+ typeHints[arg.ops[0].symbol]
51285
+ );
50626
51286
  }
50627
51287
  return _BaseCompiler.compile(arg, localTarget);
50628
51288
  }).filter((s) => s !== "");
@@ -51113,6 +51773,9 @@ Error in definition of "${name}"`,
51113
51773
  _setSerializeJson(serializeJson);
51114
51774
  _setProduct(Product);
51115
51775
  _setCompile(compile);
51776
+ _setGetPolynomialCoefficients(getPolynomialCoefficients);
51777
+ _setGetPolynomialDegree(polynomialDegree);
51778
+ _setFindUnivariateRoots(findUnivariateRoots);
51116
51779
 
51117
51780
  // src/compute-engine/symbolic/simplify-logic.ts
51118
51781
  function simplifyLogicFunction(x) {
@@ -54051,6 +54714,27 @@ Error in definition of "${name}"`,
54051
54714
  if (result.isSame(x)) return void 0;
54052
54715
  return { value: result, because: "cancel common polynomial factors" };
54053
54716
  },
54717
+ //
54718
+ // Auto partial fraction decomposition for Divide with factored denominator
54719
+ // e.g., 1/((x+1)(x+2)) → 1/(x+1) - 1/(x+2)
54720
+ // Only triggers when denominator is already in factored form (Multiply or Power)
54721
+ //
54722
+ // IMPORTANT: partialFraction must not call .simplify() on its result
54723
+ //
54724
+ (x) => {
54725
+ if (!isFunction2(x, "Divide")) return void 0;
54726
+ const denom = x.op2;
54727
+ const denomOp = denom.operator;
54728
+ if (denomOp !== "Multiply" && denomOp !== "Power") return void 0;
54729
+ const unknowns = x.unknowns;
54730
+ if (unknowns.length !== 1) return void 0;
54731
+ const variable = unknowns[0];
54732
+ const result = partialFraction(x, variable);
54733
+ if (result.isSame(x)) return void 0;
54734
+ const ce = x.engine;
54735
+ if (ce.costFunction(result) >= ce.costFunction(x)) return void 0;
54736
+ return { value: result, because: "partial fraction decomposition" };
54737
+ },
54054
54738
  // Quick a/a -> 1 check for identical numerator/denominator
54055
54739
  // Must run before expand to avoid decomposing the fraction first
54056
54740
  (x) => {
@@ -57815,7 +58499,8 @@ Error in definition of "${name}"`,
57815
58499
  return `_gpu_fresnelS(${compile3(x)})`;
57816
58500
  },
57817
58501
  BesselJ: ([n, x], compile3, target) => {
57818
- if (n === null || x === null) throw new Error("BesselJ: need two arguments");
58502
+ if (n === null || x === null)
58503
+ throw new Error("BesselJ: need two arguments");
57819
58504
  const intCast = target?.language === "wgsl" ? "i32" : "int";
57820
58505
  return `_gpu_besselJ(${intCast}(${compile3(n)}), ${compile3(x)})`;
57821
58506
  },
@@ -57917,8 +58602,7 @@ Error in definition of "${name}"`,
57917
58602
  throw new Error("Loop: expected Element(index, Range(lo, hi))");
57918
58603
  const indexExpr = indexing.ops[0];
57919
58604
  const rangeExpr = indexing.ops[1];
57920
- if (!isSymbol2(indexExpr))
57921
- throw new Error("Loop: index must be a symbol");
58605
+ if (!isSymbol2(indexExpr)) throw new Error("Loop: index must be a symbol");
57922
58606
  if (!isFunction2(rangeExpr, "Range"))
57923
58607
  throw new Error("Loop: expected Range(lo, hi)");
57924
58608
  const index = indexExpr.symbol;
@@ -59170,7 +59854,9 @@ ${indented};
59170
59854
  const params = parameters.map(([name, type2]) => `${name}: ${toWGSLType(type2)}`).join(", ");
59171
59855
  if (body.includes("\n")) {
59172
59856
  const indented = body.split("\n").map((l) => ` ${l}`).join("\n");
59173
- return `fn ${functionName}(${params}) -> ${toWGSLType(returnType)} {
59857
+ return `fn ${functionName}(${params}) -> ${toWGSLType(
59858
+ returnType
59859
+ )} {
59174
59860
  ${indented};
59175
59861
  }`;
59176
59862
  }
@@ -59818,7 +60504,7 @@ ${workgroupAttr}fn main(${paramStr})${returnStr} {
59818
60504
  ];
59819
60505
  return ok({ lo: Math.min(...vals), hi: Math.max(...vals) });
59820
60506
  }
59821
- function gcd4(a, b) {
60507
+ function gcd5(a, b) {
59822
60508
  const uA = unwrapOrPropagate(a);
59823
60509
  if (!Array.isArray(uA)) return uA;
59824
60510
  const uB = unwrapOrPropagate(b);
@@ -60470,7 +61156,7 @@ ${workgroupAttr}fn main(${paramStr})${returnStr} {
60470
61156
  factorial: factorial5,
60471
61157
  factorial2: factorial24,
60472
61158
  binomial: binomial2,
60473
- gcd: gcd4,
61159
+ gcd: gcd5,
60474
61160
  lcm: lcm4,
60475
61161
  chop: chop4,
60476
61162
  erf: erf2,
@@ -64249,6 +64935,11 @@ ${workgroupAttr}fn main(${paramStr})${returnStr} {
64249
64935
  if (this.atEnd) return lhs;
64250
64936
  console.assert(lhs !== null);
64251
64937
  const index = this.index;
64938
+ if (this.options.strict === false && typeof lhs === "string" && lhs.length === 1 && /^[a-zA-Z]$/.test(lhs) && /^[2-9]$/.test(this.peek)) {
64939
+ const digit = parseInt(this.peek);
64940
+ this.index++;
64941
+ return this.parseSupsub(["Power", lhs, digit]);
64942
+ }
64252
64943
  this.skipSpace();
64253
64944
  const superscripts = [];
64254
64945
  const subscripts = [];
@@ -66353,9 +67044,9 @@ ${code}`;
66353
67044
  return ce._fn("Tan", [tanCArg]).neg();
66354
67045
  }
66355
67046
  function lcm5(a, b) {
66356
- return Math.abs(a * b) / gcd5(a, b);
67047
+ return Math.abs(a * b) / gcd6(a, b);
66357
67048
  }
66358
- function gcd5(a, b) {
67049
+ function gcd6(a, b) {
66359
67050
  a = Math.abs(a);
66360
67051
  b = Math.abs(b);
66361
67052
  while (b) {
@@ -68041,10 +68732,10 @@ ${code}`;
68041
68732
  _setComputeEngineClass(ComputeEngine);
68042
68733
 
68043
68734
  // src/compute-engine.ts
68044
- var version = "0.53.1";
68735
+ var version = "0.54.0";
68045
68736
  globalThis[/* @__PURE__ */ Symbol.for("io.cortexjs.compute-engine")] = {
68046
68737
  ComputeEngine: ComputeEngine.prototype.constructor,
68047
- version: "0.53.1"
68738
+ version: "0.54.0"
68048
68739
  };
68049
68740
  return __toCommonJS(compute_engine_exports);
68050
68741
  })();