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,424 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.reduceTrigPower = reduceTrigPower;
4
+ exports.trigReduce = trigReduce;
5
+ exports.expandDoubleAngle = expandDoubleAngle;
6
+ exports.productToSum = productToSum;
7
+ exports.convertToDoubleAngle = convertToDoubleAngle;
8
+ const Expression_1 = require("../../core/classes/expression/Expression");
9
+ const shortcuts_1 = require("../../core/classes/expression/shortcuts");
10
+ const constants_1 = require("../../core/classes/parser/constants");
11
+ const trig_1 = require("../../math/trig");
12
+ // ============================================================================
13
+ // POWER REDUCTION (trigreduce)
14
+ //
15
+ // Reduces powers of trig functions using double-angle identities:
16
+ // sin²(u) → (1 - cos(2u)) / 2
17
+ // cos²(u) → (1 + cos(2u)) / 2
18
+ // sin²(u)·cos²(u) → (1 - cos(4u)) / 8 (via sin(2u)²/4)
19
+ //
20
+ // Higher powers are handled recursively:
21
+ // sin³(u) → sin(u)·sin²(u) → sin(u)·(1 - cos(2u))/2
22
+ // sin⁴(u) → (sin²(u))² → ((1 - cos(2u))/2)² → (3 - 4cos(2u) + cos(4u))/8
23
+ // ============================================================================
24
+ /**
25
+ * Applies power reduction to a single trig function with an integer power ≥ 2.
26
+ *
27
+ * sin(u)^(2k) → expanded using repeated application of half-angle
28
+ * cos(u)^(2k) → expanded using repeated application of half-angle
29
+ * sin(u)^(2k+1) → sin(u) · [sin(u)^(2k) reduced]
30
+ * cos(u)^(2k+1) → cos(u) · [cos(u)^(2k) reduced]
31
+ *
32
+ * Only applies when the power is an integer ≥ 2 (or ≤ -2).
33
+ * Fractional powers like sin(x)^(1/2) are left unchanged.
34
+ */
35
+ function reduceTrigPower(e) {
36
+ if (!e.isFunction(constants_1.SIN) && !e.isFunction(constants_1.COS)) {
37
+ return e;
38
+ }
39
+ const p = e.getPower();
40
+ const m = e.getMultiplier();
41
+ const args = e.getArguments();
42
+ if (args.length === 0) {
43
+ return e;
44
+ }
45
+ const u = args[0];
46
+ const isSin = e.isFunction(constants_1.SIN);
47
+ // Only reduce integer powers with |n| >= 2.
48
+ // The power is an Expression. Check that it's a pure integer by inspecting
49
+ // its Rational multiplier: it must be an integer (denominator === 1n)
50
+ // and the power itself must be a NUM type (no symbolic component).
51
+ if (!p.isNUM()) {
52
+ return e;
53
+ }
54
+ const pRat = p.getMultiplier(); // Rational
55
+ if (pRat.denominator !== 1n && pRat.denominator !== -1n) {
56
+ // Fractional power — not an integer, leave unchanged
57
+ return e;
58
+ }
59
+ const nBig = pRat.numerator / (pRat.denominator < 0n ? -pRat.denominator : pRat.denominator);
60
+ const nAbs = nBig < 0n ? -nBig : nBig;
61
+ if (nAbs < 2n) {
62
+ return e;
63
+ }
64
+ // For negative powers, reduce the positive power and invert
65
+ if (nBig < 0n) {
66
+ const positive = reduceTrigPower(isSin
67
+ ? (0, trig_1.sin)(u).pow(Expression_1.Expression.Number(nAbs))
68
+ : (0, trig_1.cos)(u).pow(Expression_1.Expression.Number(nAbs)));
69
+ return Expression_1.Expression.fromRational(m).times(positive.invert());
70
+ }
71
+ const n = Number(nAbs);
72
+ let result;
73
+ if (n === 2) {
74
+ // sin²(u) = (1 - cos(2u)) / 2
75
+ // cos²(u) = (1 + cos(2u)) / 2
76
+ const twoU = u.times((0, shortcuts_1.two)());
77
+ if (isSin) {
78
+ result = (0, shortcuts_1.one)().minus((0, trig_1.cos)(twoU)).div((0, shortcuts_1.two)());
79
+ }
80
+ else {
81
+ result = (0, shortcuts_1.one)().plus((0, trig_1.cos)(twoU)).div((0, shortcuts_1.two)());
82
+ }
83
+ }
84
+ else if (n % 2 === 0) {
85
+ // Even power: sin^(2k)(u) = (sin²(u))^k, then reduce sin²
86
+ const halfPower = n / 2;
87
+ const squared = reduceTrigPower(isSin ? (0, trig_1.sin)(u).pow((0, shortcuts_1.two)()) : (0, trig_1.cos)(u).pow((0, shortcuts_1.two)()));
88
+ result = squared.pow(Expression_1.Expression.create(`${halfPower}`));
89
+ }
90
+ else {
91
+ // Odd power: sin^(2k+1)(u) = sin(u) · sin^(2k)(u)
92
+ const evenPart = reduceTrigPower(isSin
93
+ ? (0, trig_1.sin)(u).pow(Expression_1.Expression.create(`${n - 1}`))
94
+ : (0, trig_1.cos)(u).pow(Expression_1.Expression.create(`${n - 1}`)));
95
+ result = (isSin ? (0, trig_1.sin)(u) : (0, trig_1.cos)(u)).times(evenPart);
96
+ }
97
+ if (!m.isOne()) {
98
+ result = result.times(Expression_1.Expression.fromRational(m));
99
+ }
100
+ return result;
101
+ }
102
+ /**
103
+ * Applies power reduction to all trig powers in an expression.
104
+ * Descends into sums and products.
105
+ */
106
+ function trigReduce(x) {
107
+ // Direct trig function
108
+ if ((x.isFunction(constants_1.SIN) || x.isFunction(constants_1.COS)) && x.getPower().isInteger()) {
109
+ const p = x.getPower();
110
+ if (p.abs().gte((0, shortcuts_1.two)())) {
111
+ return reduceTrigPower(x);
112
+ }
113
+ }
114
+ // Sum: reduce each term
115
+ if (x.isSum()) {
116
+ const m = x.getMultiplier();
117
+ const p = x.getPower();
118
+ let result = (0, shortcuts_1.zero)();
119
+ for (const term of x.elementsArray()) {
120
+ result = result.plus(trigReduce(term));
121
+ }
122
+ if (!p.isOne()) {
123
+ result = result.pow(p);
124
+ }
125
+ if (!m.isOne()) {
126
+ result = result.times(Expression_1.Expression.fromRational(m));
127
+ }
128
+ return result;
129
+ }
130
+ // Product: reduce each factor
131
+ if (x.isProduct()) {
132
+ const m = x.getMultiplier();
133
+ const p = x.getPower();
134
+ let result = (0, shortcuts_1.one)();
135
+ for (const element of x.elementsArray()) {
136
+ result = result.times(trigReduce(element));
137
+ }
138
+ if (!p.isOne()) {
139
+ result = result.pow(p);
140
+ }
141
+ if (!m.isOne()) {
142
+ result = result.times(Expression_1.Expression.fromRational(m));
143
+ }
144
+ return result;
145
+ }
146
+ return x;
147
+ }
148
+ // ============================================================================
149
+ // DOUBLE ANGLE IDENTITIES
150
+ //
151
+ // Expansion direction (useful for simplification):
152
+ // sin(2u) → 2·sin(u)·cos(u)
153
+ // cos(2u) → cos²(u) - sin²(u)
154
+ // → 2·cos²(u) - 1
155
+ // → 1 - 2·sin²(u)
156
+ //
157
+ // Reverse direction (useful for reducing products):
158
+ // 2·sin(u)·cos(u) → sin(2u)
159
+ // cos²(u) - sin²(u) → cos(2u)
160
+ // ============================================================================
161
+ /**
162
+ * Expands double angle: sin(2u) → 2·sin(u)·cos(u)
163
+ * Only applies if the argument has a factor of 2.
164
+ */
165
+ function expandDoubleAngleSin(e) {
166
+ if (!e.isFunction(constants_1.SIN)) {
167
+ return null;
168
+ }
169
+ const args = e.getArguments();
170
+ if (args.length === 0) {
171
+ return null;
172
+ }
173
+ const arg = args[0];
174
+ const m = e.getMultiplier();
175
+ const p = e.getPower();
176
+ // Check if argument is 2*u for some u
177
+ const u = extractHalfArgument(arg);
178
+ if (!u) {
179
+ return null;
180
+ }
181
+ // sin(2u) = 2·sin(u)·cos(u)
182
+ let result = (0, shortcuts_1.two)().times((0, trig_1.sin)(u)).times((0, trig_1.cos)(u));
183
+ if (!p.isOne()) {
184
+ result = result.pow(p);
185
+ }
186
+ if (!m.isOne()) {
187
+ result = result.times(Expression_1.Expression.fromRational(m));
188
+ }
189
+ return result;
190
+ }
191
+ /**
192
+ * Expands double angle: cos(2u) → cos²(u) - sin²(u)
193
+ * Only applies if the argument has a factor of 2.
194
+ */
195
+ function expandDoubleAngleCos(e) {
196
+ if (!e.isFunction(constants_1.COS)) {
197
+ return null;
198
+ }
199
+ const args = e.getArguments();
200
+ if (args.length === 0) {
201
+ return null;
202
+ }
203
+ const arg = args[0];
204
+ const m = e.getMultiplier();
205
+ const p = e.getPower();
206
+ const u = extractHalfArgument(arg);
207
+ if (!u) {
208
+ return null;
209
+ }
210
+ // cos(2u) = cos²(u) - sin²(u)
211
+ let result = (0, trig_1.cos)(u).pow((0, shortcuts_1.two)()).minus((0, trig_1.sin)(u).pow((0, shortcuts_1.two)()));
212
+ if (!p.isOne()) {
213
+ result = result.pow(p);
214
+ }
215
+ if (!m.isOne()) {
216
+ result = result.times(Expression_1.Expression.fromRational(m));
217
+ }
218
+ return result;
219
+ }
220
+ /**
221
+ * If the argument is of the form 2*u, returns u. Otherwise returns null.
222
+ */
223
+ function extractHalfArgument(arg) {
224
+ const m = arg.getMultiplier();
225
+ // Check if the multiplier is even (has a factor of 2)
226
+ if (m.numerator % 2n === 0n) {
227
+ // Divide multiplier by 2
228
+ const half = arg.div((0, shortcuts_1.two)());
229
+ return half;
230
+ }
231
+ return null;
232
+ }
233
+ /**
234
+ * Expands all double-angle trig functions in an expression.
235
+ */
236
+ function expandDoubleAngle(x) {
237
+ if (x.isFunction(constants_1.SIN)) {
238
+ const expanded = expandDoubleAngleSin(x);
239
+ if (expanded) {
240
+ return expanded;
241
+ }
242
+ }
243
+ if (x.isFunction(constants_1.COS)) {
244
+ const expanded = expandDoubleAngleCos(x);
245
+ if (expanded) {
246
+ return expanded;
247
+ }
248
+ }
249
+ if (x.isSum()) {
250
+ const m = x.getMultiplier();
251
+ const p = x.getPower();
252
+ let result = (0, shortcuts_1.zero)();
253
+ for (const term of x.elementsArray()) {
254
+ result = result.plus(expandDoubleAngle(term));
255
+ }
256
+ if (!p.isOne()) {
257
+ result = result.pow(p);
258
+ }
259
+ if (!m.isOne()) {
260
+ result = result.times(Expression_1.Expression.fromRational(m));
261
+ }
262
+ return result;
263
+ }
264
+ if (x.isProduct()) {
265
+ const m = x.getMultiplier();
266
+ const p = x.getPower();
267
+ let result = (0, shortcuts_1.one)();
268
+ for (const element of x.elementsArray()) {
269
+ result = result.times(expandDoubleAngle(element));
270
+ }
271
+ if (!p.isOne()) {
272
+ result = result.pow(p);
273
+ }
274
+ if (!m.isOne()) {
275
+ result = result.times(Expression_1.Expression.fromRational(m));
276
+ }
277
+ return result;
278
+ }
279
+ return x;
280
+ }
281
+ /**
282
+ * Extracts sin/cos factors from a product for product-to-sum conversion.
283
+ * Only extracts factors with power = 1 (linear trig factors).
284
+ */
285
+ function extractTrigFactors(x) {
286
+ const trigFactors = [];
287
+ let rest = Expression_1.Expression.fromRational(x.getMultiplier());
288
+ if (!x.isProduct()) {
289
+ // Check if x itself is a single trig function
290
+ if ((x.isFunction(constants_1.SIN) || x.isFunction(constants_1.COS)) && x.getPower().eq((0, shortcuts_1.one)())) {
291
+ const args = x.getArguments();
292
+ if (args.length > 0) {
293
+ trigFactors.push({
294
+ fn: x.isFunction(constants_1.SIN) ? constants_1.SIN : constants_1.COS,
295
+ arg: args[0],
296
+ power: x.getPower(),
297
+ });
298
+ rest = Expression_1.Expression.fromRational(x.getMultiplier());
299
+ return { trigFactors, rest };
300
+ }
301
+ }
302
+ return { trigFactors: [], rest: x };
303
+ }
304
+ for (const element of x.elementsArray()) {
305
+ if ((element.isFunction(constants_1.SIN) || element.isFunction(constants_1.COS)) && element.getPower().eq((0, shortcuts_1.one)())) {
306
+ const args = element.getArguments();
307
+ if (args.length > 0) {
308
+ trigFactors.push({
309
+ fn: element.isFunction(constants_1.SIN) ? constants_1.SIN : constants_1.COS,
310
+ arg: args[0],
311
+ power: element.getPower(),
312
+ });
313
+ // Include the element's own multiplier in rest
314
+ if (!element.getMultiplier().isOne()) {
315
+ rest = rest.times(Expression_1.Expression.fromRational(element.getMultiplier()));
316
+ }
317
+ continue;
318
+ }
319
+ }
320
+ rest = rest.times(element);
321
+ }
322
+ return { trigFactors, rest };
323
+ }
324
+ /**
325
+ * Converts a product of two trig functions to a sum using product-to-sum identities.
326
+ *
327
+ * sin(a)·cos(b) → (1/2)[sin(a+b) + sin(a-b)]
328
+ * cos(a)·cos(b) → (1/2)[cos(a-b) + cos(a+b)]
329
+ * sin(a)·sin(b) → (1/2)[cos(a-b) - cos(a+b)]
330
+ */
331
+ function productToSum(x) {
332
+ const { trigFactors, rest } = extractTrigFactors(x);
333
+ // Need at least 2 trig factors to apply product-to-sum
334
+ if (trigFactors.length < 2) {
335
+ return x;
336
+ }
337
+ // Process pairs of trig factors
338
+ let result = rest;
339
+ let i = 0;
340
+ while (i < trigFactors.length - 1) {
341
+ const f1 = trigFactors[i];
342
+ const f2 = trigFactors[i + 1];
343
+ const a = f1.arg;
344
+ const b = f2.arg;
345
+ const aPlusB = a.plus(b);
346
+ const aMinusB = a.minus(b);
347
+ const half = (0, shortcuts_1.one)().div((0, shortcuts_1.two)());
348
+ let converted;
349
+ if (f1.fn === constants_1.SIN && f2.fn === constants_1.COS) {
350
+ // sin(a)·cos(b) = (1/2)[sin(a+b) + sin(a-b)]
351
+ converted = half.times((0, trig_1.sin)(aPlusB).plus((0, trig_1.sin)(aMinusB)));
352
+ }
353
+ else if (f1.fn === constants_1.COS && f2.fn === constants_1.SIN) {
354
+ // cos(a)·sin(b) = (1/2)[sin(a+b) - sin(a-b)]
355
+ converted = half.times((0, trig_1.sin)(aPlusB).minus((0, trig_1.sin)(aMinusB)));
356
+ }
357
+ else if (f1.fn === constants_1.COS && f2.fn === constants_1.COS) {
358
+ // cos(a)·cos(b) = (1/2)[cos(a-b) + cos(a+b)]
359
+ converted = half.times((0, trig_1.cos)(aMinusB).plus((0, trig_1.cos)(aPlusB)));
360
+ }
361
+ else {
362
+ // sin(a)·sin(b) = (1/2)[cos(a-b) - cos(a+b)]
363
+ converted = half.times((0, trig_1.cos)(aMinusB).minus((0, trig_1.cos)(aPlusB)));
364
+ }
365
+ result = result.times(converted);
366
+ i += 2;
367
+ }
368
+ // If there's an unpaired trig factor, multiply it back in
369
+ if (i < trigFactors.length) {
370
+ const leftover = trigFactors[i];
371
+ const fn = leftover.fn === constants_1.SIN ? trig_1.sin : trig_1.cos;
372
+ result = result.times(fn(leftover.arg));
373
+ }
374
+ return result;
375
+ }
376
+ /**
377
+ * Converts sin(u)·cos(u) products into double-angle form.
378
+ *
379
+ * k·sin(u)·cos(u) → (k/2)·sin(2u)
380
+ *
381
+ * This is the reverse of expandDoubleAngle for sin.
382
+ */
383
+ function convertToDoubleAngle(x) {
384
+ if (!x.isProduct()) {
385
+ return x;
386
+ }
387
+ const { trigFactors, rest } = extractTrigFactors(x);
388
+ // Look for sin(u)·cos(u) pairs with matching arguments
389
+ const usedIndices = new Set();
390
+ let result = rest;
391
+ for (let i = 0; i < trigFactors.length; i++) {
392
+ if (usedIndices.has(i)) {
393
+ continue;
394
+ }
395
+ for (let j = i + 1; j < trigFactors.length; j++) {
396
+ if (usedIndices.has(j)) {
397
+ continue;
398
+ }
399
+ const a = trigFactors[i];
400
+ const b = trigFactors[j];
401
+ // Check for sin(u)·cos(u) or cos(u)·sin(u) with same argument
402
+ if (a.arg.eq(b.arg) &&
403
+ ((a.fn === constants_1.SIN && b.fn === constants_1.COS) || (a.fn === constants_1.COS && b.fn === constants_1.SIN))) {
404
+ // sin(u)·cos(u) = (1/2)·sin(2u)
405
+ const u = a.arg;
406
+ result = result.times((0, shortcuts_1.one)()
407
+ .div((0, shortcuts_1.two)())
408
+ .times((0, trig_1.sin)(u.times((0, shortcuts_1.two)()))));
409
+ usedIndices.add(i);
410
+ usedIndices.add(j);
411
+ break;
412
+ }
413
+ }
414
+ }
415
+ // Add back any unmatched trig factors
416
+ for (let i = 0; i < trigFactors.length; i++) {
417
+ if (!usedIndices.has(i)) {
418
+ const f = trigFactors[i];
419
+ const fn = f.fn === constants_1.SIN ? trig_1.sin : trig_1.cos;
420
+ result = result.times(fn(f.arg));
421
+ }
422
+ }
423
+ return result;
424
+ }
@@ -0,0 +1,17 @@
1
+ import { Expression } from '../../core/classes/expression/Expression';
2
+ /**
3
+ * Determines whether an expression contains any tan, sec, csc, or cot functions.
4
+ */
5
+ export declare function hasDerivedTrig(x: Expression): boolean;
6
+ /**
7
+ * Recursively rewrites all tan, sec, csc, cot in an expression tree to sin/cos form.
8
+ * This is a deep rewrite — it descends into sums, products, and function arguments.
9
+ */
10
+ export declare function rewrite(x: Expression): Expression;
11
+ /**
12
+ * Attempts to rewrite derived trig functions to sin/cos and checks if the result
13
+ * is simpler (fewer terms or lower complexity). Returns the simpler form.
14
+ *
15
+ * This is the "only rewrite when it leads to cancellation" strategy.
16
+ */
17
+ export declare function tryRewriteTrig(x: Expression): Expression;
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hasDerivedTrig = hasDerivedTrig;
4
+ exports.rewrite = rewrite;
5
+ exports.tryRewriteTrig = tryRewriteTrig;
6
+ const Expression_1 = require("../../core/classes/expression/Expression");
7
+ const shortcuts_1 = require("../../core/classes/expression/shortcuts");
8
+ const constants_1 = require("../../core/classes/parser/constants");
9
+ const trig_1 = require("../../math/trig");
10
+ /**
11
+ * Determines whether an expression contains any tan, sec, csc, or cot functions.
12
+ */
13
+ function hasDerivedTrig(x) {
14
+ let found = false;
15
+ x.forEveryElement(e => {
16
+ if (e.isFunction(constants_1.TAN) || e.isFunction(constants_1.SEC) || e.isFunction(constants_1.CSC) || e.isFunction(constants_1.COT)) {
17
+ found = true;
18
+ }
19
+ return e;
20
+ });
21
+ return found;
22
+ }
23
+ /**
24
+ * Rewrites a single trig function element in terms of sin and cos.
25
+ *
26
+ * tan(u)^n → sin(u)^n * cos(u)^(-n)
27
+ * cot(u)^n → cos(u)^n * sin(u)^(-n)
28
+ * sec(u)^n → cos(u)^(-n)
29
+ * csc(u)^n → sin(u)^(-n)
30
+ *
31
+ * Multiplier and arguments are preserved.
32
+ */
33
+ function rewriteTrigElement(e) {
34
+ const m = e.getMultiplier();
35
+ const p = e.getPower();
36
+ const args = e.getArguments();
37
+ if (e.isFunction(constants_1.TAN) && args.length > 0) {
38
+ const u = args[0];
39
+ return Expression_1.Expression.fromRational(m).times((0, trig_1.sin)(u).pow(p)).times((0, trig_1.cos)(u).pow(p.neg()));
40
+ }
41
+ if (e.isFunction(constants_1.COT) && args.length > 0) {
42
+ const u = args[0];
43
+ return Expression_1.Expression.fromRational(m).times((0, trig_1.cos)(u).pow(p)).times((0, trig_1.sin)(u).pow(p.neg()));
44
+ }
45
+ if (e.isFunction(constants_1.SEC) && args.length > 0) {
46
+ const u = args[0];
47
+ return Expression_1.Expression.fromRational(m).times((0, trig_1.cos)(u).pow(p.neg()));
48
+ }
49
+ if (e.isFunction(constants_1.CSC) && args.length > 0) {
50
+ const u = args[0];
51
+ return Expression_1.Expression.fromRational(m).times((0, trig_1.sin)(u).pow(p.neg()));
52
+ }
53
+ return e;
54
+ }
55
+ /**
56
+ * Recursively rewrites all tan, sec, csc, cot in an expression tree to sin/cos form.
57
+ * This is a deep rewrite — it descends into sums, products, and function arguments.
58
+ */
59
+ function rewrite(x) {
60
+ // If it's a direct derived trig function, rewrite it
61
+ if (x.isFunction(constants_1.TAN) || x.isFunction(constants_1.COT) || x.isFunction(constants_1.SEC) || x.isFunction(constants_1.CSC)) {
62
+ return rewriteTrigElement(x);
63
+ }
64
+ // For sums: rewrite each term
65
+ if (x.isSum()) {
66
+ const m = x.getMultiplier();
67
+ const p = x.getPower();
68
+ let result = (0, shortcuts_1.zero)();
69
+ for (const term of x.elementsArray()) {
70
+ result = result.plus(rewrite(term));
71
+ }
72
+ if (!p.isOne()) {
73
+ result = result.pow(p);
74
+ }
75
+ if (!m.isOne()) {
76
+ result = result.times(Expression_1.Expression.fromRational(m));
77
+ }
78
+ return result;
79
+ }
80
+ // For products: rewrite each factor
81
+ if (x.isProduct()) {
82
+ const m = x.getMultiplier();
83
+ const p = x.getPower();
84
+ let result = (0, shortcuts_1.one)();
85
+ for (const element of x.elementsArray()) {
86
+ result = result.times(rewrite(element));
87
+ }
88
+ if (!p.isOne()) {
89
+ result = result.pow(p);
90
+ }
91
+ if (!m.isOne()) {
92
+ result = result.times(Expression_1.Expression.fromRational(m));
93
+ }
94
+ return result;
95
+ }
96
+ // For other functions (sin, cos, log, etc.): rewrite the arguments
97
+ if (x.isFunction()) {
98
+ // Don't rewrite inside sin/cos arguments — the derived trig functions
99
+ // inside arguments would be unusual, but handle it for completeness
100
+ return x;
101
+ }
102
+ return x;
103
+ }
104
+ /**
105
+ * Attempts to rewrite derived trig functions to sin/cos and checks if the result
106
+ * is simpler (fewer terms or lower complexity). Returns the simpler form.
107
+ *
108
+ * This is the "only rewrite when it leads to cancellation" strategy.
109
+ */
110
+ function tryRewriteTrig(x) {
111
+ if (!hasDerivedTrig(x)) {
112
+ return x;
113
+ }
114
+ const rewritten = rewrite(x);
115
+ // Heuristic: the rewritten form is "better" if it has fewer elements,
116
+ // fewer distinct function types, or leads to cancellation (becomes simpler text).
117
+ // A simple proxy: compare text length or element count.
118
+ if (complexity(rewritten) <= complexity(x)) {
119
+ return rewritten;
120
+ }
121
+ return x;
122
+ }
123
+ /**
124
+ * Simple complexity metric for an expression.
125
+ * Lower is simpler.
126
+ */
127
+ function complexity(x) {
128
+ const text = x.text();
129
+ // Count the number of function calls, operations, and terms as a rough proxy
130
+ let score = text.length;
131
+ // Bonus: fewer distinct trig function types is better
132
+ const types = new Set();
133
+ x.forEveryElement(e => {
134
+ if (e.isFunction(constants_1.SIN)) {
135
+ types.add(constants_1.SIN);
136
+ }
137
+ if (e.isFunction(constants_1.COS)) {
138
+ types.add(constants_1.COS);
139
+ }
140
+ if (e.isFunction(constants_1.TAN)) {
141
+ types.add(constants_1.TAN);
142
+ }
143
+ if (e.isFunction(constants_1.SEC)) {
144
+ types.add(constants_1.SEC);
145
+ }
146
+ if (e.isFunction(constants_1.CSC)) {
147
+ types.add(constants_1.CSC);
148
+ }
149
+ if (e.isFunction(constants_1.COT)) {
150
+ types.add(constants_1.COT);
151
+ }
152
+ return e;
153
+ });
154
+ score += types.size * 10;
155
+ return score;
156
+ }
@@ -0,0 +1,11 @@
1
+ import { Expression } from '../../core/classes/expression/Expression';
2
+ /**
3
+ * Simplifies trig identities in a sum expression.
4
+ *
5
+ * Applies:
6
+ * a·sin(u)² + a·cos(u)² = a (Pythagorean)
7
+ * a·sec(u)² - a·tan(u)² = a (sec²-tan²=1)
8
+ * a·csc(u)² - a·cot(u)² = a (csc²-cot²=1)
9
+ * Partial Pythagorean for mismatched coefficients
10
+ */
11
+ export declare function simplifyTrigSum(x: Expression): Expression;