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
@@ -15,18 +15,14 @@ var _factory = require("../../utils/factory.js");
15
15
 
16
16
  var _util = require("./simplify/util.js");
17
17
 
18
- var _simplifyCore = require("./simplify/simplifyCore.js");
19
-
20
18
  var _simplifyConstant = require("./simplify/simplifyConstant.js");
21
19
 
22
- var _resolve = require("./simplify/resolve.js");
23
-
24
20
  var _object = require("../../utils/object.js");
25
21
 
26
22
  var _map = require("../../utils/map.js");
27
23
 
28
24
  var name = 'simplify';
29
- 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'];
25
+ 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'];
30
26
  var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) {
31
27
  var config = _ref.config,
32
28
  typed = _ref.typed,
@@ -38,6 +34,8 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
38
34
  pow = _ref.pow,
39
35
  isZero = _ref.isZero,
40
36
  equal = _ref.equal,
37
+ resolve = _ref.resolve,
38
+ simplifyCore = _ref.simplifyCore,
41
39
  fraction = _ref.fraction,
42
40
  bignumber = _ref.bignumber,
43
41
  mathWithTransform = _ref.mathWithTransform,
@@ -67,41 +65,23 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
67
65
  OperatorNode: OperatorNode,
68
66
  SymbolNode: SymbolNode
69
67
  });
70
- var simplifyCore = (0, _simplifyCore.createSimplifyCore)({
71
- equal: equal,
72
- isZero: isZero,
73
- add: add,
74
- subtract: subtract,
75
- multiply: multiply,
76
- divide: divide,
77
- pow: pow,
78
- AccessorNode: AccessorNode,
79
- ArrayNode: ArrayNode,
80
- ConstantNode: ConstantNode,
81
- FunctionNode: FunctionNode,
82
- IndexNode: IndexNode,
83
- ObjectNode: ObjectNode,
84
- OperatorNode: OperatorNode,
85
- ParenthesisNode: ParenthesisNode
86
- });
87
- var resolve = (0, _resolve.createResolve)({
88
- parse: parse,
89
- FunctionNode: FunctionNode,
90
- OperatorNode: OperatorNode,
91
- ParenthesisNode: ParenthesisNode
92
- });
93
68
 
94
69
  var _createUtil = (0, _util.createUtil)({
95
70
  FunctionNode: FunctionNode,
96
71
  OperatorNode: OperatorNode,
97
72
  SymbolNode: SymbolNode
98
73
  }),
74
+ hasProperty = _createUtil.hasProperty,
99
75
  isCommutative = _createUtil.isCommutative,
100
76
  isAssociative = _createUtil.isAssociative,
77
+ mergeContext = _createUtil.mergeContext,
101
78
  flatten = _createUtil.flatten,
102
79
  unflattenr = _createUtil.unflattenr,
103
80
  unflattenl = _createUtil.unflattenl,
