pimath 0.0.127 → 0.0.129

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 (212) hide show
  1. package/dist/main.d.ts +39 -0
  2. package/{esm → dist}/maths/algebra/equation.d.ts +11 -10
  3. package/{esm → dist}/maths/algebra/linearSystem.d.ts +5 -4
  4. package/{esm → dist}/maths/algebra/monom.d.ts +5 -4
  5. package/{esm → dist}/maths/algebra/polynom.d.ts +11 -13
  6. package/{esm → dist}/maths/algebra/rational.d.ts +7 -9
  7. package/dist/maths/algebra/study/rationalStudy.d.ts +14 -0
  8. package/{esm → dist}/maths/algebra/study.d.ts +4 -7
  9. package/{esm → dist}/maths/geometry/circle.d.ts +9 -8
  10. package/{esm → dist}/maths/geometry/line.d.ts +17 -14
  11. package/{esm → dist}/maths/geometry/point.d.ts +11 -9
  12. package/{esm → dist}/maths/geometry/triangle.d.ts +4 -3
  13. package/{esm → dist}/maths/geometry/vector.d.ts +7 -10
  14. package/{esm → dist}/maths/randomization/random.d.ts +10 -7
  15. package/{esm → dist}/maths/randomization/rndFraction.d.ts +4 -3
  16. package/dist/maths/randomization/rndGeometryCircle.d.ts +13 -0
  17. package/{esm → dist}/maths/randomization/rndGeometryLine.d.ts +4 -3
  18. package/{esm → dist}/maths/randomization/rndGeometryPoint.d.ts +4 -3
  19. package/{esm → dist}/maths/randomization/rndMonom.d.ts +5 -4
  20. package/{esm → dist}/maths/randomization/rndPolynom.d.ts +5 -4
  21. package/{esm → dist}/maths/randomization/rndTypes.d.ts +7 -1
  22. package/dist/pimath.js +4239 -7819
  23. package/package.json +13 -7
  24. package/.eslintrc.js +0 -24
  25. package/.idea/$CACHE_FILE$ +0 -6
  26. package/.idea/PI.iml +0 -14
  27. package/.idea/codeStyles/codeStyleConfig.xml +0 -5
  28. package/.idea/inspectionProfiles/Project_Default.xml +0 -6
  29. package/.idea/misc.xml +0 -6
  30. package/.idea/modules.xml +0 -8
  31. package/.idea/php.xml +0 -19
  32. package/.idea/shelf/Uncommitted_changes_before_Checkout_at_07_11_2023_08_30_[Default_Changelist]/shelved.patch +0 -192
  33. package/.idea/shelf/Uncommitted_changes_before_Checkout_at_07_11_2023_08_30_[Default_Changelist]1/shelved.patch +0 -0
  34. package/.idea/shelf/Uncommitted_changes_before_Checkout_at_07_11_2023_08_30__Default_Changelist_.xml +0 -4
  35. package/.idea/shelf/Uncommitted_changes_before_Checkout_at_09_11_2023_10_43_[Default_Changelist]/shelved.patch +0 -2404
  36. package/.idea/shelf/Uncommitted_changes_before_Checkout_at_09_11_2023_10_43__Default_Changelist_.xml +0 -4
  37. package/.idea/shelf/Uncommitted_changes_before_Checkout_at_09_11_2023_11_01_[Default_Changelist]/shelved.patch +0 -1362
  38. package/.idea/shelf/Uncommitted_changes_before_Checkout_at_09_11_2023_11_01__Default_Changelist_.xml +0 -4
  39. package/.idea/shelf/Uncommitted_changes_before_Update_at_24_07_2023_15_31_[Default_Changelist]/shelved.patch +0 -90
  40. package/.idea/shelf/Uncommitted_changes_before_Update_at_24_07_2023_15_31__Default_Changelist_.xml +0 -4
  41. package/.idea/vcs.xml +0 -6
  42. package/dev/pimath.js +0 -7945
  43. package/dev/pimath.js.map +0 -1
  44. package/dist/pimath.js.map +0 -1
  45. package/dist/pimath.min.js +0 -2
  46. package/dist/pimath.min.js.map +0 -1
  47. package/docs/.nojekyll +0 -1
  48. package/docs/assets/highlight.css +0 -78
  49. package/docs/assets/main.js +0 -59
  50. package/docs/assets/navigation.js +0 -1
  51. package/docs/assets/search.js +0 -1
  52. package/docs/assets/style.css +0 -1383
  53. package/docs/classes/Logicalset.Logicalset.html +0 -217
  54. package/docs/classes/Polynom.Rational.html +0 -397
  55. package/docs/classes/Vector-1.Vector.html +0 -490
  56. package/docs/classes/Vector.Point.html +0 -337
  57. package/docs/classes/algebra_equation.Equation.html +0 -790
  58. package/docs/classes/algebra_linearSystem.LinearSystem.html +0 -404
  59. package/docs/classes/algebra_monom.Monom.html +0 -962
  60. package/docs/classes/algebra_polynom.Polynom.html +0 -1275
  61. package/docs/classes/coefficients_fraction.Fraction.html +0 -934
  62. package/docs/classes/geometry_circle.Circle.html +0 -472
  63. package/docs/classes/geometry_line.Line.html +0 -774
  64. package/docs/classes/geometry_triangle.Triangle.html +0 -429
  65. package/docs/classes/numeric.Numeric.html +0 -265
  66. package/docs/classes/shutingyard.Shutingyard.html +0 -250
  67. package/docs/enums/algebra_equation.PARTICULAR_SOLUTION.html +0 -83
  68. package/docs/enums/geometry_line.LinePropriety.html +0 -97
  69. package/docs/enums/shutingyard.ShutingyardMode.html +0 -97
  70. package/docs/enums/shutingyard.ShutingyardType.html +0 -111
  71. package/docs/index.html +0 -63
  72. package/docs/interfaces/algebra_equation.ISolution.html +0 -105
  73. package/docs/interfaces/algebra_polynom.IEuclidian.html +0 -87
  74. package/docs/interfaces/geometry_triangle.remarquableLines.html +0 -163
  75. package/docs/modules/Logicalset.html +0 -65
  76. package/docs/modules/Polynom.html +0 -65
  77. package/docs/modules/Vector-1.html +0 -65
  78. package/docs/modules/Vector.html +0 -65
  79. package/docs/modules/algebra_equation.html +0 -69
  80. package/docs/modules/algebra_linearSystem.html +0 -61
  81. package/docs/modules/algebra_monom.html +0 -65
  82. package/docs/modules/algebra_polynom.html +0 -69
  83. package/docs/modules/coefficients_fraction.html +0 -65
  84. package/docs/modules/geometry_circle.html +0 -61
  85. package/docs/modules/geometry_line.html +0 -65
  86. package/docs/modules/geometry_triangle.html +0 -65
  87. package/docs/modules/numeric.html +0 -61
  88. package/docs/modules/shutingyard.html +0 -75
  89. package/docs/types/algebra_monom.literalType.html +0 -61
  90. package/docs/types/algebra_polynom.PolynomParsingType.html +0 -56
  91. package/docs/types/coefficients_fraction.FractionParsingType.html +0 -56
  92. package/docs/types/shutingyard.Token.html +0 -63
  93. package/docs/types/shutingyard.tokenType.html +0 -68
  94. package/docs/variables/shutingyard.tokenConstant.html +0 -61
  95. package/esm/index.d.ts +0 -38
  96. package/esm/index.js +0 -44
  97. package/esm/index.js.map +0 -1
  98. package/esm/maths/algebra/equation.js +0 -797
  99. package/esm/maths/algebra/equation.js.map +0 -1
  100. package/esm/maths/algebra/linearSystem.js +0 -279
  101. package/esm/maths/algebra/linearSystem.js.map +0 -1
  102. package/esm/maths/algebra/logicalset.js +0 -158
  103. package/esm/maths/algebra/logicalset.js.map +0 -1
  104. package/esm/maths/algebra/monom.js +0 -909
  105. package/esm/maths/algebra/monom.js.map +0 -1
  106. package/esm/maths/algebra/polynom.js +0 -1305
  107. package/esm/maths/algebra/polynom.js.map +0 -1
  108. package/esm/maths/algebra/rational.js +0 -195
  109. package/esm/maths/algebra/rational.js.map +0 -1
  110. package/esm/maths/algebra/study/rationalStudy.d.ts +0 -28
  111. package/esm/maths/algebra/study/rationalStudy.js +0 -244
  112. package/esm/maths/algebra/study/rationalStudy.js.map +0 -1
  113. package/esm/maths/algebra/study.js +0 -380
  114. package/esm/maths/algebra/study.js.map +0 -1
  115. package/esm/maths/coefficients/fraction.js +0 -517
  116. package/esm/maths/coefficients/fraction.js.map +0 -1
  117. package/esm/maths/coefficients/nthRoot.js +0 -137
  118. package/esm/maths/coefficients/nthRoot.js.map +0 -1
  119. package/esm/maths/geometry/circle.js +0 -324
  120. package/esm/maths/geometry/circle.js.map +0 -1
  121. package/esm/maths/geometry/line.js +0 -485
  122. package/esm/maths/geometry/line.js.map +0 -1
  123. package/esm/maths/geometry/point.js +0 -167
  124. package/esm/maths/geometry/point.js.map +0 -1
  125. package/esm/maths/geometry/triangle.js +0 -276
  126. package/esm/maths/geometry/triangle.js.map +0 -1
  127. package/esm/maths/geometry/vector.js +0 -198
  128. package/esm/maths/geometry/vector.js.map +0 -1
  129. package/esm/maths/numeric.js +0 -136
  130. package/esm/maths/numeric.js.map +0 -1
  131. package/esm/maths/numexp.js +0 -186
  132. package/esm/maths/numexp.js.map +0 -1
  133. package/esm/maths/randomization/random.js +0 -79
  134. package/esm/maths/randomization/random.js.map +0 -1
  135. package/esm/maths/randomization/randomCore.js +0 -22
  136. package/esm/maths/randomization/randomCore.js.map +0 -1
  137. package/esm/maths/randomization/rndFraction.js +0 -44
  138. package/esm/maths/randomization/rndFraction.js.map +0 -1
  139. package/esm/maths/randomization/rndGeometryLine.js +0 -46
  140. package/esm/maths/randomization/rndGeometryLine.js.map +0 -1
  141. package/esm/maths/randomization/rndGeometryPoint.js +0 -61
  142. package/esm/maths/randomization/rndGeometryPoint.js.map +0 -1
  143. package/esm/maths/randomization/rndHelpers.js +0 -98
  144. package/esm/maths/randomization/rndHelpers.js.map +0 -1
  145. package/esm/maths/randomization/rndMonom.js +0 -53
  146. package/esm/maths/randomization/rndMonom.js.map +0 -1
  147. package/esm/maths/randomization/rndPolynom.js +0 -75
  148. package/esm/maths/randomization/rndPolynom.js.map +0 -1
  149. package/esm/maths/randomization/rndTypes.js +0 -3
  150. package/esm/maths/randomization/rndTypes.js.map +0 -1
  151. package/esm/maths/shutingyard.js +0 -443
  152. package/esm/maths/shutingyard.js.map +0 -1
  153. package/public/demo.css +0 -3
  154. package/public/index.html +0 -283
  155. package/public/matrices.html +0 -100
  156. package/public/playground.html +0 -168
  157. package/src/index.ts +0 -42
  158. package/src/maths/algebra/equation.ts +0 -897
  159. package/src/maths/algebra/linearSystem.ts +0 -370
  160. package/src/maths/algebra/logicalset.ts +0 -183
  161. package/src/maths/algebra/monom.ts +0 -1028
  162. package/src/maths/algebra/polynom.ts +0 -1537
  163. package/src/maths/algebra/rational.ts +0 -240
  164. package/src/maths/algebra/study/rationalStudy.ts +0 -287
  165. package/src/maths/algebra/study.ts +0 -506
  166. package/src/maths/coefficients/fraction.ts +0 -593
  167. package/src/maths/coefficients/nthRoot.ts +0 -148
  168. package/src/maths/geometry/circle.ts +0 -382
  169. package/src/maths/geometry/line.ts +0 -604
  170. package/src/maths/geometry/point.ts +0 -215
  171. package/src/maths/geometry/triangle.ts +0 -368
  172. package/src/maths/geometry/vector.ts +0 -242
  173. package/src/maths/numeric.ts +0 -162
  174. package/src/maths/numexp.ts +0 -184
  175. package/src/maths/randomization/random.ts +0 -80
  176. package/src/maths/randomization/randomCore.ts +0 -19
  177. package/src/maths/randomization/rndFraction.ts +0 -47
  178. package/src/maths/randomization/rndGeometryCircle.ts +0 -50
  179. package/src/maths/randomization/rndGeometryLine.ts +0 -53
  180. package/src/maths/randomization/rndGeometryPoint.ts +0 -69
  181. package/src/maths/randomization/rndHelpers.ts +0 -107
  182. package/src/maths/randomization/rndMonom.ts +0 -57
  183. package/src/maths/randomization/rndPolynom.ts +0 -90
  184. package/src/maths/randomization/rndTypes.ts +0 -43
  185. package/src/maths/shutingyard.ts +0 -496
  186. package/tests/algebra/equation.test.ts +0 -64
  187. package/tests/algebra/linear.test.ts +0 -58
  188. package/tests/algebra/monom.test.ts +0 -78
  189. package/tests/algebra/polynom.test.ts +0 -343
  190. package/tests/algebra/rationnal.test.ts +0 -64
  191. package/tests/algebra/study.test.ts +0 -48
  192. package/tests/coefficients/fraction.test.ts +0 -131
  193. package/tests/custom.test.ts +0 -33
  194. package/tests/geometry/circle.test.ts +0 -404
  195. package/tests/geometry/line.test.ts +0 -36
  196. package/tests/numeric.test.ts +0 -43
  197. package/tests/numexp.test.ts +0 -89
  198. package/tests/shutingyard.test.ts +0 -58
  199. package/tsconfig.json +0 -41
  200. package/tsconfig.testing.json +0 -28
  201. package/typedoc.katex.js +0 -11
  202. package/webpack-production-min.config.js +0 -26
  203. package/webpack-production.config.js +0 -26
  204. package/webpack.config.js +0 -26
  205. package/{esm → dist}/maths/algebra/logicalset.d.ts +6 -6
  206. package/{esm → dist}/maths/coefficients/fraction.d.ts +0 -0
  207. package/{esm → dist}/maths/coefficients/nthRoot.d.ts +0 -0
  208. package/{esm → dist}/maths/numeric.d.ts +0 -0
  209. package/{esm → dist}/maths/numexp.d.ts +3 -3
  210. /package/{esm → dist}/maths/randomization/randomCore.d.ts +0 -0
  211. /package/{esm → dist}/maths/randomization/rndHelpers.d.ts +0 -0
  212. /package/{esm → dist}/maths/shutingyard.d.ts +0 -0
