mathjs 10.1.1 → 10.4.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 (369) hide show
  1. package/HISTORY.md +43 -0
  2. package/docs/expressions/algebra.md +27 -0
  3. package/docs/expressions/syntax.md +31 -2
  4. package/docs/reference/functions/abs.md +6 -0
  5. package/docs/reference/functions/acos.md +6 -0
  6. package/docs/reference/functions/acosh.md +6 -0
  7. package/docs/reference/functions/acot.md +6 -0
  8. package/docs/reference/functions/acoth.md +6 -0
  9. package/docs/reference/functions/acsc.md +6 -0
  10. package/docs/reference/functions/acsch.md +6 -0
  11. package/docs/reference/functions/add.md +6 -0
  12. package/docs/reference/functions/and.md +6 -0
  13. package/docs/reference/functions/apply.md +6 -0
  14. package/docs/reference/functions/arg.md +6 -0
  15. package/docs/reference/functions/asec.md +6 -0
  16. package/docs/reference/functions/asech.md +6 -0
  17. package/docs/reference/functions/asin.md +6 -0
  18. package/docs/reference/functions/asinh.md +6 -0
  19. package/docs/reference/functions/atan.md +6 -0
  20. package/docs/reference/functions/atan2.md +6 -0
  21. package/docs/reference/functions/atanh.md +6 -0
  22. package/docs/reference/functions/bellNumbers.md +6 -0
  23. package/docs/reference/functions/bin.md +6 -0
  24. package/docs/reference/functions/bitAnd.md +6 -0
  25. package/docs/reference/functions/bitNot.md +6 -0
  26. package/docs/reference/functions/bitOr.md +6 -0
  27. package/docs/reference/functions/bitXor.md +6 -0
  28. package/docs/reference/functions/catalan.md +6 -0
  29. package/docs/reference/functions/cbrt.md +6 -0
  30. package/docs/reference/functions/ceil.md +6 -0
  31. package/docs/reference/functions/clone.md +6 -0
  32. package/docs/reference/functions/column.md +6 -0
  33. package/docs/reference/functions/combinations.md +6 -0
  34. package/docs/reference/functions/combinationsWithRep.md +6 -0
  35. package/docs/reference/functions/compare.md +6 -0
  36. package/docs/reference/functions/compareNatural.md +6 -0
  37. package/docs/reference/functions/compareText.md +6 -0
  38. package/docs/reference/functions/compile.md +6 -0
  39. package/docs/reference/functions/composition.md +6 -0
  40. package/docs/reference/functions/concat.md +6 -0
  41. package/docs/reference/functions/conj.md +6 -0
  42. package/docs/reference/functions/cos.md +6 -0
  43. package/docs/reference/functions/cosh.md +6 -0
  44. package/docs/reference/functions/cot.md +6 -0
  45. package/docs/reference/functions/coth.md +6 -0
  46. package/docs/reference/functions/count.md +6 -0
  47. package/docs/reference/functions/cross.md +6 -0
  48. package/docs/reference/functions/csc.md +6 -0
  49. package/docs/reference/functions/csch.md +6 -0
  50. package/docs/reference/functions/ctranspose.md +6 -0
  51. package/docs/reference/functions/cube.md +6 -0
  52. package/docs/reference/functions/cumsum.md +57 -0
  53. package/docs/reference/functions/deepEqual.md +6 -0
  54. package/docs/reference/functions/derivative.md +6 -0
  55. package/docs/reference/functions/det.md +6 -0
  56. package/docs/reference/functions/diag.md +6 -0
  57. package/docs/reference/functions/diff.md +6 -0
  58. package/docs/reference/functions/distance.md +6 -0
  59. package/docs/reference/functions/divide.md +6 -0
  60. package/docs/reference/functions/dot.md +6 -0
  61. package/docs/reference/functions/dotDivide.md +6 -0
  62. package/docs/reference/functions/dotMultiply.md +6 -0
  63. package/docs/reference/functions/dotPow.md +6 -0
  64. package/docs/reference/functions/eigs.md +6 -0
  65. package/docs/reference/functions/equal.md +6 -0
  66. package/docs/reference/functions/equalText.md +6 -0
  67. package/docs/reference/functions/erf.md +6 -0
  68. package/docs/reference/functions/evaluate.md +6 -0
  69. package/docs/reference/functions/exp.md +6 -0
  70. package/docs/reference/functions/expm.md +6 -0
  71. package/docs/reference/functions/expm1.md +6 -0
  72. package/docs/reference/functions/factorial.md +6 -0
  73. package/docs/reference/functions/filter.md +6 -0
  74. package/docs/reference/functions/fix.md +6 -0
  75. package/docs/reference/functions/flatten.md +6 -0
  76. package/docs/reference/functions/floor.md +6 -0
  77. package/docs/reference/functions/forEach.md +6 -0
  78. package/docs/reference/functions/format.md +7 -1
  79. package/docs/reference/functions/gamma.md +6 -0
  80. package/docs/reference/functions/gcd.md +6 -0
  81. package/docs/reference/functions/getMatrixDataType.md +6 -0
  82. package/docs/reference/functions/hasNumericValue.md +6 -0
  83. package/docs/reference/functions/help.md +6 -0
  84. package/docs/reference/functions/hex.md +6 -0
  85. package/docs/reference/functions/hypot.md +6 -0
  86. package/docs/reference/functions/identity.md +6 -0
  87. package/docs/reference/functions/im.md +6 -0
  88. package/docs/reference/functions/intersect.md +6 -0
  89. package/docs/reference/functions/inv.md +6 -0
  90. package/docs/reference/functions/invmod.md +6 -0
  91. package/docs/reference/functions/isInteger.md +6 -0
  92. package/docs/reference/functions/isNaN.md +6 -0
  93. package/docs/reference/functions/isNegative.md +6 -0
  94. package/docs/reference/functions/isNumeric.md +6 -0
  95. package/docs/reference/functions/isPositive.md +6 -0
  96. package/docs/reference/functions/isPrime.md +6 -0
  97. package/docs/reference/functions/isZero.md +6 -0
  98. package/docs/reference/functions/kldivergence.md +6 -0
  99. package/docs/reference/functions/kron.md +6 -0
  100. package/docs/reference/functions/larger.md +6 -0
  101. package/docs/reference/functions/largerEq.md +6 -0
  102. package/docs/reference/functions/lcm.md +6 -0
  103. package/docs/reference/functions/leafCount.md +52 -0
  104. package/docs/reference/functions/leftShift.md +6 -0
  105. package/docs/reference/functions/log.md +6 -0
  106. package/docs/reference/functions/log10.md +6 -0
  107. package/docs/reference/functions/log1p.md +6 -0
  108. package/docs/reference/functions/log2.md +6 -0
  109. package/docs/reference/functions/lsolve.md +6 -0
  110. package/docs/reference/functions/lsolveAll.md +6 -0
  111. package/docs/reference/functions/lup.md +6 -0
  112. package/docs/reference/functions/lusolve.md +6 -0
  113. package/docs/reference/functions/mad.md +6 -0
  114. package/docs/reference/functions/map.md +28 -5
  115. package/docs/reference/functions/matrixFromColumns.md +6 -0
  116. package/docs/reference/functions/matrixFromFunction.md +6 -0
  117. package/docs/reference/functions/matrixFromRows.md +6 -0
  118. package/docs/reference/functions/max.md +6 -0
  119. package/docs/reference/functions/mean.md +6 -0
  120. package/docs/reference/functions/median.md +6 -0
  121. package/docs/reference/functions/min.md +6 -0
  122. package/docs/reference/functions/mod.md +6 -0
  123. package/docs/reference/functions/mode.md +6 -0
  124. package/docs/reference/functions/multinomial.md +6 -0
  125. package/docs/reference/functions/multiply.md +6 -0
  126. package/docs/reference/functions/norm.md +6 -0
  127. package/docs/reference/functions/not.md +6 -0
  128. package/docs/reference/functions/nthRoot.md +6 -0
  129. package/docs/reference/functions/nthRoots.md +6 -0
  130. package/docs/reference/functions/numeric.md +6 -0
  131. package/docs/reference/functions/oct.md +6 -0
  132. package/docs/reference/functions/ones.md +6 -0
  133. package/docs/reference/functions/or.md +6 -0
  134. package/docs/reference/functions/parser.md +6 -0
  135. package/docs/reference/functions/partitionSelect.md +6 -0
  136. package/docs/reference/functions/permutations.md +6 -0
  137. package/docs/reference/functions/pickRandom.md +6 -0
  138. package/docs/reference/functions/pow.md +6 -0
  139. package/docs/reference/functions/print.md +6 -0
  140. package/docs/reference/functions/prod.md +6 -0
  141. package/docs/reference/functions/qr.md +6 -0
  142. package/docs/reference/functions/quantileSeq.md +6 -0
  143. package/docs/reference/functions/random.md +6 -0
  144. package/docs/reference/functions/randomInt.md +6 -0
  145. package/docs/reference/functions/range.md +6 -0
  146. package/docs/reference/functions/rationalize.md +7 -1
  147. package/docs/reference/functions/re.md +6 -0
  148. package/docs/reference/functions/reshape.md +7 -0
  149. package/docs/reference/functions/resize.md +6 -0
  150. package/docs/reference/functions/resolve.md +46 -0
  151. package/docs/reference/functions/rightArithShift.md +6 -0
  152. package/docs/reference/functions/rightLogShift.md +6 -0
  153. package/docs/reference/functions/rotate.md +6 -0
  154. package/docs/reference/functions/rotationMatrix.md +6 -0
  155. package/docs/reference/functions/round.md +6 -0
  156. package/docs/reference/functions/row.md +6 -0
  157. package/docs/reference/functions/sec.md +6 -0
  158. package/docs/reference/functions/sech.md +6 -0
  159. package/docs/reference/functions/setCartesian.md +6 -0
  160. package/docs/reference/functions/setDifference.md +6 -0
  161. package/docs/reference/functions/setDistinct.md +6 -0
  162. package/docs/reference/functions/setIntersect.md +6 -0
  163. package/docs/reference/functions/setIsSubset.md +6 -0
  164. package/docs/reference/functions/setMultiplicity.md +6 -0
  165. package/docs/reference/functions/setPowerset.md +6 -0
  166. package/docs/reference/functions/setSize.md +6 -0
  167. package/docs/reference/functions/setSymDifference.md +6 -0
  168. package/docs/reference/functions/setUnion.md +6 -0
  169. package/docs/reference/functions/sign.md +6 -0
  170. package/docs/reference/functions/simplify.md +43 -6
  171. package/docs/reference/functions/simplifyCore.md +50 -0
  172. package/docs/reference/functions/sin.md +6 -0
  173. package/docs/reference/functions/sinh.md +6 -0
  174. package/docs/reference/functions/size.md +6 -0
  175. package/docs/reference/functions/slu.md +6 -0
  176. package/docs/reference/functions/smaller.md +6 -0
  177. package/docs/reference/functions/smallerEq.md +6 -0
  178. package/docs/reference/functions/sort.md +6 -0
  179. package/docs/reference/functions/sqrt.md +6 -0
  180. package/docs/reference/functions/sqrtm.md +6 -0
  181. package/docs/reference/functions/square.md +6 -0
  182. package/docs/reference/functions/squeeze.md +6 -0
  183. package/docs/reference/functions/std.md +6 -0
  184. package/docs/reference/functions/stirlingS2.md +6 -0
  185. package/docs/reference/functions/subset.md +16 -2
  186. package/docs/reference/functions/subtract.md +6 -0
  187. package/docs/reference/functions/sum.md +8 -1
  188. package/docs/reference/functions/symbolicEqual.md +62 -0
  189. package/docs/reference/functions/tan.md +6 -0
  190. package/docs/reference/functions/tanh.md +6 -0
  191. package/docs/reference/functions/to.md +6 -0
  192. package/docs/reference/functions/trace.md +6 -0
  193. package/docs/reference/functions/transpose.md +6 -0
  194. package/docs/reference/functions/typeOf.md +6 -0
  195. package/docs/reference/functions/unaryMinus.md +6 -0
  196. package/docs/reference/functions/unaryPlus.md +6 -0
  197. package/docs/reference/functions/unequal.md +6 -0
  198. package/docs/reference/functions/usolve.md +6 -0
  199. package/docs/reference/functions/usolveAll.md +6 -0
  200. package/docs/reference/functions/variance.md +6 -0
  201. package/docs/reference/functions/xgcd.md +6 -0
  202. package/docs/reference/functions/xor.md +6 -0
  203. package/docs/reference/functions/zeros.md +6 -0
  204. package/docs/reference/functions.md +6 -1
  205. package/lib/browser/math.js +6 -6
  206. package/lib/browser/math.js.map +1 -1
  207. package/lib/cjs/core/create.js +4 -4
  208. package/lib/cjs/core/function/import.js +3 -3
  209. package/lib/cjs/core/function/typed.js +2 -2
  210. package/lib/cjs/defaultInstance.js +3 -3
  211. package/lib/cjs/entry/allFactoriesAny.js +1 -1
  212. package/lib/cjs/entry/allFactoriesNumber.js +1 -1
  213. package/lib/cjs/entry/configReadonly.js +1 -1
  214. package/lib/cjs/entry/dependenciesAny/dependenciesCumSum.generated.js +26 -0
  215. package/lib/cjs/entry/dependenciesAny/dependenciesCumSumTransform.generated.js +26 -0
  216. package/lib/cjs/entry/dependenciesAny/dependenciesLeafCount.generated.js +23 -0
  217. package/lib/cjs/entry/dependenciesAny/dependenciesRationalize.generated.js +3 -0
  218. package/lib/cjs/entry/dependenciesAny/dependenciesResolve.generated.js +32 -0
  219. package/lib/cjs/entry/dependenciesAny/dependenciesSimplify.generated.js +6 -0
  220. package/lib/cjs/entry/dependenciesAny/dependenciesSimplifyCore.generated.js +65 -0
  221. package/lib/cjs/entry/dependenciesAny/dependenciesSymbolicEqual.generated.js +29 -0
  222. package/lib/cjs/entry/dependenciesAny.generated.js +48 -0
  223. package/lib/cjs/entry/dependenciesNumber/dependenciesCumSum.generated.js +26 -0
  224. package/lib/cjs/entry/dependenciesNumber/dependenciesCumSumTransform.generated.js +26 -0
  225. package/lib/cjs/entry/dependenciesNumber/dependenciesRationalize.generated.js +3 -0
  226. package/lib/cjs/entry/dependenciesNumber/dependenciesResolve.generated.js +32 -0
  227. package/lib/cjs/entry/dependenciesNumber/dependenciesSimplify.generated.js +6 -0
  228. package/lib/cjs/entry/dependenciesNumber/dependenciesSimplifyCore.generated.js +65 -0
  229. package/lib/cjs/entry/dependenciesNumber.generated.js +32 -0
  230. package/lib/cjs/entry/impureFunctionsAny.generated.js +85 -33
  231. package/lib/cjs/entry/impureFunctionsNumber.generated.js +102 -64
  232. package/lib/cjs/entry/pureFunctionsAny.generated.js +68 -64
  233. package/lib/cjs/entry/pureFunctionsNumber.generated.js +51 -47
  234. package/lib/cjs/expression/Help.js +4 -0
  235. package/lib/cjs/expression/Parser.js +1 -1
  236. package/lib/cjs/expression/embeddedDocs/construction/fraction.js +3 -3
  237. package/lib/cjs/expression/embeddedDocs/core/typed.js +1 -1
  238. package/lib/cjs/expression/embeddedDocs/embeddedDocs.js +250 -235
  239. package/lib/cjs/expression/embeddedDocs/function/algebra/leafCount.js +15 -0
  240. package/lib/cjs/expression/embeddedDocs/function/algebra/resolve.js +16 -0
  241. package/lib/cjs/expression/embeddedDocs/function/algebra/simplify.js +1 -1
  242. package/lib/cjs/expression/embeddedDocs/function/algebra/simplifyCore.js +15 -0
  243. package/lib/cjs/expression/embeddedDocs/function/algebra/symbolicEqual.js +15 -0
  244. package/lib/cjs/expression/embeddedDocs/function/matrix/subset.js +2 -2
  245. package/lib/cjs/expression/embeddedDocs/function/statistics/cumsum.js +15 -0
  246. package/lib/cjs/expression/node/FunctionNode.js +80 -61
  247. package/lib/cjs/expression/node/IndexNode.js +1 -1
  248. package/lib/cjs/expression/node/Node.js +3 -3
  249. package/lib/cjs/expression/node/ObjectNode.js +1 -1
  250. package/lib/cjs/expression/node/utils/access.js +1 -1
  251. package/lib/cjs/expression/node/utils/assign.js +1 -1
  252. package/lib/cjs/expression/parse.js +13 -13
  253. package/lib/cjs/expression/transform/cumsum.transform.js +57 -0
  254. package/lib/cjs/expression/transform/sum.transform.js +1 -1
  255. package/lib/cjs/factoriesAny.js +48 -0
  256. package/lib/cjs/factoriesNumber.js +33 -1
  257. package/lib/cjs/function/algebra/decomposition/qr.js +1 -1
  258. package/lib/cjs/function/algebra/leafCount.js +66 -0
  259. package/lib/cjs/function/algebra/rationalize.js +24 -41
  260. package/lib/cjs/function/algebra/resolve.js +106 -0
  261. package/lib/cjs/function/algebra/simplify/simplifyConstant.js +5 -5
  262. package/lib/cjs/function/algebra/simplify/util.js +171 -33
  263. package/lib/cjs/function/algebra/simplify.js +562 -207
  264. package/lib/cjs/function/algebra/{simplify/simplifyCore.js → simplifyCore.js} +68 -44
  265. package/lib/cjs/function/algebra/solver/lsolveAll.js +2 -2
  266. package/lib/cjs/function/algebra/solver/usolveAll.js +2 -2
  267. package/lib/cjs/function/algebra/symbolicEqual.js +88 -0
  268. package/lib/cjs/function/arithmetic/ceil.js +3 -3
  269. package/lib/cjs/function/arithmetic/floor.js +3 -3
  270. package/lib/cjs/function/arithmetic/invmod.js +1 -1
  271. package/lib/cjs/function/arithmetic/norm.js +1 -1
  272. package/lib/cjs/function/arithmetic/round.js +1 -1
  273. package/lib/cjs/function/matrix/eigs/complexEigs.js +13 -11
  274. package/lib/cjs/function/matrix/map.js +53 -15
  275. package/lib/cjs/function/matrix/matrixFromColumns.js +1 -1
  276. package/lib/cjs/function/matrix/matrixFromRows.js +1 -1
  277. package/lib/cjs/function/matrix/subset.js +15 -5
  278. package/lib/cjs/function/probability/util/seededRNG.js +2 -2
  279. package/lib/cjs/function/relational/compareNatural.js +6 -6
  280. package/lib/cjs/function/statistics/cumsum.js +151 -0
  281. package/lib/cjs/function/statistics/sum.js +1 -1
  282. package/lib/cjs/function/string/format.js +1 -1
  283. package/lib/cjs/header.js +2 -2
  284. package/lib/cjs/plain/bignumber/index.js +1 -1
  285. package/lib/cjs/plain/number/combinations.js +18 -6
  286. package/lib/cjs/type/bignumber/BigNumber.js +2 -2
  287. package/lib/cjs/type/bignumber/function/bignumber.js +1 -1
  288. package/lib/cjs/type/boolean.js +2 -2
  289. package/lib/cjs/type/complex/Complex.js +14 -14
  290. package/lib/cjs/type/complex/function/complex.js +1 -1
  291. package/lib/cjs/type/fraction/Fraction.js +6 -6
  292. package/lib/cjs/type/fraction/function/fraction.js +21 -9
  293. package/lib/cjs/type/matrix/DenseMatrix.js +5 -5
  294. package/lib/cjs/type/matrix/SparseMatrix.js +2 -2
  295. package/lib/cjs/type/number.js +1 -1
  296. package/lib/cjs/type/string.js +2 -2
  297. package/lib/cjs/type/unit/Unit.js +8 -8
  298. package/lib/cjs/utils/collection.js +3 -27
  299. package/lib/cjs/utils/customs.js +2 -2
  300. package/lib/cjs/utils/emitter.js +1 -1
  301. package/lib/cjs/utils/function.js +2 -2
  302. package/lib/cjs/utils/is.js +6 -6
  303. package/lib/cjs/utils/latex.js +3 -3
  304. package/lib/cjs/utils/lruQueue.js +1 -1
  305. package/lib/cjs/utils/map.js +3 -3
  306. package/lib/cjs/utils/object.js +2 -2
  307. package/lib/cjs/utils/snapshot.js +7 -7
  308. package/lib/cjs/utils/string.js +2 -2
  309. package/lib/cjs/utils/switch.js +31 -0
  310. package/lib/cjs/version.js +1 -1
  311. package/lib/esm/entry/dependenciesAny/dependenciesCumSum.generated.js +14 -0
  312. package/lib/esm/entry/dependenciesAny/dependenciesCumSumTransform.generated.js +14 -0
  313. package/lib/esm/entry/dependenciesAny/dependenciesLeafCount.generated.js +12 -0
  314. package/lib/esm/entry/dependenciesAny/dependenciesRationalize.generated.js +2 -0
  315. package/lib/esm/entry/dependenciesAny/dependenciesResolve.generated.js +18 -0
  316. package/lib/esm/entry/dependenciesAny/dependenciesSimplify.generated.js +4 -0
  317. package/lib/esm/entry/dependenciesAny/dependenciesSimplifyCore.generated.js +40 -0
  318. package/lib/esm/entry/dependenciesAny/dependenciesSymbolicEqual.generated.js +16 -0
  319. package/lib/esm/entry/dependenciesAny.generated.js +6 -0
  320. package/lib/esm/entry/dependenciesNumber/dependenciesCumSum.generated.js +14 -0
  321. package/lib/esm/entry/dependenciesNumber/dependenciesCumSumTransform.generated.js +14 -0
  322. package/lib/esm/entry/dependenciesNumber/dependenciesRationalize.generated.js +2 -0
  323. package/lib/esm/entry/dependenciesNumber/dependenciesResolve.generated.js +18 -0
  324. package/lib/esm/entry/dependenciesNumber/dependenciesSimplify.generated.js +4 -0
  325. package/lib/esm/entry/dependenciesNumber/dependenciesSimplifyCore.generated.js +40 -0
  326. package/lib/esm/entry/dependenciesNumber.generated.js +4 -0
  327. package/lib/esm/entry/impureFunctionsAny.generated.js +74 -26
  328. package/lib/esm/entry/impureFunctionsNumber.generated.js +89 -53
  329. package/lib/esm/entry/pureFunctionsAny.generated.js +54 -49
  330. package/lib/esm/entry/pureFunctionsNumber.generated.js +36 -31
  331. package/lib/esm/expression/Help.js +4 -0
  332. package/lib/esm/expression/embeddedDocs/construction/fraction.js +3 -3
  333. package/lib/esm/expression/embeddedDocs/core/typed.js +1 -1
  334. package/lib/esm/expression/embeddedDocs/embeddedDocs.js +222 -212
  335. package/lib/esm/expression/embeddedDocs/function/algebra/leafCount.js +8 -0
  336. package/lib/esm/expression/embeddedDocs/function/algebra/resolve.js +9 -0
  337. package/lib/esm/expression/embeddedDocs/function/algebra/simplify.js +1 -1
  338. package/lib/esm/expression/embeddedDocs/function/algebra/simplifyCore.js +8 -0
  339. package/lib/esm/expression/embeddedDocs/function/algebra/symbolicEqual.js +8 -0
  340. package/lib/esm/expression/embeddedDocs/function/matrix/subset.js +2 -2
  341. package/lib/esm/expression/embeddedDocs/function/statistics/cumsum.js +8 -0
  342. package/lib/esm/expression/node/FunctionNode.js +70 -53
  343. package/lib/esm/expression/transform/cumsum.transform.js +48 -0
  344. package/lib/esm/expression/transform/sum.transform.js +1 -1
  345. package/lib/esm/factoriesAny.js +6 -0
  346. package/lib/esm/factoriesNumber.js +4 -0
  347. package/lib/esm/function/algebra/leafCount.js +59 -0
  348. package/lib/esm/function/algebra/rationalize.js +24 -40
  349. package/lib/esm/function/algebra/resolve.js +95 -0
  350. package/lib/esm/function/algebra/simplify/simplifyConstant.js +3 -3
  351. package/lib/esm/function/algebra/simplify/util.js +170 -34
  352. package/lib/esm/function/algebra/simplify.js +557 -202
  353. package/lib/esm/function/algebra/{simplify/simplifyCore.js → simplifyCore.js} +61 -45
  354. package/lib/esm/function/algebra/symbolicEqual.js +80 -0
  355. package/lib/esm/function/matrix/eigs/complexEigs.js +8 -6
  356. package/lib/esm/function/matrix/map.js +53 -15
  357. package/lib/esm/function/matrix/subset.js +15 -5
  358. package/lib/esm/function/statistics/cumsum.js +139 -0
  359. package/lib/esm/function/statistics/sum.js +1 -1
  360. package/lib/esm/function/string/format.js +1 -1
  361. package/lib/esm/plain/number/combinations.js +18 -6
  362. package/lib/esm/type/fraction/function/fraction.js +20 -8
  363. package/lib/esm/utils/collection.js +1 -26
  364. package/lib/esm/utils/switch.js +24 -0
  365. package/lib/esm/version.js +1 -1
  366. package/package.json +15 -10
  367. package/types/index.d.ts +155 -13
  368. package/lib/cjs/function/algebra/simplify/resolve.js +0 -76
  369. package/lib/esm/function/algebra/simplify/resolve.js +0 -67
