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,433 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.FunctionSolver = void 0;
7
+ const decimal_js_1 = __importDefault(require("decimal.js"));
8
+ const Expression_1 = require("../../core/classes/expression/Expression");
9
+ const errors_1 = require("../../core/errors");
10
+ const DEFAULT_LOWER_BOUND = -100;
11
+ const DEFAULT_UPPER_BOUND = 100;
12
+ const DEFAULT_DERIVATIVE_STEP = 1e-15;
13
+ const DEFAULT_MAX_ITERATIONS = 200;
14
+ const DEFAULT_STEP_SIZE = 0.1;
15
+ const DEFAULT_TOLERANCE = 1e-14;
16
+ const DEFAULT_MAX_ROOTS = 20;
17
+ const BRENT_METHOD = 'Brent';
18
+ const NEWTON_RAPHSON_METHOD = 'NewtonRaphson';
19
+ const DEFAULT_ROOT_FINDING_METHOD = BRENT_METHOD;
20
+ /**
21
+ * Searches a fixed interval for real roots of a univariate expression.
22
+ *
23
+ * @remarks
24
+ * {@link roots} scans the configured interval from its center toward both
25
+ * endpoints. It refines sign-changing intervals with Brent's method or
26
+ * Newton-Raphson, verifies residuals, merges nearby results, and returns roots
27
+ * in ascending order. This is a heuristic search: an even-multiplicity root
28
+ * can be missed unless a scan point lands sufficiently close to it, and
29
+ * periodic functions are limited by both the interval and `maxRoots`.
30
+ *
31
+ * Calculations use the ambient `decimal.js` precision. An Expression supplied
32
+ * to the constructor is retained rather than copied, and the public settings
33
+ * may be adjusted before a search.
34
+ *
35
+ * @example
36
+ * ```ts
37
+ * const solver = new FunctionSolver('cos(x)-x', 'x', {
38
+ * lowerBound: 0,
39
+ * upperBound: 1,
40
+ * });
41
+ * const roots = solver.roots();
42
+ * ```
43
+ */
44
+ class FunctionSolver {
45
+ derivativeStep;
46
+ func;
47
+ lowerBound;
48
+ maxIters;
49
+ maxRoots;
50
+ method;
51
+ stepSize;
52
+ tolerance;
53
+ upperBound;
54
+ variable;
55
+ verbose;
56
+ /**
57
+ * Creates a real-root solver for the configured search interval.
58
+ *
59
+ * @param func - Expression to evaluate, or a string parsed as an Expression.
60
+ * @param variable - Variable to substitute. When omitted, the expression must
61
+ * contain at most one variable.
62
+ * @param options - Search interval, refinement method, and tolerances.
63
+ * @throws {@link core!UnsupportedOperationError} If `variable` is omitted and the
64
+ * expression contains more than one variable.
65
+ */
66
+ constructor(func, variable, options = {}) {
67
+ this.func = typeof func === 'string' ? Expression_1.Expression.create(func) : func;
68
+ this.lowerBound = new decimal_js_1.default(options.lowerBound ?? DEFAULT_LOWER_BOUND);
69
+ this.upperBound = new decimal_js_1.default(options.upperBound ?? DEFAULT_UPPER_BOUND);
70
+ this.derivativeStep = new decimal_js_1.default(options.derivativeStep ?? DEFAULT_DERIVATIVE_STEP);
71
+ this.maxIters = options.maxIterations ?? DEFAULT_MAX_ITERATIONS;
72
+ this.variable = variable ?? this.getVariable();
73
+ this.stepSize = options.stepSize ?? DEFAULT_STEP_SIZE;
74
+ this.tolerance = new decimal_js_1.default(options.tolerance ?? DEFAULT_TOLERANCE);
75
+ this.maxRoots = options.maxRoots ?? DEFAULT_MAX_ROOTS;
76
+ this.verbose = options.verbose ?? false;
77
+ this.method = options.method ?? DEFAULT_ROOT_FINDING_METHOD;
78
+ }
79
+ calculateIntervals() {
80
+ const lower = this.lowerBound;
81
+ const upper = this.upperBound;
82
+ const step = new decimal_js_1.default(this.stepSize);
83
+ const length = upper.minus(lower);
84
+ const center = lower.plus(length.dividedBy(2).floor());
85
+ let x = center;
86
+ let u = center;
87
+ const intervals = [];
88
+ const lowerDistance = center.minus(lower);
89
+ const upperDistance = upper.minus(center);
90
+ const maxInterval = lowerDistance.greaterThan(upperDistance)
91
+ ? lowerDistance
92
+ : upperDistance;
93
+ for (let offset = new decimal_js_1.default(0); offset.lessThan(maxInterval); offset = offset.plus(step)) {
94
+ const y = x.minus(step);
95
+ const v = u.plus(step);
96
+ // Add the lower interval if it is still within bounds.
97
+ if (y.greaterThanOrEqualTo(lower)) {
98
+ intervals.push([x, y]);
99
+ }
100
+ // Add the upper interval if it is still within bounds.
101
+ if (v.lessThanOrEqualTo(upper)) {
102
+ intervals.push([u, v]);
103
+ }
104
+ x = y;
105
+ u = v;
106
+ }
107
+ return intervals;
108
+ }
109
+ getVariable() {
110
+ const variables = this.func.variables();
111
+ // This function can only handle univariate function
112
+ if (variables.length > 1) {
113
+ throw new errors_1.UnsupportedOperationError((0, errors_1.message)('univariateInputOnly'));
114
+ }
115
+ return variables[0];
116
+ }
117
+ /**
118
+ * Refines a bracket using Brent's combination of bisection, secant, and
119
+ * inverse-quadratic interpolation.
120
+ *
121
+ * @param a - First bracket endpoint.
122
+ * @param b - Second bracket endpoint.
123
+ * @returns Refinement metadata. Invalid brackets and exhausted iterations are
124
+ * represented in the returned {@link Root}; they are not thrown.
125
+ */
126
+ Brent(a, b) {
127
+ // Convert inputs to Decimal
128
+ let aVal = new decimal_js_1.default(a);
129
+ let bVal = new decimal_js_1.default(b);
130
+ const tol = this.tolerance;
131
+ let fa = this.evaluate(aVal);
132
+ let fb = this.evaluate(bVal);
133
+ const error = new decimal_js_1.default(Infinity);
134
+ // Check if root is at endpoint
135
+ if (fa.abs().lessThan(tol)) {
136
+ return {
137
+ root: aVal,
138
+ iterations: 0,
139
+ converged: false,
140
+ error: error,
141
+ errorMsg: (0, errors_1.message)('endPointIsRoot'),
142
+ };
143
+ }
144
+ if (fb.abs().lessThan(tol)) {
145
+ return {
146
+ root: bVal,
147
+ iterations: 0,
148
+ converged: true,
149
+ error: error,
150
+ errorMsg: (0, errors_1.message)('endPointIsRoot'),
151
+ };
152
+ }
153
+ const x = fa.times(fb);
154
+ // Ensure f(a) and f(b) have opposite signs
155
+ if (x.greaterThan(0)) {
156
+ return {
157
+ root: x,
158
+ iterations: 0,
159
+ converged: true,
160
+ error: error,
161
+ errorMsg: (0, errors_1.message)('differentSignsAtEndPointsRequired'),
162
+ };
163
+ }
164
+ // Ensure |f(a)| >= |f(b)|
165
+ if (fa.abs().lessThan(fb.abs())) {
166
+ [aVal, bVal] = [bVal, aVal];
167
+ [fa, fb] = [fb, fa];
168
+ }
169
+ let c = aVal;
170
+ let fc = fa;
171
+ let mflag = true;
172
+ let d = new decimal_js_1.default(0);
173
+ for (let iter = 0; iter < this.maxIters; iter++) {
174
+ let s;
175
+ // Use inverse quadratic interpolation if f(a), f(b), f(c) are distinct
176
+ if (!fa.equals(fc) && !fb.equals(fc)) {
177
+ s = aVal
178
+ .times(fb)
179
+ .times(fc)
180
+ .dividedBy(fa.minus(fb).times(fa.minus(fc)))
181
+ .plus(bVal
182
+ .times(fa)
183
+ .times(fc)
184
+ .dividedBy(fb.minus(fa).times(fb.minus(fc))))
185
+ .plus(c
186
+ .times(fa)
187
+ .times(fb)
188
+ .dividedBy(fc.minus(fa).times(fc.minus(fb))));
189
+ }
190
+ else {
191
+ // Use secant method
192
+ s = bVal.minus(fb.times(bVal.minus(aVal)).dividedBy(fb.minus(fa)));
193
+ }
194
+ // Conditions for bisection
195
+ const condition1 = s.lessThan(new decimal_js_1.default(3).times(aVal).plus(bVal).dividedBy(4)) ||
196
+ s.greaterThan(bVal);
197
+ const condition2 = mflag && s.minus(bVal).abs().greaterThanOrEqualTo(bVal.minus(c).abs().dividedBy(2));
198
+ const condition3 = !mflag && s.minus(bVal).abs().greaterThanOrEqualTo(c.minus(d).abs().dividedBy(2));
199
+ const condition4 = mflag && bVal.minus(c).abs().lessThan(tol);
200
+ const condition5 = !mflag && c.minus(d).abs().lessThan(tol);
201
+ if (condition1 || condition2 || condition3 || condition4 || condition5) {
202
+ // Use bisection
203
+ s = aVal.plus(bVal).dividedBy(2);
204
+ mflag = true;
205
+ }
206
+ else {
207
+ mflag = false;
208
+ }
209
+ const fs = this.evaluate(s);
210
+ d = c;
211
+ c = bVal;
212
+ fc = fb;
213
+ // Update interval
214
+ if (fa.times(fs).lessThan(0)) {
215
+ bVal = s;
216
+ fb = fs;
217
+ }
218
+ else {
219
+ aVal = s;
220
+ fa = fs;
221
+ }
222
+ // Ensure |f(a)| >= |f(b)|
223
+ if (fa.abs().lessThan(fb.abs())) {
224
+ [aVal, bVal] = [bVal, aVal];
225
+ [fa, fb] = [fb, fa];
226
+ }
227
+ const conditionA = fb.abs().lessThan(tol);
228
+ const conditionB = bVal.minus(aVal).abs().lessThan(tol);
229
+ // Check convergence
230
+ if (conditionA || conditionB) {
231
+ return {
232
+ root: bVal,
233
+ iterations: iter,
234
+ converged: true,
235
+ error: conditionA ? fb.abs().minus(tol) : bVal.minus(aVal).abs(),
236
+ };
237
+ }
238
+ }
239
+ return {
240
+ root: x,
241
+ iterations: this.maxIters,
242
+ converged: false,
243
+ error: error,
244
+ errorMsg: (0, errors_1.message)('convergenceFailed', { iter: String(this.maxIters) }),
245
+ };
246
+ }
247
+ /** Approximates the derivative with a central difference. */
248
+ df(x, h) {
249
+ const xPlusH = x.plus(h);
250
+ const xMinusH = x.minus(h);
251
+ const fPlusH = this.evaluate(xPlusH);
252
+ const fMinusH = this.evaluate(xMinusH);
253
+ // Central difference formula: (f(x+h) - f(x-h)) / (2h)
254
+ return fPlusH.minus(fMinusH).dividedBy(h.times(2));
255
+ }
256
+ /**
257
+ * Evaluates the configured expression at a real value.
258
+ *
259
+ * @throws {@link core!UnexpectedInputError} If evaluation does not produce a scalar
260
+ * Expression.
261
+ */
262
+ evaluate(at) {
263
+ const value = this.func.evaluate({ [this.variable]: at });
264
+ if (!Expression_1.Expression.isExpression(value)) {
265
+ throw new errors_1.UnexpectedInputError((0, errors_1.message)('unsupportedType'));
266
+ }
267
+ if (!value.isNUM()) {
268
+ throw new errors_1.UnexpectedInputError((0, errors_1.message)('wrongInput', {
269
+ expected: 'a real numeric value',
270
+ received: value.text(),
271
+ }));
272
+ }
273
+ return value.getMultiplier().toDecimal();
274
+ }
275
+ /**
276
+ * Refines a root from an initial guess using Newton-Raphson and a numerical
277
+ * derivative.
278
+ *
279
+ * @returns Refinement metadata, including non-convergence or a zero derivative.
280
+ */
281
+ NewtonRaphson(guess) {
282
+ const tol = this.tolerance;
283
+ const h = new decimal_js_1.default(this.derivativeStep);
284
+ let x = new decimal_js_1.default(guess);
285
+ let iterations = 0;
286
+ let error = new decimal_js_1.default(Infinity);
287
+ for (let i = 0; i < this.maxIters; i++) {
288
+ const fx = this.evaluate(x);
289
+ const fpx = this.df(x, h);
290
+ // Check for zero derivative (would cause division by zero)
291
+ if (fpx.isZero()) {
292
+ return {
293
+ root: x,
294
+ iterations: i,
295
+ converged: false,
296
+ error: fx.abs(),
297
+ errorMsg: (0, errors_1.message)('zeroDerivative', { x: x.toString() }),
298
+ };
299
+ }
300
+ // Newton-Raphson update: x_new = x - f(x) / f'(x)
301
+ const xNew = x.minus(fx.dividedBy(fpx));
302
+ // Calculate error as the absolute difference between iterations
303
+ error = xNew.minus(x).abs();
304
+ iterations = i + 1;
305
+ // Check for convergence
306
+ if (error.lessThanOrEqualTo(tol)) {
307
+ return {
308
+ root: xNew,
309
+ iterations,
310
+ converged: true,
311
+ error,
312
+ };
313
+ }
314
+ x = xNew;
315
+ }
316
+ // Did not converge within max iterations
317
+ return {
318
+ root: x,
319
+ iterations,
320
+ converged: false,
321
+ error,
322
+ };
323
+ }
324
+ /**
325
+ * Searches the configured interval for real roots.
326
+ *
327
+ * @returns Verified, deduplicated roots in ascending order, limited by
328
+ * `maxRoots`. Failed evaluations and failed refinements are skipped.
329
+ */
330
+ roots() {
331
+ const bVal = this.upperBound;
332
+ const tol = this.tolerance;
333
+ const roots = [];
334
+ let exit = false;
335
+ const evaluationCache = new Map();
336
+ const evaluatePoint = (point) => {
337
+ const key = point.toString();
338
+ let value = evaluationCache.get(key);
339
+ if (value === undefined) {
340
+ value = this.evaluate(point);
341
+ evaluationCache.set(key, value);
342
+ }
343
+ return value;
344
+ };
345
+ const addRoot = (root) => {
346
+ if (this.evaluate(root).abs().lessThan(tol)) {
347
+ roots.push(root);
348
+ }
349
+ // Check if the maximum number of roots was reached. If so we're done
350
+ if (roots.length >= this.maxRoots) {
351
+ exit = true;
352
+ }
353
+ };
354
+ const intervals = this.calculateIntervals();
355
+ for (const interval of intervals) {
356
+ if (exit) {
357
+ return roots.sort((a, b) => a.comparedTo(b)).map(x => Expression_1.Expression.create(x));
358
+ }
359
+ try {
360
+ const x1 = new decimal_js_1.default(interval[0]);
361
+ const x2 = new decimal_js_1.default(interval[1]);
362
+ const f1 = evaluatePoint(x1);
363
+ const f2 = evaluatePoint(x2);
364
+ // Check if root is at subdivision point
365
+ if (f1.abs().lessThan(tol)) {
366
+ // Avoid duplicates
367
+ if (roots.length === 0 ||
368
+ x1
369
+ .minus(roots[roots.length - 1])
370
+ .abs()
371
+ .greaterThan(tol.times(10))) {
372
+ addRoot(x1);
373
+ }
374
+ }
375
+ // Check for sign change
376
+ if (f1.times(f2).lessThan(0)) {
377
+ try {
378
+ let calculation;
379
+ switch (this.method) {
380
+ case NEWTON_RAPHSON_METHOD: {
381
+ // Start at the center of the interval
382
+ const centerOfInterval = x2.minus(x1).div(2).plus(x1);
383
+ calculation = this.NewtonRaphson(centerOfInterval);
384
+ break;
385
+ }
386
+ case BRENT_METHOD: {
387
+ calculation = this.Brent(x1, x2);
388
+ break;
389
+ }
390
+ default: {
391
+ calculation = this.Brent(x1, x2);
392
+ }
393
+ }
394
+ if (calculation.converged) {
395
+ const root = calculation.root;
396
+ // Avoid duplicate roots (within tolerance)
397
+ let isDuplicate = false;
398
+ for (const existingRoot of roots) {
399
+ if (root.minus(existingRoot).abs().lessThan(tol.times(10))) {
400
+ isDuplicate = true;
401
+ break;
402
+ }
403
+ }
404
+ if (!isDuplicate) {
405
+ addRoot(root);
406
+ }
407
+ }
408
+ }
409
+ catch { }
410
+ }
411
+ }
412
+ catch { }
413
+ }
414
+ // Check the final endpoint separately so a root exactly on the upper bound is not missed.
415
+ // Like endpoints visited during the scan, it may be outside the function's real domain.
416
+ try {
417
+ const lastPoint = bVal;
418
+ const fLast = evaluatePoint(lastPoint);
419
+ if (fLast.abs().lessThan(tol)) {
420
+ if (roots.length === 0 ||
421
+ lastPoint
422
+ .minus(roots[roots.length - 1])
423
+ .abs()
424
+ .greaterThan(tol.times(10))) {
425
+ addRoot(lastPoint);
426
+ }
427
+ }
428
+ }
429
+ catch { }
430
+ return roots.sort((a, b) => a.comparedTo(b)).map(x => Expression_1.Expression.create(x));
431
+ }
432
+ }
433
+ exports.FunctionSolver = FunctionSolver;
@@ -0,0 +1,84 @@
1
+ import { Expression } from '../../core/classes/expression/Expression';
2
+ /** Options for the finite-range multi-start search performed by {@link MultivariateSolver}. */
3
+ export interface MultivariateSolverOptions {
4
+ /** Lower bound for each variable (default: -10) */
5
+ lowerBound?: number;
6
+ /** Upper bound for each variable (default: 10) */
7
+ upperBound?: number;
8
+ /** Number of grid points per variable (default: 5) */
9
+ gridPoints?: number;
10
+ /** Maximum Newton-Raphson iterations per start (default: 100) */
11
+ maxIterations?: number;
12
+ /** Convergence tolerance (default: 1e-12) */
13
+ tolerance?: number;
14
+ /** Step size for numerical Jacobian (default: 1e-8) */
15
+ derivativeStep?: number;
16
+ /** Tolerance for deduplicating roots (default: 1e-8) */
17
+ deduplicationTolerance?: number;
18
+ }
19
+ /**
20
+ * Searches numerically for isolated real solutions of a multivariate system.
21
+ *
22
+ * Each equation is interpreted as `equation = 0`. The solver starts
23
+ * Newton-Raphson at every point in a Cartesian grid, approximates the Jacobian
24
+ * with central differences, and merges nearby converged solutions.
25
+ *
26
+ * @remarks
27
+ * This is a finite-range heuristic rather than a completeness proof. The number
28
+ * of starts is `gridPoints` raised to the number of variables, so cost grows
29
+ * rapidly with dimension. Singular Jacobians, failed evaluations, and starts
30
+ * that do not converge are discarded. Calculations use the ambient
31
+ * `decimal.js` precision, and the supplied equation and variable arrays are
32
+ * retained by the solver.
33
+ *
34
+ * The numerical linear solve requires a square Jacobian in ordinary use; this
35
+ * class is intended for isolated solutions of systems with as many equations
36
+ * as variables.
37
+ */
38
+ export declare class MultivariateSolver {
39
+ private dedupTol;
40
+ private equations;
41
+ private gridPoints;
42
+ private h;
43
+ private lowerBound;
44
+ private maxIterations;
45
+ private tolerance;
46
+ private upperBound;
47
+ private variables;
48
+ /**
49
+ * Creates a multi-start solver over the configured limits.
50
+ *
51
+ * @param equations - Expressions interpreted as equations equal to zero.
52
+ * @param variables - Ordered variables corresponding to solution coordinates.
53
+ * @param options - Grid, iteration, differentiation, and deduplication settings.
54
+ */
55
+ constructor(equations: Expression[], variables: string[], options?: MultivariateSolverOptions);
56
+ /**
57
+ * Evaluate all equations at a point, returning a vector of Decimal values.
58
+ */
59
+ private evaluateSystem;
60
+ /**
61
+ * Generate grid starting points.
62
+ */
63
+ private generateStartingPoints;
64
+ /**
65
+ * Check if a root is a duplicate of an existing one.
66
+ */
67
+ private isDuplicate;
68
+ /**
69
+ * Compute the Jacobian matrix numerically using central differences.
70
+ */
71
+ private jacobian;
72
+ /**
73
+ * Run Newton-Raphson from a single starting point.
74
+ * Returns the converged root or null if it didn't converge.
75
+ */
76
+ private newtonRaphson;
77
+ /**
78
+ * Searches for roots from every configured grid point.
79
+ *
80
+ * @returns Deduplicated solutions as maps keyed in `variables` order. An empty
81
+ * array means that no start converged; it does not prove that no root exists.
82
+ */
83
+ roots(): Map<string, Expression>[];
84
+ }