@@ -1,1362 +0,0 @@
1
- Index: src/maths/algebra/monom.ts
2
- IDEA additional info:
3
- Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP
4
- <+>/***\r\n * Monom class\r\n * The monom class represents of monom of the form:\r\n * k * x^n * y^m * z^p\r\n * k: Coefficient\r\n * n, m, p: powers as Fraction\r\n * x, y, z: letters as string\r\n */\r\nimport {Numeric} from \"../numeric\";\r\nimport {Shutingyard, ShutingyardType, Token} from \"../shutingyard\";\r\nimport {COMPARESIGNS, literalType} from \"../types\";\r\nimport {RootFraction} from \"../coefficients/rootFraction\";\r\nimport {\r\n COEFFICIENT_MODE,\r\n CoefficientCore,\r\n CoefficientParserTypes,\r\n CoefficientTypes\r\n} from \"../coefficients/coefficientCore\";\r\nimport {Fraction} from \"../coefficients/fraction\";\r\n\r\n\r\nexport class Monom {\r\n private _coefficientMode: COEFFICIENT_MODE\r\n\r\n /**\r\n * Create a Monom\r\n * Defined as \\\\(k \\\\cdot x^{n}\\\\), where \\\\( k,n \\in \\\\mathbb{Q}\\\\).\r\n * Examples: \\\\(3x^2\\\\) or \\\\(3/5x^2\\\\)\r\n * @param value (optional) string The value that should be parse. Can be a Monom, a Fraction, a string or a number. If nothing is provided, it will return the trivial monom (0).\r\n */\r\n constructor(value?: unknown) {\r\n this.zero();\r\n\r\n if (value !== undefined) {\r\n // A string is given - try to parse the value.\r\n this.parse(value);\r\n }\r\n\r\n return this;\r\n }\r\n\r\n // ------------------------------------------\r\n // Getter and setter\r\n\r\n private _coefficient: CoefficientCore<any>;\r\n\r\n // ------------------------------------------\r\n /**\r\n * Get the coefficient \\\\(k\\\\) of the Monom \\\\(k\\\\cdot x^{n}\\\\)\r\n * @returns {Fraction}\r\n */\r\n get coefficient(): CoefficientCore<any> {\r\n return this._coefficient;\r\n }\r\n\r\n /**\r\n * Set the coefficient \\\\(k\\\\) value of the monom\r\n * @param {Fraction | number | string} F\r\n */\r\n set coefficient(F: CoefficientParserTypes) {\r\n this._coefficient = this.makeCoefficient(F);\r\n }\r\n\r\n private _literal: literalType;\r\n\r\n /**\r\n * Get the literal part of \\\\(x^{n_1}y^{n_2}\\\\) as dictionary \\\\[\\\\begin{array}{ll}x&=n_1\\\\\\\\y&=n_2\\\\end{array}\\\\]\r\n * @returns {literalType}\r\n */\r\n get literal(): literalType {\r\n return this._literal;\r\n }\r\n\r\n /**\r\n * Set the literal part of the monom. Must be a dictionary {x: Fraction, y: Fraction, ...}\r\n * @param {literalType} L\r\n */\r\n set literal(L: literalType) {\r\n this._literal = L;\r\n }\r\n\r\n /**\r\n * Get the literal square roots of the Monom.\r\n * TODO: remove this getter ? Is it used and is it correct ?\r\n * @returns {literalType}\r\n */\r\n get literalSqrt(): literalType {\r\n if (this.isLiteralSquare()) {\r\n let L: literalType = {}\r\n for (let key in this._literal) {\r\n L[key] = this._literal[key].clone().sqrt()\r\n }\r\n return L;\r\n } else {\r\n return this._literal;\r\n }\r\n }\r\n\r\n /**\r\n * Set the literal part of the monom from a string\r\n * @param inputStr String like x^2y^3\r\n */\r\n set literalStr(inputStr: string) {\r\n // TODO : parse using shutingyard tree !\r\n\r\n // Match all x^n\r\n for (const v of [...inputStr.matchAll(/([a-z])\\^([+-]?[0-9]+)/g)]) {\r\n // Create the default letter entry if necessary.\r\n if (!(v[1] in this._literal)) {\r\n this._literal[v[1]] = this.makeCoefficient().zero();\r\n }\r\n\r\n // Add the new value.\r\n // TODO: actually, it adds only numeric value\r\n this._literal[v[1]].add(+v[2]);\r\n }\r\n\r\n // Match all x\r\n for (const v of [...inputStr.matchAll(/([a-z](?!\\^))/g)]) {\r\n // Match all single letters\r\n if (!(v[1] in this._literal)) {\r\n this._literal[v[1]] = this.makeCoefficient().zero();\r\n }\r\n\r\n // Add one to the value.\r\n this._literal[v[1]].add(1)\r\n }\r\n }\r\n\r\n // Getter helpers.\r\n /**\r\n * Get the variables letters\r\n */\r\n get variables(): string[] {\r\n let M = this.clone().clean();\r\n return Object.keys(M.literal)\r\n }\r\n\r\n // Display getter\r\n /**\r\n * This display getter is to be used in the polynom display getter\r\n */\r\n get display(): string {\r\n let L: string = '',\r\n letters = Object.keys(this._literal).sort()\r\n for (let letter of letters) {\r\n if (!this._literal[letter].isZero()) {\r\n L += `${letter}`;\r\n if (!this._literal[letter].isEqualTo(1)) {\r\n L += `^(${this._literal[letter].display})`;\r\n }\r\n }\r\n }\r\n\r\n if (L === '') {\r\n // No setLetter - means it's only a number !\r\n if (this._coefficient.value != 0) {\r\n return `${this._coefficient.display}`;\r\n } else {\r\n return '';\r\n }\r\n } else {\r\n if (this._coefficient.value === 1) {\r\n return L;\r\n } else if (this._coefficient.value === -1) {\r\n return `-${L}`;\r\n } else if (this._coefficient.value === 0) {\r\n return '0';\r\n } else {\r\n return `${this._coefficient.display}${L}`;\r\n }\r\n }\r\n }\r\n\r\n get dividers(): Monom[] {\r\n // Decompose only if the coefficient is a natural number\r\n if (!this.coefficient.isRelative()) {\r\n return [this.clone()]\r\n }\r\n\r\n\r\n // Decompose only if the power values are natural numbers.\r\n if (this.hasFractionCoefficient()) {\r\n return [this.clone()]\r\n }\r\n\r\n // Security : do not do this if isGreaterThan than 10000\r\n if (this.coefficient.numerator > 1000000) {\r\n return [this.clone()]\r\n }\r\n\r\n const dividers = Numeric.dividers(Math.abs(this.coefficient.numerator))\r\n\r\n // Decompose the literals parts.\r\n let literals: literalType[] = [];\r\n for (let L in this.literal) {\r\n // L is the letter.\r\n literals = this._getLiteralDividers(literals, L)\r\n }\r\n\r\n const monomDividers: Monom[] = [];\r\n if (literals.length > 0 && dividers.length > 0) {\r\n for (let N of dividers) {\r\n for (let L of literals) {\r\n let M = new Monom();\r\n M.coefficient = this.makeCoefficient(N)\r\n M.literal = L\r\n monomDividers.push(M)\r\n }\r\n }\r\n } else if (dividers.length === 0) {\r\n for (let L of literals) {\r\n let M = new Monom();\r\n M.coefficient = this.makeCoefficient().one()\r\n M.literal = L\r\n monomDividers.push(M)\r\n }\r\n } else {\r\n for (let N of dividers) {\r\n let M = new Monom();\r\n M.coefficient = this.makeCoefficient(N)\r\n monomDividers.push(M)\r\n }\r\n }\r\n\r\n return monomDividers.length === 0 ? [new Monom().one()] : monomDividers;\r\n }\r\n\r\n /**\r\n * Display the monom, forcing the '+' sign to appear\r\n */\r\n get displayWithSign(): string {\r\n let d: String = this.display;\r\n return (d[0] !== '-' ? '+' : '') + d;\r\n }\r\n\r\n get texWithSign(): string {\r\n if (this.coefficient.isStrictlyPositive()) {\r\n return '+' + this.tex\r\n }\r\n\r\n return this.tex\r\n }\r\n\r\n get plotFunction(): string {\r\n\r\n let L: string = '',\r\n letters = Object.keys(this._literal).sort()\r\n\r\n for (let letter of letters) {\r\n if (!this._literal[letter].isZero()) {\r\n L += (L === '' ? \"\" : \"*\") + `${letter}`\r\n if (!this._literal[letter].isEqualTo(1)) {\r\n L += `^(${this._literal[letter].display})`;\r\n }\r\n }\r\n }\r\n\r\n // No literal part\r\n if (L === '') {\r\n // No setLetter - means it's only a number !\r\n if (this._coefficient.value != 0) {\r\n return `${this._coefficient.display}`;\r\n } else {\r\n return '';\r\n }\r\n } else {\r\n if (this._coefficient.value === 1) {\r\n return L;\r\n } else if (this._coefficient.value === -1) {\r\n return `-${L}`;\r\n } else if (this._coefficient.value === 0) {\r\n return '0';\r\n } else {\r\n return `${this._coefficient.display}*${L}`;\r\n }\r\n }\r\n }\r\n\r\n // ------------------------------------------\r\n // Creation / parsing functions\r\n\r\n /**\r\n * Get the tex output of the monom\r\n */\r\n get tex(): string {\r\n // TODO: display with square root !\r\n let L: string = '',\r\n letters = Object.keys(this._literal).sort()\r\n\r\n for (let letter of letters) {\r\n if (!this._literal[letter].isZero()) {\r\n L += `${letter}`;\r\n if (!this._literal[letter].isEqualTo(1)) {\r\n L += `^{${this._literal[letter].asTopFraction().tex}}`;\r\n }\r\n }\r\n }\r\n\r\n if (L === '') {\r\n // No setLetter - means it's only a number !\r\n if (this._coefficient.value != 0) {\r\n return `${this._coefficient.tex}`;\r\n } else {\r\n return '0';\r\n }\r\n } else {\r\n if (this._coefficient.value === 1) {\r\n return L;\r\n } else if (this._coefficient.value === -1) {\r\n return `-${L}`;\r\n } else if (this._coefficient.value === 0) {\r\n return '0';\r\n } else {\r\n return `${this._coefficient.tex}${L}`;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Get the least common multiple of monoms\r\n * @param monoms Array of monoms\r\n */\r\n static lcm = (...monoms: Monom[]): Monom => {\r\n // All the monoms must be with natural powers...\r\n for (let m of monoms) {\r\n if (m.hasFractionCoefficient()) {\r\n return new Monom().zero()\r\n }\r\n }\r\n\r\n\r\n let M = new Monom(),\r\n coeffN: number[] = monoms.map(value => value.coefficient.numerator),\r\n coeffD: number[] = monoms.map(value => value.coefficient.denominator),\r\n n = Numeric.gcd(...coeffN),\r\n d = Numeric.lcm(...coeffD);\r\n\r\n // Get the coefficient.\r\n M.coefficient = this.makeCoefficient(n, d).reduce();\r\n\r\n // Set the literal parts - go through each monoms literal parts and get only the lowest degree of each letters.\r\n for (let m of monoms) {\r\n // Remove the inexistant letters from the resulting monom\r\n for (let letter in M.literal) {\r\n if (!(letter in m.literal)) {\r\n M.literal[letter].zero();\r\n }\r\n }\r\n for (let letter in m.literal) {\r\n if (M.literal[letter] === undefined && m.literal[letter].isStrictlyPositive()) {\r\n M.literal[letter] = m.literal[letter].clone();\r\n } else {\r\n M.literal[letter] = this.makeCoefficient(Math.min(m.literal[letter].value, M.literal[letter].value))\r\n }\r\n }\r\n }\r\n\r\n return M;\r\n };\r\n\r\n /**\r\n * Multiply two monoms and return a NEW monom.\r\n * @param monoms\r\n */\r\n static xmultiply = (...monoms: Monom[]): Monom => {\r\n let M = new Monom().one();\r\n\r\n for (let m of monoms) {\r\n M.multiply(m);\r\n }\r\n\r\n return M;\r\n };\r\n\r\n makeCoefficient = (...values: CoefficientParserTypes[]): CoefficientTypes => {\r\n if (this._coefficientMode === COEFFICIENT_MODE.FRACTION) {\r\n return new Fraction(...values as (Fraction | string | number)[])\r\n } else if (this._coefficientMode === COEFFICIENT_MODE.ROOT) {\r\n return new RootFraction(...values as (RootFraction | Fraction | string | number)[])\r\n }\r\n\r\n // TODO: add the other modes\r\n return new Fraction(...values as (Fraction | string | number)[])\r\n }\r\n\r\n// -----------------------------------------\r\n /**\r\n * Parse a string to a monom. The string may include fraction.\r\n * @param inputStr\r\n */\r\n parse = (inputStr: unknown): Monom => {\r\n\r\n if (typeof inputStr === 'string') {\r\n this._shutingYardToReducedMonom(inputStr)\r\n } else if (typeof inputStr === 'number') {\r\n this._coefficient = this.makeCoefficient(inputStr)\r\n this._literal = {}\r\n } else if (inputStr instanceof Fraction) {\r\n this._coefficient = inputStr.clone()\r\n this._literal = {}\r\n } else if (inputStr instanceof RootFraction) {\r\n this._coefficient = inputStr.clone()\r\n this._literal = {}\r\n } else if (inputStr instanceof Monom) {\r\n this._coefficient = inputStr._coefficient.clone()\r\n this._literal = this.copyLiterals(inputStr.literal)\r\n }\r\n\r\n return this;\r\n };\r\n\r\n addToken = (stack: Monom[], element: Token): void => {\r\n\r\n let q1: Monom, q2: Monom, m: Monom, letter: string, pow: CoefficientCore<any>\r\n\r\n if (element.tokenType === ShutingyardType.COEFFICIENT) {\r\n stack.push(new Monom(this.makeCoefficient(element.token)))\r\n\r\n } else if (element.tokenType === ShutingyardType.VARIABLE) {\r\n let M = new Monom().one()\r\n M.setLetter(element.token, 1)\r\n stack.push(M.clone())\r\n\r\n } else if (element.tokenType === ShutingyardType.OPERATION) {\r\n switch (element.token) {\r\n case '-':\r\n // this should only happen for negative powers or for negative coefficient.\r\n q2 = (stack.pop()) || new Monom().zero()\r\n q1 = (stack.pop()) || new Monom().zero()\r\n\r\n stack.push(q1.subtract(q2))\r\n\r\n break;\r\n case '*':\r\n // Get the last element in the stack\r\n q2 = (stack.pop()) || new Monom().one()\r\n q1 = (stack.pop()) || new Monom().one()\r\n\r\n stack.push(q1.multiply(q2))\r\n break\r\n case '/':\r\n // Get the last element in the stack\r\n q2 = (stack.pop()) || new Monom().one()\r\n q1 = (stack.pop()) || new Monom().one()\r\n\r\n stack.push(q1.divide(q2))\r\n break\r\n case '^':\r\n // get the two last elements in the stack\r\n pow = (stack.pop().coefficient) || this.makeCoefficient().one()\r\n m = (stack.pop()) || new Monom().one()\r\n\r\n letter = m.variables[0]\r\n\r\n if (letter !== undefined) {\r\n m.setLetter(letter, pow)\r\n }\r\n\r\n stack.push(m)\r\n // this.multiply(m.clone())\r\n break\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Clone the current Monom.\r\n */\r\n clone = (): Monom => {\r\n let F: Monom = new Monom();\r\n\r\n F.coefficient = this._coefficient.clone();\r\n\r\n // Copy the literal parts.\r\n for (let k in this._literal) {\r\n F.setLetter(k, this._literal[k].clone());\r\n }\r\n return F;\r\n };\r\n\r\n copyLiterals = (literal: literalType): literalType => {\r\n let L: literalType = {}\r\n\r\n for (let k in literal) {\r\n L[k] = literal[k].clone()\r\n }\r\n return L\r\n }\r\n\r\n makeSame = (M: Monom): Monom => {\r\n // Copy the literal parts.\r\n for (let k in M._literal) {\r\n this.setLetter(k, M._literal[k].clone());\r\n }\r\n return this\r\n }\r\n\r\n /**\r\n * Create a zero value monom\r\n */\r\n zero = (): Monom => {\r\n this._coefficient = this.makeCoefficient().zero();\r\n this._literal = {};\r\n return this;\r\n };\r\n\r\n /**\r\n * Create a one value monom\r\n */\r\n one = (): Monom => {\r\n this._coefficient = this.makeCoefficient().one();\r\n this._literal = {};\r\n return this;\r\n };\r\n\r\n// ------------------------------------------\r\n// Mathematical operations\r\n// ------------------------------------------\r\n\r\n /**\r\n * Clean the monom by removing each letters with a power of zero.\r\n */\r\n clean = (): Monom => {\r\n for (let letter in this._literal) {\r\n if (this._literal[letter].isZero()) {\r\n delete this._literal[letter];\r\n }\r\n }\r\n return this;\r\n };\r\n\r\n reduce = (): Monom => {\r\n this.clean()\r\n this.coefficient.reduce()\r\n return this\r\n }\r\n\r\n /**\r\n * Get the opposite\r\n * Returns a monom.\r\n */\r\n opposed = (): Monom => {\r\n this._coefficient.opposite();\r\n return this;\r\n };\r\n\r\n /**\r\n * Add all similar monoms. If they aren't similar, they are simply skipped.\r\n * @param M (Monom[]) The monoms to add.\r\n */\r\n add = (...M: Monom[]): Monom => {\r\n for (let m of M) {\r\n if (this.isSameAs(m)) {\r\n if (this.isZero()) {\r\n this.makeSame(m)\r\n }\r\n this._coefficient.add(m.coefficient);\r\n } else {\r\n console.log('Add monom: ' + this.display + ' is not similar with ', m.display);\r\n }\r\n }\r\n return this;\r\n };\r\n\r\n /**\r\n * Subtract multiple monoms\r\n * @param M (Monom[]) The monoms to subtract\r\n */\r\n subtract = (...M: Monom[]): Monom => {\r\n for (let m of M) {\r\n if (this.isSameAs(m)) {\r\n if (this.isZero()) {\r\n this.makeSame(m)\r\n }\r\n this._coefficient.add(m.clone().coefficient.opposite());\r\n } else {\r\n console.log('Subtract: Is not similar: ', m.display);\r\n }\r\n }\r\n return this;\r\n };\r\n\r\n /**\r\n * Multiple multiple monoms to the current monom\r\n * @param M (Monom[]) The monoms to multiply to.\r\n */\r\n multiply = (...M: Monom[]): Monom => {\r\n for (let m of M) {\r\n // Multiply the coefficient.\r\n this._coefficient.multiply(m.coefficient);\r\n\r\n // Multiply the literal parts.\r\n for (let letter in m.literal) {\r\n if (this._literal[letter] === undefined) {\r\n this._literal[letter] = m.literal[letter].clone()\r\n } else {\r\n this._literal[letter].add(m.literal[letter])\r\n }\r\n\r\n }\r\n }\r\n return this;\r\n };\r\n\r\n multiplyByNumber = (F: Fraction | number): Monom => {\r\n this._coefficient.multiply(F);\r\n return this;\r\n }\r\n\r\n /**\r\n * Divide the current monoms by multiple monoms\r\n * @param M (Monom[])\r\n */\r\n divide = (...M: Monom[]): Monom => {\r\n // Depending on the given value, choose the current item\r\n for (let v of M) {\r\n // Divide the coefficient\r\n this._coefficient.divide(v.coefficient);\r\n\r\n // Subtract the power values\r\n for (let letter in v.literal) {\r\n this._literal[letter] = (this._literal[letter] === undefined) ? v.literal[letter].clone().opposite() : this._literal[letter].subtract(v.literal[letter])\r\n\r\n // If the power of a particular setLetter is zero, delete it from the literal part..\r\n if (this._literal[letter].isZero()) {\r\n delete this._literal[letter];\r\n }\r\n }\r\n }\r\n return this;\r\n };\r\n\r\n /**\r\n * Get the pow of a monom.\r\n * @param nb (number) : Mathematical pow\r\n */\r\n pow = (nb: number | Fraction): Monom => {\r\n this._coefficient.pow(nb);\r\n for (let letter in this._literal) {\r\n this._literal[letter].multiply(nb)\r\n }\r\n return this;\r\n };\r\n\r\n// ------------------------------------------\r\n// Compare functions\r\n\r\n /**\r\n * Get the index-root of the monom\r\n * @param p\r\n */\r\n root = (p: number): Monom => {\r\n // TODO: determiner the index root of a monom\r\n return this;\r\n }\r\n\r\n /**\r\n * Return the square root of a monom\r\n */\r\n sqrt = (): Monom => {\r\n if (this.isSquare()) {\r\n this._coefficient.sqrt();\r\n for (let letter in this._literal) {\r\n this._literal[letter].clone().divide(2)\r\n }\r\n }\r\n return this.root(2);\r\n }\r\n\r\n// ------------------------------------------\r\n compare = (M: Monom, sign?: COMPARESIGNS): boolean => {\r\n // TODO: Build the compare systems.\r\n if (sign === undefined) {\r\n sign = COMPARESIGNS.EQUALS;\r\n }\r\n\r\n\r\n switch (sign) {\r\n case COMPARESIGNS.EQUALS:\r\n // To be equal, they must be the isSame\r\n if (!this.compare(M, COMPARESIGNS.SAME)) {\r\n return false;\r\n }\r\n\r\n // The literal parts are the isSame. The coefficient must be equal\r\n return this._coefficient.isEqualTo(M.coefficient);\r\n case COMPARESIGNS.SAME:\r\n // Get the list of all variables from both monoms.\r\n let M1: string[] = this.variables,\r\n M2: string[] = M.variables,\r\n K: string[] = M1.concat(M2.filter((item) => M1.indexOf(item) < 0));\r\n\r\n if (M1.length === 0 && M2.length === 0) {\r\n return true\r\n }\r\n // To compare, both must be different than zero.\r\n if (!this.isZero() && !M.isZero()) {\r\n for (let key of K) {\r\n // The setLetter is not available in one of the monom\r\n if (this._literal[key] === undefined || M.literal[key] === undefined) {\r\n return false;\r\n }\r\n // The setLetter does not have the isSame power in each monoms.\r\n if (!this._literal[key].isEqualTo(M.literal[key])) {\r\n return false;\r\n }\r\n }\r\n }\r\n\r\n // All are positive check - the monoms are the sames.\r\n return true;\r\n default:\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Determine if the monom is null\r\n */\r\n isZero()\r\n :\r\n boolean {\r\n return this._coefficient.value === 0;\r\n }\r\n\r\n /**\r\n * Determine if the monom is one\r\n */\r\n isOne()\r\n :\r\n boolean {\r\n return this._coefficient.value === 1 && this.variables.length === 0;\r\n }\r\n\r\n /**\r\n * Determine if two monoms are equals\r\n * @param M\r\n */\r\n isEqual = (M: Monom): boolean => {\r\n return this.compare(M, COMPARESIGNS.EQUALS);\r\n };\r\n\r\n /**\r\n * Determine if two monoms are similar\r\n * @param M\r\n */\r\n isSameAs = (M: Monom): boolean => {\r\n return this.compare(M, COMPARESIGNS.SAME);\r\n };\r\n\r\n isSquare = (): boolean => {\r\n if (!this.coefficient.isSquare()) {\r\n return false;\r\n }\r\n return this.isLiteralSquare();\r\n }\r\n// ------------------------------------------\r\n// Misc monoms functions\r\n\r\n isLiteralSquare = (): boolean => {\r\n for (let letter in this.literal) {\r\n // A literal square must have a natural power\r\n if (this.literal[letter].isRational()) {\r\n return false\r\n }\r\n\r\n // The natural power must be be even\r\n if (this.literal[letter].isEven()) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n }\r\n\r\n hasFractionCoefficient = (): boolean => {\r\n for (let letter in this._literal) {\r\n if (this._literal[letter].isRational()) {\r\n return true\r\n }\r\n }\r\n\r\n return false\r\n }\r\n\r\n// -------------------------------------\r\n /**\r\n * Determine if a monom contains a setLetter in it's literal part\r\n * @param letter\r\n */\r\n hasLetter = (letter?: string): boolean => {\r\n // The letter was not found\r\n if (this._literal[letter === undefined ? 'x' : letter] === undefined) {\r\n return false\r\n }\r\n\r\n // The letter is found and is not zero !\r\n return !this._literal[letter === undefined ? 'x' : letter].isZero();\r\n };\r\n\r\n /**\r\n * Set the power of a particular setLetter\r\n * @param letter (string) Letter to change\r\n * @param pow (number) Power of the setLetter (must be positive integer.\r\n */\r\n setLetter = (letter: string, pow: CoefficientCore<any> | number): void => {\r\n if (pow instanceof CoefficientCore) {\r\n // Set the power of the letter to zero => remove it\r\n if (this.hasLetter(letter) && pow.isZero()) {\r\n delete this._literal[letter]\r\n }\r\n\r\n this._literal[letter] = pow.clone()\r\n } else {\r\n this.setLetter(letter, this.makeCoefficient(pow))\r\n }\r\n };\r\n\r\n /**\r\n * Get the degree of a monom. If no setLetter is given, the result will be the global degree.\r\n * @param letter (string) Letter to get to degree (power)\r\n */\r\n degree = (letter?: string): CoefficientTypes => {\r\n if (this.variables.length === 0) {\r\n return this.makeCoefficient().zero();\r\n }\r\n if (letter === undefined) {\r\n // Not setLetter given -> we get the global monom degree (sum of all the letters).\r\n return Object.values(this._literal)\r\n .reduce(\r\n (t, n) => t.clone().add(n)\r\n );\r\n } else {\r\n // A setLetter is given -> get the corresponding power.\r\n return this._literal[letter] === undefined ? this.makeCoefficient().zero() : this._literal[letter].clone();\r\n }\r\n };\r\n\r\n /**\r\n * Evaluate a monom. Each setLetter must be assigned to a Fraction.\r\n * @param values Dictionary of <setLetter: Fraction>\r\n */\r\n evaluate = (values?: literalType | Fraction | number): CoefficientCore<any> => {\r\n let r = this.coefficient.clone();\r\n\r\n if (typeof values === 'number' || values instanceof Fraction) {\r\n let tmpValues: literalType = {}\r\n tmpValues[this.variables[0]] = this.makeCoefficient(values)\r\n return this.evaluate(tmpValues);\r\n }\r\n\r\n if (typeof values === 'object') {\r\n if (this.variables.length === 0) {\r\n return this.coefficient\r\n }\r\n for (let L in this._literal) {\r\n if (values[L] === undefined) {\r\n return this.makeCoefficient().zero();\r\n }\r\n\r\n let value = this.makeCoefficient(values[L])\r\n\r\n r.multiply(value.pow(this._literal[L]))\r\n }\r\n }\r\n\r\n return r;\r\n };\r\n\r\n evaluateAsNumeric = (values: { [Key: string]: number } | number): number => {\r\n let r = this.coefficient.value\r\n\r\n if (typeof values === 'number') {\r\n let tmpValues: { [Key: string]: number } = {}\r\n tmpValues[this.variables[0]] = values\r\n return this.evaluateAsNumeric(tmpValues);\r\n }\r\n\r\n if (typeof values === 'object') {\r\n if (this.variables.length === 0) {\r\n return this.coefficient.value\r\n }\r\n for (let L in this._literal) {\r\n if (values[L] === undefined) {\r\n return 0;\r\n }\r\n\r\n r *= values[L] ** (this._literal[L].value)\r\n }\r\n }\r\n\r\n return r\r\n }\r\n// ----------------------------------------\r\n// Static functions\r\n// ----------------------------------------\r\n\r\n /**\r\n * Derivative the monom\r\n * @param letter\r\n */\r\n derivative = (letter?: string): Monom => {\r\n // No setLetter given - assume it's the setLetter 'x'\r\n if (letter === undefined) {\r\n letter = 'x';\r\n }\r\n\r\n if (this.hasLetter(letter)) {\r\n let d = this._literal[letter].clone(),\r\n dM = this.clone();\r\n\r\n // Subtract one to the degree.\r\n dM._literal[letter].subtract(1)\r\n\r\n // Multiply the coefficient by the previous degree\r\n dM._coefficient.multiply(this.makeCoefficient(d.clone()));\r\n return dM;\r\n } else {\r\n return new Monom().zero();\r\n }\r\n };\r\n\r\n primitive = (letter?: string): Monom => {\r\n // TODO: derivative including the ln value => implies creating different monom system ?\r\n if (letter === undefined) {\r\n letter = 'x'\r\n }\r\n\r\n // Zero monom\r\n let M = this.clone(), degree\r\n\r\n if (M.hasLetter(letter)) {\r\n degree = M.degree(letter).clone().add(1)\r\n M.coefficient = M.coefficient.clone().divide(degree)\r\n M.setLetter(letter, degree)\r\n } else {\r\n // There is no letter.\r\n\r\n // The coefficient might be zero (=> x) or a number a (=> ax)\r\n if (M.coefficient.isZero()) {\r\n M.coefficient = this.makeCoefficient().one()\r\n }\r\n M.setLetter(letter, 1)\r\n }\r\n\r\n return M\r\n }\r\n\r\n// TODO: The rest of the functions are not used or unnecessary ?\r\n /**\r\n * Determine if multiple monoms are similar\r\n * @param M\r\n */\r\n areSameAs = (...M: Monom[]): boolean => {\r\n let result: boolean = true;\r\n\r\n // Check all monoms if they are the isSame as the \"this\" one.\r\n for (let i = 0; i < M.length; i++) {\r\n if (!this.isSameAs(M[i])) {\r\n return false;\r\n }\r\n }\r\n\r\n // All check passed -> all the monoms are similar.\r\n return result;\r\n };\r\n\r\n /**\r\n * Determine if multiple monoms are equals\r\n * @param M\r\n */\r\n areEquals = (...M: Monom[]): boolean => {\r\n // They are not similar.\r\n if (!this.areSameAs(...M)) {\r\n return false;\r\n }\r\n\r\n // Check all coefficient. They must be equals.\r\n for (let m of M) {\r\n if (!this._coefficient.isEqualTo(m.coefficient)) {\r\n return false;\r\n }\r\n }\r\n\r\n // All checks passed.\r\n return true;\r\n };\r\n\r\n isDivisible = (div: Monom): boolean => {\r\n // For all variables (letters), the current monom must have a degree higher than the divider\r\n if (div.degree().isStrictlyPositive()) {\r\n for (let letter of div.variables) {\r\n if (!this.degree(letter).isGreaterOrEqualTo(div.degree(letter))) {\r\n return false\r\n }\r\n }\r\n }\r\n\r\n // If the coefficient is rational, we suppose we don't need to check the division by the coefficient.\r\n if (this.coefficient.isRational() || div.coefficient.isRational()) {\r\n return true\r\n }\r\n\r\n return this.coefficient.clone().divide(div.coefficient).isRelative()\r\n }\r\n\r\n isInverted(M\r\n :\r\n Monom\r\n ):\r\n boolean {\r\n return this.clone().multiply(M).isOne();\r\n }\r\n\r\n isNegativeOne()\r\n :\r\n boolean {\r\n return this._coefficient.value === -1 && this.variables.length === 0;\r\n }\r\n\r\n isNotEqual(M\r\n :\r\n Monom\r\n ):\r\n boolean {\r\n return !this.isEqual(M);\r\n }\r\n\r\n isNotZero()\r\n :\r\n boolean {\r\n return !this.isZero();\r\n }\r\n\r\n isOpposed(M\r\n :\r\n Monom\r\n ):\r\n boolean {\r\n return this.clone().subtract(M).isZero();\r\n }\r\n\r\n isReduced()\r\n :\r\n boolean {\r\n // By construction, it is already reduced (litterals\r\n return this.coefficient.isReduced();\r\n }\r\n\r\n reset()\r\n :\r\n any {\r\n this._coefficient = this.makeCoefficient()\r\n this._literal = {}\r\n }\r\n\r\n _getLiteralDividers(arr: literalType[], letter: string):\r\n literalType[] {\r\n let tmpList: { [key: string]: CoefficientTypes }[] = [];\r\n\r\n // Be default, this.literal[letter] should be a rational number.\r\n for (let d = 0; d <= this.literal[letter].value; d++) {\r\n if (arr.length === 0) {\r\n let litt: literalType = {}\r\n litt[letter] = this.makeCoefficient(d)\r\n tmpList.push(litt)\r\n } else {\r\n for (let item of arr) {\r\n let litt: literalType = {}\r\n for (let currentLetter in item) {\r\n litt[currentLetter] = item[currentLetter]\r\n }\r\n litt[letter] = this.makeCoefficient(d)\r\n tmpList.push(litt)\r\n }\r\n }\r\n }\r\n return tmpList;\r\n }\r\n\r\n _shutingYardToReducedMonom = (inputStr: string): Monom => {\r\n // Get the RPN array of the current expression\r\n const SY: Shutingyard = new Shutingyard().parse(inputStr);\r\n const rpn: { token: string, tokenType: string }[] = SY.rpn;\r\n\r\n let stack: Monom[] = []\r\n\r\n if (rpn.length === 0) {\r\n this.zero()\r\n return this\r\n } else if (rpn.length === 1) {\r\n const element = rpn[0]\r\n\r\n this.one()\r\n if (element.tokenType === 'coefficient') {\r\n this.coefficient = this.makeCoefficient(element.token)\r\n } else if (element.tokenType === 'variable') {\r\n this.setLetter(element.token, 1)\r\n }\r\n return this\r\n } else {\r\n // Reset the monom\r\n for (const element of rpn) {\r\n this.addToken(stack, element)\r\n }\r\n }\r\n\r\n this.one()\r\n this.multiply(stack[0])\r\n return this\r\n }\r\n}\r\n
5
- Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
6
- <+>UTF-8
7
- ===================================================================
8
- diff --git a/src/maths/algebra/monom.ts b/src/maths/algebra/monom.ts
9
- --- a/src/maths/algebra/monom.ts
10
- +++ b/src/maths/algebra/monom.ts
11
- @@ -1,1113 +1,203 @@
12
- -/***
13
- - * Monom class
14
- - * The monom class represents of monom of the form:
15
- - * k * x^n * y^m * z^p
16
- - * k: Coefficient
17
- - * n, m, p: powers as Fraction
18
- - * x, y, z: letters as string
19
- - */
20
- -import {Numeric} from "../numeric";
21
- -import {Shutingyard, ShutingyardType, Token} from "../shutingyard";
22
- -import {COMPARESIGNS, literalType} from "../types";
23
- -import {RootFraction} from "../coefficients/rootFraction";
24
- import {
25
- - COEFFICIENT_MODE,
26
- - CoefficientCore,
27
- - CoefficientParserTypes,
28
- - CoefficientTypes
29
- -} from "../coefficients/coefficientCore";
30
- -import {Fraction} from "../coefficients/fraction";
31
- -
32
- -
33
- -export class Monom {
34
- - private _coefficientMode: COEFFICIENT_MODE
35
- -
36
- - /**
37
- - * Create a Monom
38
- - * Defined as \\(k \\cdot x^{n}\\), where \\( k,n \in \\mathbb{Q}\\).
39
- - * Examples: \\(3x^2\\) or \\(3/5x^2\\)
40
- - * @param value (optional) string The value that should be parse. Can be a Monom, a Fraction, a string or a number. If nothing is provided, it will return the trivial monom (0).
41
- - */
42
- - constructor(value?: unknown) {
43
- - this.zero();
44
- -
45
- - if (value !== undefined) {
46
- - // A string is given - try to parse the value.
47
- - this.parse(value);
48
- - }
49
- -
50
- - return this;
51
- - }
52
- -
53
- - // ------------------------------------------
54
- - // Getter and setter
55
- -
56
- - private _coefficient: CoefficientCore<any>;
57
- -
58
- - // ------------------------------------------
59
- - /**
60
- - * Get the coefficient \\(k\\) of the Monom \\(k\\cdot x^{n}\\)
61
- - * @returns {Fraction}
62
- - */
63
- - get coefficient(): CoefficientCore<any> {
64
- - return this._coefficient;
65
- - }
66
- -
67
- - /**
68
- - * Set the coefficient \\(k\\) value of the monom
69
- - * @param {Fraction | number | string} F
70
- - */
71
- - set coefficient(F: CoefficientParserTypes) {
72
- - this._coefficient = this.makeCoefficient(F);
73
- - }
74
- -
75
- - private _literal: literalType;
76
- -
77
- - /**
78
- - * Get the literal part of \\(x^{n_1}y^{n_2}\\) as dictionary \\[\\begin{array}{ll}x&=n_1\\\\y&=n_2\\end{array}\\]
79
- - * @returns {literalType}
80
- - */
81
- - get literal(): literalType {
82
- - return this._literal;
83
- - }
84
- -
85
- - /**
86
- - * Set the literal part of the monom. Must be a dictionary {x: Fraction, y: Fraction, ...}
87
- - * @param {literalType} L
88
- - */
89
- - set literal(L: literalType) {
90
- - this._literal = L;
91
- - }
92
- + coreInterface,
93
- + equalityInterface,
94
- + expressionElementInterface,
95
- + expressionInterface,
96
- + operationInterface
97
- +} from "../types";
98
- +import {Coefficient} from "../coefficients/coefficient";
99
-
100
- - /**
101
- - * Get the literal square roots of the Monom.
102
- - * TODO: remove this getter ? Is it used and is it correct ?
103
- - * @returns {literalType}
104
- - */
105
- - get literalSqrt(): literalType {
106
- - if (this.isLiteralSquare()) {
107
- - let L: literalType = {}
108
- - for (let key in this._literal) {
109
- - L[key] = this._literal[key].clone().sqrt()
110
- - }
111
- - return L;
112
- - } else {
113
- - return this._literal;
114
- - }
115
- - }
116
-
117
- - /**
118
- - * Set the literal part of the monom from a string
119
- - * @param inputStr String like x^2y^3
120
- - */
121
- - set literalStr(inputStr: string) {
122
- - // TODO : parse using shutingyard tree !
123
- -
124
- - // Match all x^n
125
- - for (const v of [...inputStr.matchAll(/([a-z])\^([+-]?[0-9]+)/g)]) {
126
- - // Create the default letter entry if necessary.
127
- - if (!(v[1] in this._literal)) {
128
- - this._literal[v[1]] = this.makeCoefficient().zero();
129
- - }
130
- +/**
131
- + * A polynom element is a coefficient with one or more variables and an exponent (which is a power and a root).
132
- + *
133
- + */
134
- +export class Monom implements coreInterface, operationInterface, equalityInterface, expressionInterface {
135
- + constructor(...values: unknown[]) {
136
-
137
- - // Add the new value.
138
- - // TODO: actually, it adds only numeric value
139
- - this._literal[v[1]].add(+v[2]);
140
- + if (values.length > 0) {
141
- + return this.parse(...values)
142
- }
143
- -
144
- - // Match all x
145
- - for (const v of [...inputStr.matchAll(/([a-z](?!\^))/g)]) {
146
- - // Match all single letters
147
- - if (!(v[1] in this._literal)) {
148
- - this._literal[v[1]] = this.makeCoefficient().zero();
149
- - }
150
- + return this
151
- + }
152
-
153
- - // Add one to the value.
154
- - this._literal[v[1]].add(1)
155
- - }
156
- - }
157
- + private _literal: expressionElementInterface = {}
158
-
159
- - // Getter helpers.
160
- - /**
161
- - * Get the variables letters
162
- - */
163
- get variables(): string[] {
164
- - let M = this.clone().clean();
165
- - return Object.keys(M.literal)
166
- + return Object.keys(this._literal).sort()
167
- }
168
- -
169
- - // Display getter
170
- - /**
171
- - * This display getter is to be used in the polynom display getter
172
- - */
173
- - get display(): string {
174
- - let L: string = '',
175
- - letters = Object.keys(this._literal).sort()
176
- - for (let letter of letters) {
177
- - if (!this._literal[letter].isZero()) {
178
- - L += `${letter}`;
179
- - if (!this._literal[letter].isEqualTo(1)) {
180
- - L += `^(${this._literal[letter].display})`;
181
- - }
182
- - }
183
- - }
184
- -
185
- - if (L === '') {
186
- - // No setLetter - means it's only a number !
187
- - if (this._coefficient.value != 0) {
188
- - return `${this._coefficient.display}`;
189
- - } else {
190
- - return '';
191
- - }
192
- - } else {
193
- - if (this._coefficient.value === 1) {
194
- - return L;
195
- - } else if (this._coefficient.value === -1) {
196
- - return `-${L}`;
197
- - } else if (this._coefficient.value === 0) {
198
- - return '0';
199
- - } else {
200
- - return `${this._coefficient.display}${L}`;
201
- - }
202
- - }
203
- - }
204
- -
205
- - get dividers(): Monom[] {
206
- - // Decompose only if the coefficient is a natural number
207
- - if (!this.coefficient.isRelative()) {
208
- - return [this.clone()]
209
- - }
210
- -
211
- -
212
- - // Decompose only if the power values are natural numbers.
213
- - if (this.hasFractionCoefficient()) {
214
- - return [this.clone()]
215
- - }
216
- -
217
- - // Security : do not do this if isGreaterThan than 10000
218
- - if (this.coefficient.numerator > 1000000) {
219
- - return [this.clone()]
220
- - }
221
- -
222
- - const dividers = Numeric.dividers(Math.abs(this.coefficient.numerator))
223
- -
224
- - // Decompose the literals parts.
225
- - let literals: literalType[] = [];
226
- - for (let L in this.literal) {
227
- - // L is the letter.
228
- - literals = this._getLiteralDividers(literals, L)
229
- - }
230
- -
231
- - const monomDividers: Monom[] = [];
232
- - if (literals.length > 0 && dividers.length > 0) {
233
- - for (let N of dividers) {
234
- - for (let L of literals) {
235
- - let M = new Monom();
236
- - M.coefficient = this.makeCoefficient(N)
237
- - M.literal = L
238
- - monomDividers.push(M)
239
- - }
240
- - }
241
- - } else if (dividers.length === 0) {
242
- - for (let L of literals) {
243
- - let M = new Monom();
244
- - M.coefficient = this.makeCoefficient().one()
245
- - M.literal = L
246
- - monomDividers.push(M)
247
- - }
248
- - } else {
249
- - for (let N of dividers) {
250
- - let M = new Monom();
251
- - M.coefficient = this.makeCoefficient(N)
252
- - monomDividers.push(M)
253
- - }
254
- - }
255
- -
256
- - return monomDividers.length === 0 ? [new Monom().one()] : monomDividers;
257
- - }
258
- -
259
- - /**
260
- - * Display the monom, forcing the '+' sign to appear
261
- - */
262
- - get displayWithSign(): string {
263
- - let d: String = this.display;
264
- - return (d[0] !== '-' ? '+' : '') + d;
265
- - }
266
- -
267
- - get texWithSign(): string {
268
- - if (this.coefficient.isStrictlyPositive()) {
269
- - return '+' + this.tex
270
- - }
271
- -
272
- - return this.tex
273
- - }
274
- -
275
- - get plotFunction(): string {
276
- -
277
- - let L: string = '',
278
- - letters = Object.keys(this._literal).sort()
279
- -
280
- - for (let letter of letters) {
281
- - if (!this._literal[letter].isZero()) {
282
- - L += (L === '' ? "" : "*") + `${letter}`
283
- - if (!this._literal[letter].isEqualTo(1)) {
284
- - L += `^(${this._literal[letter].display})`;
285
- - }
286
- - }
287
- - }
288
- -
289
- - // No literal part
290
- - if (L === '') {
291
- - // No setLetter - means it's only a number !
292
- - if (this._coefficient.value != 0) {
293
- - return `${this._coefficient.display}`;
294
- - } else {
295
- - return '';
296
- - }
297
- - } else {
298
- - if (this._coefficient.value === 1) {
299
- - return L;
300
- - } else if (this._coefficient.value === -1) {
301
- - return `-${L}`;
302
- - } else if (this._coefficient.value === 0) {
303
- - return '0';
304
- - } else {
305
- - return `${this._coefficient.display}*${L}`;
306
- - }
307
- - }
308
- - }
309
- -
310
- - // ------------------------------------------
311
- - // Creation / parsing functions
312
- -
313
- - /**
314
- - * Get the tex output of the monom
315
- - */
316
- - get tex(): string {
317
- - // TODO: display with square root !
318
- - let L: string = '',
319
- - letters = Object.keys(this._literal).sort()
320
- -
321
- - for (let letter of letters) {
322
- - if (!this._literal[letter].isZero()) {
323
- - L += `${letter}`;
324
- - if (!this._literal[letter].isEqualTo(1)) {
325
- - L += `^{${this._literal[letter].asTopFraction().tex}}`;
326
- - }
327
- - }
328
- - }
329
- -
330
- - if (L === '') {
331
- - // No setLetter - means it's only a number !
332
- - if (this._coefficient.value != 0) {
333
- - return `${this._coefficient.tex}`;
334
- - } else {
335
- - return '0';
336
- - }
337
- - } else {
338
- - if (this._coefficient.value === 1) {
339
- - return L;
340
- - } else if (this._coefficient.value === -1) {
341
- - return `-${L}`;
342
- - } else if (this._coefficient.value === 0) {
343
- - return '0';
344
- - } else {
345
- - return `${this._coefficient.tex}${L}`;
346
- - }
347
- - }
348
- - }
349
- -
350
- - /**
351
- - * Get the least common multiple of monoms
352
- - * @param monoms Array of monoms
353
- - */
354
- - static lcm = (...monoms: Monom[]): Monom => {
355
- - // All the monoms must be with natural powers...
356
- - for (let m of monoms) {
357
- - if (m.hasFractionCoefficient()) {
358
- - return new Monom().zero()
359
- - }
360
- - }
361
- -
362
- -
363
- - let M = new Monom(),
364
- - coeffN: number[] = monoms.map(value => value.coefficient.numerator),
365
- - coeffD: number[] = monoms.map(value => value.coefficient.denominator),
366
- - n = Numeric.gcd(...coeffN),
367
- - d = Numeric.lcm(...coeffD);
368
- -
369
- - // Get the coefficient.
370
- - M.coefficient = this.makeCoefficient(n, d).reduce();
371
- -
372
- - // Set the literal parts - go through each monoms literal parts and get only the lowest degree of each letters.
373
- - for (let m of monoms) {
374
- - // Remove the inexistant letters from the resulting monom
375
- - for (let letter in M.literal) {
376
- - if (!(letter in m.literal)) {
377
- - M.literal[letter].zero();
378
- - }
379
- - }
380
- - for (let letter in m.literal) {
381
- - if (M.literal[letter] === undefined && m.literal[letter].isStrictlyPositive()) {
382
- - M.literal[letter] = m.literal[letter].clone();
383
- - } else {
384
- - M.literal[letter] = this.makeCoefficient(Math.min(m.literal[letter].value, M.literal[letter].value))
385
- - }
386
- - }
387
- - }
388
- -
389
- - return M;
390
- - };
391
- -
392
- - /**
393
- - * Multiply two monoms and return a NEW monom.
394
- - * @param monoms
395
- - */
396
- - static xmultiply = (...monoms: Monom[]): Monom => {
397
- - let M = new Monom().one();
398
- -
399
- - for (let m of monoms) {
400
- - M.multiply(m);
401
- - }
402
-
403
- - return M;
404
- - };
405
- -
406
- - makeCoefficient = (...values: CoefficientParserTypes[]): CoefficientTypes => {
407
- - if (this._coefficientMode === COEFFICIENT_MODE.FRACTION) {
408
- - return new Fraction(...values as (Fraction | string | number)[])
409
- - } else if (this._coefficientMode === COEFFICIENT_MODE.ROOT) {
410
- - return new RootFraction(...values as (RootFraction | Fraction | string | number)[])
411
- - }
412
- + get literal(): expressionElementInterface {
413
- + return this._literal;
414
- + }
415
-
416
- - // TODO: add the other modes
417
- - return new Fraction(...values as (Fraction | string | number)[])
418
- + set literal(value: expressionElementInterface) {
419
- + this._literal = value;
420
- }
421
-
422
- -// -----------------------------------------
423
- - /**
424
- - * Parse a string to a monom. The string may include fraction.
425
- - * @param inputStr
426
- - */
427
- - parse = (inputStr: unknown): Monom => {
428
- + private _coefficient: Coefficient = new Coefficient()
429
-
430
- - if (typeof inputStr === 'string') {
431
- - this._shutingYardToReducedMonom(inputStr)
432
- - } else if (typeof inputStr === 'number') {
433
- - this._coefficient = this.makeCoefficient(inputStr)
434
- - this._literal = {}
435
- - } else if (inputStr instanceof Fraction) {
436
- - this._coefficient = inputStr.clone()
437
- - this._literal = {}
438
- - } else if (inputStr instanceof RootFraction) {
439
- - this._coefficient = inputStr.clone()
440
- - this._literal = {}
441
- - } else if (inputStr instanceof Monom) {
442
- - this._coefficient = inputStr._coefficient.clone()
443
- - this._literal = this.copyLiterals(inputStr.literal)
444
- - }
445
- + get coefficient(): Coefficient {
446
- + return this._coefficient;
447
- + }
448
-
449
- - return this;
450
- - };
451
- -
452
- - addToken = (stack: Monom[], element: Token): void => {
453
- -
454
- - let q1: Monom, q2: Monom, m: Monom, letter: string, pow: CoefficientCore<any>
455
- -
456
- - if (element.tokenType === ShutingyardType.COEFFICIENT) {
457
- - stack.push(new Monom(this.makeCoefficient(element.token)))
458
- -
459
- - } else if (element.tokenType === ShutingyardType.VARIABLE) {
460
- - let M = new Monom().one()
461
- - M.setLetter(element.token, 1)
462
- - stack.push(M.clone())
463
- -
464
- - } else if (element.tokenType === ShutingyardType.OPERATION) {
465
- - switch (element.token) {
466
- - case '-':
467
- - // this should only happen for negative powers or for negative coefficient.
468
- - q2 = (stack.pop()) || new Monom().zero()
469
- - q1 = (stack.pop()) || new Monom().zero()
470
- -
471
- - stack.push(q1.subtract(q2))
472
- -
473
- - break;
474
- - case '*':
475
- - // Get the last element in the stack
476
- - q2 = (stack.pop()) || new Monom().one()
477
- - q1 = (stack.pop()) || new Monom().one()
478
- -
479
- - stack.push(q1.multiply(q2))
480
- - break
481
- - case '/':
482
- - // Get the last element in the stack
483
- - q2 = (stack.pop()) || new Monom().one()
484
- - q1 = (stack.pop()) || new Monom().one()
485
- -
486
- - stack.push(q1.divide(q2))
487
- - break
488
- - case '^':
489
- - // get the two last elements in the stack
490
- - pow = (stack.pop().coefficient) || this.makeCoefficient().one()
491
- - m = (stack.pop()) || new Monom().one()
492
- -
493
- - letter = m.variables[0]
494
- -
495
- - if (letter !== undefined) {
496
- - m.setLetter(letter, pow)
497
- - }
498
- -
499
- - stack.push(m)
500
- - // this.multiply(m.clone())
501
- - break
502
- - }
503
- - }
504
- + set coefficient(value: Coefficient) {
505
- + this._coefficient = value;
506
- }
507
-
508
- - /**
509
- - * Clone the current Monom.
510
- - */
511
- - clone = (): Monom => {
512
- - let F: Monom = new Monom();
513
- + add(...values: Monom[]): this {
514
- + if (values.length === 0) return this
515
-
516
- - F.coefficient = this._coefficient.clone();
517
- -
518
- - // Copy the literal parts.
519
- - for (let k in this._literal) {
520
- - F.setLetter(k, this._literal[k].clone());
521
- + // Check that all the monoms are similar.
522
- + if (!values.every(x => this.isSimilarTo(x))) {
523
- + throw new Error('The monoms are not similar.')
524
- }
525
- - return F;
526
- - };
527
-
528
- - copyLiterals = (literal: literalType): literalType => {
529
- - let L: literalType = {}
530
- + // Add the coefficients.
531
- + this._coefficient.add(...values.map(x => x.coefficient))
532
-
533
- - for (let k in literal) {
534
- - L[k] = literal[k].clone()
535
- - }
536
- - return L
537
- - }
538
- -
539
- - makeSame = (M: Monom): Monom => {
540
- - // Copy the literal parts.
541
- - for (let k in M._literal) {
542
- - this.setLetter(k, M._literal[k].clone());
543
- - }
544
- return this
545
- }
546
-
547
- - /**
548
- - * Create a zero value monom
549
- - */
550
- - zero = (): Monom => {
551
- - this._coefficient = this.makeCoefficient().zero();
552
- - this._literal = {};
553
- - return this;
554
- - };
555
- -
556
- - /**
557
- - * Create a one value monom
558
- - */
559
- - one = (): Monom => {
560
- - this._coefficient = this.makeCoefficient().one();
561
- - this._literal = {};
562
- - return this;
563
- - };
564
- -
565
- -// ------------------------------------------
566
- -// Mathematical operations
567
- -// ------------------------------------------
568
- -
569
- - /**
570
- - * Clean the monom by removing each letters with a power of zero.
571
- - */
572
- - clean = (): Monom => {
573
- - for (let letter in this._literal) {
574
- - if (this._literal[letter].isZero()) {
575
- - delete this._literal[letter];
576
- - }
577
- - }
578
- - return this;
579
- - };
580
- + subtract(...values: Monom[]): this {
581
- + return this.add(...values.map(x => x.opposite()))
582
- + }
583
-
584
- - reduce = (): Monom => {
585
- - this.clean()
586
- - this.coefficient.reduce()
587
- + multiply(...values: Monom[]): this {
588
- return this
589
- }
590
-
591
- - /**
592
- - * Get the opposite
593
- - * Returns a monom.
594
- - */
595
- - opposed = (): Monom => {
596
- - this._coefficient.opposite();
597
- - return this;
598
- - };
599
- -
600
- - /**
601
- - * Add all similar monoms. If they aren't similar, they are simply skipped.
602
- - * @param M (Monom[]) The monoms to add.
603
- - */
604
- - add = (...M: Monom[]): Monom => {
605
- - for (let m of M) {
606
- - if (this.isSameAs(m)) {
607
- - if (this.isZero()) {
608
- - this.makeSame(m)
609
- - }
610
- - this._coefficient.add(m.coefficient);
611
- - } else {
612
- - console.log('Add monom: ' + this.display + ' is not similar with ', m.display);
613
- - }
614
- - }
615
- - return this;
616
- - };
617
- + divide(value: Monom): this {
618
- + return this
619
- + }
620
-
621
- - /**
622
- - * Subtract multiple monoms
623
- - * @param M (Monom[]) The monoms to subtract
624
- - */
625
- - subtract = (...M: Monom[]): Monom => {
626
- - for (let m of M) {
627
- - if (this.isSameAs(m)) {
628
- - if (this.isZero()) {
629
- - this.makeSame(m)
630
- - }
631
- - this._coefficient.add(m.clone().coefficient.opposite());
632
- - } else {
633
- - console.log('Subtract: Is not similar: ', m.display);
634
- - }
635
- - }
636
- - return this;
637
- - };
638
- -
639
- - /**
640
- - * Multiple multiple monoms to the current monom
641
- - * @param M (Monom[]) The monoms to multiply to.
642
- - */
643
- - multiply = (...M: Monom[]): Monom => {
644
- - for (let m of M) {
645
- - // Multiply the coefficient.
646
- - this._coefficient.multiply(m.coefficient);
647
- + opposite(): this {
648
- + this._coefficient.opposite()
649
- + return this
650
- + }
651
-
652
- - // Multiply the literal parts.
653
- - for (let letter in m.literal) {
654
- - if (this._literal[letter] === undefined) {
655
- - this._literal[letter] = m.literal[letter].clone()
656
- - } else {
657
- - this._literal[letter].add(m.literal[letter])
658
- - }
659
- + invert(): this {
660
- + return this
661
- + }
662
-
663
- - }
664
- - }
665
- - return this;
666
- - };
667
- + pow(value: number): this {
668
- + return this
669
- + }
670
-
671
- - multiplyByNumber = (F: Fraction | number): Monom => {
672
- - this._coefficient.multiply(F);
673
- - return this;
674
- + root(value: number): this {
675
- + return this
676
- }
677
-
678
- - /**
679
- - * Divide the current monoms by multiple monoms
680
- - * @param M (Monom[])
681
- - */
682
- - divide = (...M: Monom[]): Monom => {
683
- - // Depending on the given value, choose the current item
684
- - for (let v of M) {
685
- - // Divide the coefficient
686
- - this._coefficient.divide(v.coefficient);
687
- -
688
- - // Subtract the power values
689
- - for (let letter in v.literal) {
690
- - this._literal[letter] = (this._literal[letter] === undefined) ? v.literal[letter].clone().opposite() : this._literal[letter].subtract(v.literal[letter])
691
- -
692
- - // If the power of a particular setLetter is zero, delete it from the literal part..
693
- - if (this._literal[letter].isZero()) {
694
- - delete this._literal[letter];
695
- - }
696
- - }
697
- - }
698
- - return this;
699
- - };
700
- + reduce(): this {
701
- + return this
702
- + }
703
-
704
- - /**
705
- - * Get the pow of a monom.
706
- - * @param nb (number) : Mathematical pow
707
- - */
708
- - pow = (nb: number | Fraction): Monom => {
709
- - this._coefficient.pow(nb);
710
- - for (let letter in this._literal) {
711
- - this._literal[letter].multiply(nb)
712
- - }
713
- - return this;
714
- - };
715
- + isSimilarTo(value: Monom): boolean {
716
- + // To be similar, the variables must be similar.
717
- + // The coefficient can be different.
718
-
719
- -// ------------------------------------------
720
- -// Compare functions
721
- + // They must have the same number of variables.
722
- + if (this.variables.length !== (value as Monom).variables.length) return false
723
-
724
- - /**
725
- - * Get the index-root of the monom
726
- - * @param p
727
- - */
728
- - root = (p: number): Monom => {
729
- - // TODO: determiner the index root of a monom
730
- - return this;
731
- - }
732
- -
733
- - /**
734
- - * Return the square root of a monom
735
- - */
736
- - sqrt = (): Monom => {
737
- - if (this.isSquare()) {
738
- - this._coefficient.sqrt();
739
- - for (let letter in this._literal) {
740
- - this._literal[letter].clone().divide(2)
741
- - }
742
- - }
743
- - return this.root(2);
744
- - }
745
- + // They must have the same variables.
746
- + if (this.variables.every(x => (value as Monom).variables.includes(x))) return false
747
-
748
- -// ------------------------------------------
749
- - compare = (M: Monom, sign?: COMPARESIGNS): boolean => {
750
- - // TODO: Build the compare systems.
751
- - if (sign === undefined) {
752
- - sign = COMPARESIGNS.EQUALS;
753
- - }
754
- -
755
- -
756
- - switch (sign) {
757
- - case COMPARESIGNS.EQUALS:
758
- - // To be equal, they must be the isSame
759
- - if (!this.compare(M, COMPARESIGNS.SAME)) {
760
- - return false;
761
- - }
762
- -
763
- - // The literal parts are the isSame. The coefficient must be equal
764
- - return this._coefficient.isEqualTo(M.coefficient);
765
- - case COMPARESIGNS.SAME:
766
- - // Get the list of all variables from both monoms.
767
- - let M1: string[] = this.variables,
768
- - M2: string[] = M.variables,
769
- - K: string[] = M1.concat(M2.filter((item) => M1.indexOf(item) < 0));
770
- -
771
- - if (M1.length === 0 && M2.length === 0) {
772
- - return true
773
- - }
774
- - // To compare, both must be different than zero.
775
- - if (!this.isZero() && !M.isZero()) {
776
- - for (let key of K) {
777
- - // The setLetter is not available in one of the monom
778
- - if (this._literal[key] === undefined || M.literal[key] === undefined) {
779
- - return false;
780
- - }
781
- - // The setLetter does not have the isSame power in each monoms.
782
- - if (!this._literal[key].isEqualTo(M.literal[key])) {
783
- - return false;
784
- - }
785
- - }
786
- - }
787
- -
788
- - // All are positive check - the monoms are the sames.
789
- - return true;
790
- - default:
791
- - return false;
792
- - }
793
- + return true
794
- }
795
- -
796
- - /**
797
- - * Determine if the monom is null
798
- - */
799
- - isZero()
800
- - :
801
- - boolean {
802
- - return this._coefficient.value === 0;
803
- - }
804
- -
805
- - /**
806
- - * Determine if the monom is one
807
- - */
808
- - isOne()
809
- - :
810
- - boolean {
811
- - return this._coefficient.value === 1 && this.variables.length === 0;
812
- - }
813
- -
814
- - /**
815
- - * Determine if two monoms are equals
816
- - * @param M
817
- - */
818
- - isEqual = (M: Monom): boolean => {
819
- - return this.compare(M, COMPARESIGNS.EQUALS);
820
- - };
821
-
822
- - /**
823
- - * Determine if two monoms are similar
824
- - * @param M
825
- - */
826
- - isSameAs = (M: Monom): boolean => {
827
- - return this.compare(M, COMPARESIGNS.SAME);
828
- - };
829
- -
830
- - isSquare = (): boolean => {
831
- - if (!this.coefficient.isSquare()) {
832
- - return false;
833
- - }
834
- - return this.isLiteralSquare();
835
- - }
836
- -// ------------------------------------------
837
- -// Misc monoms functions
838
- -
839
- - isLiteralSquare = (): boolean => {
840
- - for (let letter in this.literal) {
841
- - // A literal square must have a natural power
842
- - if (this.literal[letter].isRational()) {
843
- - return false
844
- - }
845
- + isEqualTo(value: unknown): boolean {
846
- + return false
847
- + }
848
-
849
- - // The natural power must be be even
850
- - if (this.literal[letter].isEven()) {
851
- - return false;
852
- - }
853
- - }
854
- -
855
- - return true;
856
- - }
857
- -
858
- - hasFractionCoefficient = (): boolean => {
859
- - for (let letter in this._literal) {
860
- - if (this._literal[letter].isRational()) {
861
- - return true
862
- - }
863
- - }
864
- -
865
- + isReduced(): boolean {
866
- return false
867
- }
868
-
869
- -// -------------------------------------
870
- - /**
871
- - * Determine if a monom contains a setLetter in it's literal part
872
- - * @param letter
873
- - */
874
- - hasLetter = (letter?: string): boolean => {
875
- - // The letter was not found
876
- - if (this._literal[letter === undefined ? 'x' : letter] === undefined) {
877
- - return false
878
- - }
879
- + isOne(): boolean {
880
- + return false
881
- + }
882
-
883
- - // The letter is found and is not zero !
884
- - return !this._literal[letter === undefined ? 'x' : letter].isZero();
885
- - };
886
- -
887
- - /**
888
- - * Set the power of a particular setLetter
889
- - * @param letter (string) Letter to change
890
- - * @param pow (number) Power of the setLetter (must be positive integer.
891
- - */
892
- - setLetter = (letter: string, pow: CoefficientCore<any> | number): void => {
893
- - if (pow instanceof CoefficientCore) {
894
- - // Set the power of the letter to zero => remove it
895
- - if (this.hasLetter(letter) && pow.isZero()) {
896
- - delete this._literal[letter]
897
- - }
898
- -
899
- - this._literal[letter] = pow.clone()
900
- - } else {
901
- - this.setLetter(letter, this.makeCoefficient(pow))
902
- - }
903
- - };
904
- -
905
- - /**
906
- - * Get the degree of a monom. If no setLetter is given, the result will be the global degree.
907
- - * @param letter (string) Letter to get to degree (power)
908
- - */
909
- - degree = (letter?: string): CoefficientTypes => {
910
- - if (this.variables.length === 0) {
911
- - return this.makeCoefficient().zero();
912
- - }
913
- - if (letter === undefined) {
914
- - // Not setLetter given -> we get the global monom degree (sum of all the letters).
915
- - return Object.values(this._literal)
916
- - .reduce(
917
- - (t, n) => t.clone().add(n)
918
- - );
919
- - } else {
920
- - // A setLetter is given -> get the corresponding power.
921
- - return this._literal[letter] === undefined ? this.makeCoefficient().zero() : this._literal[letter].clone();
922
- - }
923
- - };
924
- -
925
- - /**
926
- - * Evaluate a monom. Each setLetter must be assigned to a Fraction.
927
- - * @param values Dictionary of <setLetter: Fraction>
928
- - */
929
- - evaluate = (values?: literalType | Fraction | number): CoefficientCore<any> => {
930
- - let r = this.coefficient.clone();
931
- -
932
- - if (typeof values === 'number' || values instanceof Fraction) {
933
- - let tmpValues: literalType = {}
934
- - tmpValues[this.variables[0]] = this.makeCoefficient(values)
935
- - return this.evaluate(tmpValues);
936
- - }
937
- -
938
- - if (typeof values === 'object') {
939
- - if (this.variables.length === 0) {
940
- - return this.coefficient
941
- - }
942
- - for (let L in this._literal) {
943
- - if (values[L] === undefined) {
944
- - return this.makeCoefficient().zero();
945
- - }
946
- -
947
- - let value = this.makeCoefficient(values[L])
948
- -
949
- - r.multiply(value.pow(this._literal[L]))
950
- - }
951
- - }
952
- -
953
- - return r;
954
- - };
955
- -
956
- - evaluateAsNumeric = (values: { [Key: string]: number } | number): number => {
957
- - let r = this.coefficient.value
958
- -
959
- - if (typeof values === 'number') {
960
- - let tmpValues: { [Key: string]: number } = {}
961
- - tmpValues[this.variables[0]] = values
962
- - return this.evaluateAsNumeric(tmpValues);
963
- - }
964
- -
965
- - if (typeof values === 'object') {
966
- - if (this.variables.length === 0) {
967
- - return this.coefficient.value
968
- - }
969
- - for (let L in this._literal) {
970
- - if (values[L] === undefined) {
971
- - return 0;
972
- - }
973
- -
974
- - r *= values[L] ** (this._literal[L].value)
975
- - }
976
- - }
977
- -
978
- - return r
979
- - }
980
- -// ----------------------------------------
981
- -// Static functions
982
- -// ----------------------------------------
983
- -
984
- - /**
985
- - * Derivative the monom
986
- - * @param letter
987
- - */
988
- - derivative = (letter?: string): Monom => {
989
- - // No setLetter given - assume it's the setLetter 'x'
990
- - if (letter === undefined) {
991
- - letter = 'x';
992
- - }
993
- -
994
- - if (this.hasLetter(letter)) {
995
- - let d = this._literal[letter].clone(),
996
- - dM = this.clone();
997
- -
998
- - // Subtract one to the degree.
999
- - dM._literal[letter].subtract(1)
1000
- -
1001
- - // Multiply the coefficient by the previous degree
1002
- - dM._coefficient.multiply(this.makeCoefficient(d.clone()));
1003
- - return dM;
1004
- - } else {
1005
- - return new Monom().zero();
1006
- - }
1007
- - };
1008
- -
1009
- - primitive = (letter?: string): Monom => {
1010
- - // TODO: derivative including the ln value => implies creating different monom system ?
1011
- - if (letter === undefined) {
1012
- - letter = 'x'
1013
- - }
1014
- -
1015
- - // Zero monom
1016
- - let M = this.clone(), degree
1017
- -
1018
- - if (M.hasLetter(letter)) {
1019
- - degree = M.degree(letter).clone().add(1)
1020
- - M.coefficient = M.coefficient.clone().divide(degree)
1021
- - M.setLetter(letter, degree)
1022
- - } else {
1023
- - // There is no letter.
1024
- -
1025
- - // The coefficient might be zero (=> x) or a number a (=> ax)
1026
- - if (M.coefficient.isZero()) {
1027
- - M.coefficient = this.makeCoefficient().one()
1028
- - }
1029
- - M.setLetter(letter, 1)
1030
- - }
1031
- -
1032
- - return M
1033
- - }
1034
- -
1035
- -// TODO: The rest of the functions are not used or unnecessary ?
1036
- - /**
1037
- - * Determine if multiple monoms are similar
1038
- - * @param M
1039
- - */
1040
- - areSameAs = (...M: Monom[]): boolean => {
1041
- - let result: boolean = true;
1042
- -
1043
- - // Check all monoms if they are the isSame as the "this" one.
1044
- - for (let i = 0; i < M.length; i++) {
1045
- - if (!this.isSameAs(M[i])) {
1046
- - return false;
1047
- - }
1048
- - }
1049
- -
1050
- - // All check passed -> all the monoms are similar.
1051
- - return result;
1052
- - };
1053
- -
1054
- - /**
1055
- - * Determine if multiple monoms are equals
1056
- - * @param M
1057
- - */
1058
- - areEquals = (...M: Monom[]): boolean => {
1059
- - // They are not similar.
1060
- - if (!this.areSameAs(...M)) {
1061
- - return false;
1062
- - }
1063
- -
1064
- - // Check all coefficient. They must be equals.
1065
- - for (let m of M) {
1066
- - if (!this._coefficient.isEqualTo(m.coefficient)) {
1067
- - return false;
1068
- - }
1069
- - }
1070
- -
1071
- - // All checks passed.
1072
- - return true;
1073
- - };
1074
- -
1075
- - isDivisible = (div: Monom): boolean => {
1076
- - // For all variables (letters), the current monom must have a degree higher than the divider
1077
- - if (div.degree().isStrictlyPositive()) {
1078
- - for (let letter of div.variables) {
1079
- - if (!this.degree(letter).isGreaterOrEqualTo(div.degree(letter))) {
1080
- - return false
1081
- - }
1082
- - }
1083
- - }
1084
- -
1085
- - // If the coefficient is rational, we suppose we don't need to check the division by the coefficient.
1086
- - if (this.coefficient.isRational() || div.coefficient.isRational()) {
1087
- - return true
1088
- - }
1089
- -
1090
- - return this.coefficient.clone().divide(div.coefficient).isRelative()
1091
- + isMinusOne(): boolean {
1092
- + return false
1093
- }
1094
- -
1095
- - isInverted(M
1096
- - :
1097
- - Monom
1098
- - ):
1099
- - boolean {
1100
- - return this.clone().multiply(M).isOne();
1101
- - }
1102
- -
1103
- - isNegativeOne()
1104
- - :
1105
- - boolean {
1106
- - return this._coefficient.value === -1 && this.variables.length === 0;
1107
- - }
1108
-
1109
- - isNotEqual(M
1110
- - :
1111
- - Monom
1112
- - ):
1113
- - boolean {
1114
- - return !this.isEqual(M);
1115
- + isUnit(): boolean {
1116
- + return false
1117
- }
1118
-
1119
- - isNotZero()
1120
- - :
1121
- - boolean {
1122
- - return !this.isZero();
1123
- + isZero(): boolean {
1124
- + return false
1125
- }
1126
-
1127
- - isOpposed(M
1128
- - :
1129
- - Monom
1130
- - ):
1131
- - boolean {
1132
- - return this.clone().subtract(M).isZero();
1133
- - }
1134
- -
1135
- - isReduced()
1136
- - :
1137
- - boolean {
1138
- - // By construction, it is already reduced (litterals
1139
- - return this.coefficient.isReduced();
1140
- - }
1141
- -
1142
- - reset()
1143
- - :
1144
- - any {
1145
- - this._coefficient = this.makeCoefficient()
1146
- + private reset() {
1147
- + this._coefficient = new Coefficient().zero()
1148
- this._literal = {}
1149
- }
1150
-
1151
- - _getLiteralDividers(arr: literalType[], letter: string):
1152
- - literalType[] {
1153
- - let tmpList: { [key: string]: CoefficientTypes }[] = [];
1154
- + private parse(...values: unknown[]): Monom {
1155
- + this.reset()
1156
- +
1157
- + // Parse the values.
1158
- + if (values.length === 1) {
1159
- + if (values[0] instanceof Monom) {
1160
- + return values[0].clone()
1161
- + }
1162
- +
1163
- + if (typeof values[0] === "string") {
1164
- + // Parse the string to get the coefficient and the literal.
1165
- + }
1166
- +
1167
- + if (typeof values[0] === "number") {
1168
- + // Parse the number to get the coefficient and the literal.
1169
- + this._coefficient = new Coefficient(values[0])
1170
- + return this
1171
- + }
1172
- + }
1173
- +
1174
- + return this;
1175
- + }
1176
- +
1177
- + clone(): Monom {
1178
- +
1179
- + const m = new Monom()
1180
-
1181
- - // Be default, this.literal[letter] should be a rational number.
1182
- - for (let d = 0; d <= this.literal[letter].value; d++) {
1183
- - if (arr.length === 0) {
1184
- - let litt: literalType = {}
1185
- - litt[letter] = this.makeCoefficient(d)
1186
- - tmpList.push(litt)
1187
- + m.coefficient = this.coefficient.clone()
1188
- + for (let v of this.variables) {
1189
- + m.literal[v] = this.literal[v]
1190
- + }
1191
- +
1192
- + return m
1193
- + }
1194
- +
1195
- + get tex(): string {
1196
- + if (this.coefficient.length === 0) return "0"
1197
- +
1198
- + let result = this.coefficient.length > 1 ? `\\left(${this.coefficient.tex}\\right)` : `${this.coefficient.tex}`
1199
- +
1200
- + // TODO: handle negative exponent and root.
1201
- + for (let v of this.variables) {
1202
- + if (this.literal[v].exponent === 1) {
1203
- + result += v
1204
- } else {
1205
- - for (let item of arr) {
1206
- - let litt: literalType = {}
1207
- - for (let currentLetter in item) {
1208
- - litt[currentLetter] = item[currentLetter]
1209
- - }
1210
- - litt[letter] = this.makeCoefficient(d)
1211
- - tmpList.push(litt)
1212
- - }
1213
- + result += `${v}^{ ${this.literal[v].exponent} }`
1214
- }
1215
- }
1216
- - return tmpList;
1217
- + return result
1218
- }
1219
-
1220
- - _shutingYardToReducedMonom = (inputStr: string): Monom => {
1221
- - // Get the RPN array of the current expression
1222
- - const SY: Shutingyard = new Shutingyard().parse(inputStr);
1223
- - const rpn: { token: string, tokenType: string }[] = SY.rpn;
1224
- -
1225
- - let stack: Monom[] = []
1226
- + get display(): string {
1227
- + if (this.coefficient.length === 0) return "0"
1228
-
1229
- - if (rpn.length === 0) {
1230
- - this.zero()
1231
- - return this
1232
- - } else if (rpn.length === 1) {
1233
- - const element = rpn[0]
1234
- + let result = this.coefficient.length > 1 ? `(${this.coefficient.display})` : `${this.coefficient.display}`
1235
-
1236
- - this.one()
1237
- - if (element.tokenType === 'coefficient') {
1238
- - this.coefficient = this.makeCoefficient(element.token)
1239
- - } else if (element.tokenType === 'variable') {
1240
- - this.setLetter(element.token, 1)
1241
- - }
1242
- - return this
1243
- - } else {
1244
- - // Reset the monom
1245
- - for (const element of rpn) {
1246
- - this.addToken(stack, element)
1247
- + // TODO: handle negative exponent and root.
1248
- + for (let v of this.variables) {
1249
- + if (this.literal[v].exponent === 1) {
1250
- + result += v
1251
- + } else {
1252
- + result += `${v}^{${this.literal[v].exponent}}`
1253
- }
1254
- }
1255
- -
1256
- - this.one()
1257
- - this.multiply(stack[0])
1258
- - return this
1259
- + return result
1260
- }
1261
- -}
1262
- +}
1263
-
1264
- Index: src/maths/coefficients/coefficientCore.ts
1265
- IDEA additional info:
1266
- Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP
1267
- <+>import {Fraction} from \"./fraction\";\r\nimport {RootFraction} from \"./rootFraction\";\r\nimport {Numeric} from \"../numeric\";\r\n\r\n\r\nexport type CoefficientTypes = Fraction | RootFraction\r\nexport type CoefficientParserTypes = CoefficientTypes | number | string\r\n\r\nexport enum COEFFICIENT_MODE {\r\n \"FRACTION\",\r\n \"ROOT\",\r\n \"RADIAN\",\r\n \"COMPLEX\"\r\n}\r\n\r\nexport enum FRACTION_FRAC {\r\n \"frac\",\r\n \"dfrac\",\r\n \"tfrac\",\r\n}\r\n\r\nexport abstract class CoefficientCore<T extends CoefficientTypes> {\r\n private _fracType: FRACTION_FRAC\r\n\r\n get fracType(): FRACTION_FRAC {\r\n return this._fracType;\r\n }\r\n\r\n set fracType(value: FRACTION_FRAC) {\r\n this._fracType = value;\r\n }\r\n\r\n private _numerator: number\r\n\r\n get numerator(): number {\r\n return this._numerator;\r\n }\r\n\r\n set numerator(value: number) {\r\n this._numerator = value;\r\n }\r\n\r\n private _denominator: number\r\n\r\n get denominator(): number {\r\n return this._denominator;\r\n }\r\n\r\n set denominator(value: number) {\r\n this._denominator = value;\r\n }\r\n\r\n get value(): number {\r\n return this._numerator / this._denominator\r\n }\r\n\r\n get sign(): number {\r\n return (this.numerator * this.denominator >= 0) ? 1 : -1;\r\n };\r\n\r\n get signTeX(): string {\r\n return this.sign === 1 ? '+' : '-'\r\n }\r\n\r\n get fracTeX(): string {\r\n return this._fracType === FRACTION_FRAC.frac ? '\\\\frac' : this._fracType === FRACTION_FRAC.dfrac ? '\\\\dfrac' : '\\\\tfrac'\r\n }\r\n\r\n abstract get tex(): string\r\n\r\n abstract get display(): string\r\n\r\n static max = <T extends CoefficientTypes>(...values: T[]): T => {\r\n const [first, ...rest] = values\r\n return rest.reduce((acc, cur) => acc.isGreaterThan(cur) ? acc : cur, first)\r\n }\r\n\r\n static min = <T extends CoefficientTypes>(...values: T[]): T => {\r\n const [first, ...rest] = values\r\n return rest.reduce((acc, cur) => acc.isGreaterThan(cur) ? cur : acc, first)\r\n }\r\n\r\n static unique = <T extends CoefficientTypes>(values: T[], sort?: boolean): T[] => {\r\n let uniqueObjects: T[] = [],\r\n uniqueValues: number[] = []\r\n\r\n values.forEach((value, index) => {\r\n if (!uniqueValues.includes(value.value)) {\r\n uniqueValues.push(value.value)\r\n uniqueObjects.push(value)\r\n }\r\n })\r\n\r\n if (sort) return CoefficientCore.sort(uniqueObjects)\r\n\r\n return uniqueObjects\r\n }\r\n\r\n static sort = <T extends CoefficientTypes>(values: T[], reverse?: boolean): T[] => {\r\n let sorted = values.sort((a, b) => a.value - b.value)\r\n\r\n if (reverse) sorted = sorted.reverse()\r\n\r\n return sorted\r\n }\r\n\r\n abstract createInstance(value?: number | string | T): T\r\n\r\n abstract clone(): T\r\n\r\n abstract reduce(): T\r\n\r\n getReducedCoefficient = (): { N: number, D: number } => {\r\n if (this.numerator === 1 || this.denominator === 1) return {N: this.numerator, D: this.denominator}\r\n\r\n let g = Numeric.gcd(this.numerator, this.denominator);\r\n let [N, D] = [this.numerator, this.denominator]\r\n\r\n N = N / g;\r\n D = D / g;\r\n\r\n if (D < 0) {\r\n D = -D;\r\n N = -N;\r\n }\r\n\r\n return {N, D}\r\n };\r\n\r\n zero = (): T => {\r\n this.numerator = 0;\r\n this.denominator = 1;\r\n return this as unknown as T;\r\n };\r\n\r\n one = (): T => {\r\n this.numerator = 1;\r\n this.denominator = 1;\r\n return this as unknown as T;\r\n };\r\n\r\n infinite = (): T => {\r\n this.numerator = Infinity;\r\n this.denominator = 1;\r\n return this as unknown as T;\r\n };\r\n\r\n invalid = (): T => {\r\n this.numerator = NaN;\r\n this.denominator = 1;\r\n return this as unknown as T\r\n };\r\n\r\n abstract add(...coefficients: (T | number | string)[]): T\r\n\r\n opposite = (): T => {\r\n this.numerator = -this.numerator;\r\n return this as unknown as T;\r\n }\r\n\r\n subtract = (...coefficients: (T | number | string)[]): T => this.add(...coefficients.map(c => this.createInstance(c).opposite() as T))\r\n\r\n abstract multiply(...coefficients: (T | number | string)[]): T\r\n\r\n abstract invert(): T\r\n\r\n divide = (F: T | number): T => this.multiply(this.createInstance(F).invert() as T);\r\n\r\n abs = (): T => {\r\n this.numerator = Math.abs(this.numerator);\r\n return this as unknown as T;\r\n }\r\n\r\n pow = (value: number | CoefficientTypes): T => {\r\n if (Number.isSafeInteger(value)) {\r\n const factor = this.clone(),\r\n abs = Math.abs(value as number)\r\n for (let i = abs; i <= abs; i++) {\r\n this.multiply(factor)\r\n }\r\n\r\n if ((value as number) < 0) this.invert()\r\n } else {\r\n throw new Error('Cannot raise a coefficient to a non-integer power')\r\n }\r\n return this as unknown as T\r\n }\r\n\r\n abstract root(value: number | CoefficientTypes): T\r\n\r\n sqrt = (): T => this.root(2)\r\n\r\n asTopFraction = (): T => {\r\n this.fracType = FRACTION_FRAC.tfrac\r\n return this as unknown as T\r\n }\r\n\r\n asDisplayFraction = (): T => {\r\n this.fracType = FRACTION_FRAC.dfrac\r\n return this as unknown as T\r\n }\r\n\r\n\r\n /**\r\n * All the is* methods without argument\r\n */\r\n\r\n isReduced = (): boolean => Math.abs(Numeric.gcd(this._numerator, this._denominator)) === 1\r\n\r\n isOne = (): boolean => this._numerator === 1 && this._denominator === 1\r\n\r\n isMinusOne = (): boolean => this._numerator === -1 && this._denominator === 1\r\n\r\n isUnit = (): boolean => this.isOne() || this.isMinusOne()\r\n\r\n isZero = (): boolean => this._numerator === 0\r\n\r\n isFinite = (): boolean => !this.isInfinity() && !this.isNaN()\r\n\r\n isSquare = (): boolean => Math.sqrt(this._numerator) % 1 === 0 && Math.sqrt(this._denominator) % 1 === 0\r\n\r\n isNaN = (): boolean => isNaN(this.value)\r\n\r\n isPositive = (): boolean => this.sign === 1\r\n\r\n isNegative = (): boolean => this.sign === -1\r\n\r\n isStrictlyNegative = (): boolean => this.value < 0\r\n\r\n isStrictlyPositive = (): boolean => this.value > 0\r\n\r\n isNatural = (): boolean => this.isRelative() && this.isPositive()\r\n\r\n isRelative = (): boolean => {\r\n const {N, D} = this.getReducedCoefficient()\r\n return D === 1\r\n }\r\n\r\n isRational = (): boolean => !this.isRelative()\r\n\r\n isReal = (): boolean => true\r\n\r\n isComplex = (): boolean => false\r\n\r\n isInfinity = (): boolean => Math.abs(this.value) === Infinity\r\n\r\n isEven = (): boolean => this.isRelative() && this.value % 2 === 0\r\n\r\n isOdd = (): boolean => this.isRelative() && this.value % 2 === 1\r\n\r\n isApproximative = (): boolean => this._numerator.toString().length >= 15 && this._denominator.toString().length >= 15\r\n\r\n isExact = (): boolean => !this.isApproximative()\r\n\r\n isGreaterThan = (than: CoefficientCore<any> | number | string): boolean => this.value > this.createInstance(than as T).value;\r\n\r\n isSimilarTo = (to: CoefficientCore<any> | number | string): boolean => true;\r\n\r\n isGreaterOrEqualTo = (than: CoefficientCore<any> | number | string): boolean => this.value >= this.createInstance(than as T).value;\r\n\r\n isLesserOrEqualTo = (than: CoefficientCore<any> | number | string): boolean => this.value <= this.createInstance(than as T).value;\r\n\r\n isLesserThan = (than: CoefficientCore<any> | number | string): boolean => this.value < this.createInstance(than as T).value;\r\n\r\n isEqualTo = (than: CoefficientCore<any> | number | string): boolean => this.value === this.createInstance(than as T).value\r\n\r\n isOpposedTo = (to: CoefficientCore<any> | number | string): boolean => this.isEqualTo(this.createInstance(to as T).opposite())\r\n\r\n isInvertedTo = (to: CoefficientCore<any> | number | string): boolean => this.isEqualTo(this.createInstance(to as T).invert())\r\n\r\n}\r\n
1268
- ===================================================================
1269
- diff --git a/src/maths/coefficients/coefficientCore.ts b/src/maths/coefficients/coefficientCore.ts
1270
- --- a/src/maths/coefficients/coefficientCore.ts
1271
- +++ b/src/maths/coefficients/coefficientCore.ts
1272
- @@ -1,9 +1,10 @@
1273
- import {Fraction} from "./fraction";
1274
- import {RootFraction} from "./rootFraction";
1275
- import {Numeric} from "../numeric";
1276
- +import {Coefficient} from "./coefficient";
1277
-
1278
-
1279
- -export type CoefficientTypes = Fraction | RootFraction
1280
- +export type CoefficientTypes = Coefficient | Fraction | RootFraction
1281
- export type CoefficientParserTypes = CoefficientTypes | number | string
1282
-
1283
- export enum COEFFICIENT_MODE {
1284
- Index: src/maths/types.ts
1285
- IDEA additional info:
1286
- Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP
1287
- <+>import {Monom} from \"./algebra/monom\";\r\nimport {Polynom} from \"./algebra/polynom\";\r\nimport {Rational} from \"./algebra/rational\";\r\nimport {CoefficientTypes} from \"./coefficients/coefficientCore\";\r\n\r\ninterface coreInterface {\r\n parse: (...values: unknown[]) => ThisType<this>,\r\n clone: () => ThisType<this>,\r\n\r\n readonly tex: string,\r\n readonly display: string\r\n}\r\n\r\ninterface operationInterface {\r\n add: (...values: unknown[]) => ThisType<this>,\r\n subtract: (...values: unknown[]) => ThisType<this>,\r\n multiply: (...values: unknown[]) => ThisType<this>,\r\n divide: (value: unknown) => ThisType<this>,\r\n opposite: () => ThisType<this>,\r\n invert: () => ThisType<this>,\r\n pow: (value: unknown) => ThisType<this>,\r\n root: (value: unknown) => ThisType<this>,\r\n reduce: () => ThisType<this>,\r\n}\r\n\r\ninterface compareInterface {\r\n compare: (value: unknown, sign: COMPARESIGNS) => boolean,\r\n isEqualTo: (value: unknown) => boolean,\r\n isReduced: () => boolean,\r\n isOne: () => boolean,\r\n isMinusOne: () => boolean,\r\n isUnit: () => boolean,\r\n isZero: () => boolean,\r\n}\r\n\r\nexport interface coefficientInterface extends coreInterface, operationInterface, compareInterface {\r\n isGreaterOrEqualTo: (value: unknown) => boolean,\r\n isGreaterThan: (value: unknown) => boolean,\r\n isLesserOrEqualTo: (value: unknown) => boolean,\r\n isLesserThan: (value: unknown) => boolean,\r\n isNaN: () => boolean,\r\n isPositive: () => boolean,\r\n isNegative: () => boolean,\r\n isStrictlyNegative: () => boolean,\r\n isStrictlyPositive: () => boolean,\r\n isOpposedTo: (value: unknown) => boolean,\r\n isInvertedTo: (value: unknown) => boolean,\r\n isNatural: () => boolean,\r\n isRelative: () => boolean,\r\n isRational: () => boolean,\r\n isReal: () => boolean,\r\n isComplex: () => boolean,\r\n isInfinity: () => boolean,\r\n isEven: () => boolean,\r\n isOdd: () => boolean,\r\n readonly value: number,\r\n}\r\n\r\nexport interface coefficientStaticTypes {\r\n average: (...values: unknown[]) => coefficientInterface,\r\n max: (...values: unknown[]) => coefficientInterface,\r\n min: (...values: unknown[]) => coefficientInterface,\r\n sort: (...values: unknown[]) => coefficientInterface[],\r\n unique: (...values: unknown[]) => coefficientInterface[],\r\n}\r\n\r\nexport interface expressionInterface extends coreInterface, operationInterface, compareInterface {\r\n // variables getter\r\n readonly variables: string[],\r\n hasLetter: (letter?: string) => boolean\r\n\r\n // Evaluate\r\n evaluate: (value?: evaluateType) => numericType,\r\n\r\n // Helpers\r\n isDivisible?: (value: unknown) => boolean,\r\n}\r\n\r\n\r\nexport type literalType = { [Key: string]: CoefficientTypes }\r\nexport type numericType = number | string | CoefficientTypes\r\nexport type expressionType = Monom | Polynom | Rational\r\nexport type evaluateType = numericType | { [key: string]: numericType }\r\n\r\nexport enum COMPARESIGNS {\r\n \"EQUALS\" = \"=\",\r\n \"SAME\" = \"same\",\r\n \"GREATER\" = \">\",\r\n \"GEQ\" = \">=\",\r\n \"LESSER\" = \"<\",\r\n \"LEQ\" = \"<=\",\r\n \"DIFFERENT\" = \"<>\"\r\n}
1288
- ===================================================================
1289
- diff --git a/src/maths/types.ts b/src/maths/types.ts
1290
- --- a/src/maths/types.ts
1291
- +++ b/src/maths/types.ts
1292
- @@ -1,9 +1,6 @@
1293
- -import {Monom} from "./algebra/monom";
1294
- -import {Polynom} from "./algebra/polynom";
1295
- -import {Rational} from "./algebra/rational";
1296
- import {CoefficientTypes} from "./coefficients/coefficientCore";
1297
-
1298
- -interface coreInterface {
1299
- +export interface coreInterface {
1300
- parse: (...values: unknown[]) => ThisType<this>,
1301
- clone: () => ThisType<this>,
1302
-
1303
- @@ -11,7 +8,7 @@
1304
- readonly display: string
1305
- }
1306
-
1307
- -interface operationInterface {
1308
- +export interface operationInterface {
1309
- add: (...values: unknown[]) => ThisType<this>,
1310
- subtract: (...values: unknown[]) => ThisType<this>,
1311
- multiply: (...values: unknown[]) => ThisType<this>,
1312
- @@ -23,7 +20,7 @@
1313
- reduce: () => ThisType<this>,
1314
- }
1315
-
1316
- -interface compareInterface {
1317
- +export interface equalityInterface {
1318
- compare: (value: unknown, sign: COMPARESIGNS) => boolean,
1319
- isEqualTo: (value: unknown) => boolean,
1320
- isReduced: () => boolean,
1321
- @@ -33,7 +30,7 @@
1322
- isZero: () => boolean,
1323
- }
1324
-
1325
- -export interface coefficientInterface extends coreInterface, operationInterface, compareInterface {
1326
- +export interface compareInterface {
1327
- isGreaterOrEqualTo: (value: unknown) => boolean,
1328
- isGreaterThan: (value: unknown) => boolean,
1329
- isLesserOrEqualTo: (value: unknown) => boolean,
1330
- @@ -56,17 +53,17 @@
1331
- readonly value: number,
1332
- }
1333
-
1334
- -export interface coefficientStaticTypes {
1335
- - average: (...values: unknown[]) => coefficientInterface,
1336
- - max: (...values: unknown[]) => coefficientInterface,
1337
- - min: (...values: unknown[]) => coefficientInterface,
1338
- - sort: (...values: unknown[]) => coefficientInterface[],
1339
- - unique: (...values: unknown[]) => coefficientInterface[],
1340
- +export interface expressionElementInterface {
1341
- + [name: string]: {
1342
- + exponent: number,
1343
- + root: number,
1344
- + }
1345
- }
1346
-
1347
- -export interface expressionInterface extends coreInterface, operationInterface, compareInterface {
1348
- +export interface expressionInterface {
1349
- // variables getter
1350
- readonly variables: string[],
1351
- + readonly literal: expressionElementInterface,
1352
- hasLetter: (letter?: string) => boolean
1353
-
1354
- // Evaluate
1355
- @@ -79,7 +76,6 @@
1356
-
1357
- export type literalType = { [Key: string]: CoefficientTypes }
1358
- export type numericType = number | string | CoefficientTypes
1359
- -export type expressionType = Monom | Polynom | Rational
1360
- export type evaluateType = numericType | { [key: string]: numericType }
1361
-
1362
- export enum COMPARESIGNS {