nerdamer 1.1.13 → 2.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (341) hide show
  1. package/LICENSE.md +184 -0
  2. package/README.md +293 -312
  3. package/dist/bundle.js +2 -0
  4. package/dist/bundle.js.LICENSE.txt +7 -0
  5. package/dist/parser.js +2 -0
  6. package/dist/parser.js.LICENSE.txt +7 -0
  7. package/docs-data/parser-functions.json +1960 -0
  8. package/index.d.ts +10 -426
  9. package/output/algebra/adapters.d.ts +33 -0
  10. package/output/algebra/adapters.js +109 -0
  11. package/output/algebra/algorithms/arith.d.ts +84 -0
  12. package/output/algebra/algorithms/arith.js +323 -0
  13. package/output/algebra/algorithms/factor.d.ts +3 -0
  14. package/output/algebra/algorithms/factor.js +5 -0
  15. package/output/algebra/algorithms/factorMultivariate.d.ts +23 -0
  16. package/output/algebra/algorithms/factorMultivariate.js +2393 -0
  17. package/output/algebra/algorithms/factorUnivariate.d.ts +72 -0
  18. package/output/algebra/algorithms/factorUnivariate.js +1072 -0
  19. package/output/algebra/algorithms/gcd.d.ts +22 -0
  20. package/output/algebra/algorithms/gcd.js +690 -0
  21. package/output/algebra/algorithms/groebnerBase.d.ts +157 -0
  22. package/output/algebra/algorithms/groebnerBase.js +1166 -0
  23. package/output/algebra/algorithms/multiPoly/MultiPoly.d.ts +137 -0
  24. package/output/algebra/algorithms/multiPoly/MultiPoly.js +346 -0
  25. package/output/algebra/algorithms/poly.d.ts +228 -0
  26. package/output/algebra/algorithms/poly.js +1299 -0
  27. package/output/algebra/algorithms/rational.d.ts +17 -0
  28. package/output/algebra/algorithms/rational.js +115 -0
  29. package/output/algebra/factor/factor.d.ts +62 -0
  30. package/output/algebra/factor/factor.js +158 -0
  31. package/output/algebra/gcd/gcd.d.ts +29 -0
  32. package/output/algebra/gcd/gcd.js +141 -0
  33. package/output/algebra/groebner.d.ts +21 -0
  34. package/output/algebra/groebner.js +42 -0
  35. package/output/algebra/partfrac.d.ts +19 -0
  36. package/output/algebra/partfrac.js +398 -0
  37. package/output/algebra/polynomialize.d.ts +20 -0
  38. package/output/algebra/polynomialize.js +24 -0
  39. package/output/algebra/simplify/complexsimp.d.ts +7 -0
  40. package/output/algebra/simplify/complexsimp.js +24 -0
  41. package/output/algebra/simplify/factorCommon.d.ts +13 -0
  42. package/output/algebra/simplify/factorCommon.js +136 -0
  43. package/output/algebra/simplify/funcsimp.d.ts +26 -0
  44. package/output/algebra/simplify/funcsimp.js +633 -0
  45. package/output/algebra/simplify/invtrigrewrite.d.ts +10 -0
  46. package/output/algebra/simplify/invtrigrewrite.js +96 -0
  47. package/output/algebra/simplify/ratsimp.d.ts +21 -0
  48. package/output/algebra/simplify/ratsimp.js +140 -0
  49. package/output/algebra/simplify/simplify.d.ts +25 -0
  50. package/output/algebra/simplify/simplify.js +228 -0
  51. package/output/algebra/simplify/trigreduce.d.ts +38 -0
  52. package/output/algebra/simplify/trigreduce.js +424 -0
  53. package/output/algebra/simplify/trigrewrite.d.ts +17 -0
  54. package/output/algebra/simplify/trigrewrite.js +156 -0
  55. package/output/algebra/simplify/trigsimp.d.ts +11 -0
  56. package/output/algebra/simplify/trigsimp.js +369 -0
  57. package/output/algebra/simplify/utils.d.ts +32 -0
  58. package/output/algebra/simplify/utils.js +56 -0
  59. package/output/algebra/utils.d.ts +32 -0
  60. package/output/algebra/utils.js +48 -0
  61. package/output/api/advanced.d.ts +7 -0
  62. package/output/api/advanced.js +18 -0
  63. package/output/api/algebra.d.ts +17 -0
  64. package/output/api/algebra.js +32 -0
  65. package/output/api/assumptions.d.ts +4 -0
  66. package/output/api/assumptions.js +11 -0
  67. package/output/api/calculus.d.ts +9 -0
  68. package/output/api/calculus.js +21 -0
  69. package/output/api/core.d.ts +17 -0
  70. package/output/api/core.js +41 -0
  71. package/output/api/debug.d.ts +16 -0
  72. package/output/api/debug.js +23 -0
  73. package/output/api/parser.d.ts +85 -0
  74. package/output/api/parser.js +16 -0
  75. package/output/api/solve.d.ts +10 -0
  76. package/output/api/solve.js +16 -0
  77. package/output/api/structures.d.ts +10 -0
  78. package/output/api/structures.js +22 -0
  79. package/output/calculus/derivative/diff.d.ts +30 -0
  80. package/output/calculus/derivative/diff.js +238 -0
  81. package/output/calculus/fresnel.d.ts +16 -0
  82. package/output/calculus/fresnel.js +39 -0
  83. package/output/calculus/integrate/byParts.d.ts +18 -0
  84. package/output/calculus/integrate/byParts.js +339 -0
  85. package/output/calculus/integrate/bySubstitution.d.ts +135 -0
  86. package/output/calculus/integrate/bySubstitution.js +411 -0
  87. package/output/calculus/integrate/integrate.d.ts +38 -0
  88. package/output/calculus/integrate/integrate.js +652 -0
  89. package/output/calculus/integrate/integrationTable.d.ts +2 -0
  90. package/output/calculus/integrate/integrationTable.js +914 -0
  91. package/output/calculus/integrate/utils.d.ts +28 -0
  92. package/output/calculus/integrate/utils.js +96 -0
  93. package/output/calculus/laplace/ilaplace.d.ts +31 -0
  94. package/output/calculus/laplace/ilaplace.js +192 -0
  95. package/output/calculus/laplace/ilaplaceTable.d.ts +2 -0
  96. package/output/calculus/laplace/ilaplaceTable.js +200 -0
  97. package/output/calculus/laplace/laplace.d.ts +22 -0
  98. package/output/calculus/laplace/laplace.js +109 -0
  99. package/output/calculus/laplace/laplaceTable.d.ts +2 -0
  100. package/output/calculus/laplace/laplaceTable.js +187 -0
  101. package/output/calculus/limit/limit.d.ts +35 -0
  102. package/output/calculus/limit/limit.js +1183 -0
  103. package/output/calculus/limit/limitsTable.d.ts +2 -0
  104. package/output/calculus/limit/limitsTable.js +7 -0
  105. package/output/core/Settings.d.ts +32 -0
  106. package/output/core/Settings.js +68 -0
  107. package/output/core/adapters.d.ts +18 -0
  108. package/output/core/adapters.js +40 -0
  109. package/output/core/classes/assumption/Assumption.d.ts +218 -0
  110. package/output/core/classes/assumption/Assumption.js +605 -0
  111. package/output/core/classes/assumption/assertiveFunctions.d.ts +6 -0
  112. package/output/core/classes/assumption/assertiveFunctions.js +64 -0
  113. package/output/core/classes/assumption/assume.d.ts +90 -0
  114. package/output/core/classes/assumption/assume.js +145 -0
  115. package/output/core/classes/collection/Collection.d.ts +107 -0
  116. package/output/core/classes/collection/Collection.js +231 -0
  117. package/output/core/classes/complex/Complex.d.ts +99 -0
  118. package/output/core/classes/complex/Complex.js +135 -0
  119. package/output/core/classes/decimalSet/DecimalSet.d.ts +226 -0
  120. package/output/core/classes/decimalSet/DecimalSet.js +453 -0
  121. package/output/core/classes/dictionary/Dictionary.d.ts +102 -0
  122. package/output/core/classes/dictionary/Dictionary.js +213 -0
  123. package/output/core/classes/equation/Equation.d.ts +256 -0
  124. package/output/core/classes/equation/Equation.js +350 -0
  125. package/output/core/classes/expression/CoeffObject.d.ts +100 -0
  126. package/output/core/classes/expression/CoeffObject.js +198 -0
  127. package/output/core/classes/expression/Expression.d.ts +1674 -0
  128. package/output/core/classes/expression/Expression.js +2332 -0
  129. package/output/core/classes/expression/analysis.d.ts +25 -0
  130. package/output/core/classes/expression/analysis.js +218 -0
  131. package/output/core/classes/expression/collect.d.ts +9 -0
  132. package/output/core/classes/expression/collect.js +49 -0
  133. package/output/core/classes/expression/format.d.ts +45 -0
  134. package/output/core/classes/expression/format.js +217 -0
  135. package/output/core/classes/expression/products.d.ts +23 -0
  136. package/output/core/classes/expression/products.js +115 -0
  137. package/output/core/classes/expression/shortcuts.d.ts +35 -0
  138. package/output/core/classes/expression/shortcuts.js +129 -0
  139. package/output/core/classes/expression/traversal.d.ts +31 -0
  140. package/output/core/classes/expression/traversal.js +216 -0
  141. package/output/core/classes/expression/trig.d.ts +25 -0
  142. package/output/core/classes/expression/trig.js +40 -0
  143. package/output/core/classes/expression/utils.d.ts +52 -0
  144. package/output/core/classes/expression/utils.js +189 -0
  145. package/output/core/classes/lookupTable/LookupTable.d.ts +12 -0
  146. package/output/core/classes/lookupTable/LookupTable.js +55 -0
  147. package/output/core/classes/matrix/Matrix.d.ts +227 -0
  148. package/output/core/classes/matrix/Matrix.js +889 -0
  149. package/output/core/classes/matrix/Sylvester.d.ts +11 -0
  150. package/output/core/classes/matrix/Sylvester.js +54 -0
  151. package/output/core/classes/matrix/functions.d.ts +26 -0
  152. package/output/core/classes/matrix/functions.js +52 -0
  153. package/output/core/classes/matrix/utils.d.ts +9 -0
  154. package/output/core/classes/matrix/utils.js +22 -0
  155. package/output/core/classes/parser/Parser.d.ts +480 -0
  156. package/output/core/classes/parser/Parser.js +1812 -0
  157. package/output/core/classes/parser/Token.d.ts +58 -0
  158. package/output/core/classes/parser/Token.js +137 -0
  159. package/output/core/classes/parser/constants.d.ts +160 -0
  160. package/output/core/classes/parser/constants.js +227 -0
  161. package/output/core/classes/parser/helpers.d.ts +21 -0
  162. package/output/core/classes/parser/helpers.js +42 -0
  163. package/output/core/classes/parser/operations/add.d.ts +15 -0
  164. package/output/core/classes/parser/operations/add.js +238 -0
  165. package/output/core/classes/parser/operations/comma.d.ts +7 -0
  166. package/output/core/classes/parser/operations/comma.js +11 -0
  167. package/output/core/classes/parser/operations/compare.d.ts +21 -0
  168. package/output/core/classes/parser/operations/compare.js +461 -0
  169. package/output/core/classes/parser/operations/divide.d.ts +2 -0
  170. package/output/core/classes/parser/operations/divide.js +72 -0
  171. package/output/core/classes/parser/operations/functions.d.ts +46 -0
  172. package/output/core/classes/parser/operations/functions.js +430 -0
  173. package/output/core/classes/parser/operations/multiply.d.ts +11 -0
  174. package/output/core/classes/parser/operations/multiply.js +321 -0
  175. package/output/core/classes/parser/operations/power.d.ts +48 -0
  176. package/output/core/classes/parser/operations/power.js +673 -0
  177. package/output/core/classes/parser/operations/subtract.d.ts +3 -0
  178. package/output/core/classes/parser/operations/subtract.js +35 -0
  179. package/output/core/classes/parser/preprocess.d.ts +14 -0
  180. package/output/core/classes/parser/preprocess.js +259 -0
  181. package/output/core/classes/parser/scripting/controlFlow.d.ts +121 -0
  182. package/output/core/classes/parser/scripting/controlFlow.js +355 -0
  183. package/output/core/classes/parser/scripting/evaluate.d.ts +10 -0
  184. package/output/core/classes/parser/scripting/evaluate.js +112 -0
  185. package/output/core/classes/parser/scripting/functions.d.ts +14 -0
  186. package/output/core/classes/parser/scripting/functions.js +59 -0
  187. package/output/core/classes/parser/scripting/scope.d.ts +35 -0
  188. package/output/core/classes/parser/scripting/scope.js +155 -0
  189. package/output/core/classes/parser/types.d.ts +125 -0
  190. package/output/core/classes/parser/types.js +2 -0
  191. package/output/core/classes/parser/wrappers/IndexedReference.d.ts +31 -0
  192. package/output/core/classes/parser/wrappers/IndexedReference.js +68 -0
  193. package/output/core/classes/parser/wrappers/KeyValuePair.d.ts +24 -0
  194. package/output/core/classes/parser/wrappers/KeyValuePair.js +51 -0
  195. package/output/core/classes/polynomial/Polynomial.d.ts +500 -0
  196. package/output/core/classes/polynomial/Polynomial.js +1149 -0
  197. package/output/core/classes/polynomial/Term.d.ts +222 -0
  198. package/output/core/classes/polynomial/Term.js +430 -0
  199. package/output/core/classes/polynomial/functions.d.ts +69 -0
  200. package/output/core/classes/polynomial/functions.js +126 -0
  201. package/output/core/classes/polynomial/utils.d.ts +62 -0
  202. package/output/core/classes/polynomial/utils.js +206 -0
  203. package/output/core/classes/rational/Rational.d.ts +504 -0
  204. package/output/core/classes/rational/Rational.js +779 -0
  205. package/output/core/classes/seq/SEQ.d.ts +13 -0
  206. package/output/core/classes/seq/SEQ.js +137 -0
  207. package/output/core/classes/valuesSet/ValuesSet.d.ts +179 -0
  208. package/output/core/classes/valuesSet/ValuesSet.js +381 -0
  209. package/output/core/classes/vector/Vector.d.ts +222 -0
  210. package/output/core/classes/vector/Vector.js +497 -0
  211. package/output/core/classes/vector/functions.d.ts +28 -0
  212. package/output/core/classes/vector/functions.js +47 -0
  213. package/output/core/common/classes/MathematicalAggregate.d.ts +53 -0
  214. package/output/core/common/classes/MathematicalAggregate.js +140 -0
  215. package/output/core/common/classes/Scope.d.ts +62 -0
  216. package/output/core/common/classes/Scope.js +122 -0
  217. package/output/core/common/classes/StructuredEntity.d.ts +55 -0
  218. package/output/core/common/classes/StructuredEntity.js +151 -0
  219. package/output/core/common/common.d.ts +63 -0
  220. package/output/core/common/common.js +279 -0
  221. package/output/core/common/functions/functions.d.ts +14 -0
  222. package/output/core/common/functions/functions.js +33 -0
  223. package/output/core/common/functions/structuredEntityUtils.d.ts +27 -0
  224. package/output/core/common/functions/structuredEntityUtils.js +40 -0
  225. package/output/core/converters/BaseConverter.d.ts +97 -0
  226. package/output/core/converters/BaseConverter.js +405 -0
  227. package/output/core/converters/Converter.d.ts +111 -0
  228. package/output/core/converters/Converter.js +802 -0
  229. package/output/core/converters/Pattern.d.ts +71 -0
  230. package/output/core/converters/Pattern.js +302 -0
  231. package/output/core/dispatch.d.ts +34 -0
  232. package/output/core/dispatch.js +304 -0
  233. package/output/core/errors.d.ts +531 -0
  234. package/output/core/errors.js +621 -0
  235. package/output/core/functions/bigint/bigint.d.ts +121 -0
  236. package/output/core/functions/bigint/bigint.js +392 -0
  237. package/output/core/functions/bigint/primeFactor.d.ts +49 -0
  238. package/output/core/functions/bigint/primeFactor.js +267 -0
  239. package/output/core/functions/bigint/primes.d.ts +1 -0
  240. package/output/core/functions/bigint/primes.js +11 -0
  241. package/output/core/functions/build/definitions.d.ts +12 -0
  242. package/output/core/functions/build/definitions.js +133 -0
  243. package/output/core/functions/build/index.d.ts +32 -0
  244. package/output/core/functions/build/index.js +136 -0
  245. package/output/core/functions/complex.d.ts +90 -0
  246. package/output/core/functions/complex.js +482 -0
  247. package/output/core/functions/decimal.d.ts +24 -0
  248. package/output/core/functions/decimal.js +664 -0
  249. package/output/core/functions/expand/expand.d.ts +42 -0
  250. package/output/core/functions/expand/expand.js +376 -0
  251. package/output/core/functions/fresnelNumeric.d.ts +12 -0
  252. package/output/core/functions/fresnelNumeric.js +123 -0
  253. package/output/core/functions/numeric.d.ts +140 -0
  254. package/output/core/functions/numeric.js +790 -0
  255. package/output/core/functions/rationalNormalization.d.ts +11 -0
  256. package/output/core/functions/rationalNormalization.js +117 -0
  257. package/output/core/functions/setFunction.d.ts +19 -0
  258. package/output/core/functions/setFunction.js +75 -0
  259. package/output/core/functions/string.d.ts +26 -0
  260. package/output/core/functions/string.js +101 -0
  261. package/output/core/functions/subst.d.ts +90 -0
  262. package/output/core/functions/subst.js +498 -0
  263. package/output/core/functions/utils.d.ts +24 -0
  264. package/output/core/functions/utils.js +51 -0
  265. package/output/core/types.d.ts +48 -0
  266. package/output/core/types.js +2 -0
  267. package/output/index.d.ts +339 -0
  268. package/output/index.js +715 -0
  269. package/output/math/defint/defintDecimal.d.ts +37 -0
  270. package/output/math/defint/defintDecimal.js +320 -0
  271. package/output/math/defint/defintNative.d.ts +57 -0
  272. package/output/math/defint/defintNative.js +292 -0
  273. package/output/math/geometry.d.ts +8 -0
  274. package/output/math/geometry.js +32 -0
  275. package/output/math/math.d.ts +655 -0
  276. package/output/math/math.js +1811 -0
  277. package/output/math/trig.d.ts +518 -0
  278. package/output/math/trig.js +1444 -0
  279. package/output/math/trunc.d.ts +19 -0
  280. package/output/math/trunc.js +36 -0
  281. package/output/math/utils.d.ts +60 -0
  282. package/output/math/utils.js +180 -0
  283. package/output/solve/classes/DecimalMatrix.d.ts +17 -0
  284. package/output/solve/classes/DecimalMatrix.js +86 -0
  285. package/output/solve/classes/FunctionSolver.d.ts +135 -0
  286. package/output/solve/classes/FunctionSolver.js +433 -0
  287. package/output/solve/classes/MultivariateSolver.d.ts +84 -0
  288. package/output/solve/classes/MultivariateSolver.js +240 -0
  289. package/output/solve/classes/PolynomialSolver.d.ts +85 -0
  290. package/output/solve/classes/PolynomialSolver.js +292 -0
  291. package/output/solve/classes/SolutionSet.d.ts +153 -0
  292. package/output/solve/classes/SolutionSet.js +357 -0
  293. package/output/solve/classes/Solver.d.ts +17 -0
  294. package/output/solve/classes/Solver.js +132 -0
  295. package/output/solve/classes/SymbolicSolver.d.ts +74 -0
  296. package/output/solve/classes/SymbolicSolver.js +601 -0
  297. package/output/solve/linsolve.d.ts +51 -0
  298. package/output/solve/linsolve.js +225 -0
  299. package/output/solve/solve.d.ts +34 -0
  300. package/output/solve/solve.js +260 -0
  301. package/output/solve/solveSystem.d.ts +31 -0
  302. package/output/solve/solveSystem.js +290 -0
  303. package/output/solve/utils.d.ts +9 -0
  304. package/output/solve/utils.js +62 -0
  305. package/output/utils/array.d.ts +42 -0
  306. package/output/utils/array.js +98 -0
  307. package/output/utils/debug.d.ts +131 -0
  308. package/output/utils/debug.js +295 -0
  309. package/output/utils/decimal.d.ts +3 -0
  310. package/output/utils/decimal.js +16 -0
  311. package/output/utils/numeric.d.ts +14 -0
  312. package/output/utils/numeric.js +51 -0
  313. package/output/utils/object.d.ts +26 -0
  314. package/output/utils/object.js +56 -0
  315. package/package.json +213 -57
  316. package/.travis.yml +0 -3
  317. package/Algebra.js +0 -4568
  318. package/BREAKING_CHANGES.md +0 -5
  319. package/CODE_OF_CONDUCT.md +0 -46
  320. package/CONTRIBUTING.md +0 -14
  321. package/Calculus.js +0 -2675
  322. package/Extra.js +0 -622
  323. package/Solve.js +0 -1783
  324. package/all.js +0 -16
  325. package/all.min.js +0 -1
  326. package/gulpfile.js +0 -16
  327. package/index.html +0 -158
  328. package/license.txt +0 -19
  329. package/nerdamer.core.js +0 -12510
  330. package/spec/LaTeX.spec.js +0 -302
  331. package/spec/TeXConvert.spec.js +0 -8
  332. package/spec/algebra.spec.js +0 -287
  333. package/spec/basic_parser.spec.js +0 -134
  334. package/spec/build.spec.js +0 -131
  335. package/spec/calculus.spec.js +0 -183
  336. package/spec/core.spec.js +0 -2970
  337. package/spec/extra.spec.js +0 -54
  338. package/spec/solve.spec.js +0 -126
  339. package/spec/support/jasmine.json +0 -11
  340. package/spec/support/utils.js +0 -42
  341. package/spec/text.spec.js +0 -132