104
- createMakeNodeFunction = _createUtil.createMakeNodeFunction;
81
+ createMakeNodeFunction = _createUtil.createMakeNodeFunction,
82
+ defaultContext = _createUtil.defaultContext,
83
+ realContext = _createUtil.realContext,
84
+ positiveContext = _createUtil.positiveContext;
105
85
  /**
106
86
  * Simplify an expression tree.
107
87
  *
@@ -132,6 +112,19 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
132
112
  * The default list of rules is exposed on the function as `simplify.rules`
133
113
  * and can be used as a basis to built a set of custom rules.
134
114
  *
115
+ * To specify a rule as a string, separate the left and right pattern by '->'
116
+ * When specifying a rule as an object, the following keys are meaningful:
117
+ * - l - the left pattern
118
+ * - r - the right pattern
119
+ * - s - in lieu of l and r, the string form that is broken at -> to give them
120
+ * - repeat - whether to repeat this rule until the expression stabilizes
121
+ * - assuming - gives a context object, as in the 'context' option to
122
+ * simplify. Every property in the context object must match the current
123
+ * context in order, or else the rule will not be applied.
124
+ * - imposeContext - gives a context object, as in the 'context' option to
125
+ * simplify. Any settings specified will override the incoming context
126
+ * for all matches of this rule.
127
+ *
135
128
  * For more details on the theory, see:
136
129
  *
137
130
  * - [Strategies for simplifying math expressions (Stackoverflow)](https://stackoverflow.com/questions/7540227/strategies-for-simplifying-math-expressions)
@@ -140,12 +133,28 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
140
133
  * An optional `options` argument can be passed as last argument of `simplify`.
141
134
  * Currently available options (defaults in parentheses):
142
135
  * - `consoleDebug` (false): whether to write the expression being simplified
143
- and any changes to it, along with the rule responsible, to console
136
+ * and any changes to it, along with the rule responsible, to console
137
+ * - `context` (simplify.defaultContext): an object giving properties of
138
+ * each operator, which determine what simplifications are allowed. The
139
+ * currently meaningful properties are commutative, associative,
140
+ * total (whether the operation is defined for all arguments), and
141
+ * trivial (whether the operation applied to a single argument leaves
142
+ * that argument unchanged). The default context is very permissive and
143
+ * allows almost all simplifications. Only properties differing from
144
+ * the default need to be specified; the default context is used as a
145
+ * fallback. Additional contexts `simplify.realContext` and
146
+ * `simplify.positiveContext` are supplied to cause simplify to perform
147
+ * just simplifications guaranteed to preserve all values of the expression
148
+ * assuming all variables and subexpressions are real numbers or
149
+ * positive real numbers, respectively. (Note that these are in some cases
150
+ * more restrictive than the default context; for example, the default
151
+ * context will allow `x/x` to simplify to 1, whereas
152
+ * `simplify.realContext` will not, as `0/0` is not equal to 1.)
144
153
  * - `exactFractions` (true): whether to try to convert all constants to
145
- exact rational numbers.
154
+ * exact rational numbers.
146
155
  * - `fractionsLimit` (10000): when `exactFractions` is true, constants will
147
- be expressed as fractions only when both numerator and denominator
148
- are smaller than `fractionsLimit`.
156
+ * be expressed as fractions only when both numerator and denominator
157
+ * are smaller than `fractionsLimit`.
149
158
  *
150
159
  * Syntax:
151
160
  *
@@ -168,7 +177,7 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
168
177
  *
169
178
  * See also:
170
179
  *
171
- * derivative, parse, evaluate, rationalize
180
+ * simplifyCore, derivative, evaluate, parse, rationalize, resolve
172
181
  *
173
182
  * @param {Node | string} expr
174
183
  * The expression to be simplified
@@ -217,7 +226,7 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
217
226
  },
218
227
  'Node, Array, Map, Object': function NodeArrayMapObject(expr, rules, scope, options) {
219
228
  var debug = options.consoleDebug;
220
- rules = _buildRules(rules);
229
+ rules = _buildRules(rules, options.context);
221
230
  var res = resolve(expr, scope);
222
231
  res = removeParens(res);
223
232
  var visited = {};
@@ -239,8 +248,8 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
239
248
  res = rules[i](res, options);
240
249
  if (debug) rulestr = rules[i].name;
241
250
  } else {
242
- flatten(res);
243
- res = applyRule(res, rules[i]);
251
+ flatten(res, options.context);
252
+ res = applyRule(res, rules[i], options.context);
244
253
 
245
254
  if (debug) {
246
255
  rulestr = "".concat(rules[i].l.toString(), " -> ").concat(rules[i].r.toString());
@@ -257,8 +266,12 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
257
266
  laststr = newstr;
258
267
  }
259
268
  }
269
+ /* Use left-heavy binary tree internally,
270
+ * since custom rule functions may expect it
271
+ */
260
272
 
261
- unflattenl(res); // using left-heavy binary tree here since custom rule functions may expect it
273
+
274
+ unflattenl(res, options.context);
262
275
  }
263
276
 
264
277
  str = res.toString({
@@ -269,8 +282,9 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
269
282
  return res;
270
283
  }
271
284
  });
272
- simplify.simplifyCore = simplifyCore;
273
- simplify.resolve = resolve;
285
+ simplify.defaultContext = defaultContext;
286
+ simplify.realContext = realContext;
287
+ simplify.positiveContext = positiveContext;
274
288
 