@@ -1,13 +1,11 @@
1
1
  import { isConstantNode, isParenthesisNode } from '../../utils/is.js';
2
2
  import { factory } from '../../utils/factory.js';
3
3
  import { createUtil } from './simplify/util.js';
4
- import { createSimplifyCore } from './simplify/simplifyCore.js';
5
4
  import { createSimplifyConstant } from './simplify/simplifyConstant.js';
6
- import { createResolve } from './simplify/resolve.js';
7
5
  import { hasOwnProperty } from '../../utils/object.js';
8
6
  import { createEmptyMap, createMap } from '../../utils/map.js';
9
7
  var name = 'simplify';
10
- var dependencies = ['config', 'typed', 'parse', 'add', 'subtract', 'multiply', 'divide', 'pow', 'isZero', 'equal', '?fraction', '?bignumber', 'mathWithTransform', 'matrix', 'AccessorNode', 'ArrayNode', 'ConstantNode', 'FunctionNode', 'IndexNode', 'ObjectNode', 'OperatorNode', 'ParenthesisNode', 'SymbolNode'];
8
+ var dependencies = ['config', 'typed', 'parse', 'add', 'subtract', 'multiply', 'divide', 'pow', 'isZero', 'equal', 'resolve', 'simplifyCore', '?fraction', '?bignumber', 'mathWithTransform', 'matrix', 'AccessorNode', 'ArrayNode', 'ConstantNode', 'FunctionNode', 'IndexNode', 'ObjectNode', 'OperatorNode', 'ParenthesisNode', 'SymbolNode'];
11
9
  export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