@@ -0,0 +1,339 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.tryIntegrationByParts = tryIntegrationByParts;
4
+ const Expression_1 = require("../../core/classes/expression/Expression");
5
+ const shortcuts_1 = require("../../core/classes/expression/shortcuts");
6
+ const trig_1 = require("../../core/classes/expression/trig");
7
+ const constants_1 = require("../../core/classes/parser/constants");
8
+ const math_1 = require("../../math/math");
9
+ const diff_1 = require("../derivative/diff");
10
+ /**
11
+ * LIATE priority constants.
12
+ * Higher number = should be chosen as u.
13
+ */
14
+ const LIATE = {
15
+ EXP: 0,
16
+ TRIG: 1,
17
+ ALGEBRAIC: 2,
18
+ INVERSE_TRIG: 3,
19
+ LOG: 4,
20
+ };
21
+ /**
22
+ * Maximum number of recursive IBP applications within a single
23
+ * integration attempt. This is independent of integrate's own
24
+ * MAX_DEPTH and exists to prevent runaway recursion from
25
+ * pathological integrands like e^x·tan(x).
26
+ */
27
+ const MAX_IBP_DEPTH = 4;
28
+ /**
29
+ * Extracts the maximum power of the integration variable in an expression.
30
+ * For a product like x^3·sin(x), returns 3. For a sum produced by
31
+ * linearity (e.g. 2·x·sin(x) + ...), returns the maximum across terms.
32
+ * Returns 0 if the variable does not appear algebraically (e.g. pure sin(x)).
33
+ */
34
+ function maxAlgebraicDegree(expr, v) {
35
+ let retval = undefined;
36
+ if (expr.isVAR() && expr.hasVariable(v)) {
37
+ // x^n — getPower() returns the exponent
38
+ retval = expr.getPower();
39
+ }
40
+ else if (expr.isProduct()) {
41
+ let maxDeg = (0, shortcuts_1.zero)();
42
+ for (const factor of expr.elementsArray()) {
43
+ if (factor.isVAR() && factor.hasVariable(v)) {
44
+ const p = factor.getPower();
45
+ maxDeg = (0, math_1.max)(maxDeg, p);
46
+ }
47
+ }
48
+ retval = maxDeg;
49
+ }
50
+ else if (expr.isSum()) {
51
+ let maxDeg = (0, shortcuts_1.zero)();
52
+ expr.each((term) => {
53
+ maxDeg = (0, math_1.max)(maxDeg, maxAlgebraicDegree(term, v));
54
+ });
55
+ retval = maxDeg;
56
+ }
57
+ return retval ?? (0, shortcuts_1.zero)();
58
+ }
59
+ /**
60
+ * Counts the number of function applications (sin, cos, log, etc.)
61
+ * in an expression. Used as a structural complexity measure for
62
+ * non-algebraic IBP progress checking.
63
+ */
64
+ function functionCount(expr) {
65
+ let count = 0;
66
+ if (expr.isFunction()) {
67
+ count = 1;
68
+ }
69
+ if (expr.isProduct() || expr.isSum()) {
70
+ expr.each((child) => {
71
+ count += functionCount(child);
72
+ });
73
+ }
74
+ return count;
75
+ }
76
+ /**
77
+ * Determines whether IBP has made progress by producing a simpler
78
+ * remainder integrand. The definition of "progress" depends on the
79
+ * LIATE category of u:
80
+ *
81
+ * - ALGEBRAIC u (polynomial × trig/exp): progress means the polynomial
82
+ * degree in the integration variable strictly decreased. This is the
83
+ * fundamental guarantee of IBP for x^n·f(x) — each round reduces
84
+ * the degree by 1, terminating after n rounds.
85
+ *
86
+ * - LOG or INVERSE_TRIG u: one round of IBP eliminates the
87
+ * transcendental factor, replacing it with an algebraic derivative.
88
+ * Progress means the new integrand has fewer function nodes than
89
+ * the original.
90
+ *
91
+ * - Anything else: fallback to a structural comparison — the new
92
+ * integrand must have strictly fewer function nodes.
93
+ *
94
+ * Returns true if the new integrand represents progress.
95
+ */
96
+ function isProgress(original, newIntegrand, uCategory, v) {
97
+ if (uCategory === LIATE.ALGEBRAIC) {
98
+ // Polynomial degree must strictly decrease
99
+ const oldDeg = maxAlgebraicDegree(original, v);
100
+ const newDeg = maxAlgebraicDegree(newIntegrand, v);
101
+ return newDeg < oldDeg;
102
+ }
103
+ if (uCategory === LIATE.LOG || uCategory === LIATE.INVERSE_TRIG) {
104
+ // Function count must decrease (log/invtrig disappears after differentiation)
105
+ return functionCount(newIntegrand) < functionCount(original);
106
+ }
107
+ // Fallback: structural complexity must decrease
108
+ return functionCount(newIntegrand) < functionCount(original);
109
+ }
110
+ /**
111
+ * Classifies an expression by LIATE category.
112
+ * Returns -1 if unclassifiable.
113
+ */
114
+ function liatePriority(expr) {
115
+ // Algebraic: x^n (variable with a power)
116
+ if (expr.isVAR()) {
117
+ return LIATE.ALGEBRAIC;
118
+ }
119
+ // Exponential: e^(ax) or a^(bx)
120
+ if (expr.isEXP()) {
121
+ return LIATE.EXP;
122
+ }
123
+ if (expr.isFunction()) {
124
+ const name = expr.name;
125
+ // Logarithmic
126
+ if (name === constants_1.LOG || name === constants_1.LN) {
127
+ return LIATE.LOG;
128
+ }
129
+ // Inverse trig
130
+ if ((0, trig_1.isInverseTrig)(expr)) {
131
+ return LIATE.INVERSE_TRIG;
132
+ }
133
+ // Trigonometric
134
+ if ((0, trig_1.isTrig)(expr)) {
135
+ return LIATE.TRIG;
136
+ }
137
+ // Hyperbolic (treat like trig for LIATE purposes)
138
+ if ((0, trig_1.isHyperbolicTrig)(expr)) {
139
+ return LIATE.TRIG;
140
+ }
141
+ }
142
+ return -1;
143
+ }
144
+ /**
145
+ * Detects whether a pair of LIATE categories is known to produce
146
+ * non-terminating IBP recursion. This goes beyond the simple
147
+ * same-category check to catch cross-category pathological pairs.
148
+ *
149
+ * Known problematic pairs:
150
+ * - TRIG + TRIG: e.g. sin(x)·cos(x) — cyclic
151
+ * - EXP + EXP: e.g. e^x·2^x — cyclic
152
+ * - EXP + TRIG with non-integrable trig: e.g. e^x·tan(x) —
153
+ * produces increasingly complex trig powers
154
+ *
155
+ * LOG + EXP (e.g. e^x·log(x)) and LOG + TRIG (e.g. sin(x)·log(x))
156
+ * are NOT blocked here. After one IBP round, the remainder is of the
157
+ * form f(x)/x which maps to special functions (Ei, Si, Ci) via the
158
+ * integration table. The isProgress guard prevents spiraling if the
159
+ * table entry is missing.
160
+ *
161
+ * The EXP+TRIG pair is only problematic when the trig function
162
+ * is not one whose integral stays in the same family (sin/cos).
163
+ * e^x·sin(x) and e^x·cos(x) are handled by the table, so they
164
+ * never reach IBP. But e^x·tan(x), e^x·sec(x), etc. spiral.
165
+ */
166
+ function isCyclicPair(p0, p1, u, dv) {
167
+ // Same category: trig+trig or exp+exp
168
+ if (p0 === p1 && (p0 === LIATE.TRIG || p0 === LIATE.EXP)) {
169
+ return true;
170
+ }
171
+ // EXP + TRIG where the trig function is not sin/cos
172
+ // (sin/cos pairs are handled by the integration table and never reach here,
173
+ // but tan, sec, csc, cot produce ever-growing powers under IBP)
174
+ if ((p0 === LIATE.EXP && p1 === LIATE.TRIG) || (p0 === LIATE.TRIG && p1 === LIATE.EXP)) {
175
+ const trigFactor = p0 === LIATE.TRIG ? u : dv;
176
+ if (trigFactor.isFunction()) {
177
+ const name = trigFactor.name;
178
+ // sin and cos are safe (table handles e^x·sin/cos directly)
179
+ // Everything else spirals
180
+ if (name !== constants_1.SIN && name !== constants_1.COS) {
181
+ return true;
182
+ }
183
+ }
184
+ }
185
+ return false;
186
+ }
187
+ function tryMergeDerivativePair(varFactors, v) {
188
+ if (varFactors.length < 3) {
189
+ return undefined;
190
+ }
191
+ const dx = Expression_1.Expression.create(v);
192
+ for (let i = 0; i < varFactors.length; i++) {
193
+ const candidate = varFactors[i];
194
+ const dCandidate = (0, diff_1.diff)(candidate, dx);
195
+ if (dCandidate.isFunction(constants_1.DIFF)) {
196
+ continue;
197
+ }
198
+ for (let j = 0; j < varFactors.length; j++) {
199
+ if (j === i) {
200
+ continue;
201
+ }
202
+ let rest;
203
+ for (let k = 0; k < varFactors.length; k++) {
204
+ if (k === i || k === j) {
205
+ continue;
206
+ }
207
+ rest = rest ? rest.times(varFactors[k]) : varFactors[k];
208
+ }
209
+ if (!rest) {
210
+ continue;
211
+ }
212
+ // Check whether dCandidate is proportional to rest
213
+ const q = dCandidate.div(rest);
214
+ if (!q.hasVariable(v)) {
215
+ return [candidate, varFactors[j]];
216
+ }
217
+ }
218
+ }
219
+ return undefined;
220
+ }
221
+ /**
222
+ * Attempts integration by parts for a product with two variable-dependent factors.
223
+ *
224
+ * LIATE priority selects `u`; independent multipliers are preserved separately.
225
+ * Category-specific progress checks and a dedicated recursion bound reject
226
+ * cyclic or increasingly complex decompositions.
227
+ *
228
+ * @param x - Product integrand.
229
+ * @param v - Integration variable.
230
+ * @param integrate - Recursive integration strategy supplied by the caller.
231
+ * @param depth - Current outer integration depth.
232
+ * @param ibpDepth - Current integration-by-parts depth.
233
+ * @returns An antiderivative when the transformation makes progress, otherwise
234
+ * `undefined` so another strategy can run.
235
+ */
236
+ function tryIntegrationByParts(x, v, integrate, depth = 0, ibpDepth = 0) {
237
+ if (!x.isProduct()) {
238
+ return undefined;
239
+ }
240
+ // IBP-specific depth guard: prevent runaway recursion independent of
241
+ // integrate's own MAX_DEPTH. This fires much sooner and avoids the
242
+ // long delays caused by exhausting the global depth limit.
243
+ if (ibpDepth >= MAX_IBP_DEPTH) {
244
+ return undefined;
245
+ }
246
+ const factors = x.elementsArray();
247
+ // Extract the overall multiplier and variable-containing factors
248
+ const varFactors = [];
249
+ // IMPORTANT: elementsArray() does not include the product's own multiplier, so pull it from the expression.
250
+ let coefficient = x.getMultiplier(true);
251
+ for (let factor of factors) {
252
+ if (!factor.hasVariable(v)) {
253
+ // Constant factor: fold it into the coefficient
254
+ coefficient = coefficient.times(factor);
255
+ }
256
+ else {
257
+ // Variable factor: also peel off its own multiplier so it doesn't get dropped in recursive IBP.
258
+ // Example: 3*x^2*e^x can appear with the 3 sitting on the product multiplier OR on the factor.
259
+ const m = factor.getMultiplier(true);
260
+ if (!m.isOne()) {
261
+ coefficient = coefficient.times(m);
262
+ factor = factor.div(m);
263
+ }
264
+ varFactors.push(factor);
265
+ }
266
+ }
267
+ if (varFactors.length > 2) {
268
+ const merged = tryMergeDerivativePair(varFactors, v);
269
+ if (merged) {
270
+ varFactors.length = 0;
271
+ varFactors.push(...merged);
272
+ }
273
+ }
274
+ // IBP needs exactly 2 variable-containing factors
275
+ if (varFactors.length !== 2) {
276
+ return undefined;
277
+ }
278
+ // Classify and assign u and dv using LIATE priority
279
+ const p0 = liatePriority(varFactors[0]);
280
+ const p1 = liatePriority(varFactors[1]);
281
+ // If either factor is unclassified, bail
282
+ if (p0 < 0 || p1 < 0) {
283
+ return undefined;
284
+ }
285
+ // Higher priority → u (differentiates to something simpler)
286
+ let u, dv;
287
+ if (p0 >= p1) {
288
+ u = varFactors[0];
289
+ dv = varFactors[1];
290
+ }
291
+ else {
292
+ u = varFactors[1];
293
+ dv = varFactors[0];
294
+ }
295
+ // Detect cyclic or pathological LIATE pairings that will never converge
296
+ const uCategory = p0 >= p1 ? p0 : p1;
297
+ if (isCyclicPair(p0, p1, u, dv)) {
298
+ return undefined;
299
+ }
300
+ // Compute du = d/dx(u)
301
+ const du = (0, diff_1.diff)(u, Expression_1.Expression.create(v));
302
+ // If diff returned a symbolic diff(...) expression, it couldn't compute the derivative
303
+ if (du.isFunction(constants_1.DIFF)) {
304
+ return undefined;
305
+ }
306
+ // Compute v_result = ∫ dv dx
307
+ const vResult = integrate(dv, v, depth);
308
+ if (vResult.isFunction(constants_1.INTEGRATE)) {
309
+ return undefined;
310
+ } // dv can't be integrated
311
+ // ∫ u·dv = u·v - ∫ v·du
312
+ const uv = coefficient.times(u).times(vResult);
313
+ // Build the new integrand: v·du (with the original coefficient)
314
+ const newIntegrand = coefficient.times(vResult).times(du);
315
+ // Progress guard: verify IBP is actually simplifying the integrand.
316
+ // The definition of "progress" is LIATE-category-aware:
317
+ // - Algebraic u: polynomial degree must decrease
318
+ // - Log/InvTrig u: function count must decrease
319
+ // - Fallback: structural function count must decrease
320
+ if (!isProgress(x, newIntegrand, uCategory, v)) {
321
+ return undefined;
322
+ }
323
+ // Try to integrate v·du
324
+ const remainder = integrate(newIntegrand, v, depth);
325
+ // If the remainder is fully symbolic (nothing was integrated), IBP didn't help
326
+ // But allow partial results (some terms integrated via linearity)
327
+ let retval;
328
+ if (remainder.isFunction(constants_1.INTEGRATE)) {
329
+ // One more check: try IBP recursively on the remainder
330
+ const innerResult = tryIntegrationByParts(newIntegrand, v, integrate, depth + 1, ibpDepth + 1);
331
+ if (innerResult !== undefined) {
332
+ retval = uv.plus(innerResult.times((0, shortcuts_1.minusOne)()));
333
+ }
334
+ }
335
+ else {
336
+ retval = uv.plus(remainder.times((0, shortcuts_1.minusOne)()));
337
+ }
338
+ return retval;
339
+ }
@@ -0,0 +1,135 @@
1
+ import { Expression } from '../../core/classes/expression/Expression';
2
+ /**
3
+ * Attempts to detect an f(x)·f'(x) substitution structure from a list of
4
+ * multiplicative factors.
5
+ *
6
+ * The algorithm performs a contiguous range search over the factors.
7
+ * For each contiguous block it builds a candidate f(x) and compares it
8
+ * against the remaining factors.
9
+ *
10
+ * Example structure detected:
11
+ *
12
+ * (a^x*log(a)*cos(x) - a^x*sin(x)) * a^x*cos(x)
13
+ *
14
+ * which matches
15
+ *
16
+ * f(x) = a^x*cos(x)
17
+ * f'(x) = a^x*log(a)*cos(x) - a^x*sin(x)
18
+ *
19
+ * yielding
20
+ *
21
+ * ∫ f f' dx = f² / 2
22
+ *
23
+ * To reduce symbolic overhead:
24
+ *
25
+ * - The total product is computed once.
26
+ * - The left candidate product grows incrementally.
27
+ * - The complementary product is obtained via division.
28
+ *
29
+ * @param factors multiplicative factors of the integrand
30
+ * @param x integration variable
31
+ * @returns substitution match or undefined if none found
32
+ */
33
+ export declare function bySubstitution(factors: Expression[], x: string): {
34
+ fx: Expression;
35
+ constant: Expression;
36
+ power: Expression;
37
+ } | undefined;
38
+ /**
39
+ * Attempts to integrate an expression using product-style substitution.
40
+ *
41
+ * This function prepares the expression for substitution detection
42
+ * by extracting multiplicative factors and then delegating to
43
+ * {@link bySubstitution}.
44
+ *
45
+ * The method specifically searches for integrands of the form
46
+ *
47
+ * c * f(x) * f'(x)
48
+ *
49
+ * which integrate to
50
+ *
51
+ * c * f(x)² / 2
52
+ *
53
+ * Factorization is only performed when necessary to avoid the
54
+ * significant cost of factoring expressions unnecessarily.
55
+ *
56
+ * @param fx expression to integrate
57
+ * @param x integration variable
58
+ * @returns substitution match information or undefined
59
+ */
60
+ export declare function tryIntegrateBySubstitution(fx: Expression, x: string): {
61
+ fx: Expression;
62
+ constant: Expression;
63
+ power: Expression;
64
+ } | undefined;
65
+ /**
66
+ * Attempts substitution when one factor wraps an inner expression and the
67
+ * remaining factors are proportional to its derivative.
68
+ *
69
+ * @param fx - Complete product integrand, used to select a fresh variable.
70
+ * @param factors - Multiplicative factors to test.
71
+ * @param x - Integration variable.
72
+ * @returns The back-substituted antiderivative, or `undefined` when the outer
73
+ * factor is not covered by the integration table.
74
+ */
75
+ export declare function tryIntegrateByWrappedFactorSubstitution(fx: Expression, factors: Expression[], x: string): Expression | undefined;
76
+ /**
77
+ * Attempts to detect a logarithmic substitution structure of the form
78
+ *
79
+ * c * f'(x) / f(x)
80
+ *
81
+ * by extracting the numerator and denominator of the expression and
82
+ * testing whether the numerator is proportional to the derivative of
83
+ * the denominator.
84
+ *
85
+ * This is much cheaper than the contiguous-factor search used for
86
+ * product-style substitution because the denominator already provides
87
+ * the natural candidate for f(x).
88
+ *
89
+ * Examples:
90
+ *
91
+ * (2*x)/(1+x^2) -> f(x) = 1+x^2, constant = 1
92
+ * cos(x)/sin(x) -> f(x) = sin(x), constant = 1
93
+ * 3*cos(x)/sin(x) -> f(x) = sin(x), constant = 3
94
+ *
95
+ * Non-example:
96
+ *
97
+ * f(x)/f'(x)
98
+ *
99
+ * That is not the logarithmic rule and should not be handled here.
100
+ *
101
+ * @param fx expression to analyze
102
+ * @param x integration variable
103
+ * @returns logarithmic substitution match information or undefined
104
+ */
105
+ export declare function tryIntegrateByLogSubstitution(fx: Expression, x: string): {
106
+ fx: Expression;
107
+ constant: Expression;
108
+ } | undefined;
109
+ /**
110
+ * Attempts to detect a generalized power-quotient substitution structure:
111
+ *
112
+ * integrand = c * f'(x) / f(x)^n
113
+ *
114
+ * which integrates to
115
+ *
116
+ * c * f(x)^(1-n) / (1-n) for n ≠ 1
117
+ *
118
+ * The n=1 case is the logarithmic substitution handled by
119
+ * tryIntegrateByLogSubstitution. This function handles n ≠ 1,
120
+ * including fractional powers like n=1/2 (square root denominators).
121
+ *
122
+ * This catches integrands like:
123
+ *
124
+ * x / sqrt(1-x²) → f = 1-x², f' = -2x, n = 1/2
125
+ * x / (1+x²)² → f = 1+x², f' = 2x, n = 2
126
+ *
127
+ * @param fx expression to analyze
128
+ * @param x integration variable
129
+ * @returns match with fx (the inner function), constant, and power (the denominator exponent n)
130
+ */
131
+ export declare function tryIntegrateByPowerSubstitution(fx: Expression, x: string): {
132
+ fx: Expression;
133
+ constant: Expression;
134
+ power: Expression;
135
+ } | undefined;