275
289
  function removeParens(node) {
276
290
  return node.transform(function (node, path, parent) {
@@ -280,8 +294,8 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
280
294
 
281
295
 
282
296
  var SUPPORTED_CONSTANTS = {
283
- "true": true,
284
- "false": true,
297
+ true: true,
298
+ false: true,
285
299
  e: true,
286
300
  i: true,
287
301
  Infinity: true,
@@ -322,41 +336,155 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
322
336
  // Note initially we tend constants to the right because like-term
323
337
  // collection prefers the left, and we would rather collect nonconstants
324
338
  {
325
- l: 'n-n1',
326
- r: 'n+-n1'
327
- }, // temporarily replace 'subtract' so we can further flatten the 'add' operator
328
- {
329
- l: '-(c*v)',
330
- r: 'v * (-c)'
331
- }, // make non-constant terms positive
332
- {
339
+ s: 'n-n1 -> n+-n1',
340
+ // temporarily replace 'subtract' so we can further flatten the 'add' operator
341
+ assuming: {
342
+ subtract: {
343
+ total: true
344
+ }
345
+ }
346
+ }, {
347
+ s: 'n-n -> 0',
348
+ // partial alternative when we can't always subtract
349
+ assuming: {
350
+ subtract: {
351
+ total: false
352
+ }
353
+ }
354
+ }, {
355
+ s: '-(c*v) -> v * (-c)',
356
+ // make non-constant terms positive
357
+ assuming: {
358
+ multiply: {
359
+ commutative: true
360
+ },
361
+ subtract: {
362
+ total: true
363
+ }
364
+ }
365
+ }, {
366
+ s: '-(c*v) -> (-c) * v',
367
+ // non-commutative version, part 1
368
+ assuming: {
369
+ multiply: {
370
+ commutative: false
371
+ },
372
+ subtract: {
373
+ total: true
374
+ }
375
+ }
376
+ }, {
377
+ s: '-(v*c) -> v * (-c)',
378
+ // non-commutative version, part 2
379
+ assuming: {
380
+ multiply: {
381
+ commutative: false
382
+ },
383
+ subtract: {
384
+ total: true
385
+ }
386
+ }
387
+ }, {
388
+ l: '-(n1/n2)',
389
+ r: '-n1/n2'
390
+ }, {
333
391
  l: '-v',
334
392
  r: 'v * (-1)'
335
- }, {
393
+ }, // finish making non-constant terms positive
394
+ {
395
+ l: '(n1 + n2)*(-1)',
396
+ r: 'n1*(-1) + n2*(-1)',
397
+ repeat: true
398
+ }, // expand negations to achieve as much sign cancellation as possible
399
+ {
336
400
  l: 'n/n1^n2',
337
401
  r: 'n*n1^-n2'
338
402
  }, // temporarily replace 'divide' so we can further flatten the 'multiply' operator
339
403
  {
340
404
  l: 'n/n1',
341
405
  r: 'n*n1^-1'
342
- }, simplifyConstant, // expand nested exponentiation
406
+ }, {
407
+ s: '(n1*n2)^n3 -> n1^n3 * n2^n3',
408
+ assuming: {
409
+ multiply: {
410
+ commutative: true
411
+ }
412
+ }
413
+ }, {
414
+ s: '(n1*n2)^(-1) -> n2^(-1) * n1^(-1)',
415
+ assuming: {
416
+ multiply: {
417
+ commutative: false
418
+ }
419
+ }
420
+ }, // expand nested exponentiation
343
421
  {
344
- l: '(n ^ n1) ^ n2',
345
- r: 'n ^ (n1 * n2)'
346
- }, // collect like factors
422
+ s: '(n ^ n1) ^ n2 -> n ^ (n1 * n2)',
423
+ assuming: {
424
+ divide: {
425
+ total: true
426
+ }
427
+ } // 1/(1/n) = n needs 1/n to exist
428
+
429
+ }, // collect like factors; into a sum, only do this for nonconstants
347
430
  {
431
+ l: ' v * ( v * n1 + n2)',
432
+ r: 'v^2 * n1 + v * n2'
433
+ }, {
434
+ s: ' v * (v^n4 * n1 + n2) -> v^(1+n4) * n1 + v * n2',
435
+ assuming: {
436
+ divide: {
437
+ total: true
438
+ }
439
+ } // v*1/v = v^(1+-1) needs 1/v
440
+
441
+ }, {
442
+ s: 'v^n3 * ( v * n1 + n2) -> v^(n3+1) * n1 + v^n3 * n2',
443
+ assuming: {
444
+ divide: {
445
+ total: true
446
+ }
447
+ }
448
+ }, {
449
+ s: 'v^n3 * (v^n4 * n1 + n2) -> v^(n3+n4) * n1 + v^n3 * n2',
450
+ assuming: {
451
+ divide: {
452
+ total: true
453
+ }
454
+ }
455
+ }, {
348
456
  l: 'n*n',
349
457
  r: 'n^2'
350
458
  }, {
351
- l: 'n * n^n1',
352
- r: 'n^(n1+1)'
459
+ s: 'n * n^n1 -> n^(n1+1)',
460
+ assuming: {
461
+ divide: {
462
+ total: true
463
+ }
464
+ } // n*1/n = n^(-1+1) needs 1/n
465
+
353
466
  }, {
354
- l: 'n^n1 * n^n2',
355
- r: 'n^(n1+n2)'
356
- }, // collect like terms
467
+ s: 'n^n1 * n^n2 -> n^(n1+n2)',
468
+ assuming: {
469
+ divide: {
470
+ total: true
471
+ }
472
+ } // ditto for n^2*1/n^2
473
+
474
+ }, // Unfortunately, to deal with more complicated cancellations, it
475
+ // becomes necessary to simplify constants twice per pass. It's not
476
+ // terribly expensive compared to matching rules, so this should not
477
+ // pose a performance problem.
478
+ simplifyConstant, // First: before collecting like terms
479
+ // collect like terms
357
480
  {
358
- l: 'n+n',
359
- r: '2*n'
481
+ s: 'n+n -> 2*n',
482
+ assuming: {
483
+ add: {
484
+ total: true
485
+ }
486
+ } // 2 = 1 + 1 needs to exist
487
+
360
488
  }, {
361
489
  l: 'n+-n',
362
490
  r: '0'
@@ -369,33 +497,91 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
369
497
  r: 'n3*(n1+n2)'
370
498
  }, // All sub-monomials tried there.
371
499
  {
500
+ l: 'n3^(-n4)*n1 + n3 * n2',
501
+ r: 'n3^(-n4)*(n1 + n3^(n4+1) *n2)'
502
+ }, {
503
+ l: 'n3^(-n4)*n1 + n3^n5 * n2',
504
+ r: 'n3^(-n4)*(n1 + n3^(n4+n5)*n2)'
505
+ }, {
506
+ s: 'n*v + v -> (n+1)*v',
507
+ // noncommutative additional cases
508
+ assuming: {
509
+ multiply: {
510
+ commutative: false
511
+ }
512
+ }
513
+ }, {
514
+ s: 'n1*n3 + n2*n3 -> (n1+n2)*n3',
515
+ assuming: {
516
+ multiply: {
517
+ commutative: false
518
+ }
519
+ }
520
+ }, {
521
+ s: 'n1*n3^(-n4) + n2 * n3 -> (n1 + n2*n3^(n4 + 1))*n3^(-n4)',
522
+ assuming: {
523
+ multiply: {
524
+ commutative: false
525
+ }
526
+ }
527
+ }, {
528
+ s: 'n1*n3^(-n4) + n2 * n3^n5 -> (n1 + n2*n3^(n4 + n5))*n3^(-n4)',
529
+ assuming: {
530
+ multiply: {
531
+ commutative: false
532
+ }
533
+ }
534
+ }, {
372
535
  l: 'n*c + c',
373
536
  r: '(n+1)*c'
374
- }, // remove parenthesis in the case of negating a quantity
375
- // (It might seem this rule should precede collecting like terms,
376
- // but putting it after gives another chance of noticing like terms,
377
- // and any new like terms produced by this will be collected
378
- // on the next pass through all the rules.)
379
- {
380
- l: 'n1 + (n2 + n3)*(-1)',
381
- r: 'n1 + n2*(-1) + n3*(-1)'
382
- }, // make factors positive (and undo 'make non-constant terms positive')
537
+ }, {
538
+ s: 'c*n + c -> c*(n+1)',
539
+ assuming: {
540
+ multiply: {
541
+ commutative: false
542
+ }
543
+ }
544
+ }, simplifyConstant, // Second: before returning expressions to "standard form"
545
+ // make factors positive (and undo 'make non-constant terms positive')
383
546
  {
384
- l: '(-n)*n1',
385
- r: '-(n*n1)'
547
+ s: '(-n)*n1 -> -(n*n1)',
548
+ assuming: {
549
+ subtract: {
550
+ total: true
551
+ }
552
+ }
553
+ }, {
554
+ s: 'n1*(-n) -> -(n1*n)',
555
+ // in case * non-commutative
556
+ assuming: {
557
+ subtract: {
558
+ total: true
559
+ },
560
+ multiply: {
561
+ commutative: false
562
+ }
563
+ }
386
564
  }, // final ordering of constants
