@cortex-js/compute-engine 0.53.0 → 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 (227) hide show
  1. package/dist/compute-engine.esm.js +1684 -333
  2. package/dist/compute-engine.min.esm.js +527 -55
  3. package/dist/compute-engine.min.umd.cjs +1035 -0
  4. package/dist/{compute-engine.umd.js → compute-engine.umd.cjs} +1684 -333
  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.js → math-json.min.umd.cjs} +2 -2
  8. package/dist/{math-json.umd.js → 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 +68 -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 +9 -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 +2 -2
  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
  227. package/dist/compute-engine.min.umd.js +0 -563
@@ -1,4 +1,4 @@
1
- /** Compute Engine 0.53.0 */
1
+ /** Compute Engine 0.54.0 */
2
2
 
3
3
  // node_modules/complex-esm/dist/src/complex.js
4
4
  var cosh = Math.cosh || function(x) {
@@ -11083,7 +11083,7 @@ function parseWhereExpression(parser, lhs, until) {
11083
11083
  condition: (p) => {
11084
11084
  if (until?.condition?.(p)) return true;
11085
11085
  const saved = p.index;
11086
- p.skipSpace();
11086
+ p.skipVisualSpace();
11087
11087
  const isComma = p.peek === ",";
11088
11088
  p.index = saved;
11089
11089
  return isComma;
@@ -11091,11 +11091,11 @@ function parseWhereExpression(parser, lhs, until) {
11091
11091
  };
11092
11092
  const bindings = [];
11093
11093
  do {
11094
- parser.skipSpace();
11094
+ parser.skipVisualSpace();
11095
11095
  const binding = parser.parseExpression(bindingTerminator);
11096
11096
  if (!binding) break;
11097
11097
  bindings.push(binding);
11098
- parser.skipSpace();
11098
+ parser.skipVisualSpace();
11099
11099
  } while (parser.match(","));
11100
11100
  if (bindings.length === 0) return null;
11101
11101
  const block = [];
@@ -11594,14 +11594,11 @@ function* factorial3(n) {
11594
11594
  let loop = n;
11595
11595
  let sum2 = n;
11596
11596
  let val = n;
11597
- let counter = 0;
11598
11597
  while (loop > 2) {
11599
11598
  loop -= BigInt(2);
11600
11599
  sum2 += loop;
11601
11600
  val *= sum2;
11602
- counter += 1;
11603
- if (counter % 5e4 === 0 || counter > 1e4 && counter % 500 === 0)
11604
- yield val;
11601
+ yield val;
11605
11602
  }
11606
11603
  return val;
11607
11604
  }
@@ -12293,6 +12290,18 @@ var _expandForIs;
12293
12290
  function _setExpandForIs(fn) {
12294
12291
  _expandForIs = fn;
12295
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
+ }
12296
12305
  var EXPANDABLE_OPS = ["Multiply", "Power", "Negate", "Divide"];
12297
12306
  function _couldBenefitFromExpand(a, b) {
12298
12307
  if (a.has(EXPANDABLE_OPS)) return true;
@@ -12608,6 +12617,34 @@ var _BoxedExpression = class __BoxedExpression {
12608
12617
  factors() {
12609
12618
  return [this];
12610
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
+ }
12611
12648
  is(other, tolerance) {
12612
12649
  if (this.isSame(other)) return true;
12613
12650
  if (_expandForIs && _couldBenefitFromExpand(this, other)) {
@@ -16067,10 +16104,14 @@ function isSqrt(expr) {
16067
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;
16068
16105
  }
16069
16106
  function asRadical(expr) {
16070
- 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
+ }
16071
16112
  if (isFunction2(expr, "Divide") && expr.op1.isSame(1) && isSqrt(expr.op2)) {
16072
16113
  const n = expr.op2.re;
16073
- if (!Number.isInteger(n)) return null;
16114
+ if (!Number.isInteger(n) || n <= 0) return null;
16074
16115
  return [1, n];
16075
16116
  }
16076
16117
  return null;
@@ -16670,13 +16711,14 @@ function gcd3(a, b) {
16670
16711
  function lcm3(a, b) {
16671
16712
  return a.mul(b).div(gcd3(a, b));
16672
16713
  }
16673
- function factorial23(ce, n) {
16714
+ function* factorial23(ce, n) {
16674
16715
  if (!n.isInteger() || n.isNegative()) return ce._BIGNUM_NAN;
16675
16716
  if (n.lessThan(1)) return ce._BIGNUM_ONE;
16676
16717
  let result = n;
16677
16718
  while (n.greaterThan(2)) {
16678
16719
  n = n.minus(2);
16679
16720
  result = result.mul(n);
16721
+ yield result;
16680
16722
  }
16681
16723
  return result;
16682
16724
  }
@@ -20193,24 +20235,30 @@ var COLLECTIONS_LIBRARY = {
20193
20235
  if (initial.type.matches("real") && collection.type.matches(ce.type("collection<real>"))) {
20194
20236
  const compiled = ce._compile(fn);
20195
20237
  if (compiled.calling !== "lambda" || !compiled.run) return void 0;
20196
- let accumulator2 = initial.re;
20197
- let first2 = true;
20198
- for (const item of collection.each()) {
20199
- if (first2) accumulator2 = item.re;
20200
- else accumulator2 = compiled.run(accumulator2, item.re);
20201
- first2 = false;
20202
- }
20203
- return ce.box(accumulator2);
20238
+ return run(
20239
+ (function* () {
20240
+ let accumulator = initial.re;
20241
+ let first = true;
20242
+ for (const item of collection.each()) {
20243
+ if (first) accumulator = item.re;
20244
+ else accumulator = compiled.run(accumulator, item.re);
20245
+ first = false;
20246
+ yield;
20247
+ }
20248
+ return ce.box(accumulator);
20249
+ })(),
20250
+ ce._timeRemaining
20251
+ );
20204
20252
  }
20205
20253
  const f = applicable(fn);
20206
- let accumulator = initial;
20207
- let first = true;
20208
- for (const item of collection.each()) {
20209
- if (first) accumulator = item;
20210
- else accumulator = f([accumulator, item]) ?? ce.Nothing;
20211
- first = false;
20212
- }
20213
- return accumulator;
20254
+ return run(
20255
+ reduceCollection(
20256
+ collection,
20257
+ (acc, x) => f([acc, x]) ?? ce.Nothing,
20258
+ initial
20259
+ ),
20260
+ ce._timeRemaining
20261
+ );
20214
20262
  }
20215
20263
  },
20216
20264
  Join: {
@@ -21435,12 +21483,10 @@ function tally(collection) {
21435
21483
  }
21436
21484
  function* reduceCollection(collection, fn, initial) {
21437
21485
  let acc = initial;
21438
- let counter = 0;
21439
21486
  for (const x of collection.each()) {
21440
21487
  const result = fn(acc, x);
21441
21488
  if (result === null) return void 0;
21442
- counter += 1;
21443
- if (counter % 1e3 === 0) yield acc;
21489
+ yield acc;
21444
21490
  acc = result;
21445
21491
  }
21446
21492
  return acc;
@@ -22859,12 +22905,10 @@ function* reduceBigOp(body, indexes, fn, initial) {
22859
22905
  const indexingSets = normalizeIndexingSets(indexes);
22860
22906
  const cartesianArray = indexingSetCartesianProduct(indexingSets);
22861
22907
  let result = initial;
22862
- let counter = 0;
22863
22908
  for (const element of cartesianArray) {
22864
22909
  indexingSets.forEach((x, i) => ce.assign(x.index, element[i]));
22865
22910
  result = fn(result, body) ?? void 0;
22866
- counter += 1;
22867
- if (counter % 1e3 === 0) yield result;
22911
+ yield result;
22868
22912
  if (result === void 0) break;
22869
22913
  }
22870
22914
  return result ?? void 0;
@@ -22931,7 +22975,6 @@ function* reduceElementIndexingSets(body, indexes, fn, initial, returnReason = f
22931
22975
  return initial;
22932
22976
  }
22933
22977
  let result = initial;
22934
- let counter = 0;
22935
22978
  while (true) {
22936
22979
  for (let i = 0; i < elementDomains.length; i++) {
22937
22980
  ce.assign(
@@ -22940,8 +22983,7 @@ function* reduceElementIndexingSets(body, indexes, fn, initial, returnReason = f
22940
22983
  );
22941
22984
  }
22942
22985
  result = fn(result, body) ?? void 0;
22943
- counter++;
22944
- if (counter % 1e3 === 0) yield result;
22986
+ yield result;
22945
22987
  if (result === void 0) break;
22946
22988
  let dim = elementDomains.length - 1;
22947
22989
  while (dim >= 0) {
@@ -23911,7 +23953,8 @@ var ARITHMETIC_LIBRARY = [
23911
23953
  ce._timeRemaining
23912
23954
  )
23913
23955
  );
23914
- } catch {
23956
+ } catch (e) {
23957
+ if (e instanceof CancellationError) throw e;
23915
23958
  return void 0;
23916
23959
  }
23917
23960
  },
@@ -23930,7 +23973,8 @@ var ARITHMETIC_LIBRARY = [
23930
23973
  signal
23931
23974
  )
23932
23975
  );
23933
- } catch {
23976
+ } catch (e) {
23977
+ if (e instanceof CancellationError) throw e;
23934
23978
  return void 0;
23935
23979
  }
23936
23980
  }
@@ -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(factorial23(ce, ce.bignum(n)));
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
- }
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);
27505
27669
  }
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;
27572
- }
27573
- return newNumerator.div(newDenominator);
27670
+ return roots;
27574
27671
  }
27575
27672
 
27576
27673
  // src/compute-engine/symbolic/antiderivative.ts
@@ -33539,7 +33636,7 @@ function* runLoop(body, collection, ce) {
33539
33636
  if (isFunction2(result, "Break")) return result.op1;
33540
33637
  if (result.operator === "Return") return result;
33541
33638
  i2 += 1;
33542
- if (i2 % 1e3 === 0) yield result;
33639
+ yield result;
33543
33640
  if (i2 > ce.iterationLimit)
33544
33641
  throw new CancellationError({ cause: "iteration-limit-exceeded" });
33545
33642
  }
@@ -33551,7 +33648,7 @@ function* runLoop(body, collection, ce) {
33551
33648
  if (isFunction2(result, "Break")) return result.op1;
33552
33649
  if (result.operator === "Return") return result;
33553
33650
  i += 1;
33554
- if (i % 1e3 === 0) yield result;
33651
+ yield result;
33555
33652
  if (i > ce.iterationLimit)
33556
33653
  throw new CancellationError({ cause: "iteration-limit-exceeded" });
33557
33654
  }
@@ -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;
@@ -48911,9 +49572,11 @@ function withDeadline(engine, fn) {
48911
49572
  return () => {
48912
49573
  if (engine._deadline === void 0) {
48913
49574
  engine._deadline = Date.now() + engine.timeLimit;
48914
- const result = fn();
48915
- engine._deadline = void 0;
48916
- return result;
49575
+ try {
49576
+ return fn();
49577
+ } finally {
49578
+ engine._deadline = void 0;
49579
+ }
48917
49580
  }
48918
49581
  return fn();
48919
49582
  };
@@ -48922,9 +49585,11 @@ function withDeadlineAsync(engine, fn) {
48922
49585
  return async () => {
48923
49586
  if (engine._deadline === void 0) {
48924
49587
  engine._deadline = Date.now() + engine.timeLimit;
48925
- const result = await fn();
48926
- engine._deadline = void 0;
48927
- return result;
49588
+ try {
49589
+ return await fn();
49590
+ } finally {
49591
+ engine._deadline = void 0;
49592
+ }
48928
49593
  }
48929
49594
  return fn();
48930
49595
  };
@@ -50422,6 +51087,9 @@ var BaseCompiler = class _BaseCompiler {
50422
51087
  }
50423
51088
  }
50424
51089
  if (h === "Function") {
51090
+ const fnFn = target.functions?.(h);
51091
+ if (typeof fnFn === "function")
51092
+ return fnFn(args, (expr) => _BaseCompiler.compile(expr, target), target);
50425
51093
  const params = args.slice(1).map((x) => isSymbol2(x) ? x.symbol : "_");
50426
51094
  return `((${params.join(", ")}) => ${_BaseCompiler.compile(
50427
51095
  args[0].canonical,
@@ -50431,15 +51099,26 @@ var BaseCompiler = class _BaseCompiler {
50431
51099
  }
50432
51100
  )})`;
50433
51101
  }
50434
- if (h === "Declare")
50435
- return `let ${isSymbol2(args[0]) ? args[0].symbol : "_"}`;
51102
+ if (h === "Declare") {
51103
+ const name = isSymbol2(args[0]) ? args[0].symbol : "_";
51104
+ return target.declare ? target.declare(name) : `let ${name}`;
51105
+ }
50436
51106
  if (h === "Assign")
50437
51107
  return `${isSymbol2(args[0]) ? args[0].symbol : "_"} = ${_BaseCompiler.compile(args[1], target)}`;
50438
51108
  if (h === "Return")
50439
51109
  return `return ${_BaseCompiler.compile(args[0], target)}`;
50440
51110
  if (h === "Break") return "break";
50441
51111
  if (h === "Continue") return "continue";
50442
- if (h === "Loop") return _BaseCompiler.compileForLoop(args, target);
51112
+ if (h === "Loop") {
51113
+ const loopFn = target.functions?.(h);
51114
+ if (typeof loopFn === "function")
51115
+ return loopFn(
51116
+ args,
51117
+ (expr) => _BaseCompiler.compile(expr, target),
51118
+ target
51119
+ );
51120
+ return _BaseCompiler.compileForLoop(args, target);
51121
+ }
50443
51122
  if (h === "If") {
50444
51123
  if (args.length !== 3) throw new Error("If: wrong number of arguments");
50445
51124
  const fn2 = target.functions?.(h);
@@ -50516,16 +51195,38 @@ var BaseCompiler = class _BaseCompiler {
50516
51195
  if (args.length === 1 && locals.length === 0) {
50517
51196
  return _BaseCompiler.compile(args[0], target);
50518
51197
  }
50519
- const result = args.filter((a) => !isSymbol2(a, "Nothing")).map(
50520
- (arg) => _BaseCompiler.compile(arg, {
50521
- ...target,
50522
- var: (id) => {
50523
- if (locals.includes(id)) return id;
50524
- return target.var(id);
51198
+ const typeHints = {};
51199
+ if (target.declare && target.language) {
51200
+ const isWGSL = target.language === "wgsl";
51201
+ for (const local of locals) {
51202
+ for (const arg of args) {
51203
+ if (isFunction2(arg, "Assign") && isSymbol2(arg.ops[0], local)) {
51204
+ if (_BaseCompiler.isComplexValued(arg.ops[1])) {
51205
+ typeHints[local] = isWGSL ? "vec2f" : "vec2";
51206
+ }
51207
+ break;
51208
+ }
50525
51209
  }
50526
- })
50527
- ).filter((s) => s !== "");
51210
+ }
51211
+ }
51212
+ const localTarget = {
51213
+ ...target,
51214
+ var: (id) => {
51215
+ if (locals.includes(id)) return id;
51216
+ return target.var(id);
51217
+ }
51218
+ };
51219
+ const result = args.filter((a) => !isSymbol2(a, "Nothing")).map((arg) => {
51220
+ if (isFunction2(arg, "Declare") && isSymbol2(arg.ops[0]) && target.declare) {
51221
+ return target.declare(
51222
+ arg.ops[0].symbol,
51223
+ typeHints[arg.ops[0].symbol]
51224
+ );
51225
+ }
51226
+ return _BaseCompiler.compile(arg, localTarget);
51227
+ }).filter((s) => s !== "");
50528
51228
  if (result.length === 0) return "";
51229
+ if (target.block) return target.block(result);
50529
51230
  result[result.length - 1] = `return ${result[result.length - 1]}`;
50530
51231
  return `(() => {${target.ws("\n")}${result.join(
50531
51232
  `;${target.ws("\n")}`
@@ -51011,6 +51712,9 @@ _setExpandForIs(expand2);
51011
51712
  _setSerializeJson(serializeJson);
51012
51713
  _setProduct(Product);
51013
51714
  _setCompile(compile);
51715
+ _setGetPolynomialCoefficients(getPolynomialCoefficients);
51716
+ _setGetPolynomialDegree(polynomialDegree);
51717
+ _setFindUnivariateRoots(findUnivariateRoots);
51014
51718
 
51015
51719
  // src/compute-engine/symbolic/simplify-logic.ts
51016
51720
  function simplifyLogicFunction(x) {
@@ -53949,6 +54653,27 @@ var SIMPLIFY_RULES = [
53949
54653
  if (result.isSame(x)) return void 0;
53950
54654
  return { value: result, because: "cancel common polynomial factors" };
53951
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
+ },
53952
54677
  // Quick a/a -> 1 check for identical numerator/denominator
53953
54678
  // Must run before expand to avoid decomposing the fraction first
53954
54679
  (x) => {
@@ -57291,6 +58016,62 @@ var GPU_OPERATORS = {
57291
58016
  function gpuVec2(target) {
57292
58017
  return target?.language === "wgsl" ? "vec2f" : "vec2";
57293
58018
  }
58019
+ var GPU_UNROLL_LIMIT = 100;
58020
+ function compileGPUSumProduct(kind, args, _compile2, target) {
58021
+ if (!args[0]) throw new Error(`${kind}: no body`);
58022
+ if (!args[1]) throw new Error(`${kind}: no indexing set`);
58023
+ if (BaseCompiler.isComplexValued(args[0]))
58024
+ throw new Error(
58025
+ `${kind}: complex-valued body not supported in GPU targets`
58026
+ );
58027
+ const limitsExpr = args[1];
58028
+ if (!isFunction2(limitsExpr, "Limits"))
58029
+ throw new Error(`${kind}: expected Limits indexing set`);
58030
+ const limitsOps = limitsExpr.ops;
58031
+ const index = isSymbol2(limitsOps[0]) ? limitsOps[0].symbol : "_";
58032
+ const lowerRe = limitsOps[1].re;
58033
+ const upperRe = limitsOps[2].re;
58034
+ const lowerNum = !isNaN(lowerRe) && Number.isFinite(lowerRe) ? Math.floor(lowerRe) : void 0;
58035
+ const upperNum = !isNaN(upperRe) && Number.isFinite(upperRe) ? Math.floor(upperRe) : void 0;
58036
+ const isSum = kind === "Sum";
58037
+ const op = isSum ? "+" : "*";
58038
+ const identity = isSum ? "0.0" : "1.0";
58039
+ const isWGSL = target.language === "wgsl";
58040
+ const bothConstant = lowerNum !== void 0 && upperNum !== void 0;
58041
+ if (bothConstant && lowerNum > upperNum) return identity;
58042
+ if (bothConstant && upperNum - lowerNum + 1 <= GPU_UNROLL_LIMIT) {
58043
+ const terms = [];
58044
+ for (let k = lowerNum; k <= upperNum; k++) {
58045
+ const kStr = formatGPUNumber(k);
58046
+ const innerTarget = {
58047
+ ...target,
58048
+ var: (id) => id === index ? kStr : target.var(id)
58049
+ };
58050
+ terms.push(`(${BaseCompiler.compile(args[0], innerTarget)})`);
58051
+ }
58052
+ return `(${terms.join(` ${op} `)})`;
58053
+ }
58054
+ const acc = BaseCompiler.tempVar();
58055
+ const floatType = isWGSL ? "f32" : "float";
58056
+ const intType = isWGSL ? "i32" : "int";
58057
+ const bodyTarget = {
58058
+ ...target,
58059
+ var: (id) => id === index ? isWGSL ? `f32(${index})` : `float(${index})` : target.var(id)
58060
+ };
58061
+ const body = BaseCompiler.compile(args[0], bodyTarget);
58062
+ const lowerStr = lowerNum !== void 0 ? String(lowerNum) : BaseCompiler.compile(limitsOps[1], target);
58063
+ const upperStr = upperNum !== void 0 ? String(upperNum) : BaseCompiler.compile(limitsOps[2], target);
58064
+ const accDecl = isWGSL ? `var ${acc}: ${floatType}` : `${floatType} ${acc}`;
58065
+ const indexDecl = isWGSL ? `var ${index}: ${intType}` : `${intType} ${index}`;
58066
+ const lines = [
58067
+ `${accDecl} = ${identity};`,
58068
+ `for (${indexDecl} = ${lowerStr}; ${index} <= ${upperStr}; ${index}++) {`,
58069
+ ` ${acc} ${op}= ${body};`,
58070
+ `}`,
58071
+ `return ${acc}`
58072
+ ];
58073
+ return lines.join("\n");
58074
+ }
57294
58075
  var GPU_FUNCTIONS = {
57295
58076
  // Variadic arithmetic (for function-call form, e.g., with vectors)
57296
58077
  Add: (args, compile3, target) => {
@@ -57640,6 +58421,28 @@ var GPU_FUNCTIONS = {
57640
58421
  if (x === null) throw new Error("ErfInv: no argument");
57641
58422
  return `_gpu_erfinv(${compile3(x)})`;
57642
58423
  },
58424
+ Heaviside: ([x], compile3) => {
58425
+ if (x === null) throw new Error("Heaviside: no argument");
58426
+ return `_gpu_heaviside(${compile3(x)})`;
58427
+ },
58428
+ Sinc: ([x], compile3) => {
58429
+ if (x === null) throw new Error("Sinc: no argument");
58430
+ return `_gpu_sinc(${compile3(x)})`;
58431
+ },
58432
+ FresnelC: ([x], compile3) => {
58433
+ if (x === null) throw new Error("FresnelC: no argument");
58434
+ return `_gpu_fresnelC(${compile3(x)})`;
58435
+ },
58436
+ FresnelS: ([x], compile3) => {
58437
+ if (x === null) throw new Error("FresnelS: no argument");
58438
+ return `_gpu_fresnelS(${compile3(x)})`;
58439
+ },
58440
+ BesselJ: ([n, x], compile3, target) => {
58441
+ if (n === null || x === null)
58442
+ throw new Error("BesselJ: need two arguments");
58443
+ const intCast = target?.language === "wgsl" ? "i32" : "int";
58444
+ return `_gpu_besselJ(${intCast}(${compile3(n)}), ${compile3(x)})`;
58445
+ },
57643
58446
  // Additional math functions
57644
58447
  Lb: "log2",
57645
58448
  Log: (args, compile3) => {
@@ -57725,7 +58528,44 @@ var GPU_FUNCTIONS = {
57725
58528
  Length: "length",
57726
58529
  Normalize: "normalize",
57727
58530
  Reflect: "reflect",
57728
- Refract: "refract"
58531
+ Refract: "refract",
58532
+ // Sum/Product — unrolled or for-loop
58533
+ Sum: (args, compile3, target) => compileGPUSumProduct("Sum", args, compile3, target),
58534
+ Product: (args, compile3, target) => compileGPUSumProduct("Product", args, compile3, target),
58535
+ // Loop — GPU for-loop (no IIFE, no let)
58536
+ Loop: (args, _compile2, target) => {
58537
+ if (!args[0]) throw new Error("Loop: no body");
58538
+ if (!args[1]) throw new Error("Loop: no indexing set");
58539
+ const indexing = args[1];
58540
+ if (!isFunction2(indexing, "Element"))
58541
+ throw new Error("Loop: expected Element(index, Range(lo, hi))");
58542
+ const indexExpr = indexing.ops[0];
58543
+ const rangeExpr = indexing.ops[1];
58544
+ if (!isSymbol2(indexExpr)) throw new Error("Loop: index must be a symbol");
58545
+ if (!isFunction2(rangeExpr, "Range"))
58546
+ throw new Error("Loop: expected Range(lo, hi)");
58547
+ const index = indexExpr.symbol;
58548
+ const lower = Math.floor(rangeExpr.ops[0].re);
58549
+ const upper = Math.floor(rangeExpr.ops[1].re);
58550
+ if (!Number.isFinite(lower) || !Number.isFinite(upper))
58551
+ throw new Error("Loop: bounds must be finite numbers");
58552
+ const isWGSL = target.language === "wgsl";
58553
+ const intType = isWGSL ? "i32" : "int";
58554
+ const bodyCode = BaseCompiler.compile(args[0], {
58555
+ ...target,
58556
+ var: (id) => id === index ? index : target.var(id)
58557
+ });
58558
+ const indexDecl = isWGSL ? `var ${index}: ${intType}` : `${intType} ${index}`;
58559
+ return `for (${indexDecl} = ${lower}; ${index} <= ${upper}; ${index}++) {
58560
+ ${bodyCode};
58561
+ }`;
58562
+ },
58563
+ // Function (lambda) — not supported in GPU
58564
+ Function: () => {
58565
+ throw new Error(
58566
+ "Anonymous functions (Function) are not supported in GPU targets"
58567
+ );
58568
+ }
57729
58569
  };
57730
58570
  function compileGPUMatrix(args, compile3, vecFn, matFn, arrayFn) {
57731
58571
  const body = args[0];
@@ -57806,6 +58646,476 @@ float _gpu_erfinv(float x) {
57806
58646
  return sqrt(pi) * 0.5 * (x + (pi / 12.0) * x3 + (7.0 * pi * pi / 480.0) * x5 + (127.0 * pi * pi * pi / 40320.0) * x7 + (4369.0 * pi * pi * pi * pi / 5806080.0) * x9);
57807
58647
  }
57808
58648
  `;
58649
+ var GPU_HEAVISIDE_PREAMBLE_GLSL = `
58650
+ float _gpu_heaviside(float x) {
58651
+ if (x < 0.0) return 0.0;
58652
+ if (x > 0.0) return 1.0;
58653
+ return 0.5;
58654
+ }
58655
+ `;
58656
+ var GPU_HEAVISIDE_PREAMBLE_WGSL = `
58657
+ fn _gpu_heaviside(x: f32) -> f32 {
58658
+ if (x < 0.0) { return 0.0; }
58659
+ if (x > 0.0) { return 1.0; }
58660
+ return 0.5;
58661
+ }
58662
+ `;
58663
+ var GPU_SINC_PREAMBLE_GLSL = `
58664
+ float _gpu_sinc(float x) {
58665
+ if (abs(x) < 1e-10) return 1.0;
58666
+ return sin(x) / x;
58667
+ }
58668
+ `;
58669
+ var GPU_SINC_PREAMBLE_WGSL = `
58670
+ fn _gpu_sinc(x: f32) -> f32 {
58671
+ if (abs(x) < 1e-10) { return 1.0; }
58672
+ return sin(x) / x;
58673
+ }
58674
+ `;
58675
+ var GPU_POLEVL_PREAMBLE_GLSL = `
58676
+ float _gpu_polevl(float x, float c[12], int n) {
58677
+ float ans = c[0];
58678
+ for (int i = 1; i < n; i++) ans = ans * x + c[i];
58679
+ return ans;
58680
+ }
58681
+ `;
58682
+ var GPU_POLEVL_PREAMBLE_WGSL = `
58683
+ fn _gpu_polevl(x: f32, c: array<f32, 12>, n: i32) -> f32 {
58684
+ var ans = c[0];
58685
+ for (var i: i32 = 1; i < n; i++) { ans = ans * x + c[i]; }
58686
+ return ans;
58687
+ }
58688
+ `;
58689
+ var GPU_FRESNELC_PREAMBLE_GLSL = `
58690
+ float _gpu_fresnelC(float x_in) {
58691
+ float sgn = x_in < 0.0 ? -1.0 : 1.0;
58692
+ float x = abs(x_in);
58693
+
58694
+ if (x < 1.6) {
58695
+ float x2 = x * x;
58696
+ float t = x2 * x2;
58697
+ float cn[6] = float[6](
58698
+ -4.98843114573573548651e-8, 9.50428062829859605134e-6,
58699
+ -6.45191435683965050962e-4, 1.88843319396703850064e-2,
58700
+ -2.05525900955013891793e-1, 9.99999999999999998822e-1
58701
+ );
58702
+ float cd[7] = float[7](
58703
+ 3.99982968972495980367e-12, 9.15439215774657478799e-10,
58704
+ 1.25001862479598821474e-7, 1.22262789024179030997e-5,
58705
+ 8.68029542941784300606e-4, 4.12142090722199792936e-2, 1.0
58706
+ );
58707
+ return sgn * x * _gpu_polevl(t, cn, 6) / _gpu_polevl(t, cd, 7);
58708
+ }
58709
+
58710
+ if (x < 36.0) {
58711
+ float x2 = x * x;
58712
+ float t = 3.14159265358979 * x2;
58713
+ float u = 1.0 / (t * t);
58714
+ float fn[10] = float[10](
58715
+ 4.21543555043677546506e-1, 1.43407919780758885261e-1,
58716
+ 1.15220955073585758835e-2, 3.450179397825740279e-4,
58717
+ 4.63613749287867322088e-6, 3.05568983790257605827e-8,
58718
+ 1.02304514164907233465e-10, 1.72010743268161828879e-13,
58719
+ 1.34283276233062758925e-16, 3.76329711269987889006e-20
58720
+ );
58721
+ float fd[11] = float[11](
58722
+ 1.0, 7.51586398353378947175e-1,
58723
+ 1.16888925859191382142e-1, 6.44051526508858611005e-3,
58724
+ 1.55934409164153020873e-4, 1.8462756734893054587e-6,
58725
+ 1.12699224763999035261e-8, 3.60140029589371370404e-11,
58726
+ 5.8875453362157841001e-14, 4.52001434074129701496e-17,
58727
+ 1.25443237090011264384e-20
58728
+ );
58729
+ float gn[11] = float[11](
58730
+ 5.04442073643383265887e-1, 1.97102833525523411709e-1,
58731
+ 1.87648584092575249293e-2, 6.84079380915393090172e-4,
58732
+ 1.15138826111884280931e-5, 9.82852443688422223854e-8,
58733
+ 4.45344415861750144738e-10, 1.08268041139020870318e-12,
58734
+ 1.37555460633261799868e-15, 8.36354435630677421531e-19,
58735
+ 1.86958710162783235106e-22
58736
+ );
58737
+ float gd[12] = float[12](
58738
+ 1.0, 1.47495759925128324529,
58739
+ 3.37748989120019970451e-1, 2.53603741420338795122e-2,
58740
+ 8.14679107184306179049e-4, 1.27545075667729118702e-5,
58741
+ 1.04314589657571990585e-7, 4.60680728515232032307e-10,
58742
+ 1.10273215066240270757e-12, 1.38796531259578871258e-15,
58743
+ 8.39158816283118707363e-19, 1.86958710162783236342e-22
58744
+ );
58745
+ float f = 1.0 - u * _gpu_polevl(u, fn, 10) / _gpu_polevl(u, fd, 11);
58746
+ float g = (1.0 / t) * _gpu_polevl(u, gn, 11) / _gpu_polevl(u, gd, 12);
58747
+ float z = 1.5707963267948966 * x2;
58748
+ float c = cos(z);
58749
+ float s = sin(z);
58750
+ return sgn * (0.5 + (f * s - g * c) / (3.14159265358979 * x));
58751
+ }
58752
+
58753
+ return sgn * 0.5;
58754
+ }
58755
+ `;
58756
+ var GPU_FRESNELC_PREAMBLE_WGSL = `
58757
+ fn _gpu_fresnelC(x_in: f32) -> f32 {
58758
+ let sgn: f32 = select(1.0, -1.0, x_in < 0.0);
58759
+ let x = abs(x_in);
58760
+
58761
+ if (x < 1.6) {
58762
+ let x2 = x * x;
58763
+ let t = x2 * x2;
58764
+ var cn = array<f32, 12>(
58765
+ -4.98843114573573548651e-8, 9.50428062829859605134e-6,
58766
+ -6.45191435683965050962e-4, 1.88843319396703850064e-2,
58767
+ -2.05525900955013891793e-1, 9.99999999999999998822e-1,
58768
+ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
58769
+ );
58770
+ var cd = array<f32, 12>(
58771
+ 3.99982968972495980367e-12, 9.15439215774657478799e-10,
58772
+ 1.25001862479598821474e-7, 1.22262789024179030997e-5,
58773
+ 8.68029542941784300606e-4, 4.12142090722199792936e-2, 1.0,
58774
+ 0.0, 0.0, 0.0, 0.0, 0.0
58775
+ );
58776
+ return sgn * x * _gpu_polevl(t, cn, 6) / _gpu_polevl(t, cd, 7);
58777
+ }
58778
+
58779
+ if (x < 36.0) {
58780
+ let x2 = x * x;
58781
+ let t = 3.14159265358979 * x2;
58782
+ let u = 1.0 / (t * t);
58783
+ var fn = array<f32, 12>(
58784
+ 4.21543555043677546506e-1, 1.43407919780758885261e-1,
58785
+ 1.15220955073585758835e-2, 3.450179397825740279e-4,
58786
+ 4.63613749287867322088e-6, 3.05568983790257605827e-8,
58787
+ 1.02304514164907233465e-10, 1.72010743268161828879e-13,
58788
+ 1.34283276233062758925e-16, 3.76329711269987889006e-20,
58789
+ 0.0, 0.0
58790
+ );
58791
+ var fd = array<f32, 12>(
58792
+ 1.0, 7.51586398353378947175e-1,
58793
+ 1.16888925859191382142e-1, 6.44051526508858611005e-3,
58794
+ 1.55934409164153020873e-4, 1.8462756734893054587e-6,
58795
+ 1.12699224763999035261e-8, 3.60140029589371370404e-11,
58796
+ 5.8875453362157841001e-14, 4.52001434074129701496e-17,
58797
+ 1.25443237090011264384e-20, 0.0
58798
+ );
58799
+ var gn = array<f32, 12>(
58800
+ 5.04442073643383265887e-1, 1.97102833525523411709e-1,
58801
+ 1.87648584092575249293e-2, 6.84079380915393090172e-4,
58802
+ 1.15138826111884280931e-5, 9.82852443688422223854e-8,
58803
+ 4.45344415861750144738e-10, 1.08268041139020870318e-12,
58804
+ 1.37555460633261799868e-15, 8.36354435630677421531e-19,
58805
+ 1.86958710162783235106e-22, 0.0
58806
+ );
58807
+ var gd = array<f32, 12>(
58808
+ 1.0, 1.47495759925128324529,
58809
+ 3.37748989120019970451e-1, 2.53603741420338795122e-2,
58810
+ 8.14679107184306179049e-4, 1.27545075667729118702e-5,
58811
+ 1.04314589657571990585e-7, 4.60680728515232032307e-10,
58812
+ 1.10273215066240270757e-12, 1.38796531259578871258e-15,
58813
+ 8.39158816283118707363e-19, 1.86958710162783236342e-22
58814
+ );
58815
+ let f = 1.0 - u * _gpu_polevl(u, fn, 10) / _gpu_polevl(u, fd, 11);
58816
+ let g = (1.0 / t) * _gpu_polevl(u, gn, 11) / _gpu_polevl(u, gd, 12);
58817
+ let z = 1.5707963267948966 * x2;
58818
+ let c = cos(z);
58819
+ let s = sin(z);
58820
+ return sgn * (0.5 + (f * s - g * c) / (3.14159265358979 * x));
58821
+ }
58822
+
58823
+ return sgn * 0.5;
58824
+ }
58825
+ `;
58826
+ var GPU_FRESNELS_PREAMBLE_GLSL = `
58827
+ float _gpu_fresnelS(float x_in) {
58828
+ float sgn = x_in < 0.0 ? -1.0 : 1.0;
58829
+ float x = abs(x_in);
58830
+
58831
+ if (x < 1.6) {
58832
+ float x2 = x * x;
58833
+ float t = x2 * x2;
58834
+ float sn[6] = float[6](
58835
+ -2.99181919401019853726e3, 7.08840045257738576863e5,
58836
+ -6.29741486205862506537e7, 2.54890880573376359104e9,
58837
+ -4.42979518059697779103e10, 3.18016297876567817986e11
58838
+ );
58839
+ float sd[7] = float[7](
58840
+ 1.0, 2.81376268889994315696e2, 4.55847810806532581675e4,
58841
+ 5.1734388877009640073e6, 4.19320245898111231129e8, 2.2441179564534092094e10,
58842
+ 6.07366389490084914091e11
58843
+ );
58844
+ return sgn * x * x2 * _gpu_polevl(t, sn, 6) / _gpu_polevl(t, sd, 7);
58845
+ }
58846
+
58847
+ if (x < 36.0) {
58848
+ float x2 = x * x;
58849
+ float t = 3.14159265358979 * x2;
58850
+ float u = 1.0 / (t * t);
58851
+ float fn[10] = float[10](
58852
+ 4.21543555043677546506e-1, 1.43407919780758885261e-1,
58853
+ 1.15220955073585758835e-2, 3.450179397825740279e-4,
58854
+ 4.63613749287867322088e-6, 3.05568983790257605827e-8,
58855
+ 1.02304514164907233465e-10, 1.72010743268161828879e-13,
58856
+ 1.34283276233062758925e-16, 3.76329711269987889006e-20
58857
+ );
58858
+ float fd[11] = float[11](
58859
+ 1.0, 7.51586398353378947175e-1,
58860
+ 1.16888925859191382142e-1, 6.44051526508858611005e-3,
58861
+ 1.55934409164153020873e-4, 1.8462756734893054587e-6,
58862
+ 1.12699224763999035261e-8, 3.60140029589371370404e-11,
58863
+ 5.8875453362157841001e-14, 4.52001434074129701496e-17,
58864
+ 1.25443237090011264384e-20
58865
+ );
58866
+ float gn[11] = float[11](
58867
+ 5.04442073643383265887e-1, 1.97102833525523411709e-1,
58868
+ 1.87648584092575249293e-2, 6.84079380915393090172e-4,
58869
+ 1.15138826111884280931e-5, 9.82852443688422223854e-8,
58870
+ 4.45344415861750144738e-10, 1.08268041139020870318e-12,
58871
+ 1.37555460633261799868e-15, 8.36354435630677421531e-19,
58872
+ 1.86958710162783235106e-22
58873
+ );
58874
+ float gd[12] = float[12](
58875
+ 1.0, 1.47495759925128324529,
58876
+ 3.37748989120019970451e-1, 2.53603741420338795122e-2,
58877
+ 8.14679107184306179049e-4, 1.27545075667729118702e-5,
58878
+ 1.04314589657571990585e-7, 4.60680728515232032307e-10,
58879
+ 1.10273215066240270757e-12, 1.38796531259578871258e-15,
58880
+ 8.39158816283118707363e-19, 1.86958710162783236342e-22
58881
+ );
58882
+ float f = 1.0 - u * _gpu_polevl(u, fn, 10) / _gpu_polevl(u, fd, 11);
58883
+ float g = (1.0 / t) * _gpu_polevl(u, gn, 11) / _gpu_polevl(u, gd, 12);
58884
+ float z = 1.5707963267948966 * x2;
58885
+ float c = cos(z);
58886
+ float s = sin(z);
58887
+ return sgn * (0.5 - (f * c + g * s) / (3.14159265358979 * x));
58888
+ }
58889
+
58890
+ return sgn * 0.5;
58891
+ }
58892
+ `;
58893
+ var GPU_FRESNELS_PREAMBLE_WGSL = `
58894
+ fn _gpu_fresnelS(x_in: f32) -> f32 {
58895
+ let sgn: f32 = select(1.0, -1.0, x_in < 0.0);
58896
+ let x = abs(x_in);
58897
+
58898
+ if (x < 1.6) {
58899
+ let x2 = x * x;
58900
+ let t = x2 * x2;
58901
+ var sn = array<f32, 12>(
58902
+ -2.99181919401019853726e3, 7.08840045257738576863e5,
58903
+ -6.29741486205862506537e7, 2.54890880573376359104e9,
58904
+ -4.42979518059697779103e10, 3.18016297876567817986e11,
58905
+ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
58906
+ );
58907
+ var sd = array<f32, 12>(
58908
+ 1.0, 2.81376268889994315696e2, 4.55847810806532581675e4,
58909
+ 5.1734388877009640073e6, 4.19320245898111231129e8, 2.2441179564534092094e10,
58910
+ 6.07366389490084914091e11,
58911
+ 0.0, 0.0, 0.0, 0.0, 0.0
58912
+ );
58913
+ return sgn * x * x2 * _gpu_polevl(t, sn, 6) / _gpu_polevl(t, sd, 7);
58914
+ }
58915
+
58916
+ if (x < 36.0) {
58917
+ let x2 = x * x;
58918
+ let t = 3.14159265358979 * x2;
58919
+ let u = 1.0 / (t * t);
58920
+ var fn = array<f32, 12>(
58921
+ 4.21543555043677546506e-1, 1.43407919780758885261e-1,
58922
+ 1.15220955073585758835e-2, 3.450179397825740279e-4,
58923
+ 4.63613749287867322088e-6, 3.05568983790257605827e-8,
58924
+ 1.02304514164907233465e-10, 1.72010743268161828879e-13,
58925
+ 1.34283276233062758925e-16, 3.76329711269987889006e-20,
58926
+ 0.0, 0.0
58927
+ );
58928
+ var fd = array<f32, 12>(
58929
+ 1.0, 7.51586398353378947175e-1,
58930
+ 1.16888925859191382142e-1, 6.44051526508858611005e-3,
58931
+ 1.55934409164153020873e-4, 1.8462756734893054587e-6,
58932
+ 1.12699224763999035261e-8, 3.60140029589371370404e-11,
58933
+ 5.8875453362157841001e-14, 4.52001434074129701496e-17,
58934
+ 1.25443237090011264384e-20, 0.0
58935
+ );
58936
+ var gn = array<f32, 12>(
58937
+ 5.04442073643383265887e-1, 1.97102833525523411709e-1,
58938
+ 1.87648584092575249293e-2, 6.84079380915393090172e-4,
58939
+ 1.15138826111884280931e-5, 9.82852443688422223854e-8,
58940
+ 4.45344415861750144738e-10, 1.08268041139020870318e-12,
58941
+ 1.37555460633261799868e-15, 8.36354435630677421531e-19,
58942
+ 1.86958710162783235106e-22, 0.0
58943
+ );
58944
+ var gd = array<f32, 12>(
58945
+ 1.0, 1.47495759925128324529,
58946
+ 3.37748989120019970451e-1, 2.53603741420338795122e-2,
58947
+ 8.14679107184306179049e-4, 1.27545075667729118702e-5,
58948
+ 1.04314589657571990585e-7, 4.60680728515232032307e-10,
58949
+ 1.10273215066240270757e-12, 1.38796531259578871258e-15,
58950
+ 8.39158816283118707363e-19, 1.86958710162783236342e-22
58951
+ );
58952
+ let f = 1.0 - u * _gpu_polevl(u, fn, 10) / _gpu_polevl(u, fd, 11);
58953
+ let g = (1.0 / t) * _gpu_polevl(u, gn, 11) / _gpu_polevl(u, gd, 12);
58954
+ let z = 1.5707963267948966 * x2;
58955
+ let c = cos(z);
58956
+ let s = sin(z);
58957
+ return sgn * (0.5 - (f * c + g * s) / (3.14159265358979 * x));
58958
+ }
58959
+
58960
+ return sgn * 0.5;
58961
+ }
58962
+ `;
58963
+ var GPU_BESSELJ_PREAMBLE_GLSL = `
58964
+ float _gpu_factorial(int n) {
58965
+ float f = 1.0;
58966
+ for (int i = 2; i <= n; i++) f *= float(i);
58967
+ return f;
58968
+ }
58969
+
58970
+ float _gpu_besselJ_series(int n, float x) {
58971
+ float halfX = x / 2.0;
58972
+ float negQ = -(x * x) / 4.0;
58973
+ float term = 1.0;
58974
+ for (int i = 1; i <= n; i++) term /= float(i);
58975
+ float s = term;
58976
+ for (int k = 1; k <= 60; k++) {
58977
+ term *= negQ / (float(k) * float(n + k));
58978
+ s += term;
58979
+ if (abs(term) < abs(s) * 1e-7) break;
58980
+ }
58981
+ return s * pow(halfX, float(n));
58982
+ }
58983
+
58984
+ float _gpu_besselJ_asymptotic(int n, float x) {
58985
+ float mu = 4.0 * float(n) * float(n);
58986
+ float P = 1.0;
58987
+ float Q = 0.0;
58988
+ float ak = 1.0;
58989
+ float e8x = 8.0 * x;
58990
+ for (int k = 1; k <= 12; k++) {
58991
+ float twokm1 = float(2 * k - 1);
58992
+ ak *= mu - twokm1 * twokm1;
58993
+ float denom = _gpu_factorial(k) * pow(e8x, float(k));
58994
+ float contrib = ak / denom;
58995
+ if (k == 1 || k == 3 || k == 5 || k == 7 || k == 9 || k == 11) {
58996
+ // odd k: contributes to Q
58997
+ if (((k - 1) / 2) % 2 == 0) Q += contrib;
58998
+ else Q -= contrib;
58999
+ } else {
59000
+ // even k: contributes to P
59001
+ if ((k / 2) % 2 == 1) P -= contrib;
59002
+ else P += contrib;
59003
+ }
59004
+ if (abs(contrib) < 1e-7) break;
59005
+ }
59006
+ float chi = x - (float(n) / 2.0 + 0.25) * 3.14159265358979;
59007
+ return sqrt(2.0 / (3.14159265358979 * x)) * (P * cos(chi) - Q * sin(chi));
59008
+ }
59009
+
59010
+ float _gpu_besselJ(int n, float x) {
59011
+ if (x == 0.0) return n == 0 ? 1.0 : 0.0;
59012
+ float sgn = 1.0;
59013
+ if (n < 0) {
59014
+ n = -n;
59015
+ if (n % 2 != 0) sgn = -1.0;
59016
+ }
59017
+ if (x < 0.0) {
59018
+ x = -x;
59019
+ if (n % 2 != 0) sgn *= -1.0;
59020
+ }
59021
+ if (x > 25.0 + float(n * n) / 2.0) return sgn * _gpu_besselJ_asymptotic(n, x);
59022
+ if (x < 5.0 + float(n)) return sgn * _gpu_besselJ_series(n, x);
59023
+ // Miller's backward recurrence
59024
+ int M = max(n + 20, int(ceil(x)) + 30);
59025
+ if (M > 200) return sgn * _gpu_besselJ_series(n, x);
59026
+ float vals[201];
59027
+ float jp1 = 0.0;
59028
+ float jk = 1.0;
59029
+ vals[M] = jk;
59030
+ for (int k = M; k >= 1; k--) {
59031
+ float jm1 = (2.0 * float(k) / x) * jk - jp1;
59032
+ jp1 = jk;
59033
+ jk = jm1;
59034
+ vals[k - 1] = jk;
59035
+ }
59036
+ float norm = vals[0];
59037
+ for (int k = 2; k <= M; k += 2) norm += 2.0 * vals[k];
59038
+ return sgn * vals[n] / norm;
59039
+ }
59040
+ `;
59041
+ var GPU_BESSELJ_PREAMBLE_WGSL = `
59042
+ fn _gpu_factorial(n: i32) -> f32 {
59043
+ var f: f32 = 1.0;
59044
+ for (var i: i32 = 2; i <= n; i++) { f *= f32(i); }
59045
+ return f;
59046
+ }
59047
+
59048
+ fn _gpu_besselJ_series(n_in: i32, x: f32) -> f32 {
59049
+ let halfX = x / 2.0;
59050
+ let negQ = -(x * x) / 4.0;
59051
+ var term: f32 = 1.0;
59052
+ for (var i: i32 = 1; i <= n_in; i++) { term /= f32(i); }
59053
+ var s = term;
59054
+ for (var k: i32 = 1; k <= 60; k++) {
59055
+ term *= negQ / (f32(k) * f32(n_in + k));
59056
+ s += term;
59057
+ if (abs(term) < abs(s) * 1e-7) { break; }
59058
+ }
59059
+ return s * pow(halfX, f32(n_in));
59060
+ }
59061
+
59062
+ fn _gpu_besselJ_asymptotic(n_in: i32, x: f32) -> f32 {
59063
+ let mu = 4.0 * f32(n_in) * f32(n_in);
59064
+ var P: f32 = 1.0;
59065
+ var Q: f32 = 0.0;
59066
+ var ak: f32 = 1.0;
59067
+ let e8x = 8.0 * x;
59068
+ for (var k: i32 = 1; k <= 12; k++) {
59069
+ let twokm1 = f32(2 * k - 1);
59070
+ ak *= mu - twokm1 * twokm1;
59071
+ let denom = _gpu_factorial(k) * pow(e8x, f32(k));
59072
+ let contrib = ak / denom;
59073
+ if (k == 1 || k == 3 || k == 5 || k == 7 || k == 9 || k == 11) {
59074
+ if (((k - 1) / 2) % 2 == 0) { Q += contrib; }
59075
+ else { Q -= contrib; }
59076
+ } else {
59077
+ if ((k / 2) % 2 == 1) { P -= contrib; }
59078
+ else { P += contrib; }
59079
+ }
59080
+ if (abs(contrib) < 1e-7) { break; }
59081
+ }
59082
+ let chi = x - (f32(n_in) / 2.0 + 0.25) * 3.14159265358979;
59083
+ return sqrt(2.0 / (3.14159265358979 * x)) * (P * cos(chi) - Q * sin(chi));
59084
+ }
59085
+
59086
+ fn _gpu_besselJ(n_in: i32, x_in: f32) -> f32 {
59087
+ var n = n_in;
59088
+ var x = x_in;
59089
+ if (x == 0.0) { return select(0.0, 1.0, n == 0); }
59090
+ var sgn: f32 = 1.0;
59091
+ if (n < 0) {
59092
+ n = -n;
59093
+ if (n % 2 != 0) { sgn = -1.0; }
59094
+ }
59095
+ if (x < 0.0) {
59096
+ x = -x;
59097
+ if (n % 2 != 0) { sgn *= -1.0; }
59098
+ }
59099
+ if (x > 25.0 + f32(n * n) / 2.0) { return sgn * _gpu_besselJ_asymptotic(n, x); }
59100
+ if (x < 5.0 + f32(n)) { return sgn * _gpu_besselJ_series(n, x); }
59101
+ // Miller's backward recurrence
59102
+ var M = max(n + 20, i32(ceil(x)) + 30);
59103
+ if (M > 200) { return sgn * _gpu_besselJ_series(n, x); }
59104
+ var vals: array<f32, 201>;
59105
+ var jp1: f32 = 0.0;
59106
+ var jk: f32 = 1.0;
59107
+ vals[M] = jk;
59108
+ for (var k: i32 = M; k >= 1; k--) {
59109
+ let jm1 = (2.0 * f32(k) / x) * jk - jp1;
59110
+ jp1 = jk;
59111
+ jk = jm1;
59112
+ vals[k - 1] = jk;
59113
+ }
59114
+ var norm = vals[0];
59115
+ for (var k2: i32 = 2; k2 <= M; k2 += 2) { norm += 2.0 * vals[k2]; }
59116
+ return sgn * vals[n] / norm;
59117
+ }
59118
+ `;
57809
59119
  var GPU_FRACTAL_PREAMBLE_GLSL = `
57810
59120
  float _fractal_mandelbrot(vec2 c, int maxIter) {
57811
59121
  vec2 z = vec2(0.0, 0.0);
@@ -58268,6 +59578,16 @@ var GPUShaderTarget = class {
58268
59578
  indent: 0,
58269
59579
  ws: (s) => s ?? "",
58270
59580
  preamble: "",
59581
+ declare: (name, typeHint) => {
59582
+ const type2 = typeHint ?? (this.languageId === "wgsl" ? "f32" : "float");
59583
+ return this.languageId === "wgsl" ? `var ${name}: ${type2}` : `${type2} ${name}`;
59584
+ },
59585
+ block: (stmts) => {
59586
+ if (stmts.length === 0) return "";
59587
+ const last = stmts.length - 1;
59588
+ stmts[last] = `return ${stmts[last]}`;
59589
+ return stmts.join(";\n");
59590
+ },
58271
59591
  ...options
58272
59592
  };
58273
59593
  }
@@ -58302,6 +59622,18 @@ var GPUShaderTarget = class {
58302
59622
  preamble += buildComplexPreamble(code, this.languageId);
58303
59623
  if (code.includes("_gpu_gamma")) preamble += GPU_GAMMA_PREAMBLE;
58304
59624
  if (code.includes("_gpu_erf")) preamble += GPU_ERF_PREAMBLE;
59625
+ if (code.includes("_gpu_heaviside"))
59626
+ preamble += this.languageId === "wgsl" ? GPU_HEAVISIDE_PREAMBLE_WGSL : GPU_HEAVISIDE_PREAMBLE_GLSL;
59627
+ if (code.includes("_gpu_sinc"))
59628
+ preamble += this.languageId === "wgsl" ? GPU_SINC_PREAMBLE_WGSL : GPU_SINC_PREAMBLE_GLSL;
59629
+ if (code.includes("_gpu_fresnel"))
59630
+ preamble += this.languageId === "wgsl" ? GPU_POLEVL_PREAMBLE_WGSL : GPU_POLEVL_PREAMBLE_GLSL;
59631
+ if (code.includes("_gpu_fresnelC"))
59632
+ preamble += this.languageId === "wgsl" ? GPU_FRESNELC_PREAMBLE_WGSL : GPU_FRESNELC_PREAMBLE_GLSL;
59633
+ if (code.includes("_gpu_fresnelS"))
59634
+ preamble += this.languageId === "wgsl" ? GPU_FRESNELS_PREAMBLE_WGSL : GPU_FRESNELS_PREAMBLE_GLSL;
59635
+ if (code.includes("_gpu_besselJ"))
59636
+ preamble += this.languageId === "wgsl" ? GPU_BESSELJ_PREAMBLE_WGSL : GPU_BESSELJ_PREAMBLE_GLSL;
58305
59637
  if (code.includes("_fractal_")) {
58306
59638
  preamble += this.languageId === "wgsl" ? GPU_FRACTAL_PREAMBLE_WGSL : GPU_FRACTAL_PREAMBLE_GLSL;
58307
59639
  }
@@ -58350,6 +59682,12 @@ var GLSLTarget = class extends GPUShaderTarget {
58350
59682
  const target = this.createTarget();
58351
59683
  const body = BaseCompiler.compile(expr, target);
58352
59684
  const params = parameters.map(([name, type2]) => `${type2} ${name}`).join(", ");
59685
+ if (body.includes("\n")) {
59686
+ const indented = body.split("\n").map((l) => ` ${l}`).join("\n");
59687
+ return `${returnType} ${functionName}(${params}) {
59688
+ ${indented};
59689
+ }`;
59690
+ }
58353
59691
  return `${returnType} ${functionName}(${params}) {
58354
59692
  return ${body};
58355
59693
  }`;
@@ -58453,6 +59791,14 @@ var WGSLTarget = class extends GPUShaderTarget {
58453
59791
  const target = this.createTarget();
58454
59792
  const body = BaseCompiler.compile(expr, target);
58455
59793
  const params = parameters.map(([name, type2]) => `${name}: ${toWGSLType(type2)}`).join(", ");
59794
+ if (body.includes("\n")) {
59795
+ const indented = body.split("\n").map((l) => ` ${l}`).join("\n");
59796
+ return `fn ${functionName}(${params}) -> ${toWGSLType(
59797
+ returnType
59798
+ )} {
59799
+ ${indented};
59800
+ }`;
59801
+ }
58456
59802
  return `fn ${functionName}(${params}) -> ${toWGSLType(returnType)} {
58457
59803
  return ${body};
58458
59804
  }`;
@@ -59097,7 +60443,7 @@ function binomial2(n, k) {
59097
60443
  ];
59098
60444
  return ok({ lo: Math.min(...vals), hi: Math.max(...vals) });
59099
60445
  }
59100
- function gcd4(a, b) {
60446
+ function gcd5(a, b) {
59101
60447
  const uA = unwrapOrPropagate(a);
59102
60448
  if (!Array.isArray(uA)) return uA;
59103
60449
  const uB = unwrapOrPropagate(b);
@@ -59749,7 +61095,7 @@ var IntervalArithmetic = {
59749
61095
  factorial: factorial5,
59750
61096
  factorial2: factorial24,
59751
61097
  binomial: binomial2,
59752
- gcd: gcd4,
61098
+ gcd: gcd5,
59753
61099
  lcm: lcm4,
59754
61100
  chop: chop4,
59755
61101
  erf: erf2,
@@ -63528,6 +64874,11 @@ var _Parser = class __Parser {
63528
64874
  if (this.atEnd) return lhs;
63529
64875
  console.assert(lhs !== null);
63530
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
+ }
63531
64882
  this.skipSpace();
63532
64883
  const superscripts = [];
63533
64884
  const subscripts = [];
@@ -65632,9 +66983,9 @@ function TR12i(expr) {
65632
66983
  return ce._fn("Tan", [tanCArg]).neg();
65633
66984
  }
65634
66985
  function lcm5(a, b) {
65635
- return Math.abs(a * b) / gcd5(a, b);
66986
+ return Math.abs(a * b) / gcd6(a, b);
65636
66987
  }
65637
- function gcd5(a, b) {
66988
+ function gcd6(a, b) {
65638
66989
  a = Math.abs(a);
65639
66990
  b = Math.abs(b);
65640
66991
  while (b) {
@@ -67320,10 +68671,10 @@ var ComputeEngine = class _ComputeEngine {
67320
68671
  _setComputeEngineClass(ComputeEngine);
67321
68672
 
67322
68673
  // src/compute-engine.ts
67323
- var version = "0.53.0";
68674
+ var version = "0.54.0";
67324
68675
  globalThis[/* @__PURE__ */ Symbol.for("io.cortexjs.compute-engine")] = {
67325
68676
  ComputeEngine: ComputeEngine.prototype.constructor,
67326
- version: "0.53.0"
68677
+ version: "0.54.0"
67327
68678
  };
67328
68679
  export {
67329
68680
  BaseCompiler,