12
10
  var {
13
11
  config,
@@ -20,6 +18,8 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
20
18
  pow,
21
19
  isZero,
22
20
  equal,
21
+ resolve,
22
+ simplifyCore,
23
23
  fraction,
24
24
  bignumber,
25
25
  mathWithTransform,
@@ -50,36 +50,18 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
50
50
  OperatorNode,
51
51
  SymbolNode
52
52
  });
53
- var simplifyCore = createSimplifyCore({
54
- equal,
55
- isZero,
56
- add,
57
- subtract,
58
- multiply,
59
- divide,
60
- pow,
61
- AccessorNode,
62
- ArrayNode,
63
- ConstantNode,
64
- FunctionNode,
65
- IndexNode,
66
- ObjectNode,
67
- OperatorNode,
68
- ParenthesisNode
69
- });
70
- var resolve = createResolve({
71
- parse,
72
- FunctionNode,
73
- OperatorNode,
74
- ParenthesisNode
75
- });
76
53
  var {
54
+ hasProperty,
77
55
  isCommutative,
78
56
  isAssociative,
57
+ mergeContext,
79
58
  flatten,
80
59
  unflattenr,
81
60
  unflattenl,
82
- createMakeNodeFunction
61
+ createMakeNodeFunction,
62
+ defaultContext,
63
+ realContext,
64
+ positiveContext
83
65
  } = createUtil({
84
66
  FunctionNode,
85
67
  OperatorNode,
@@ -115,6 +97,19 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
115
97
  * The default list of rules is exposed on the function as `simplify.rules`
116
98
  * and can be used as a basis to built a set of custom rules.
117
99
  *
100
+ * To specify a rule as a string, separate the left and right pattern by '->'
101
+ * When specifying a rule as an object, the following keys are meaningful:
102
+ * - l - the left pattern
103
+ * - r - the right pattern
104
+ * - s - in lieu of l and r, the string form that is broken at -> to give them
105
+ * - repeat - whether to repeat this rule until the expression stabilizes
106
+ * - assuming - gives a context object, as in the 'context' option to
107
+ * simplify. Every property in the context object must match the current
108
+ * context in order, or else the rule will not be applied.
109
+ * - imposeContext - gives a context object, as in the 'context' option to
110
+ * simplify. Any settings specified will override the incoming context
111
+ * for all matches of this rule.
112
+ *
118
113
  * For more details on the theory, see:
119
114
  *
120
115
  * - [Strategies for simplifying math expressions (Stackoverflow)](https://stackoverflow.com/questions/7540227/strategies-for-simplifying-math-expressions)
@@ -123,12 +118,28 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
123
118
  * An optional `options` argument can be passed as last argument of `simplify`.
124
119
  * Currently available options (defaults in parentheses):
125
120
  * - `consoleDebug` (false): whether to write the expression being simplified
126
- and any changes to it, along with the rule responsible, to console
121
+ * and any changes to it, along with the rule responsible, to console
122
+ * - `context` (simplify.defaultContext): an object giving properties of
123
+ * each operator, which determine what simplifications are allowed. The
124
+ * currently meaningful properties are commutative, associative,
125
+ * total (whether the operation is defined for all arguments), and
126
+ * trivial (whether the operation applied to a single argument leaves
127
+ * that argument unchanged). The default context is very permissive and
128
+ * allows almost all simplifications. Only properties differing from
129
+ * the default need to be specified; the default context is used as a
130
+ * fallback. Additional contexts `simplify.realContext` and
131
+ * `simplify.positiveContext` are supplied to cause simplify to perform
132
+ * just simplifications guaranteed to preserve all values of the expression
133
+ * assuming all variables and subexpressions are real numbers or
134
+ * positive real numbers, respectively. (Note that these are in some cases
135
+ * more restrictive than the default context; for example, the default
136
+ * context will allow `x/x` to simplify to 1, whereas
137
+ * `simplify.realContext` will not, as `0/0` is not equal to 1.)
127
138
  * - `exactFractions` (true): whether to try to convert all constants to
128
- exact rational numbers.
139
+ * exact rational numbers.
129
140
  * - `fractionsLimit` (10000): when `exactFractions` is true, constants will
130
- be expressed as fractions only when both numerator and denominator
131
- are smaller than `fractionsLimit`.
141
+ * be expressed as fractions only when both numerator and denominator
142
+ * are smaller than `fractionsLimit`.
132
143
  *
133
144
  * Syntax:
134
145
  *
@@ -151,7 +162,7 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
151
162
  *
152
163
  * See also:
153
164
  *
154
- * derivative, parse, evaluate, rationalize
165
+ * simplifyCore, derivative, evaluate, parse, rationalize, resolve
155
166
  *
156
167
  * @param {Node | string} expr
157
168
  * The expression to be simplified
@@ -199,7 +210,7 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
199
210
  },
200
211
  'Node, Array, Map, Object': function NodeArrayMapObject(expr, rules, scope, options) {
201
212
  var debug = options.consoleDebug;
202
- rules = _buildRules(rules);
213
+ rules = _buildRules(rules, options.context);
203
214
  var res = resolve(expr, scope);
204
215
  res = removeParens(res);
205
216
  var visited = {};
@@ -221,8 +232,8 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
221
232
  res = rules[i](res, options);
222
233
  if (debug) rulestr = rules[i].name;
223
234
  } else {
224
- flatten(res);
225
- res = applyRule(res, rules[i]);
235
+ flatten(res, options.context);
236
+ res = applyRule(res, rules[i], options.context);
226
237
 
227
238
  if (debug) {
228
239
  rulestr = "".concat(rules[i].l.toString(), " -> ").concat(rules[i].r.toString());
@@ -239,8 +250,12 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
239
250
  laststr = newstr;
240
251
  }
241
252
  }
253
+ /* Use left-heavy binary tree internally,
254
+ * since custom rule functions may expect it
255
+ */
242
256
 
243
- unflattenl(res); // using left-heavy binary tree here since custom rule functions may expect it
257
+
258
+ unflattenl(res, options.context);
244
259
  }
245
260
 
246
261
  str = res.toString({
@@ -251,8 +266,9 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
251
266
  return res;
252
267
  }
253
268
  });