387
565
  {
388
- l: 'c+v',
389
- r: 'v+c',
390
- context: {
566
+ s: 'c+v -> v+c',
567
+ assuming: {
568
+ add: {
569
+ commutative: true
570
+ }
571
+ },
572
+ imposeContext: {
391
573
  add: {
392
574
  commutative: false
393
575
  }
394
576
  }
395
577
  }, {
396
- l: 'v*c',
397
- r: 'c*v',
398
- context: {
578
+ s: 'v*c -> c*v',
579
+ assuming: {
580
+ multiply: {
581
+ commutative: true
582
+ }
583
+ },
584
+ imposeContext: {
399
585
  multiply: {
400
586
  commutative: false
401
587
  }
@@ -407,36 +593,127 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
407
593
  r: 'n-n1'
408
594
  }, // undo replace 'subtract'
409
595
  {
410
- l: 'n*(n1^-1)',
411
- r: 'n/n1'
412
- }, // undo replace 'divide'
413
- {
414
- l: 'n*n1^-n2',
415
- r: 'n/n1^n2'
596
+ s: 'n*(n1^-1) -> n/n1',
597
+ // undo replace 'divide'; for * commutative
598
+ assuming: {
599
+ multiply: {
600
+ commutative: true
601
+ }
602
+ } // o.w. / not conventional
603
+
416
604
  }, {
417
- l: 'n1^-1',
418
- r: '1/n1'
605
+ s: 'n*n1^-n2 -> n/n1^n2',
606
+ assuming: {
607
+ multiply: {
608
+ commutative: true
609
+ }
610
+ } // o.w. / not conventional
611
+
419
612
  }, {
420
- l: 'n*(n1/n2)',
421
- r: '(n*n1)/n2'
422
- }, // '*' before '/'
613
+ s: 'n^-1 -> 1/n',
614
+ assuming: {
615
+ multiply: {
616
+ commutative: true
617
+ }
618
+ } // o.w. / not conventional
619
+
620
+ }, {
621
+ l: 'n^1',
622
+ r: 'n'
623
+ }, // can be produced by power cancellation
423
624
  {
424
- l: 'n-(n1+n2)',
425
- r: 'n-n1-n2'
426
- }, // '-' before '+'
427
- // { l: '(n1/n2)/n3', r: 'n1/(n2*n3)' },
625
+ s: 'n*(n1/n2) -> (n*n1)/n2',
626
+ // '*' before '/'
627
+ assuming: {
628
+ multiply: {
629
+ associative: true
630
+ }
631
+ }
632
+ }, {
633
+ s: 'n-(n1+n2) -> n-n1-n2',
634
+ // '-' before '+'
635
+ assuming: {
636
+ addition: {
637
+ associative: true,
638
+ commutative: true
639
+ }
640
+ }
641
+ }, // { l: '(n1/n2)/n3', r: 'n1/(n2*n3)' },
428
642
  // { l: '(n*n1)/(n*n2)', r: 'n1/n2' },
643
+ // simplifyConstant can leave an extra factor of 1, which can always
644
+ // be eliminated, since the identity always commutes
429
645
  {
430
646
  l: '1*n',
431
- r: 'n'
432
- }, // this pattern can be produced by simplifyConstant
433
- {
434
- l: 'n1/(n2/n3)',
435
- r: '(n1*n3)/n2'
647
+ r: 'n',
648
+ imposeContext: {
649
+ multiply: {
650
+ commutative: true
651
+ }
652
+ }
653
+ }, {
654
+ s: 'n1/(n2/n3) -> (n1*n3)/n2',
655
+ assuming: {
656
+ multiply: {
657
+ associative: true
658
+ }
659
+ }
436
660
  }, {
437
661
  l: 'n1/(-n2)',
438
662
  r: '-n1/n2'
439
663
  }];
664
+ /**
665
+ * Takes any rule object as allowed by the specification in simplify
666
+ * and puts it in a standard form used by applyRule
667
+ */
668
+
669
+ function _canonicalizeRule(ruleObject, context) {
670
+ var newRule = {};
671
+
672
+ if (ruleObject.s) {
673
+ var lr = ruleObject.s.split('->');
674
+
675
+ if (lr.length === 2) {
676
+ newRule.l = lr[0];
677
+ newRule.r = lr[1];
678
+ } else {
679
+ throw SyntaxError('Could not parse rule: ' + ruleObject.s);
680
+ }
681
+ } else {
682
+ newRule.l = ruleObject.l;
683
+ newRule.r = ruleObject.r;
684
+ }
685
+
686
+ newRule.l = removeParens(parse(newRule.l));
687
+ newRule.r = removeParens(parse(newRule.r));
688
+
689
+ for (var _i = 0, _arr = ['imposeContext', 'repeat', 'assuming']; _i < _arr.length; _i++) {
690
+ var prop = _arr[_i];
691
+
692
+ if (prop in ruleObject) {
693
+ newRule[prop] = ruleObject[prop];
694
+ }
695
+ }
696
+
697
+ if (ruleObject.evaluate) {
698
+ newRule.evaluate = parse(ruleObject.evaluate);
699
+ }
700
+
701
+ if (isAssociative(newRule.l, context)) {
702
+ var makeNode = createMakeNodeFunction(newRule.l);
703
+
704
+ var expandsym = _getExpandPlaceholderSymbol();
705
+
706
+ newRule.expanded = {};
707
+ newRule.expanded.l = makeNode([newRule.l.clone(), expandsym]); // Push the expandsym into the deepest possible branch.
708
+ // This helps to match the newRule against nodes returned from getSplits() later on.
709
+
710
+ flatten(newRule.expanded.l, context);
711
+ unflattenr(newRule.expanded.l, context);
712
+ newRule.expanded.r = makeNode([newRule.r, expandsym]);
713
+ }
714
+
715
+ return newRule;
716
+ }
440
717
  /**
441
718
  * Parse the string array of rules into nodes
442
719
  *
@@ -454,60 +731,26 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
454
731
  * 'n1 * c1 -> c1 * n1'
455
732
  */
456
733
 