254
- simplify.simplifyCore = simplifyCore;
255
- simplify.resolve = resolve;
269
+ simplify.defaultContext = defaultContext;
270
+ simplify.realContext = realContext;
271
+ simplify.positiveContext = positiveContext;
256
272
 
257
273
  function removeParens(node) {
258
274
  return node.transform(function (node, path, parent) {
@@ -304,41 +320,155 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
304
320
  // Note initially we tend constants to the right because like-term
305
321
  // collection prefers the left, and we would rather collect nonconstants
306
322
  {
307
- l: 'n-n1',
308
- r: 'n+-n1'
309
- }, // temporarily replace 'subtract' so we can further flatten the 'add' operator
310
- {
311
- l: '-(c*v)',
312
- r: 'v * (-c)'
313
- }, // make non-constant terms positive
314
- {
323
+ s: 'n-n1 -> n+-n1',
324
+ // temporarily replace 'subtract' so we can further flatten the 'add' operator
325
+ assuming: {
326
+ subtract: {
327
+ total: true
328
+ }
329
+ }
330
+ }, {
331
+ s: 'n-n -> 0',
332
+ // partial alternative when we can't always subtract
333
+ assuming: {
334
+ subtract: {
335
+ total: false
336
+ }
337
+ }
338
+ }, {
339
+ s: '-(c*v) -> v * (-c)',
340
+ // make non-constant terms positive
341
+ assuming: {
342
+ multiply: {
343
+ commutative: true
344
+ },
345
+ subtract: {
346
+ total: true
347
+ }
348
+ }
349
+ }, {
350
+ s: '-(c*v) -> (-c) * v',
351
+ // non-commutative version, part 1
352
+ assuming: {
353
+ multiply: {
354
+ commutative: false
355
+ },
356
+ subtract: {
357
+ total: true
358
+ }
359
+ }
360
+ }, {
361
+ s: '-(v*c) -> v * (-c)',
362
+ // non-commutative version, part 2
363
+ assuming: {
364
+ multiply: {
365
+ commutative: false
366
+ },
367
+ subtract: {
368
+ total: true
369
+ }
370
+ }
371
+ }, {
372
+ l: '-(n1/n2)',
373
+ r: '-n1/n2'
374
+ }, {
315
375
  l: '-v',
316
376
  r: 'v * (-1)'
317
- }, {
377
+ }, // finish making non-constant terms positive
378
+ {
379
+ l: '(n1 + n2)*(-1)',
380
+ r: 'n1*(-1) + n2*(-1)',
381
+ repeat: true
382
+ }, // expand negations to achieve as much sign cancellation as possible
383
+ {
318
384
  l: 'n/n1^n2',
319
385
  r: 'n*n1^-n2'
320
386
  }, // temporarily replace 'divide' so we can further flatten the 'multiply' operator
321
387
  {
322
388
  l: 'n/n1',
323
389
  r: 'n*n1^-1'
324
- }, simplifyConstant, // expand nested exponentiation
390
+ }, {
391
+ s: '(n1*n2)^n3 -> n1^n3 * n2^n3',
392
+ assuming: {
393
+ multiply: {
394
+ commutative: true
395
+ }
396
+ }
397
+ }, {
398
+ s: '(n1*n2)^(-1) -> n2^(-1) * n1^(-1)',
399
+ assuming: {
400
+ multiply: {
401
+ commutative: false
402
+ }
403
+ }
404
+ }, // expand nested exponentiation
325
405
  {
326
- l: '(n ^ n1) ^ n2',
327
- r: 'n ^ (n1 * n2)'
328
- }, // collect like factors
406
+ s: '(n ^ n1) ^ n2 -> n ^ (n1 * n2)',
407
+ assuming: {
408
+ divide: {
409
+ total: true
410
+ }
411
+ } // 1/(1/n) = n needs 1/n to exist
412
+
413
+ }, // collect like factors; into a sum, only do this for nonconstants
329
414
  {
415
+ l: ' v * ( v * n1 + n2)',
416
+ r: 'v^2 * n1 + v * n2'
417
+ }, {
418
+ s: ' v * (v^n4 * n1 + n2) -> v^(1+n4) * n1 + v * n2',
419
+ assuming: {
420
+ divide: {
421
+ total: true
422
+ }
423
+ } // v*1/v = v^(1+-1) needs 1/v
424
+
425
+ }, {
426
+ s: 'v^n3 * ( v * n1 + n2) -> v^(n3+1) * n1 + v^n3 * n2',
427
+ assuming: {
428
+ divide: {
429
+ total: true
430
+ }
431
+ }
432
+ }, {
433
+ s: 'v^n3 * (v^n4 * n1 + n2) -> v^(n3+n4) * n1 + v^n3 * n2',
434
+ assuming: {
435
+ divide: {
436
+ total: true
437
+ }
438
+ }
439
+ }, {
330
440
  l: 'n*n',
331
441
  r: 'n^2'
332
442
  }, {
333
- l: 'n * n^n1',
334
- r: 'n^(n1+1)'
443
+ s: 'n * n^n1 -> n^(n1+1)',
444
+ assuming: {
445
+ divide: {
446
+ total: true
447
+ }
448
+ } // n*1/n = n^(-1+1) needs 1/n
449
+
335
450
  }, {
336
- l: 'n^n1 * n^n2',
337
- r: 'n^(n1+n2)'
338
- }, // collect like terms
451
+ s: 'n^n1 * n^n2 -> n^(n1+n2)',
452
+ assuming: {
453
+ divide: {
454
+ total: true
455
+ }
456
+ } // ditto for n^2*1/n^2
457
+
458
+ }, // Unfortunately, to deal with more complicated cancellations, it
459
+ // becomes necessary to simplify constants twice per pass. It's not
460
+ // terribly expensive compared to matching rules, so this should not
461
+ // pose a performance problem.
462
+ simplifyConstant, // First: before collecting like terms
463
+ // collect like terms
339
464
  {
340
- l: 'n+n',
341
- r: '2*n'
465
+ s: 'n+n -> 2*n',
466
+ assuming: {
467
+ add: {
468
+ total: true
469
+ }
470
+ } // 2 = 1 + 1 needs to exist
471
+
342
472
  }, {
343
473
  l: 'n+-n',
344
474
  r: '0'
@@ -351,33 +481,91 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
351
481
  r: 'n3*(n1+n2)'
352
482
  }, // All sub-monomials tried there.