457
- function _buildRules(rules) {
734
+
735
+ function _buildRules(rules, context) {
458
736
  // Array of rules to be used to simplify expressions
459
737
  var ruleSet = [];
460
738
 
461
739
  for (var i = 0; i < rules.length; i++) {
462
740
  var rule = rules[i];
463
741
  var newRule = void 0;
464
- var ruleType = (0, _typeof2["default"])(rule);
742
+ var ruleType = (0, _typeof2.default)(rule);
465
743
 
466
744
  switch (ruleType) {
467
745
  case 'string':
468
- {
469
- var lr = rule.split('->');
470
-
471
- if (lr.length === 2) {
472
- rule = {
473
- l: lr[0],
474
- r: lr[1]
475
- };
476
- } else {
477
- throw SyntaxError('Could not parse rule: ' + rule);
478
- }
479
- }
746
+ rule = {
747
+ s: rule
748
+ };
480
749
 
481
750
  /* falls through */
482
751
 
483
752
  case 'object':
484
- newRule = {
485
- l: removeParens(parse(rule.l)),
486
- r: removeParens(parse(rule.r))
487
- };
488
-
489
- if (rule.context) {
490
- newRule.context = rule.context;
491
- }
492
-
493
- if (rule.evaluate) {
494
- newRule.evaluate = parse(rule.evaluate);
495
- }
496
-
497
- if (isAssociative(newRule.l)) {
498
- var makeNode = createMakeNodeFunction(newRule.l);
499
-
500
- var expandsym = _getExpandPlaceholderSymbol();
501
-
502
- newRule.expanded = {};
503
- newRule.expanded.l = makeNode([newRule.l.clone(), expandsym]); // Push the expandsym into the deepest possible branch.
504
- // This helps to match the newRule against nodes returned from getSplits() later on.
505
-
506
- flatten(newRule.expanded.l);
507
- unflattenr(newRule.expanded.l);
508
- newRule.expanded.r = makeNode([newRule.r, expandsym]);
509
- }
510
-
753
+ newRule = _canonicalizeRule(rule, context);
511
754
  break;
512
755
 
513
756
  case 'function':
@@ -532,90 +775,155 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
532
775
  return new SymbolNode('_p' + _lastsym++);
533
776
  }
534
777
 
535
- function mapRule(nodes, rule) {
778
+ function mapRule(nodes, rule, context) {
779
+ var resNodes = nodes;
780
+
536
781
  if (nodes) {
537
782
  for (var i = 0; i < nodes.length; ++i) {
538
- nodes[i] = applyRule(nodes[i], rule);
783
+ var newNode = applyRule(nodes[i], rule, context);
784
+
785
+ if (newNode !== nodes[i]) {
786
+ if (resNodes === nodes) {
787
+ resNodes = nodes.slice();
788
+ }
789
+
790
+ resNodes[i] = newNode;
791
+ }
539
792
  }
540
793
  }
794
+
795
+ return resNodes;
541
796
  }
542
797
  /**
543
798
  * Returns a simplfied form of node, or the original node if no simplification was possible.
544
799
  *
545
800
  * @param {ConstantNode | SymbolNode | ParenthesisNode | FunctionNode | OperatorNode} node
801
+ * @param {Object | Function} rule
802
+ * @param {Object} context -- information about assumed properties of operators
546
803
  * @return {ConstantNode | SymbolNode | ParenthesisNode | FunctionNode | OperatorNode} The simplified form of `expr`, or the original node if no simplification was possible.
547
804
  */
548
805
 
549
806
 
550
- var applyRule = typed('applyRule', {
551
- 'Node, Object': function NodeObject(node, rule) {
552
- // console.log('Entering applyRule(' + node.toString() + ')')
553
- // Do not clone node unless we find a match
554
- var res = node; // First replace our child nodes with their simplified versions
555
- // If a child could not be simplified, applying the rule to it
556
- // will have no effect since the node is returned unchanged
557
-
558
- if (res instanceof OperatorNode || res instanceof FunctionNode) {
559
- mapRule(res.args, rule);
560
- } else if (res instanceof ParenthesisNode) {
561
- if (res.content) {
562
- res.content = applyRule(res.content, rule);
563
- }
564
- } else if (res instanceof ArrayNode) {
565
- mapRule(res.items, rule);
566
- } else if (res instanceof AccessorNode) {
567
- if (res.object) {
568
- res.object = applyRule(res.object, rule);
807
+ function applyRule(node, rule, context) {
808
+ // console.log('Entering applyRule("', rule.l.toString({parenthesis:'all'}), '->', rule.r.toString({parenthesis:'all'}), '",', node.toString({parenthesis:'all'}),')')
809
+ // check that the assumptions for this rule are satisfied by the current
810
+ // context:
811
+ if (rule.assuming) {
812
+ for (var symbol in rule.assuming) {
813
+ for (var property in rule.assuming[symbol]) {
814
+ if (hasProperty(symbol, property, context) !== rule.assuming[symbol][property]) {
815
+ return node;
816
+ }
569
817
  }
818
+ }
819
+ }
570
820
 
571
- if (res.index) {
572
- res.index = applyRule(res.index, rule);
573
- }
574
- } else if (res instanceof IndexNode) {
575
- mapRule(res.dimensions, rule);
576
- } else if (res instanceof ObjectNode) {
577
- for (var prop in res.properties) {
578
- res.properties[prop] = applyRule(res.properties[prop], rule);
821
+ var mergedContext = mergeContext(rule.imposeContext, context); // Do not clone node unless we find a match
822
+
823
+ var res = node; // First replace our child nodes with their simplified versions
824
+ // If a child could not be simplified, applying the rule to it
825
+ // will have no effect since the node is returned unchanged
826
+
827
+ if (res instanceof OperatorNode || res instanceof FunctionNode) {
828
+ var newArgs = mapRule(res.args, rule, context);
829
+
830
+ if (newArgs !== res.args) {
831
+ res = res.clone();
832
+ res.args = newArgs;
833
+ }
834
+ } else if (res instanceof ParenthesisNode) {
835
+ if (res.content) {
836
+ var newContent = applyRule(res.content, rule, context);
837
+
838
+ if (newContent !== res.content) {
839
+ res = new ParenthesisNode(newContent);
579
840
  }
580
- } // Try to match a rule against this node
841
+ }
842
+ } else if (res instanceof ArrayNode) {
843
+ var newItems = mapRule(res.items, rule, context);
581
844
 
845
+ if (newItems !== res.items) {
846
+ res = new ArrayNode(newItems);
847
+ }
848
+ } else if (res instanceof AccessorNode) {
849
+ var newObj = res.object;
582
850
 
583
- var repl = rule.r;
851
+ if (res.object) {
852
+ newObj = applyRule(res.object, rule, context);
853
+ }
584
854
 
585
- var matches = _ruleMatch(rule.l, res)[0]; // If the rule is associative operator, we can try matching it while allowing additional terms.
586
- // 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.
855
+ var newIndex = res.index;
587
856
 
857
+ if (res.index) {
858
+ newIndex = applyRule(res.index, rule, context);
859
+ }
588
860
 
589
- if (!matches && rule.expanded) {
590
- repl = rule.expanded.r;
591
- matches = _ruleMatch(rule.expanded.l, res)[0];
861
+ if (newObj !== res.object || newIndex !== res.index) {
862
+ res = new AccessorNode(newObj, newIndex);
592
863
  }
864
+ } else if (res instanceof IndexNode) {
865
+ var newDims = mapRule(res.dimensions, rule, context);
593
866
 
594
- if (matches) {
595
- // const before = res.toString({parenthesis: 'all'})
596
- // Create a new node by cloning the rhs of the matched rule
597
- // we keep any implicit multiplication state if relevant
598
- var implicit = res.implicit;
599
- res = repl.clone();
867
+ if (newDims !== res.dimensions) {
868
+ res = new IndexNode(newDims);
869
+ }
870
+ } else if (res instanceof ObjectNode) {
871
+ var changed = false;
872
+ var newProps = {};
600
873
 
601
- if (implicit && 'implicit' in repl) {
602
- res.implicit = true;
603
- } // Replace placeholders with their respective nodes without traversing deeper into the replaced nodes
874
+ for (var prop in res.properties) {
875
+ newProps[prop] = applyRule(res.properties[prop], rule, context);
604
876
 
877
+ if (newProps[prop] !== res.properties[prop]) {
878
+ changed = true;
879
+ }
880
+ }
605
881
 
606
- res = res.transform(function (node) {
607
- if (node.isSymbolNode && (0, _object.hasOwnProperty)(matches.placeholders, node.name)) {
608
- return matches.placeholders[node.name].clone();
609
- } else {
610
- return node;
611
- }
612
- }); // const after = res.toString({parenthesis: 'all'})
613
- // console.log('Simplified ' + before + ' to ' + after)
882
+ if (changed) {
883
+ res = new ObjectNode(newProps);
614
884
  }
885
+ } // Try to match a rule against this node
615
886
 
616
- return res;
887
+
888
+ var repl = rule.r;
889
+
890
+ var matches = _ruleMatch(rule.l, res, mergedContext)[0]; // If the rule is associative operator, we can try matching it while allowing additional terms.
891
+ // 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.
892
+
893
+
894
+ if (!matches && rule.expanded) {
895
+ repl = rule.expanded.r;
896
+ matches = _ruleMatch(rule.expanded.l, res, mergedContext)[0];
617
897
  }
618
- });
898
+
899
+ if (matches) {
900
+ // const before = res.toString({parenthesis: 'all'})
901
+ // Create a new node by cloning the rhs of the matched rule
902
+ // we keep any implicit multiplication state if relevant
903
+ var implicit = res.implicit;
904
+ res = repl.clone();
905
+
906
+ if (implicit && 'implicit' in repl) {
907
+ res.implicit = true;
908
+ } // Replace placeholders with their respective nodes without traversing deeper into the replaced nodes
909
+
910
+
911
+ res = res.transform(function (node) {
912
+ if (node.isSymbolNode && (0, _object.hasOwnProperty)(matches.placeholders, node.name)) {
913
+ return matches.placeholders[node.name].clone();
914
+ } else {
915
+ return node;
916
+ }
917
+ }); // const after = res.toString({parenthesis: 'all'})
918
+ // console.log('Simplified ' + before + ' to ' + after)
919
+ }
920
+
921
+ if (rule.repeat && res !== node) {
922
+ res = applyRule(res, rule, context);
923
+ }
924
+
925
+ return res;
926
+ }
619
927
  /**
620
928
  * Get (binary) combinations of a flattened binary node
621
929
  * e.g. +(node1, node2, node3) -> [
@@ -625,6 +933,7 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
625
933
  *
626
934
  */
627
935
 
936
+
628
937
  function getSplits(node, context) {
629
938
  var res = [];
630
939
  var right, rightArgs;
@@ -638,9 +947,18 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
638
947
  res.push(makeNode([node.args[i], right]));
639
948
  }
640
949
  } else {
641
- rightArgs = node.args.slice(1);
642
- right = rightArgs.length === 1 ? rightArgs[0] : makeNode(rightArgs);
643
- res.push(makeNode([node.args[0], right]));
950
+ // Keep order, but try all parenthesizations
951
+ for (var _i2 = 1; _i2 < node.args.length; _i2++) {
952
+ var left = node.args[0];
953
+
954
+ if (_i2 > 1) {
955
+ left = makeNode(node.args.slice(0, _i2));
956
+ }
957
+
958
+ rightArgs = node.args.slice(_i2);
959
+ right = rightArgs.length === 1 ? rightArgs[0] : makeNode(rightArgs);
960
+ res.push(makeNode([left, right]));
961
+ }
644
962
  }
645
963
 
646
964
  return res;
@@ -743,15 +1061,19 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
743
1061
  *
744
1062
  * @param {ConstantNode | SymbolNode | ParenthesisNode | FunctionNode | OperatorNode} rule
745
1063
  * @param {ConstantNode | SymbolNode | ParenthesisNode | FunctionNode | OperatorNode} node
1064
+ * @param {Object} context -- provides assumed properties of operators
1065
+ * @param {Boolean} isSplit -- whether we are in process of splitting an
1066
+ * n-ary operator node into possible binary combinations.
1067
+ * Defaults to false.
746
1068
  * @return {Object} Information about the match, if it exists.
747
1069
  */
748
1070
 
749
1071
 
750
- function _ruleMatch(rule, node, isSplit) {
1072
+ function _ruleMatch(rule, node, context, isSplit) {
751
1073
  // console.log('Entering _ruleMatch(' + JSON.stringify(rule) + ', ' + JSON.stringify(node) + ')')
752
1074
  // console.log('rule = ' + rule)
753
1075
  // console.log('node = ' + node)
754
- // console.log('Entering _ruleMatch(' + rule.toString() + ', ' + node.toString() + ')')
1076
+ // console.log('Entering _ruleMatch(', rule.toString({parenthesis:'all'}), ', ', node.toString({parenthesis:'all'}), ', ', context, ')')
755
1077
  var res = [{
756
1078
  placeholders: {}
757
1079
  }];
@@ -769,32 +1091,65 @@ var createSimplify = /* #__PURE__ */(0, _factory.factory)(name, dependencies, fu
769
1091
  } // rule and node match. Search the children of rule and node.
770
1092
 
771
1093
 
772
- if (node.args.length === 1 && rule.args.length === 1 || !isAssociative(node) && node.args.length === rule.args.length || isSplit) {
773
- // Expect non-associative operators to match exactly
1094
+ if (node.args.length === 1 && rule.args.length === 1 || !isAssociative(node, context) && node.args.length === rule.args.length || isSplit) {
1095
+ // Expect non-associative operators to match exactly,
1096
+ // except in any order if operator is commutative
774
1097
  var childMatches = [];
775
1098
 
776
1099
  for (var i = 0; i < rule.args.length; i++) {
777
- var childMatch = _ruleMatch(rule.args[i], node.args[i]);
1100
+ var childMatch = _ruleMatch(rule.args[i], node.args[i], context);
778
1101
 
779
1102
  if (childMatch.length === 0) {
780
1103
  // Child did not match, so stop searching immediately
781
- return [];
1104
+ break;
782
1105
  } // The child matched, so add the information returned from the child to our result
783
1106
 
784
1107
 
785
1108
  childMatches.push(childMatch);
786
1109
  }
787
1110
 
1111
+ if (childMatches.length !== rule.args.length) {
1112
+ if (!isCommutative(node, context) || // exact match in order needed
1113
+ rule.args.length === 1) {
1114
+ // nothing to commute
1115
+ return [];
1116
+ }
1117
+
1118
+ if (rule.args.length > 2) {
1119
+ /* Need to generate all permutations and try them.
1120
+ * It's a bit complicated, and unlikely to come up since there
1121
+ * are very few ternary or higher operators. So punt for now.
1122
+ */
1123
+ throw new Error('permuting >2 commutative non-associative rule arguments not yet implemented');
1124
+ }
1125
+ /* Exactly two arguments, try them reversed */
1126
+
1127
+
1128
+ var leftMatch = _ruleMatch(rule.args[0], node.args[1], context);
1129
+
1130
+ if (leftMatch.length === 0) {
1131
+ return [];
1132
+ }
1133
+
1134
+ var rightMatch = _ruleMatch(rule.args[1], node.args[0], context);
1135
+
1136
+ if (rightMatch.length === 0) {
1137
+ return [];
1138
+ }
1139
+
1140
+ childMatches = [leftMatch, rightMatch];
1141
+ }
1142
+
788
1143
  res = mergeChildMatches(childMatches);
789
1144
  } else if (node.args.length >= 2 && rule.args.length === 2) {
790
1145
  // node is flattened, rule is not
791
1146
  // Associative operators/functions can be split in different ways so we check if the rule matches each
792
1147
  // them and return their union.
793
- var splits = getSplits(node, rule.context);
1148
+ var splits = getSplits(node, context);
794
1149
  var splitMatches = [];
795
1150
 
796
- for (var _i = 0; _i < splits.length; _i++) {
797
- var matchSet = _ruleMatch(rule, splits[_i], true); // recursing at the same tree depth here
1151
+ for (var _i3 = 0; _i3 < splits.length; _i3++) {
1152
+ var matchSet = _ruleMatch(rule, splits[_i3], context, true); // recursing at the same tree depth here
798
1153
 
799
1154
 
800
1155
  splitMatches = splitMatches.concat(matchSet);