353
483
  {
484
+ l: 'n3^(-n4)*n1 + n3 * n2',
485
+ r: 'n3^(-n4)*(n1 + n3^(n4+1) *n2)'
486
+ }, {
487
+ l: 'n3^(-n4)*n1 + n3^n5 * n2',
488
+ r: 'n3^(-n4)*(n1 + n3^(n4+n5)*n2)'
489
+ }, {
490
+ s: 'n*v + v -> (n+1)*v',
491
+ // noncommutative additional cases
492
+ assuming: {
493
+ multiply: {
494
+ commutative: false
495
+ }
496
+ }
497
+ }, {
498
+ s: 'n1*n3 + n2*n3 -> (n1+n2)*n3',
499
+ assuming: {
500
+ multiply: {
501
+ commutative: false
502
+ }
503
+ }
504
+ }, {
505
+ s: 'n1*n3^(-n4) + n2 * n3 -> (n1 + n2*n3^(n4 + 1))*n3^(-n4)',
506
+ assuming: {
507
+ multiply: {
508
+ commutative: false
509
+ }
510
+ }
511
+ }, {
512
+ s: 'n1*n3^(-n4) + n2 * n3^n5 -> (n1 + n2*n3^(n4 + n5))*n3^(-n4)',
513
+ assuming: {
514
+ multiply: {
515
+ commutative: false
516
+ }
517
+ }
518
+ }, {
354
519
  l: 'n*c + c',
355
520
  r: '(n+1)*c'
356
- }, // remove parenthesis in the case of negating a quantity
357
- // (It might seem this rule should precede collecting like terms,
358
- // but putting it after gives another chance of noticing like terms,
359
- // and any new like terms produced by this will be collected
360
- // on the next pass through all the rules.)
361
- {
362
- l: 'n1 + (n2 + n3)*(-1)',
363
- r: 'n1 + n2*(-1) + n3*(-1)'
364
- }, // make factors positive (and undo 'make non-constant terms positive')
521
+ }, {
522
+ s: 'c*n + c -> c*(n+1)',
523
+ assuming: {
524
+ multiply: {
525
+ commutative: false
526
+ }
527
+ }
528
+ }, simplifyConstant, // Second: before returning expressions to "standard form"
529
+ // make factors positive (and undo 'make non-constant terms positive')
365
530
  {
366
- l: '(-n)*n1',
367
- r: '-(n*n1)'
531
+ s: '(-n)*n1 -> -(n*n1)',
532
+ assuming: {
533
+ subtract: {
534
+ total: true
535
+ }
536
+ }
537
+ }, {
538
+ s: 'n1*(-n) -> -(n1*n)',
539
+ // in case * non-commutative
540
+ assuming: {
541
+ subtract: {
542
+ total: true
543
+ },
544
+ multiply: {
545
+ commutative: false
546
+ }
547
+ }
368
548
  }, // final ordering of constants
369
549
  {
370
- l: 'c+v',
371
- r: 'v+c',
372
- context: {
550
+ s: 'c+v -> v+c',
551
+ assuming: {
552
+ add: {
553
+ commutative: true
554
+ }
555
+ },
556
+ imposeContext: {
373
557
  add: {
374
558
  commutative: false
375
559
  }
376
560
  }
377
561
  }, {
378
- l: 'v*c',
379
- r: 'c*v',
380
- context: {
562
+ s: 'v*c -> c*v',
563
+ assuming: {
564
+ multiply: {
565
+ commutative: true
566
+ }
567
+ },
568
+ imposeContext: {
381
569
  multiply: {
382
570
  commutative: false
383
571
  }
@@ -389,36 +577,125 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
389
577
  r: 'n-n1'
390
578
  }, // undo replace 'subtract'
391
579
  {
392
- l: 'n*(n1^-1)',
393
- r: 'n/n1'
394
- }, // undo replace 'divide'
395
- {
396
- l: 'n*n1^-n2',
397
- r: 'n/n1^n2'
580
+ s: 'n*(n1^-1) -> n/n1',
581
+ // undo replace 'divide'; for * commutative
582
+ assuming: {
583
+ multiply: {
584
+ commutative: true
585
+ }
586
+ } // o.w. / not conventional
587
+
398
588
  }, {
399
- l: 'n1^-1',
400
- r: '1/n1'
589
+ s: 'n*n1^-n2 -> n/n1^n2',
590
+ assuming: {
591
+ multiply: {
592
+ commutative: true
593
+ }
594
+ } // o.w. / not conventional
595
+
401
596
  }, {
402
- l: 'n*(n1/n2)',
403
- r: '(n*n1)/n2'
404
- }, // '*' before '/'
597
+ s: 'n^-1 -> 1/n',
598
+ assuming: {
599
+ multiply: {
600
+ commutative: true
601
+ }
602
+ } // o.w. / not conventional
603
+
604
+ }, {
605
+ l: 'n^1',
606
+ r: 'n'
607
+ }, // can be produced by power cancellation
405
608
  {
406
- l: 'n-(n1+n2)',
407
- r: 'n-n1-n2'
408
- }, // '-' before '+'
409
- // { l: '(n1/n2)/n3', r: 'n1/(n2*n3)' },
609
+ s: 'n*(n1/n2) -> (n*n1)/n2',
610
+ // '*' before '/'
611
+ assuming: {
612
+ multiply: {
613
+ associative: true
614
+ }
615
+ }
616
+ }, {
617
+ s: 'n-(n1+n2) -> n-n1-n2',
618
+ // '-' before '+'
619
+ assuming: {
620
+ addition: {
621
+ associative: true,
622
+ commutative: true
623
+ }
624
+ }
625
+ }, // { l: '(n1/n2)/n3', r: 'n1/(n2*n3)' },
410
626
  // { l: '(n*n1)/(n*n2)', r: 'n1/n2' },
627
+ // simplifyConstant can leave an extra factor of 1, which can always
628
+ // be eliminated, since the identity always commutes
411
629
  {
412
630
  l: '1*n',
413
- r: 'n'
414
- }, // this pattern can be produced by simplifyConstant
415
- {
416
- l: 'n1/(n2/n3)',
417
- r: '(n1*n3)/n2'
631
+ r: 'n',
632
+ imposeContext: {
633
+ multiply: {
634
+ commutative: true
635
+ }
636
+ }
637
+ }, {
638
+ s: 'n1/(n2/n3) -> (n1*n3)/n2',
639
+ assuming: {
640
+ multiply: {
641
+ associative: true
642
+ }
643
+ }
418
644
  }, {
419
645
  l: 'n1/(-n2)',
420
646
  r: '-n1/n2'
421
647
  }];
648
+ /**
649
+ * Takes any rule object as allowed by the specification in simplify
650
+ * and puts it in a standard form used by applyRule
651
+ */
652
+
653
+ function _canonicalizeRule(ruleObject, context) {
654
+ var newRule = {};
655
+
656
+ if (ruleObject.s) {
657
+ var lr = ruleObject.s.split('->');
658
+
659
+ if (lr.length === 2) {
660
+ newRule.l = lr[0];
661
+ newRule.r = lr[1];
662
+ } else {
663
+ throw SyntaxError('Could not parse rule: ' + ruleObject.s);
664
+ }
665
+ } else {
666
+ newRule.l = ruleObject.l;
667
+ newRule.r = ruleObject.r;
668
+ }
669
+
670
+ newRule.l = removeParens(parse(newRule.l));
671
+ newRule.r = removeParens(parse(newRule.r));
672
+
673
+ for (var prop of ['imposeContext', 'repeat', 'assuming']) {
674
+ if (prop in ruleObject) {
675
+ newRule[prop] = ruleObject[prop];
676
+ }
677
+ }
678
+
679
+ if (ruleObject.evaluate) {
680
+ newRule.evaluate = parse(ruleObject.evaluate);
681
+ }
682
+
683
+ if (isAssociative(newRule.l, context)) {
684
+ var makeNode = createMakeNodeFunction(newRule.l);
685
+
686
+ var expandsym = _getExpandPlaceholderSymbol();
687
+
688
+ newRule.expanded = {};
689
+ newRule.expanded.l = makeNode([newRule.l.clone(), expandsym]); // Push the expandsym into the deepest possible branch.
690
+ // This helps to match the newRule against nodes returned from getSplits() later on.
691
+
692
+ flatten(newRule.expanded.l, context);
693
+ unflattenr(newRule.expanded.l, context);
694
+ newRule.expanded.r = makeNode([newRule.r, expandsym]);
695
+ }
696
+
697
+ return newRule;
698
+ }
422
699
  /**
423
700
  * Parse the string array of rules into nodes
424
701
  *
@@ -436,7 +713,8 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
436
713
  * 'n1 * c1 -> c1 * n1'
437
714
  */
438
715
 
439
- function _buildRules(rules) {
716
+
717
+ function _buildRules(rules, context) {
440
718
  // Array of rules to be used to simplify expressions
441
719
  var ruleSet = [];
442
720
 
@@ -447,49 +725,14 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
447
725
 
448
726
  switch (ruleType) {
449
727
  case 'string':
450
- {
451
- var lr = rule.split('->');
452
-
453
- if (lr.length === 2) {
454
- rule = {
455
- l: lr[0],
456
- r: lr[1]
457
- };
458
- } else {
459
- throw SyntaxError('Could not parse rule: ' + rule);
460
- }
461
- }
728
+ rule = {
729
+ s: rule
730
+ };
462
731
 
463
732
  /* falls through */
464
733
 
465
734
  case 'object':
466
- newRule = {
467
- l: removeParens(parse(rule.l)),
468
- r: removeParens(parse(rule.r))
469
- };
470
-
471
- if (rule.context) {
472
- newRule.context = rule.context;
473
- }
474
-
475
- if (rule.evaluate) {
476
- newRule.evaluate = parse(rule.evaluate);
477
- }
478
-
479
- if (isAssociative(newRule.l)) {
480
- var makeNode = createMakeNodeFunction(newRule.l);
481
-
482
- var expandsym = _getExpandPlaceholderSymbol();
483
-
484
- newRule.expanded = {};
485
- newRule.expanded.l = makeNode([newRule.l.clone(), expandsym]); // Push the expandsym into the deepest possible branch.
486
- // This helps to match the newRule against nodes returned from getSplits() later on.
487
-
488
- flatten(newRule.expanded.l);
489
- unflattenr(newRule.expanded.l);
490
- newRule.expanded.r = makeNode([newRule.r, expandsym]);
491
- }
492
-
735
+ newRule = _canonicalizeRule(rule, context);
493
736
  break;
494
737
 
495
738
  case 'function':
@@ -514,90 +757,155 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
514
757
  return new SymbolNode('_p' + _lastsym++);
515
758
  }
516
759
 
517
- function mapRule(nodes, rule) {
760
+ function mapRule(nodes, rule, context) {
761
+ var resNodes = nodes;
762
+
518
763
  if (nodes) {
519
764
  for (var i = 0; i < nodes.length; ++i) {
520
- nodes[i] = applyRule(nodes[i], rule);
765
+ var newNode = applyRule(nodes[i], rule, context);
766
+
767
+ if (newNode !== nodes[i]) {
768
+ if (resNodes === nodes) {
769
+ resNodes = nodes.slice();
770
+ }
771
+
772
+ resNodes[i] = newNode;
773
+ }
521
774
  }
522
775
  }
776
+
777
+ return resNodes;
523
778
  }
524
779
  /**
525
780
  * Returns a simplfied form of node, or the original node if no simplification was possible.
526
781
  *
527
782
  * @param {ConstantNode | SymbolNode | ParenthesisNode | FunctionNode | OperatorNode} node
783
+ * @param {Object | Function} rule
784
+ * @param {Object} context -- information about assumed properties of operators
528
785
  * @return {ConstantNode | SymbolNode | ParenthesisNode | FunctionNode | OperatorNode} The simplified form of `expr`, or the original node if no simplification was possible.
529
786
  */
530
787
 
531
788
 
532
- var applyRule = typed('applyRule', {
533
- 'Node, Object': function NodeObject(node, rule) {
534
- // console.log('Entering applyRule(' + node.toString() + ')')
535
- // Do not clone node unless we find a match
536
- var res = node; // First replace our child nodes with their simplified versions
537
- // If a child could not be simplified, applying the rule to it
538
- // will have no effect since the node is returned unchanged
539
-
540
- if (res instanceof OperatorNode || res instanceof FunctionNode) {
541
- mapRule(res.args, rule);
542
- } else if (res instanceof ParenthesisNode) {
543
- if (res.content) {
544
- res.content = applyRule(res.content, rule);
545
- }
546
- } else if (res instanceof ArrayNode) {
547
- mapRule(res.items, rule);
548
- } else if (res instanceof AccessorNode) {
549
- if (res.object) {
550
- res.object = applyRule(res.object, rule);
789
+ function applyRule(node, rule, context) {
790
+ // console.log('Entering applyRule("', rule.l.toString({parenthesis:'all'}), '->', rule.r.toString({parenthesis:'all'}), '",', node.toString({parenthesis:'all'}),')')
791
+ // check that the assumptions for this rule are satisfied by the current
792
+ // context:
793
+ if (rule.assuming) {
794
+ for (var symbol in rule.assuming) {
795
+ for (var property in rule.assuming[symbol]) {
796
+ if (hasProperty(symbol, property, context) !== rule.assuming[symbol][property]) {
797
+ return node;
798
+ }
551
799
  }
800
+ }
801
+ }
552
802
 
553
- if (res.index) {
554
- res.index = applyRule(res.index, rule);
555
- }
556
- } else if (res instanceof IndexNode) {
557
- mapRule(res.dimensions, rule);
558
- } else if (res instanceof ObjectNode) {
559
- for (var prop in res.properties) {
560
- res.properties[prop] = applyRule(res.properties[prop], rule);
803
+ var mergedContext = mergeContext(rule.imposeContext, context); // Do not clone node unless we find a match
804
+
805
+ var res = node; // First replace our child nodes with their simplified versions
806
+ // If a child could not be simplified, applying the rule to it
807
+ // will have no effect since the node is returned unchanged
808
+
809
+ if (res instanceof OperatorNode || res instanceof FunctionNode) {
810
+ var newArgs = mapRule(res.args, rule, context);
811
+
812
+ if (newArgs !== res.args) {
813
+ res = res.clone();
814
+ res.args = newArgs;
815
+ }
816
+ } else if (res instanceof ParenthesisNode) {
817
+ if (res.content) {
818
+ var newContent = applyRule(res.content, rule, context);
819
+
820
+ if (newContent !== res.content) {
821
+ res = new ParenthesisNode(newContent);
561
822
  }
562
- } // Try to match a rule against this node
823
+ }
824
+ } else if (res instanceof ArrayNode) {
825
+ var newItems = mapRule(res.items, rule, context);
563
826
 
827
+ if (newItems !== res.items) {
828
+ res = new ArrayNode(newItems);
829
+ }
830
+ } else if (res instanceof AccessorNode) {
831
+ var newObj = res.object;
564
832
 
565
- var repl = rule.r;
833
+ if (res.object) {
834
+ newObj = applyRule(res.object, rule, context);
835
+ }
566
836
 
567
- var matches = _ruleMatch(rule.l, res)[0]; // If the rule is associative operator, we can try matching it while allowing additional terms.
568
- // This allows us to match rules like 'n+n' to the expression '(1+x)+x' or even 'x+1+x' if the operator is commutative.
837
+ var newIndex = res.index;
569
838
 
839
+ if (res.index) {
840
+ newIndex = applyRule(res.index, rule, context);
841
+ }
570
842
 
571
- if (!matches && rule.expanded) {
572
- repl = rule.expanded.r;
573
- matches = _ruleMatch(rule.expanded.l, res)[0];
843
+ if (newObj !== res.object || newIndex !== res.index) {
844
+ res = new AccessorNode(newObj, newIndex);
574
845
  }
846
+ } else if (res instanceof IndexNode) {
847
+ var newDims = mapRule(res.dimensions, rule, context);
575
848
 
576
- if (matches) {
577
- // const before = res.toString({parenthesis: 'all'})
578
- // Create a new node by cloning the rhs of the matched rule
579
- // we keep any implicit multiplication state if relevant
580
- var implicit = res.implicit;
581
- res = repl.clone();
849
+ if (newDims !== res.dimensions) {
850
+ res = new IndexNode(newDims);
851
+ }
852
+ } else if (res instanceof ObjectNode) {
853
+ var changed = false;
854
+ var newProps = {};
582
855
 
583
- if (implicit && 'implicit' in repl) {
584
- res.implicit = true;
585
- } // Replace placeholders with their respective nodes without traversing deeper into the replaced nodes
856
+ for (var prop in res.properties) {
857
+ newProps[prop] = applyRule(res.properties[prop], rule, context);
586
858
 
859
+ if (newProps[prop] !== res.properties[prop]) {
860
+ changed = true;
861
+ }
862
+ }
587
863
 
588
- res = res.transform(function (node) {
589
- if (node.isSymbolNode && hasOwnProperty(matches.placeholders, node.name)) {
590
- return matches.placeholders[node.name].clone();
591
- } else {
592
- return node;
593
- }
594
- }); // const after = res.toString({parenthesis: 'all'})
595
- // console.log('Simplified ' + before + ' to ' + after)
864
+ if (changed) {
865
+ res = new ObjectNode(newProps);
596
866
  }
867
+ } // Try to match a rule against this node
597
868
 
598
- return res;
869
+
870
+ var repl = rule.r;
871
+
872
+ var matches = _ruleMatch(rule.l, res, mergedContext)[0]; // If the rule is associative operator, we can try matching it while allowing additional terms.
873
+ // This allows us to match rules like 'n+n' to the expression '(1+x)+x' or even 'x+1+x' if the operator is commutative.
874
+
875
+
876
+ if (!matches && rule.expanded) {
877
+ repl = rule.expanded.r;
878
+ matches = _ruleMatch(rule.expanded.l, res, mergedContext)[0];
599
879
  }
600
- });
880
+
881
+ if (matches) {
882
+ // const before = res.toString({parenthesis: 'all'})
883
+ // Create a new node by cloning the rhs of the matched rule
884
+ // we keep any implicit multiplication state if relevant
885
+ var implicit = res.implicit;
886
+ res = repl.clone();
887
+
888
+ if (implicit && 'implicit' in repl) {
889
+ res.implicit = true;
890
+ } // Replace placeholders with their respective nodes without traversing deeper into the replaced nodes
891
+
892
+
893
+ res = res.transform(function (node) {
894
+ if (node.isSymbolNode && hasOwnProperty(matches.placeholders, node.name)) {
895
+ return matches.placeholders[node.name].clone();
896
+ } else {
897
+ return node;
898
+ }
899
+ }); // const after = res.toString({parenthesis: 'all'})
900
+ // console.log('Simplified ' + before + ' to ' + after)
901
+ }
902
+
903
+ if (rule.repeat && res !== node) {
904
+ res = applyRule(res, rule, context);
905
+ }
906
+
907
+ return res;
908
+ }
601
909
  /**
602
910
  * Get (binary) combinations of a flattened binary node
603
911
  * e.g. +(node1, node2, node3) -> [
@@ -607,6 +915,7 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
607
915
  *
608
916
  */
609
917
 
918
+
610
919
  function getSplits(node, context) {
611
920
  var res = [];
612
921
  var right, rightArgs;
@@ -620,9 +929,18 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
620
929
  res.push(makeNode([node.args[i], right]));
621
930
  }
622
931
  } else {
623
- rightArgs = node.args.slice(1);
624
- right = rightArgs.length === 1 ? rightArgs[0] : makeNode(rightArgs);
625
- res.push(makeNode([node.args[0], right]));
932
+ // Keep order, but try all parenthesizations
933
+ for (var _i = 1; _i < node.args.length; _i++) {
934
+ var left = node.args[0];
935
+
936
+ if (_i > 1) {
937
+ left = makeNode(node.args.slice(0, _i));
938
+ }
939
+
940
+ rightArgs = node.args.slice(_i);
941
+ right = rightArgs.length === 1 ? rightArgs[0] : makeNode(rightArgs);
942
+ res.push(makeNode([left, right]));
943
+ }
626
944
  }
627
945
 
628
946
  return res;
@@ -725,15 +1043,19 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
725
1043
  *
726
1044
  * @param {ConstantNode | SymbolNode | ParenthesisNode | FunctionNode | OperatorNode} rule
727
1045
  * @param {ConstantNode | SymbolNode | ParenthesisNode | FunctionNode | OperatorNode} node
1046
+ * @param {Object} context -- provides assumed properties of operators
1047
+ * @param {Boolean} isSplit -- whether we are in process of splitting an
1048
+ * n-ary operator node into possible binary combinations.
1049
+ * Defaults to false.
728
1050
  * @return {Object} Information about the match, if it exists.
729
1051
  */
730
1052
 
731
1053
 
732
- function _ruleMatch(rule, node, isSplit) {
1054
+ function _ruleMatch(rule, node, context, isSplit) {
733
1055
  // console.log('Entering _ruleMatch(' + JSON.stringify(rule) + ', ' + JSON.stringify(node) + ')')
734
1056
  // console.log('rule = ' + rule)
735
1057
  // console.log('node = ' + node)
736
- // console.log('Entering _ruleMatch(' + rule.toString() + ', ' + node.toString() + ')')
1058
+ // console.log('Entering _ruleMatch(', rule.toString({parenthesis:'all'}), ', ', node.toString({parenthesis:'all'}), ', ', context, ')')
737
1059
  var res = [{
738
1060
  placeholders: {}
739
1061
  }];
@@ -751,32 +1073,65 @@ export var createSimplify = /* #__PURE__ */factory(name, dependencies, _ref => {
751
1073
  } // rule and node match. Search the children of rule and node.
752
1074
 
753
1075
 
754
- if (node.args.length === 1 && rule.args.length === 1 || !isAssociative(node) && node.args.length === rule.args.length || isSplit) {
755
- // Expect non-associative operators to match exactly
1076
+ if (node.args.length === 1 && rule.args.length === 1 || !isAssociative(node, context) && node.args.length === rule.args.length || isSplit) {
1077
+ // Expect non-associative operators to match exactly,
1078
+ // except in any order if operator is commutative
756
1079
  var childMatches = [];
757
1080
 
758
1081
  for (var i = 0; i < rule.args.length; i++) {
759
- var childMatch = _ruleMatch(rule.args[i], node.args[i]);
1082
+ var childMatch = _ruleMatch(rule.args[i], node.args[i], context);
760
1083
 
761
1084
  if (childMatch.length === 0) {
762
1085
  // Child did not match, so stop searching immediately
763
- return [];
1086
+ break;
764
1087
  } // The child matched, so add the information returned from the child to our result
765
1088
 
766
1089
 
767
1090
  childMatches.push(childMatch);
768
1091
  }
769
1092
 
1093
+ if (childMatches.length !== rule.args.length) {
1094
+ if (!isCommutative(node, context) || // exact match in order needed
1095
+ rule.args.length === 1) {
1096
+ // nothing to commute
1097
+ return [];
1098
+ }
1099
+
1100
+ if (rule.args.length > 2) {
1101
+ /* Need to generate all permutations and try them.
1102
+ * It's a bit complicated, and unlikely to come up since there
1103
+ * are very few ternary or higher operators. So punt for now.
1104
+ */
1105
+ throw new Error('permuting >2 commutative non-associative rule arguments not yet implemented');
1106
+ }
1107
+ /* Exactly two arguments, try them reversed */
1108
+
1109
+
1110
+ var leftMatch = _ruleMatch(rule.args[0], node.args[1], context);
1111
+
1112
+ if (leftMatch.length === 0) {
1113
+ return [];
1114
+ }
1115
+
1116
+ var rightMatch = _ruleMatch(rule.args[1], node.args[0], context);
1117
+
1118
+ if (rightMatch.length === 0) {
1119
+ return [];
1120
+ }
1121
+
1122
+ childMatches = [leftMatch, rightMatch];
1123
+ }
1124
+
770
1125
  res = mergeChildMatches(childMatches);
771
1126
  } else if (node.args.length >= 2 && rule.args.length === 2) {
772
1127
  // node is flattened, rule is not
773
1128
  // Associative operators/functions can be split in different ways so we check if the rule matches each
774
1129
  // them and return their union.
775
- var splits = getSplits(node, rule.context);
1130
+ var splits = getSplits(node, context);
776
1131
  var splitMatches = [];
777
1132
 
778
- for (var _i = 0; _i < splits.length; _i++) {
779
- var matchSet = _ruleMatch(rule, splits[_i], true); // recursing at the same tree depth here
1133
+ for (var _i2 = 0; _i2 < splits.length; _i2++) {
1134
+ var matchSet = _ruleMatch(rule, splits[_i2], context, true); // recursing at the same tree depth here
780
1135
 
781
1136
 
782
1137
  splitMatches = splitMatches.concat(matchSet);