pimath 0.0.120 → 0.0.122

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 (175) hide show
  1. package/.idea/PI.iml +7 -1
  2. package/.idea/shelf/Uncommitted_changes_before_Update_at_24_07_2023_15_31_[Default_Changelist]/shelved.patch +90 -0
  3. package/.idea/shelf/Uncommitted_changes_before_Update_at_24_07_2023_15_31_[Default_Changelist]1/shelved.patch +107 -0
  4. package/.idea/shelf/Uncommitted_changes_before_Update_at_24_07_2023_15_31__Default_Changelist_.xml +4 -0
  5. package/.idea/shelf/Uncommitted_changes_before_Update_at_24_07_2023_15_31__Default_Changelist_1.xml +4 -0
  6. package/LICENSE.md +1 -1
  7. package/dev/pimath.js +7929 -0
  8. package/dev/pimath.js.map +1 -0
  9. package/dist/{pi.js → pimath.js} +7613 -7840
  10. package/dist/pimath.js.map +1 -0
  11. package/dist/pimath.min.js +2 -0
  12. package/dist/pimath.min.js.map +1 -0
  13. package/docs/assets/main.js +58 -58
  14. package/docs/assets/search.js +1 -1
  15. package/docs/assets/style.css +1367 -1280
  16. package/docs/classes/Logicalset.Logicalset.html +221 -212
  17. package/docs/classes/Polynom.Rational.html +391 -388
  18. package/docs/classes/Vector-1.Vector.html +494 -448
  19. package/docs/classes/Vector.Point.html +341 -342
  20. package/docs/classes/algebra_equation.Equation.html +796 -753
  21. package/docs/classes/algebra_linearSystem.LinearSystem.html +408 -397
  22. package/docs/classes/algebra_monom.Monom.html +967 -910
  23. package/docs/classes/algebra_polynom.Polynom.html +1281 -1260
  24. package/docs/classes/coefficients_fraction.Fraction.html +939 -931
  25. package/docs/classes/geometry_circle.Circle.html +476 -476
  26. package/docs/classes/geometry_line.Line.html +779 -719
  27. package/docs/classes/geometry_triangle.Triangle.html +429 -420
  28. package/docs/classes/numeric.Numeric.html +269 -263
  29. package/docs/classes/shutingyard.Shutingyard.html +259 -248
  30. package/docs/enums/algebra_equation.PARTICULAR_SOLUTION.html +89 -88
  31. package/docs/enums/geometry_line.LinePropriety.html +102 -102
  32. package/docs/enums/shutingyard.ShutingyardMode.html +106 -102
  33. package/docs/enums/shutingyard.ShutingyardType.html +120 -116
  34. package/docs/index.html +63 -65
  35. package/docs/interfaces/algebra_equation.ISolution.html +111 -109
  36. package/docs/interfaces/algebra_polynom.IEuclidian.html +93 -92
  37. package/docs/interfaces/geometry_triangle.remarquableLines.html +150 -150
  38. package/docs/modules/Logicalset.html +69 -74
  39. package/docs/modules/Polynom.html +69 -74
  40. package/docs/modules/Vector-1.html +69 -74
  41. package/docs/modules/Vector.html +69 -74
  42. package/docs/modules/algebra_equation.html +75 -81
  43. package/docs/modules/algebra_linearSystem.html +65 -71
  44. package/docs/modules/algebra_monom.html +70 -76
  45. package/docs/modules/algebra_polynom.html +75 -81
  46. package/docs/modules/coefficients_fraction.html +70 -76
  47. package/docs/modules/geometry_circle.html +65 -71
  48. package/docs/modules/geometry_line.html +70 -76
  49. package/docs/modules/geometry_triangle.html +70 -76
  50. package/docs/modules/numeric.html +65 -71
  51. package/docs/modules/shutingyard.html +84 -90
  52. package/docs/types/algebra_monom.literalType.html +66 -70
  53. package/docs/types/algebra_polynom.PolynomParsingType.html +62 -66
  54. package/docs/types/coefficients_fraction.FractionParsingType.html +61 -65
  55. package/docs/types/shutingyard.Token.html +72 -76
  56. package/docs/types/shutingyard.tokenType.html +77 -81
  57. package/docs/variables/shutingyard.tokenConstant.html +70 -74
  58. package/esm/index.d.ts +38 -41
  59. package/esm/index.js +43 -46
  60. package/esm/index.js.map +1 -1
  61. package/esm/maths/algebra/equation.d.ts +119 -117
  62. package/esm/maths/algebra/equation.js +796 -785
  63. package/esm/maths/algebra/equation.js.map +1 -1
  64. package/esm/maths/algebra/linearSystem.d.ts +39 -38
  65. package/esm/maths/algebra/linearSystem.js +278 -262
  66. package/esm/maths/algebra/linearSystem.js.map +1 -1
  67. package/esm/maths/algebra/logicalset.d.ts +28 -28
  68. package/esm/maths/algebra/logicalset.js +157 -157
  69. package/esm/maths/algebra/monom.d.ts +206 -206
  70. package/esm/maths/algebra/monom.js +908 -908
  71. package/esm/maths/algebra/monom.js.map +1 -1
  72. package/esm/maths/algebra/polynom.d.ts +157 -157
  73. package/esm/maths/algebra/polynom.js +1277 -1277
  74. package/esm/maths/algebra/rational.d.ts +45 -45
  75. package/esm/maths/algebra/rational.js +183 -183
  76. package/esm/maths/algebra/study/rationalStudy.d.ts +28 -28
  77. package/esm/maths/algebra/study/rationalStudy.js +243 -243
  78. package/esm/maths/algebra/study.d.ts +143 -142
  79. package/esm/maths/algebra/study.js +378 -377
  80. package/esm/maths/algebra/study.js.map +1 -1
  81. package/esm/maths/coefficients/fraction.d.ts +90 -90
  82. package/esm/maths/coefficients/fraction.js +516 -516
  83. package/esm/maths/coefficients/fraction.js.map +1 -1
  84. package/esm/maths/coefficients/nthRoot.d.ts +23 -23
  85. package/esm/maths/coefficients/nthRoot.js +136 -136
  86. package/esm/maths/geometry/circle.d.ts +45 -45
  87. package/esm/maths/geometry/circle.js +323 -323
  88. package/esm/maths/geometry/line.d.ts +99 -99
  89. package/esm/maths/geometry/line.js +481 -481
  90. package/esm/maths/geometry/line.js.map +1 -1
  91. package/esm/maths/geometry/point.d.ts +34 -34
  92. package/esm/maths/geometry/point.js +166 -166
  93. package/esm/maths/geometry/point.js.map +1 -1
  94. package/esm/maths/geometry/triangle.d.ts +85 -85
  95. package/esm/maths/geometry/triangle.js +268 -268
  96. package/esm/maths/geometry/vector.d.ts +41 -41
  97. package/esm/maths/geometry/vector.js +197 -197
  98. package/esm/maths/geometry/vector.js.map +1 -1
  99. package/esm/maths/numeric.d.ts +28 -28
  100. package/esm/maths/numeric.js +180 -180
  101. package/esm/maths/numexp.d.ts +19 -0
  102. package/esm/maths/numexp.js +186 -0
  103. package/esm/maths/numexp.js.map +1 -0
  104. package/esm/maths/randomization/random.d.ts +23 -23
  105. package/esm/maths/randomization/random.js +78 -78
  106. package/esm/maths/randomization/random.js.map +1 -1
  107. package/esm/maths/randomization/randomCore.d.ts +7 -7
  108. package/esm/maths/randomization/randomCore.js +21 -21
  109. package/esm/maths/randomization/rndFraction.d.ts +12 -12
  110. package/esm/maths/randomization/rndFraction.js +43 -43
  111. package/esm/maths/randomization/rndGeometryLine.d.ts +12 -12
  112. package/esm/maths/randomization/rndGeometryLine.js +45 -45
  113. package/esm/maths/randomization/rndGeometryPoint.d.ts +12 -12
  114. package/esm/maths/randomization/rndGeometryPoint.js +60 -60
  115. package/esm/maths/randomization/rndHelpers.d.ts +23 -23
  116. package/esm/maths/randomization/rndHelpers.js +76 -76
  117. package/esm/maths/randomization/rndMonom.d.ts +12 -12
  118. package/esm/maths/randomization/rndMonom.js +52 -52
  119. package/esm/maths/randomization/rndPolynom.d.ts +13 -13
  120. package/esm/maths/randomization/rndPolynom.js +74 -74
  121. package/esm/maths/randomization/rndTypes.d.ts +34 -34
  122. package/esm/maths/randomization/rndTypes.js +2 -2
  123. package/esm/maths/shutingyard.d.ts +59 -59
  124. package/esm/maths/shutingyard.js +442 -442
  125. package/esm/maths/shutingyard.js.map +1 -1
  126. package/package.json +11 -11
  127. package/public/index.html +50 -81
  128. package/public/playground.html +7 -8
  129. package/src/index.ts +1 -4
  130. package/src/maths/algebra/equation.ts +16 -0
  131. package/src/maths/algebra/linearSystem.ts +20 -0
  132. package/src/maths/algebra/study.ts +12 -10
  133. package/src/maths/{expressions/numexp.ts → numexp.ts} +2 -2
  134. package/tests/algebra/equation.test.ts +19 -5
  135. package/tests/algebra/linear.test.ts +3 -11
  136. package/tests/algebra/polynom.test.ts +7 -8
  137. package/tests/algebra/rationnal.test.ts +1 -1
  138. package/tests/algebra/study.test.ts +2 -9
  139. package/tests/coefficients/fraction.test.ts +8 -8
  140. package/tests/custom.test.ts +33 -37
  141. package/tests/numeric.test.ts +1 -2
  142. package/tests/numexp.test.ts +13 -5
  143. package/tests/shutingyard.test.ts +3 -3
  144. package/webpack-production-min.config.js +1 -1
  145. package/webpack-production.config.js +1 -1
  146. package/webpack.config.js +1 -1
  147. package/dist/pi.js.map +0 -1
  148. package/dist/pi.min.js +0 -2
  149. package/dist/pi.min.js.map +0 -1
  150. package/docs/classes/expressions_numexp.NumExp.html +0 -236
  151. package/docs/classes/expressions_polynomexp.PolynomExpFactor.html +0 -317
  152. package/docs/classes/expressions_polynomexp.PolynomExpProduct.html +0 -285
  153. package/docs/modules/expressions_numexp.html +0 -71
  154. package/docs/modules/expressions_polynomexp.html +0 -73
  155. package/docs/modules.html +0 -76
  156. package/graph.svg +0 -1033
  157. package/src/maths/expressions/ExpressionTree.ts +0 -172
  158. package/src/maths/expressions/expression.ts +0 -286
  159. package/src/maths/expressions/expressionFactor.ts +0 -190
  160. package/src/maths/expressions/expressionMember.ts +0 -233
  161. package/src/maths/expressions/expressionOperators.ts +0 -49
  162. package/src/maths/expressions/expressionParser.ts +0 -295
  163. package/src/maths/expressions/factors/ExpFactor.ts +0 -39
  164. package/src/maths/expressions/factors/ExpFactorConstant.ts +0 -60
  165. package/src/maths/expressions/factors/ExpFactorExponential.ts +0 -26
  166. package/src/maths/expressions/factors/ExpFactorNumber.ts +0 -72
  167. package/src/maths/expressions/factors/ExpFactorPower.ts +0 -42
  168. package/src/maths/expressions/factors/ExpFactorTrigo.ts +0 -53
  169. package/src/maths/expressions/factors/ExpFactorVariable.ts +0 -45
  170. package/src/maths/expressions/internals.ts +0 -14
  171. package/src/maths/expressions/polynomexp.bkp.ts +0 -221
  172. package/src/maths/expressions/polynomexp.ts +0 -310
  173. package/tests/expressions/expressions.test.ts +0 -145
  174. package/tests/expressions/expressiontree.test.ts +0 -11
  175. package/tests/polynomexp.test.ts +0 -12
@@ -1,909 +1,909 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Monom = void 0;
4
- /***
5
- * Monom class
6
- */
7
- const numeric_1 = require("../numeric");
8
- const shutingyard_1 = require("../shutingyard");
9
- const fraction_1 = require("../coefficients/fraction");
10
- class Monom {
11
- /**
12
- * Create a Monom
13
- * Defined as \\(k \\cdot x^{n}\\), where \\( k,n \in \\mathbb{Q}\\).
14
- * Examples: \\(3x^2\\) or \\(3/5x^2\\)
15
- * @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).
16
- */
17
- constructor(value) {
18
- // ------------------------------------------
19
- // Creation / parsing functions
20
- // -----------------------------------------
21
- /**
22
- * Parse a string to a monom. The string may include fraction.
23
- * @param inputStr
24
- */
25
- this.parse = (inputStr) => {
26
- if (typeof inputStr === 'string') {
27
- this._shutingYardToReducedMonom(inputStr);
28
- }
29
- else if (typeof inputStr === 'number') {
30
- this._coefficient = new fraction_1.Fraction(inputStr);
31
- this._literal = {};
32
- }
33
- else if (inputStr instanceof fraction_1.Fraction) {
34
- this._coefficient = inputStr.clone();
35
- this._literal = {};
36
- }
37
- else if (inputStr instanceof Monom) {
38
- this._coefficient = inputStr._coefficient.clone();
39
- this._literal = this.copyLiterals(inputStr.literal);
40
- }
41
- return this;
42
- };
43
- this.addToken = (stack, element) => {
44
- let q1, q2, m, letter, pow;
45
- if (element.tokenType === shutingyard_1.ShutingyardType.COEFFICIENT) {
46
- stack.push(new Monom(new fraction_1.Fraction(element.token)));
47
- }
48
- else if (element.tokenType === shutingyard_1.ShutingyardType.VARIABLE) {
49
- let M = new Monom().one();
50
- M.setLetter(element.token, 1);
51
- stack.push(M.clone());
52
- }
53
- else if (element.tokenType === shutingyard_1.ShutingyardType.OPERATION) {
54
- switch (element.token) {
55
- case '-':
56
- // this should only happen for negative powers or for negative coefficient.
57
- q2 = (stack.pop()) || new Monom().zero();
58
- q1 = (stack.pop()) || new Monom().zero();
59
- stack.push(q1.subtract(q2));
60
- break;
61
- case '*':
62
- // Get the last element in the stack
63
- q2 = (stack.pop()) || new Monom().one();
64
- q1 = (stack.pop()) || new Monom().one();
65
- stack.push(q1.multiply(q2));
66
- break;
67
- case '/':
68
- // Get the last element in the stack
69
- q2 = (stack.pop()) || new Monom().one();
70
- q1 = (stack.pop()) || new Monom().one();
71
- stack.push(q1.divide(q2));
72
- break;
73
- case '^':
74
- // get the two last elements in the stack
75
- pow = (stack.pop().coefficient) || new fraction_1.Fraction().one();
76
- m = (stack.pop()) || new Monom().one();
77
- letter = m.variables[0];
78
- if (letter !== undefined) {
79
- m.setLetter(letter, pow);
80
- }
81
- stack.push(m);
82
- // this.multiply(m.clone())
83
- break;
84
- }
85
- }
86
- };
87
- this._shutingYardToReducedMonom = (inputStr) => {
88
- // Get the RPN array of the current expression
89
- const SY = new shutingyard_1.Shutingyard().parse(inputStr);
90
- const rpn = SY.rpn;
91
- let stack = [], m, pow, letter, q1, q2;
92
- if (rpn.length === 0) {
93
- this.zero();
94
- return this;
95
- }
96
- else if (rpn.length === 1) {
97
- const element = rpn[0];
98
- this.one();
99
- if (element.tokenType === 'coefficient') {
100
- this.coefficient = new fraction_1.Fraction(element.token);
101
- }
102
- else if (element.tokenType === 'variable') {
103
- this.setLetter(element.token, 1);
104
- }
105
- return this;
106
- }
107
- else {
108
- // Reset the monom
109
- for (const element of rpn) {
110
- this.addToken(stack, element);
111
- }
112
- }
113
- this.one();
114
- this.multiply(stack[0]);
115
- return this;
116
- };
117
- /**
118
- * Clone the current Monom.
119
- */
120
- this.clone = () => {
121
- let F = new Monom();
122
- F.coefficient = this._coefficient.clone();
123
- // Copy the literal parts.
124
- for (let k in this._literal) {
125
- F.setLetter(k, this._literal[k].clone());
126
- }
127
- return F;
128
- };
129
- this.copyLiterals = (literal) => {
130
- let L = {};
131
- for (let k in literal) {
132
- L[k] = literal[k].clone();
133
- }
134
- return L;
135
- };
136
- this.makeSame = (M) => {
137
- // Copy the literal parts.
138
- for (let k in M._literal) {
139
- this.setLetter(k, M._literal[k].clone());
140
- }
141
- return this;
142
- };
143
- /**
144
- * Create a zero value monom
145
- */
146
- this.zero = () => {
147
- this._coefficient = new fraction_1.Fraction().zero();
148
- this._literal = {};
149
- return this;
150
- };
151
- /**
152
- * Create a one value monom
153
- */
154
- this.one = () => {
155
- this._coefficient = new fraction_1.Fraction().one();
156
- this._literal = {};
157
- return this;
158
- };
159
- /**
160
- * Clean the monom by removing each letters with a power of zero.
161
- */
162
- this.clean = () => {
163
- for (let letter in this._literal) {
164
- if (this._literal[letter].isZero()) {
165
- delete this._literal[letter];
166
- }
167
- }
168
- return this;
169
- };
170
- this.reduce = () => {
171
- this.clean();
172
- this.coefficient.reduce();
173
- return this;
174
- };
175
- // ------------------------------------------
176
- // Mathematical operations
177
- // ------------------------------------------
178
- /**
179
- * Get the opposed
180
- * Returns a monom.
181
- */
182
- this.opposed = () => {
183
- this._coefficient.opposed();
184
- return this;
185
- };
186
- /**
187
- * Add all similar monoms. If they aren't similar, they are simply skipped.
188
- * @param M (Monom[]) The monoms to add.
189
- */
190
- this.add = (...M) => {
191
- for (let m of M) {
192
- if (this.isSameAs(m)) {
193
- if (this.isZero()) {
194
- this.makeSame(m);
195
- }
196
- this._coefficient.add(m.coefficient);
197
- }
198
- else {
199
- console.log('Add monom: ' + this.display + ' is not similar with ', m.display);
200
- }
201
- }
202
- return this;
203
- };
204
- /**
205
- * Subtract multiple monoms
206
- * @param M (Monom[]) The monoms to subtract
207
- */
208
- this.subtract = (...M) => {
209
- for (let m of M) {
210
- if (this.isSameAs(m)) {
211
- if (this.isZero()) {
212
- this.makeSame(m);
213
- }
214
- this._coefficient.add(m.clone().coefficient.opposed());
215
- }
216
- else {
217
- console.log('Subtract: Is not similar: ', m.display);
218
- }
219
- }
220
- return this;
221
- };
222
- /**
223
- * Multiple multiple monoms to the current monom
224
- * @param M (Monom[]) The monoms to multiply to.
225
- */
226
- this.multiply = (...M) => {
227
- for (let m of M) {
228
- // Multiply the coefficient.
229
- this._coefficient.multiply(m.coefficient);
230
- // Multiply the literal parts.
231
- for (let letter in m.literal) {
232
- if (this._literal[letter] === undefined) {
233
- this._literal[letter] = m.literal[letter].clone();
234
- }
235
- else {
236
- this._literal[letter].add(m.literal[letter]);
237
- }
238
- }
239
- }
240
- return this;
241
- };
242
- this.multiplyByNumber = (F) => {
243
- this._coefficient.multiply(F);
244
- return this;
245
- };
246
- /**
247
- * Divide the current monoms by multiple monoms
248
- * @param M (Monom[])
249
- */
250
- this.divide = (...M) => {
251
- // Depending on the given value, choose the current item
252
- for (let v of M) {
253
- // Divide the coefficient
254
- this._coefficient.divide(v.coefficient);
255
- // Subtract the power values
256
- for (let letter in v.literal) {
257
- this._literal[letter] = (this._literal[letter] === undefined) ? v.literal[letter].clone().opposed() : this._literal[letter].subtract(v.literal[letter]);
258
- // If the power of a particular setLetter is zero, delete it from the literal part..
259
- if (this._literal[letter].isZero()) {
260
- delete this._literal[letter];
261
- }
262
- }
263
- }
264
- return this;
265
- };
266
- /**
267
- * Get the pow of a monom.
268
- * @param nb (number) : Mathematical pow
269
- */
270
- this.pow = (nb) => {
271
- this._coefficient.pow(nb);
272
- for (let letter in this._literal) {
273
- this._literal[letter].multiply(nb);
274
- }
275
- return this;
276
- };
277
- /**
278
- * Get the nth-root of the monom
279
- * @param p
280
- */
281
- this.root = (p) => {
282
- // TODO: determiner the nth root of a monom
283
- return this;
284
- };
285
- /**
286
- * Return the square root of a monom
287
- */
288
- this.sqrt = () => {
289
- if (this.isSquare()) {
290
- this._coefficient.sqrt();
291
- for (let letter in this._literal) {
292
- this._literal[letter].clone().divide(2);
293
- }
294
- }
295
- return this.root(2);
296
- };
297
- // ------------------------------------------
298
- // Compare functions
299
- // ------------------------------------------
300
- this.compare = (M, sign) => {
301
- // TODO: Build the compare systems.
302
- if (sign === undefined) {
303
- sign = '=';
304
- }
305
- switch (sign) {
306
- case '=':
307
- // To be equal, they must be the isSame
308
- if (!this.compare(M, 'same')) {
309
- return false;
310
- }
311
- // The literal parts are the isSame. The coefficient must be equal
312
- return this._coefficient.isEqual(M.coefficient);
313
- case 'same':
314
- // Get the list of all variables from both monoms.
315
- let M1 = this.variables, M2 = M.variables, K = M1.concat(M2.filter((item) => M1.indexOf(item) < 0));
316
- if (M1.length === 0 && M2.length === 0) {
317
- return true;
318
- }
319
- // To compare, both must be different than zero.
320
- if (!this.isZero() && !M.isZero()) {
321
- for (let key of K) {
322
- // The setLetter is not available in one of the monom
323
- if (this._literal[key] === undefined || M.literal[key] === undefined) {
324
- return false;
325
- }
326
- // The setLetter does not have the isSame power in each monoms.
327
- if (!this._literal[key].isEqual(M.literal[key])) {
328
- return false;
329
- }
330
- }
331
- }
332
- // All are positive check - the monoms are the sames.
333
- return true;
334
- default:
335
- return false;
336
- }
337
- };
338
- /**
339
- * Determine if two monoms are equals
340
- * @param M
341
- */
342
- this.isEqual = (M) => {
343
- return this.compare(M, '=');
344
- };
345
- /**
346
- * Determine if two monoms are similar
347
- * @param M
348
- */
349
- this.isSameAs = (M) => {
350
- return this.compare(M, 'same');
351
- };
352
- this.isSquare = () => {
353
- if (!this.coefficient.isSquare()) {
354
- return false;
355
- }
356
- return this.isLiteralSquare();
357
- };
358
- this.isLiteralSquare = () => {
359
- for (let letter in this.literal) {
360
- // A literal square must have a natural power
361
- if (this.literal[letter].isRational()) {
362
- return false;
363
- }
364
- // The natural power must be be even
365
- if (this.literal[letter].isEven()) {
366
- return false;
367
- }
368
- }
369
- return true;
370
- };
371
- this.hasFractionCoefficient = () => {
372
- for (let letter in this._literal) {
373
- if (this._literal[letter].isRational()) {
374
- return true;
375
- }
376
- }
377
- return false;
378
- };
379
- // ------------------------------------------
380
- // Misc monoms functions
381
- // -------------------------------------
382
- /**
383
- * Determine if a monom contains a setLetter in it's literal part
384
- * @param letter
385
- */
386
- this.hasLetter = (letter) => {
387
- // The letter was not found
388
- if (this._literal[letter === undefined ? 'x' : letter] === undefined) {
389
- return false;
390
- }
391
- // The letter is found and is not zero !
392
- return this._literal[letter === undefined ? 'x' : letter].isNotZero();
393
- };
394
- /**
395
- * Set the power of a particular setLetter
396
- * @param letter (string) Letter to change
397
- * @param pow (number) Power of the setLetter (must be positive integer.
398
- */
399
- this.setLetter = (letter, pow) => {
400
- if (pow instanceof fraction_1.Fraction) {
401
- // Set the power of the letter to zero => remove it
402
- if (this.hasLetter(letter) && pow.isZero()) {
403
- delete this._literal[letter];
404
- }
405
- this._literal[letter] = pow.clone();
406
- }
407
- else {
408
- this.setLetter(letter, new fraction_1.Fraction(pow));
409
- }
410
- };
411
- /**
412
- * Get the degree of a monom. If no setLetter is given, the result will be the global degree.
413
- * @param letter (string) Letter to get to degree (power)
414
- */
415
- this.degree = (letter) => {
416
- if (this.variables.length === 0) {
417
- return new fraction_1.Fraction().zero();
418
- }
419
- if (letter === undefined) {
420
- // Not setLetter given -> we get the global monom degree (sum of all the letters).
421
- return Object.values(this._literal).reduce((t, n) => t.clone().add(n));
422
- }
423
- else {
424
- // A setLetter is given -> get the corresponding power.
425
- return this._literal[letter] === undefined ? new fraction_1.Fraction().zero() : this._literal[letter].clone();
426
- }
427
- };
428
- /**
429
- * Evaluate a monom. Each setLetter must be assigned to a Fraction.
430
- * @param values Dictionary of <setLetter: Fraction>
431
- */
432
- this.evaluate = (values) => {
433
- let r = this.coefficient.clone();
434
- if (typeof values === 'number' || values instanceof fraction_1.Fraction) {
435
- let tmpValues = {};
436
- tmpValues[this.variables[0]] = new fraction_1.Fraction(values);
437
- return this.evaluate(tmpValues);
438
- }
439
- if (typeof values === 'object') {
440
- if (this.variables.length === 0) {
441
- return this.coefficient;
442
- }
443
- for (let L in this._literal) {
444
- if (values[L] === undefined) {
445
- return new fraction_1.Fraction().zero();
446
- }
447
- let value = new fraction_1.Fraction(values[L]);
448
- r.multiply(value.pow(this._literal[L]));
449
- }
450
- }
451
- return r;
452
- };
453
- this.evaluateAsNumeric = (values) => {
454
- let r = this.coefficient.value;
455
- if (typeof values === 'number') {
456
- let tmpValues = {};
457
- tmpValues[this.variables[0]] = values;
458
- return this.evaluateAsNumeric(tmpValues);
459
- }
460
- if (typeof values === 'object') {
461
- if (this.variables.length === 0) {
462
- return this.coefficient.value;
463
- }
464
- for (let L in this._literal) {
465
- if (values[L] === undefined) {
466
- return 0;
467
- }
468
- r *= values[L] ** (this._literal[L].value);
469
- }
470
- }
471
- return r;
472
- };
473
- /**
474
- * Derivative the monom
475
- * @param letter
476
- */
477
- this.derivative = (letter) => {
478
- // No setLetter given - assume it's the setLetter 'x'
479
- if (letter === undefined) {
480
- letter = 'x';
481
- }
482
- if (this.hasLetter(letter)) {
483
- let d = this._literal[letter].clone(), dM = this.clone();
484
- // Subtract one to the degree.
485
- dM._literal[letter].subtract(1);
486
- // Multiply the coefficient by the previous degree
487
- dM._coefficient.multiply(new fraction_1.Fraction(d.clone()));
488
- return dM;
489
- }
490
- else {
491
- return new Monom().zero();
492
- }
493
- };
494
- this.primitive = (letter) => {
495
- // TODO: derivative including the ln value => implies creating different monom system ?
496
- if (letter === undefined) {
497
- letter = 'x';
498
- }
499
- // Zero monom
500
- let M = this.clone(), degree;
501
- if (M.hasLetter(letter)) {
502
- degree = M.degree(letter).clone().add(1);
503
- M.coefficient = M.coefficient.clone().divide(degree);
504
- M.setLetter(letter, degree);
505
- }
506
- else {
507
- // There is no letter.
508
- // The coefficient might be zero (=> x) or a number a (=> ax)
509
- if (M.coefficient.isZero()) {
510
- M.coefficient = new fraction_1.Fraction().one();
511
- }
512
- M.setLetter(letter, 1);
513
- }
514
- return M;
515
- };
516
- // TODO: The rest of the functions are not used or unnecessary ?
517
- /**
518
- * Determine if multiple monoms are similar
519
- * @param M
520
- */
521
- this.areSameAs = (...M) => {
522
- let result = true;
523
- // Check all monoms if they are the isSame as the "this" one.
524
- for (let i = 0; i < M.length; i++) {
525
- if (!this.isSameAs(M[i])) {
526
- return false;
527
- }
528
- }
529
- // All check passed -> all the monoms are similar.
530
- return result;
531
- };
532
- /**
533
- * Determine if multiple monoms are equals
534
- * @param M
535
- */
536
- this.areEquals = (...M) => {
537
- // They are not similar.
538
- if (!this.areSameAs(...M)) {
539
- return false;
540
- }
541
- // Check all coefficient. They must be equals.
542
- for (let m of M) {
543
- if (!this._coefficient.isEqual(m.coefficient)) {
544
- return false;
545
- }
546
- }
547
- // All checks passed.
548
- return true;
549
- };
550
- this.isDivisible = (div) => {
551
- // For all variables (letters), the current monom must have a degree higher than the divider
552
- if (div.degree().isStrictlyPositive()) {
553
- for (let letter of div.variables) {
554
- if (!this.degree(letter).geq(div.degree(letter))) {
555
- return false;
556
- }
557
- }
558
- }
559
- // If the coefficient is rational, we suppose we don't need to check the division by the coefficient.
560
- if (this.coefficient.isRational() || div.coefficient.isRational()) {
561
- return true;
562
- }
563
- return this.coefficient.clone().divide(div.coefficient).isRelative();
564
- };
565
- this.zero();
566
- if (value !== undefined) {
567
- // A string is given - try to parse the value.
568
- this.parse(value);
569
- }
570
- return this;
571
- }
572
- // ------------------------------------------
573
- // Getter and setter
574
- // ------------------------------------------
575
- /**
576
- * Get the coefficient \\(k\\) of the Monom \\(k\\cdot x^{n}\\)
577
- * @returns {Fraction}
578
- */
579
- get coefficient() {
580
- return this._coefficient;
581
- }
582
- /**
583
- * Set the coefficient \\(k\\) value of the monom
584
- * @param {Fraction | number | string} F
585
- */
586
- set coefficient(F) {
587
- this._coefficient = new fraction_1.Fraction(F);
588
- }
589
- /**
590
- * Get the literal part of \\(x^{n_1}y^{n_2}\\) as dictionary \\[\\begin{array}{ll}x&=n_1\\\\y&=n_2\\end{array}\\]
591
- * @returns {literalType}
592
- */
593
- get literal() {
594
- return this._literal;
595
- }
596
- /**
597
- * Get the literal square roots of the Monom.
598
- * TODO: remove this getter ? Is it used and is it correct ?
599
- * @returns {literalType}
600
- */
601
- get literalSqrt() {
602
- if (this.isLiteralSquare()) {
603
- let L = {};
604
- for (let key in this._literal) {
605
- L[key] = this._literal[key].clone().sqrt();
606
- }
607
- return L;
608
- }
609
- else {
610
- return this._literal;
611
- }
612
- }
613
- /**
614
- * Set the literal part of the monom. Must be a dictionary {x: Fraction, y: Fraction, ...}
615
- * @param {literalType} L
616
- */
617
- set literal(L) {
618
- this._literal = L;
619
- }
620
- /**
621
- * Set the literal part of the monom from a string
622
- * @param inputStr String like x^2y^3
623
- */
624
- set literalStr(inputStr) {
625
- // TODO : parse using shutingyard tree !
626
- // Match all x^n
627
- for (const v of [...inputStr.matchAll(/([a-z])\^([+-]?[0-9]+)/g)]) {
628
- // Create the default letter entry if necessary.
629
- if (!(v[1] in this._literal)) {
630
- this._literal[v[1]] = new fraction_1.Fraction().zero();
631
- }
632
- // Add the new value.
633
- // TODO: actually, it adds only numeric value
634
- this._literal[v[1]].add(+v[2]);
635
- }
636
- // Match all x
637
- for (const v of [...inputStr.matchAll(/([a-z](?!\^))/g)]) {
638
- // Match all single letters
639
- if (!(v[1] in this._literal)) {
640
- this._literal[v[1]] = new fraction_1.Fraction().zero();
641
- }
642
- // Add one to the value.
643
- this._literal[v[1]].add(1);
644
- }
645
- }
646
- // Getter helpers.
647
- /**
648
- * Get the variables letters
649
- */
650
- get variables() {
651
- let M = this.clone().clean();
652
- return Object.keys(M.literal);
653
- }
654
- // Display getter
655
- /**
656
- * This display getter is to be used in the polynom display getter
657
- */
658
- get display() {
659
- let L = '', letters = Object.keys(this._literal).sort();
660
- for (let letter of letters) {
661
- if (this._literal[letter].isNotZero()) {
662
- L += `${letter}`;
663
- if (this._literal[letter].isNotEqual(1)) {
664
- L += `^(${this._literal[letter].display})`;
665
- }
666
- }
667
- }
668
- if (L === '') {
669
- // No setLetter - means it's only a number !
670
- if (this._coefficient.value != 0) {
671
- return `${this._coefficient.display}`;
672
- }
673
- else {
674
- return '';
675
- }
676
- }
677
- else {
678
- if (this._coefficient.value === 1) {
679
- return L;
680
- }
681
- else if (this._coefficient.value === -1) {
682
- return `-${L}`;
683
- }
684
- else if (this._coefficient.value === 0) {
685
- return '0';
686
- }
687
- else {
688
- return `${this._coefficient.display}${L}`;
689
- }
690
- }
691
- }
692
- get dividers() {
693
- // Decompose only if the coefficient is a natural number
694
- if (!this.coefficient.isRelative()) {
695
- return [this.clone()];
696
- }
697
- // Decompose only if the power values are natural numbers.
698
- if (this.hasFractionCoefficient()) {
699
- return [this.clone()];
700
- }
701
- // Security : do not do this if greater than 10000
702
- if (this.coefficient.numerator > 1000000) {
703
- return [this.clone()];
704
- }
705
- const dividers = numeric_1.Numeric.dividers(Math.abs(this.coefficient.numerator));
706
- // Decompose the literals parts.
707
- let literals = [];
708
- for (let L in this.literal) {
709
- // L is the letter.
710
- literals = this._getLiteralDividers(literals, L);
711
- }
712
- const monomDividers = [];
713
- if (literals.length > 0 && dividers.length > 0) {
714
- for (let N of dividers) {
715
- for (let L of literals) {
716
- let M = new Monom();
717
- M.coefficient = new fraction_1.Fraction(N);
718
- M.literal = L;
719
- monomDividers.push(M);
720
- }
721
- }
722
- }
723
- else if (dividers.length === 0) {
724
- for (let L of literals) {
725
- let M = new Monom();
726
- M.coefficient = new fraction_1.Fraction().one();
727
- M.literal = L;
728
- monomDividers.push(M);
729
- }
730
- }
731
- else {
732
- for (let N of dividers) {
733
- let M = new Monom();
734
- M.coefficient = new fraction_1.Fraction(N);
735
- monomDividers.push(M);
736
- }
737
- }
738
- return monomDividers.length === 0 ? [new Monom().one()] : monomDividers;
739
- }
740
- _getLiteralDividers(arr, letter) {
741
- let tmpList = [];
742
- // Be default, this.literal[letter] should be a rational number.
743
- for (let d = 0; d <= this.literal[letter].value; d++) {
744
- if (arr.length === 0) {
745
- let litt = {};
746
- litt[letter] = new fraction_1.Fraction(d);
747
- tmpList.push(litt);
748
- }
749
- else {
750
- for (let item of arr) {
751
- let litt = {};
752
- for (let currentLetter in item) {
753
- litt[currentLetter] = item[currentLetter];
754
- }
755
- litt[letter] = new fraction_1.Fraction(d);
756
- tmpList.push(litt);
757
- }
758
- }
759
- }
760
- return tmpList;
761
- }
762
- /**
763
- * Display the monom, forcing the '+' sign to appear
764
- */
765
- get displayWithSign() {
766
- let d = this.display;
767
- return (d[0] !== '-' ? '+' : '') + d;
768
- }
769
- get texWithSign() {
770
- if (this.coefficient.isStrictlyPositive()) {
771
- return '+' + this.tex;
772
- }
773
- return this.tex;
774
- }
775
- get plotFunction() {
776
- let L = '', letters = Object.keys(this._literal).sort();
777
- for (let letter of letters) {
778
- if (this._literal[letter].isNotZero()) {
779
- L += (L === '' ? "" : "*") + `${letter}`;
780
- if (this._literal[letter].isNotEqual(1)) {
781
- L += `^(${this._literal[letter].display})`;
782
- }
783
- }
784
- }
785
- // No literal part
786
- if (L === '') {
787
- // No setLetter - means it's only a number !
788
- if (this._coefficient.value != 0) {
789
- return `${this._coefficient.display}`;
790
- }
791
- else {
792
- return '';
793
- }
794
- }
795
- else {
796
- if (this._coefficient.value === 1) {
797
- return L;
798
- }
799
- else if (this._coefficient.value === -1) {
800
- return `-${L}`;
801
- }
802
- else if (this._coefficient.value === 0) {
803
- return '0';
804
- }
805
- else {
806
- return `${this._coefficient.display}*${L}`;
807
- }
808
- }
809
- }
810
- /**
811
- * Get the tex output of the monom
812
- */
813
- get tex() {
814
- // TODO: display with square root !
815
- let L = '', letters = Object.keys(this._literal).sort();
816
- for (let letter of letters) {
817
- if (this._literal[letter].isNotZero()) {
818
- L += `${letter}`;
819
- if (this._literal[letter].isNotEqual(1)) {
820
- L += `^{${this._literal[letter].tfrac}}`;
821
- }
822
- }
823
- }
824
- if (L === '') {
825
- // No setLetter - means it's only a number !
826
- if (this._coefficient.value != 0) {
827
- return `${this._coefficient.frac}`;
828
- }
829
- else {
830
- return '0';
831
- }
832
- }
833
- else {
834
- if (this._coefficient.value === 1) {
835
- return L;
836
- }
837
- else if (this._coefficient.value === -1) {
838
- return `-${L}`;
839
- }
840
- else if (this._coefficient.value === 0) {
841
- return '0';
842
- }
843
- else {
844
- return `${this._coefficient.frac}${L}`;
845
- }
846
- }
847
- }
848
- /**
849
- * Determine if the monom is null
850
- */
851
- isZero() {
852
- return this._coefficient.value === 0;
853
- }
854
- /**
855
- * Determine if the monom is one
856
- */
857
- isOne() {
858
- return this._coefficient.value === 1 && this.variables.length === 0;
859
- }
860
- }
861
- exports.Monom = Monom;
862
- // ----------------------------------------
863
- // Static functions
864
- // ----------------------------------------
865
- /**
866
- * Get the least common multiple of monoms
867
- * @param monoms Array of monoms
868
- */
869
- Monom.lcm = (...monoms) => {
870
- // All the monoms must be with natural powers...
871
- for (let m of monoms) {
872
- if (m.hasFractionCoefficient()) {
873
- return new Monom().zero();
874
- }
875
- }
876
- let M = new Monom(), coeffN = monoms.map(value => value.coefficient.numerator), coeffD = monoms.map(value => value.coefficient.denominator), n = numeric_1.Numeric.gcd(...coeffN), d = numeric_1.Numeric.lcm(...coeffD);
877
- // Get the coefficient.
878
- M.coefficient = new fraction_1.Fraction(n, d).reduce();
879
- // Set the literal parts - go through each monoms literal parts and get only the lowest degree of each letters.
880
- for (let m of monoms) {
881
- // Remove the inexistant letters from the resulting monom
882
- for (let letter in M.literal) {
883
- if (!(letter in m.literal)) {
884
- M.literal[letter].zero();
885
- }
886
- }
887
- for (let letter in m.literal) {
888
- if (M.literal[letter] === undefined && m.literal[letter].isStrictlyPositive()) {
889
- M.literal[letter] = m.literal[letter].clone();
890
- }
891
- else {
892
- M.literal[letter] = new fraction_1.Fraction(Math.min(m.literal[letter].value, M.literal[letter].value));
893
- }
894
- }
895
- }
896
- return M;
897
- };
898
- /**
899
- * Multiply two monoms and return a NEW monom.
900
- * @param monoms
901
- */
902
- Monom.xmultiply = (...monoms) => {
903
- let M = new Monom().one();
904
- for (let m of monoms) {
905
- M.multiply(m);
906
- }
907
- return M;
908
- };
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Monom = void 0;
4
+ /***
5
+ * Monom class
6
+ */
7
+ const numeric_1 = require("../numeric");
8
+ const shutingyard_1 = require("../shutingyard");
9
+ const fraction_1 = require("../coefficients/fraction");
10
+ class Monom {
11
+ /**
12
+ * Create a Monom
13
+ * Defined as \\(k \\cdot x^{n}\\), where \\( k,n \in \\mathbb{Q}\\).
14
+ * Examples: \\(3x^2\\) or \\(3/5x^2\\)
15
+ * @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).
16
+ */
17
+ constructor(value) {
18
+ // ------------------------------------------
19
+ // Creation / parsing functions
20
+ // -----------------------------------------
21
+ /**
22
+ * Parse a string to a monom. The string may include fraction.
23
+ * @param inputStr
24
+ */
25
+ this.parse = (inputStr) => {
26
+ if (typeof inputStr === 'string') {
27
+ this._shutingYardToReducedMonom(inputStr);
28
+ }
29
+ else if (typeof inputStr === 'number') {
30
+ this._coefficient = new fraction_1.Fraction(inputStr);
31
+ this._literal = {};
32
+ }
33
+ else if (inputStr instanceof fraction_1.Fraction) {
34
+ this._coefficient = inputStr.clone();
35
+ this._literal = {};
36
+ }
37
+ else if (inputStr instanceof Monom) {
38
+ this._coefficient = inputStr._coefficient.clone();
39
+ this._literal = this.copyLiterals(inputStr.literal);
40
+ }
41
+ return this;
42
+ };
43
+ this.addToken = (stack, element) => {
44
+ let q1, q2, m, letter, pow;
45
+ if (element.tokenType === shutingyard_1.ShutingyardType.COEFFICIENT) {
46
+ stack.push(new Monom(new fraction_1.Fraction(element.token)));
47
+ }
48
+ else if (element.tokenType === shutingyard_1.ShutingyardType.VARIABLE) {
49
+ let M = new Monom().one();
50
+ M.setLetter(element.token, 1);
51
+ stack.push(M.clone());
52
+ }
53
+ else if (element.tokenType === shutingyard_1.ShutingyardType.OPERATION) {
54
+ switch (element.token) {
55
+ case '-':
56
+ // this should only happen for negative powers or for negative coefficient.
57
+ q2 = (stack.pop()) || new Monom().zero();
58
+ q1 = (stack.pop()) || new Monom().zero();
59
+ stack.push(q1.subtract(q2));
60
+ break;
61
+ case '*':
62
+ // Get the last element in the stack
63
+ q2 = (stack.pop()) || new Monom().one();
64
+ q1 = (stack.pop()) || new Monom().one();
65
+ stack.push(q1.multiply(q2));
66
+ break;
67
+ case '/':
68
+ // Get the last element in the stack
69
+ q2 = (stack.pop()) || new Monom().one();
70
+ q1 = (stack.pop()) || new Monom().one();
71
+ stack.push(q1.divide(q2));
72
+ break;
73
+ case '^':
74
+ // get the two last elements in the stack
75
+ pow = (stack.pop().coefficient) || new fraction_1.Fraction().one();
76
+ m = (stack.pop()) || new Monom().one();
77
+ letter = m.variables[0];
78
+ if (letter !== undefined) {
79
+ m.setLetter(letter, pow);
80
+ }
81
+ stack.push(m);
82
+ // this.multiply(m.clone())
83
+ break;
84
+ }
85
+ }
86
+ };
87
+ this._shutingYardToReducedMonom = (inputStr) => {
88
+ // Get the RPN array of the current expression
89
+ const SY = new shutingyard_1.Shutingyard().parse(inputStr);
90
+ const rpn = SY.rpn;
91
+ let stack = [], m, pow, letter, q1, q2;
92
+ if (rpn.length === 0) {
93
+ this.zero();
94
+ return this;
95
+ }
96
+ else if (rpn.length === 1) {
97
+ const element = rpn[0];
98
+ this.one();
99
+ if (element.tokenType === 'coefficient') {
100
+ this.coefficient = new fraction_1.Fraction(element.token);
101
+ }
102
+ else if (element.tokenType === 'variable') {
103
+ this.setLetter(element.token, 1);
104
+ }
105
+ return this;
106
+ }
107
+ else {
108
+ // Reset the monom
109
+ for (const element of rpn) {
110
+ this.addToken(stack, element);
111
+ }
112
+ }
113
+ this.one();
114
+ this.multiply(stack[0]);
115
+ return this;
116
+ };
117
+ /**
118
+ * Clone the current Monom.
119
+ */
120
+ this.clone = () => {
121
+ let F = new Monom();
122
+ F.coefficient = this._coefficient.clone();
123
+ // Copy the literal parts.
124
+ for (let k in this._literal) {
125
+ F.setLetter(k, this._literal[k].clone());
126
+ }
127
+ return F;
128
+ };
129
+ this.copyLiterals = (literal) => {
130
+ let L = {};
131
+ for (let k in literal) {
132
+ L[k] = literal[k].clone();
133
+ }
134
+ return L;
135
+ };
136
+ this.makeSame = (M) => {
137
+ // Copy the literal parts.
138
+ for (let k in M._literal) {
139
+ this.setLetter(k, M._literal[k].clone());
140
+ }
141
+ return this;
142
+ };
143
+ /**
144
+ * Create a zero value monom
145
+ */
146
+ this.zero = () => {
147
+ this._coefficient = new fraction_1.Fraction().zero();
148
+ this._literal = {};
149
+ return this;
150
+ };
151
+ /**
152
+ * Create a one value monom
153
+ */
154
+ this.one = () => {
155
+ this._coefficient = new fraction_1.Fraction().one();
156
+ this._literal = {};
157
+ return this;
158
+ };
159
+ /**
160
+ * Clean the monom by removing each letters with a power of zero.
161
+ */
162
+ this.clean = () => {
163
+ for (let letter in this._literal) {
164
+ if (this._literal[letter].isZero()) {
165
+ delete this._literal[letter];
166
+ }
167
+ }
168
+ return this;
169
+ };
170
+ this.reduce = () => {
171
+ this.clean();
172
+ this.coefficient.reduce();
173
+ return this;
174
+ };
175
+ // ------------------------------------------
176
+ // Mathematical operations
177
+ // ------------------------------------------
178
+ /**
179
+ * Get the opposed
180
+ * Returns a monom.
181
+ */
182
+ this.opposed = () => {
183
+ this._coefficient.opposed();
184
+ return this;
185
+ };
186
+ /**
187
+ * Add all similar monoms. If they aren't similar, they are simply skipped.
188
+ * @param M (Monom[]) The monoms to add.
189
+ */
190
+ this.add = (...M) => {
191
+ for (let m of M) {
192
+ if (this.isSameAs(m)) {
193
+ if (this.isZero()) {
194
+ this.makeSame(m);
195
+ }
196
+ this._coefficient.add(m.coefficient);
197
+ }
198
+ else {
199
+ console.log('Add monom: ' + this.display + ' is not similar with ', m.display);
200
+ }
201
+ }
202
+ return this;
203
+ };
204
+ /**
205
+ * Subtract multiple monoms
206
+ * @param M (Monom[]) The monoms to subtract
207
+ */
208
+ this.subtract = (...M) => {
209
+ for (let m of M) {
210
+ if (this.isSameAs(m)) {
211
+ if (this.isZero()) {
212
+ this.makeSame(m);
213
+ }
214
+ this._coefficient.add(m.clone().coefficient.opposed());
215
+ }
216
+ else {
217
+ console.log('Subtract: Is not similar: ', m.display);
218
+ }
219
+ }
220
+ return this;
221
+ };
222
+ /**
223
+ * Multiple multiple monoms to the current monom
224
+ * @param M (Monom[]) The monoms to multiply to.
225
+ */
226
+ this.multiply = (...M) => {
227
+ for (let m of M) {
228
+ // Multiply the coefficient.
229
+ this._coefficient.multiply(m.coefficient);
230
+ // Multiply the literal parts.
231
+ for (let letter in m.literal) {
232
+ if (this._literal[letter] === undefined) {
233
+ this._literal[letter] = m.literal[letter].clone();
234
+ }
235
+ else {
236
+ this._literal[letter].add(m.literal[letter]);
237
+ }
238
+ }
239
+ }
240
+ return this;
241
+ };
242
+ this.multiplyByNumber = (F) => {
243
+ this._coefficient.multiply(F);
244
+ return this;
245
+ };
246
+ /**
247
+ * Divide the current monoms by multiple monoms
248
+ * @param M (Monom[])
249
+ */
250
+ this.divide = (...M) => {
251
+ // Depending on the given value, choose the current item
252
+ for (let v of M) {
253
+ // Divide the coefficient
254
+ this._coefficient.divide(v.coefficient);
255
+ // Subtract the power values
256
+ for (let letter in v.literal) {
257
+ this._literal[letter] = (this._literal[letter] === undefined) ? v.literal[letter].clone().opposed() : this._literal[letter].subtract(v.literal[letter]);
258
+ // If the power of a particular setLetter is zero, delete it from the literal part..
259
+ if (this._literal[letter].isZero()) {
260
+ delete this._literal[letter];
261
+ }
262
+ }
263
+ }
264
+ return this;
265
+ };
266
+ /**
267
+ * Get the pow of a monom.
268
+ * @param nb (number) : Mathematical pow
269
+ */
270
+ this.pow = (nb) => {
271
+ this._coefficient.pow(nb);
272
+ for (let letter in this._literal) {
273
+ this._literal[letter].multiply(nb);
274
+ }
275
+ return this;
276
+ };
277
+ /**
278
+ * Get the nth-root of the monom
279
+ * @param p
280
+ */
281
+ this.root = (p) => {
282
+ // TODO: determiner the nth root of a monom
283
+ return this;
284
+ };
285
+ /**
286
+ * Return the square root of a monom
287
+ */
288
+ this.sqrt = () => {
289
+ if (this.isSquare()) {
290
+ this._coefficient.sqrt();
291
+ for (let letter in this._literal) {
292
+ this._literal[letter].clone().divide(2);
293
+ }
294
+ }
295
+ return this.root(2);
296
+ };
297
+ // ------------------------------------------
298
+ // Compare functions
299
+ // ------------------------------------------
300
+ this.compare = (M, sign) => {
301
+ // TODO: Build the compare systems.
302
+ if (sign === undefined) {
303
+ sign = '=';
304
+ }
305
+ switch (sign) {
306
+ case '=':
307
+ // To be equal, they must be the isSame
308
+ if (!this.compare(M, 'same')) {
309
+ return false;
310
+ }
311
+ // The literal parts are the isSame. The coefficient must be equal
312
+ return this._coefficient.isEqual(M.coefficient);
313
+ case 'same':
314
+ // Get the list of all variables from both monoms.
315
+ let M1 = this.variables, M2 = M.variables, K = M1.concat(M2.filter((item) => M1.indexOf(item) < 0));
316
+ if (M1.length === 0 && M2.length === 0) {
317
+ return true;
318
+ }
319
+ // To compare, both must be different than zero.
320
+ if (!this.isZero() && !M.isZero()) {
321
+ for (let key of K) {
322
+ // The setLetter is not available in one of the monom
323
+ if (this._literal[key] === undefined || M.literal[key] === undefined) {
324
+ return false;
325
+ }
326
+ // The setLetter does not have the isSame power in each monoms.
327
+ if (!this._literal[key].isEqual(M.literal[key])) {
328
+ return false;
329
+ }
330
+ }
331
+ }
332
+ // All are positive check - the monoms are the sames.
333
+ return true;
334
+ default:
335
+ return false;
336
+ }
337
+ };
338
+ /**
339
+ * Determine if two monoms are equals
340
+ * @param M
341
+ */
342
+ this.isEqual = (M) => {
343
+ return this.compare(M, '=');
344
+ };
345
+ /**
346
+ * Determine if two monoms are similar
347
+ * @param M
348
+ */
349
+ this.isSameAs = (M) => {
350
+ return this.compare(M, 'same');
351
+ };
352
+ this.isSquare = () => {
353
+ if (!this.coefficient.isSquare()) {
354
+ return false;
355
+ }
356
+ return this.isLiteralSquare();
357
+ };
358
+ this.isLiteralSquare = () => {
359
+ for (let letter in this.literal) {
360
+ // A literal square must have a natural power
361
+ if (this.literal[letter].isRational()) {
362
+ return false;
363
+ }
364
+ // The natural power must be be even
365
+ if (this.literal[letter].isEven()) {
366
+ return false;
367
+ }
368
+ }
369
+ return true;
370
+ };
371
+ this.hasFractionCoefficient = () => {
372
+ for (let letter in this._literal) {
373
+ if (this._literal[letter].isRational()) {
374
+ return true;
375
+ }
376
+ }
377
+ return false;
378
+ };
379
+ // ------------------------------------------
380
+ // Misc monoms functions
381
+ // -------------------------------------
382
+ /**
383
+ * Determine if a monom contains a setLetter in it's literal part
384
+ * @param letter
385
+ */
386
+ this.hasLetter = (letter) => {
387
+ // The letter was not found
388
+ if (this._literal[letter === undefined ? 'x' : letter] === undefined) {
389
+ return false;
390
+ }
391
+ // The letter is found and is not zero !
392
+ return this._literal[letter === undefined ? 'x' : letter].isNotZero();
393
+ };
394
+ /**
395
+ * Set the power of a particular setLetter
396
+ * @param letter (string) Letter to change
397
+ * @param pow (number) Power of the setLetter (must be positive integer.
398
+ */
399
+ this.setLetter = (letter, pow) => {
400
+ if (pow instanceof fraction_1.Fraction) {
401
+ // Set the power of the letter to zero => remove it
402
+ if (this.hasLetter(letter) && pow.isZero()) {
403
+ delete this._literal[letter];
404
+ }
405
+ this._literal[letter] = pow.clone();
406
+ }
407
+ else {
408
+ this.setLetter(letter, new fraction_1.Fraction(pow));
409
+ }
410
+ };
411
+ /**
412
+ * Get the degree of a monom. If no setLetter is given, the result will be the global degree.
413
+ * @param letter (string) Letter to get to degree (power)
414
+ */
415
+ this.degree = (letter) => {
416
+ if (this.variables.length === 0) {
417
+ return new fraction_1.Fraction().zero();
418
+ }
419
+ if (letter === undefined) {
420
+ // Not setLetter given -> we get the global monom degree (sum of all the letters).
421
+ return Object.values(this._literal).reduce((t, n) => t.clone().add(n));
422
+ }
423
+ else {
424
+ // A setLetter is given -> get the corresponding power.
425
+ return this._literal[letter] === undefined ? new fraction_1.Fraction().zero() : this._literal[letter].clone();
426
+ }
427
+ };
428
+ /**
429
+ * Evaluate a monom. Each setLetter must be assigned to a Fraction.
430
+ * @param values Dictionary of <setLetter: Fraction>
431
+ */
432
+ this.evaluate = (values) => {
433
+ let r = this.coefficient.clone();
434
+ if (typeof values === 'number' || values instanceof fraction_1.Fraction) {
435
+ let tmpValues = {};
436
+ tmpValues[this.variables[0]] = new fraction_1.Fraction(values);
437
+ return this.evaluate(tmpValues);
438
+ }
439
+ if (typeof values === 'object') {
440
+ if (this.variables.length === 0) {
441
+ return this.coefficient;
442
+ }
443
+ for (let L in this._literal) {
444
+ if (values[L] === undefined) {
445
+ return new fraction_1.Fraction().zero();
446
+ }
447
+ let value = new fraction_1.Fraction(values[L]);
448
+ r.multiply(value.pow(this._literal[L]));
449
+ }
450
+ }
451
+ return r;
452
+ };
453
+ this.evaluateAsNumeric = (values) => {
454
+ let r = this.coefficient.value;
455
+ if (typeof values === 'number') {
456
+ let tmpValues = {};
457
+ tmpValues[this.variables[0]] = values;
458
+ return this.evaluateAsNumeric(tmpValues);
459
+ }
460
+ if (typeof values === 'object') {
461
+ if (this.variables.length === 0) {
462
+ return this.coefficient.value;
463
+ }
464
+ for (let L in this._literal) {
465
+ if (values[L] === undefined) {
466
+ return 0;
467
+ }
468
+ r *= values[L] ** (this._literal[L].value);
469
+ }
470
+ }
471
+ return r;
472
+ };
473
+ /**
474
+ * Derivative the monom
475
+ * @param letter
476
+ */
477
+ this.derivative = (letter) => {
478
+ // No setLetter given - assume it's the setLetter 'x'
479
+ if (letter === undefined) {
480
+ letter = 'x';
481
+ }
482
+ if (this.hasLetter(letter)) {
483
+ let d = this._literal[letter].clone(), dM = this.clone();
484
+ // Subtract one to the degree.
485
+ dM._literal[letter].subtract(1);
486
+ // Multiply the coefficient by the previous degree
487
+ dM._coefficient.multiply(new fraction_1.Fraction(d.clone()));
488
+ return dM;
489
+ }
490
+ else {
491
+ return new Monom().zero();
492
+ }
493
+ };
494
+ this.primitive = (letter) => {
495
+ // TODO: derivative including the ln value => implies creating different monom system ?
496
+ if (letter === undefined) {
497
+ letter = 'x';
498
+ }
499
+ // Zero monom
500
+ let M = this.clone(), degree;
501
+ if (M.hasLetter(letter)) {
502
+ degree = M.degree(letter).clone().add(1);
503
+ M.coefficient = M.coefficient.clone().divide(degree);
504
+ M.setLetter(letter, degree);
505
+ }
506
+ else {
507
+ // There is no letter.
508
+ // The coefficient might be zero (=> x) or a number a (=> ax)
509
+ if (M.coefficient.isZero()) {
510
+ M.coefficient = new fraction_1.Fraction().one();
511
+ }
512
+ M.setLetter(letter, 1);
513
+ }
514
+ return M;
515
+ };
516
+ // TODO: The rest of the functions are not used or unnecessary ?
517
+ /**
518
+ * Determine if multiple monoms are similar
519
+ * @param M
520
+ */
521
+ this.areSameAs = (...M) => {
522
+ let result = true;
523
+ // Check all monoms if they are the isSame as the "this" one.
524
+ for (let i = 0; i < M.length; i++) {
525
+ if (!this.isSameAs(M[i])) {
526
+ return false;
527
+ }
528
+ }
529
+ // All check passed -> all the monoms are similar.
530
+ return result;
531
+ };
532
+ /**
533
+ * Determine if multiple monoms are equals
534
+ * @param M
535
+ */
536
+ this.areEquals = (...M) => {
537
+ // They are not similar.
538
+ if (!this.areSameAs(...M)) {
539
+ return false;
540
+ }
541
+ // Check all coefficient. They must be equals.
542
+ for (let m of M) {
543
+ if (!this._coefficient.isEqual(m.coefficient)) {
544
+ return false;
545
+ }
546
+ }
547
+ // All checks passed.
548
+ return true;
549
+ };
550
+ this.isDivisible = (div) => {
551
+ // For all variables (letters), the current monom must have a degree higher than the divider
552
+ if (div.degree().isStrictlyPositive()) {
553
+ for (let letter of div.variables) {
554
+ if (!this.degree(letter).geq(div.degree(letter))) {
555
+ return false;
556
+ }
557
+ }
558
+ }
559
+ // If the coefficient is rational, we suppose we don't need to check the division by the coefficient.
560
+ if (this.coefficient.isRational() || div.coefficient.isRational()) {
561
+ return true;
562
+ }
563
+ return this.coefficient.clone().divide(div.coefficient).isRelative();
564
+ };
565
+ this.zero();
566
+ if (value !== undefined) {
567
+ // A string is given - try to parse the value.
568
+ this.parse(value);
569
+ }
570
+ return this;
571
+ }
572
+ // ------------------------------------------
573
+ // Getter and setter
574
+ // ------------------------------------------
575
+ /**
576
+ * Get the coefficient \\(k\\) of the Monom \\(k\\cdot x^{n}\\)
577
+ * @returns {Fraction}
578
+ */
579
+ get coefficient() {
580
+ return this._coefficient;
581
+ }
582
+ /**
583
+ * Set the coefficient \\(k\\) value of the monom
584
+ * @param {Fraction | number | string} F
585
+ */
586
+ set coefficient(F) {
587
+ this._coefficient = new fraction_1.Fraction(F);
588
+ }
589
+ /**
590
+ * Get the literal part of \\(x^{n_1}y^{n_2}\\) as dictionary \\[\\begin{array}{ll}x&=n_1\\\\y&=n_2\\end{array}\\]
591
+ * @returns {literalType}
592
+ */
593
+ get literal() {
594
+ return this._literal;
595
+ }
596
+ /**
597
+ * Get the literal square roots of the Monom.
598
+ * TODO: remove this getter ? Is it used and is it correct ?
599
+ * @returns {literalType}
600
+ */
601
+ get literalSqrt() {
602
+ if (this.isLiteralSquare()) {
603
+ let L = {};
604
+ for (let key in this._literal) {
605
+ L[key] = this._literal[key].clone().sqrt();
606
+ }
607
+ return L;
608
+ }
609
+ else {
610
+ return this._literal;
611
+ }
612
+ }
613
+ /**
614
+ * Set the literal part of the monom. Must be a dictionary {x: Fraction, y: Fraction, ...}
615
+ * @param {literalType} L
616
+ */
617
+ set literal(L) {
618
+ this._literal = L;
619
+ }
620
+ /**
621
+ * Set the literal part of the monom from a string
622
+ * @param inputStr String like x^2y^3
623
+ */
624
+ set literalStr(inputStr) {
625
+ // TODO : parse using shutingyard tree !
626
+ // Match all x^n
627
+ for (const v of [...inputStr.matchAll(/([a-z])\^([+-]?[0-9]+)/g)]) {
628
+ // Create the default letter entry if necessary.
629
+ if (!(v[1] in this._literal)) {
630
+ this._literal[v[1]] = new fraction_1.Fraction().zero();
631
+ }
632
+ // Add the new value.
633
+ // TODO: actually, it adds only numeric value
634
+ this._literal[v[1]].add(+v[2]);
635
+ }
636
+ // Match all x
637
+ for (const v of [...inputStr.matchAll(/([a-z](?!\^))/g)]) {
638
+ // Match all single letters
639
+ if (!(v[1] in this._literal)) {
640
+ this._literal[v[1]] = new fraction_1.Fraction().zero();
641
+ }
642
+ // Add one to the value.
643
+ this._literal[v[1]].add(1);
644
+ }
645
+ }
646
+ // Getter helpers.
647
+ /**
648
+ * Get the variables letters
649
+ */
650
+ get variables() {
651
+ let M = this.clone().clean();
652
+ return Object.keys(M.literal);
653
+ }
654
+ // Display getter
655
+ /**
656
+ * This display getter is to be used in the polynom display getter
657
+ */
658
+ get display() {
659
+ let L = '', letters = Object.keys(this._literal).sort();
660
+ for (let letter of letters) {
661
+ if (this._literal[letter].isNotZero()) {
662
+ L += `${letter}`;
663
+ if (this._literal[letter].isNotEqual(1)) {
664
+ L += `^(${this._literal[letter].display})`;
665
+ }
666
+ }
667
+ }
668
+ if (L === '') {
669
+ // No setLetter - means it's only a number !
670
+ if (this._coefficient.value != 0) {
671
+ return `${this._coefficient.display}`;
672
+ }
673
+ else {
674
+ return '';
675
+ }
676
+ }
677
+ else {
678
+ if (this._coefficient.value === 1) {
679
+ return L;
680
+ }
681
+ else if (this._coefficient.value === -1) {
682
+ return `-${L}`;
683
+ }
684
+ else if (this._coefficient.value === 0) {
685
+ return '0';
686
+ }
687
+ else {
688
+ return `${this._coefficient.display}${L}`;
689
+ }
690
+ }
691
+ }
692
+ get dividers() {
693
+ // Decompose only if the coefficient is a natural number
694
+ if (!this.coefficient.isRelative()) {
695
+ return [this.clone()];
696
+ }
697
+ // Decompose only if the power values are natural numbers.
698
+ if (this.hasFractionCoefficient()) {
699
+ return [this.clone()];
700
+ }
701
+ // Security : do not do this if greater than 10000
702
+ if (this.coefficient.numerator > 1000000) {
703
+ return [this.clone()];
704
+ }
705
+ const dividers = numeric_1.Numeric.dividers(Math.abs(this.coefficient.numerator));
706
+ // Decompose the literals parts.
707
+ let literals = [];
708
+ for (let L in this.literal) {
709
+ // L is the letter.
710
+ literals = this._getLiteralDividers(literals, L);
711
+ }
712
+ const monomDividers = [];
713
+ if (literals.length > 0 && dividers.length > 0) {
714
+ for (let N of dividers) {
715
+ for (let L of literals) {
716
+ let M = new Monom();
717
+ M.coefficient = new fraction_1.Fraction(N);
718
+ M.literal = L;
719
+ monomDividers.push(M);
720
+ }
721
+ }
722
+ }
723
+ else if (dividers.length === 0) {
724
+ for (let L of literals) {
725
+ let M = new Monom();
726
+ M.coefficient = new fraction_1.Fraction().one();
727
+ M.literal = L;
728
+ monomDividers.push(M);
729
+ }
730
+ }
731
+ else {
732
+ for (let N of dividers) {
733
+ let M = new Monom();
734
+ M.coefficient = new fraction_1.Fraction(N);
735
+ monomDividers.push(M);
736
+ }
737
+ }
738
+ return monomDividers.length === 0 ? [new Monom().one()] : monomDividers;
739
+ }
740
+ _getLiteralDividers(arr, letter) {
741
+ let tmpList = [];
742
+ // Be default, this.literal[letter] should be a rational number.
743
+ for (let d = 0; d <= this.literal[letter].value; d++) {
744
+ if (arr.length === 0) {
745
+ let litt = {};
746
+ litt[letter] = new fraction_1.Fraction(d);
747
+ tmpList.push(litt);
748
+ }
749
+ else {
750
+ for (let item of arr) {
751
+ let litt = {};
752
+ for (let currentLetter in item) {
753
+ litt[currentLetter] = item[currentLetter];
754
+ }
755
+ litt[letter] = new fraction_1.Fraction(d);
756
+ tmpList.push(litt);
757
+ }
758
+ }
759
+ }
760
+ return tmpList;
761
+ }
762
+ /**
763
+ * Display the monom, forcing the '+' sign to appear
764
+ */
765
+ get displayWithSign() {
766
+ let d = this.display;
767
+ return (d[0] !== '-' ? '+' : '') + d;
768
+ }
769
+ get texWithSign() {
770
+ if (this.coefficient.isStrictlyPositive()) {
771
+ return '+' + this.tex;
772
+ }
773
+ return this.tex;
774
+ }
775
+ get plotFunction() {
776
+ let L = '', letters = Object.keys(this._literal).sort();
777
+ for (let letter of letters) {
778
+ if (this._literal[letter].isNotZero()) {
779
+ L += (L === '' ? "" : "*") + `${letter}`;
780
+ if (this._literal[letter].isNotEqual(1)) {
781
+ L += `^(${this._literal[letter].display})`;
782
+ }
783
+ }
784
+ }
785
+ // No literal part
786
+ if (L === '') {
787
+ // No setLetter - means it's only a number !
788
+ if (this._coefficient.value != 0) {
789
+ return `${this._coefficient.display}`;
790
+ }
791
+ else {
792
+ return '';
793
+ }
794
+ }
795
+ else {
796
+ if (this._coefficient.value === 1) {
797
+ return L;
798
+ }
799
+ else if (this._coefficient.value === -1) {
800
+ return `-${L}`;
801
+ }
802
+ else if (this._coefficient.value === 0) {
803
+ return '0';
804
+ }
805
+ else {
806
+ return `${this._coefficient.display}*${L}`;
807
+ }
808
+ }
809
+ }
810
+ /**
811
+ * Get the tex output of the monom
812
+ */
813
+ get tex() {
814
+ // TODO: display with square root !
815
+ let L = '', letters = Object.keys(this._literal).sort();
816
+ for (let letter of letters) {
817
+ if (this._literal[letter].isNotZero()) {
818
+ L += `${letter}`;
819
+ if (this._literal[letter].isNotEqual(1)) {
820
+ L += `^{${this._literal[letter].tfrac}}`;
821
+ }
822
+ }
823
+ }
824
+ if (L === '') {
825
+ // No setLetter - means it's only a number !
826
+ if (this._coefficient.value != 0) {
827
+ return `${this._coefficient.frac}`;
828
+ }
829
+ else {
830
+ return '0';
831
+ }
832
+ }
833
+ else {
834
+ if (this._coefficient.value === 1) {
835
+ return L;
836
+ }
837
+ else if (this._coefficient.value === -1) {
838
+ return `-${L}`;
839
+ }
840
+ else if (this._coefficient.value === 0) {
841
+ return '0';
842
+ }
843
+ else {
844
+ return `${this._coefficient.frac}${L}`;
845
+ }
846
+ }
847
+ }
848
+ /**
849
+ * Determine if the monom is null
850
+ */
851
+ isZero() {
852
+ return this._coefficient.value === 0;
853
+ }
854
+ /**
855
+ * Determine if the monom is one
856
+ */
857
+ isOne() {
858
+ return this._coefficient.value === 1 && this.variables.length === 0;
859
+ }
860
+ }
861
+ exports.Monom = Monom;
862
+ // ----------------------------------------
863
+ // Static functions
864
+ // ----------------------------------------
865
+ /**
866
+ * Get the least common multiple of monoms
867
+ * @param monoms Array of monoms
868
+ */
869
+ Monom.lcm = (...monoms) => {
870
+ // All the monoms must be with natural powers...
871
+ for (let m of monoms) {
872
+ if (m.hasFractionCoefficient()) {
873
+ return new Monom().zero();
874
+ }
875
+ }
876
+ let M = new Monom(), coeffN = monoms.map(value => value.coefficient.numerator), coeffD = monoms.map(value => value.coefficient.denominator), n = numeric_1.Numeric.gcd(...coeffN), d = numeric_1.Numeric.lcm(...coeffD);
877
+ // Get the coefficient.
878
+ M.coefficient = new fraction_1.Fraction(n, d).reduce();
879
+ // Set the literal parts - go through each monoms literal parts and get only the lowest degree of each letters.
880
+ for (let m of monoms) {
881
+ // Remove the inexistant letters from the resulting monom
882
+ for (let letter in M.literal) {
883
+ if (!(letter in m.literal)) {
884
+ M.literal[letter].zero();
885
+ }
886
+ }
887
+ for (let letter in m.literal) {
888
+ if (M.literal[letter] === undefined && m.literal[letter].isStrictlyPositive()) {
889
+ M.literal[letter] = m.literal[letter].clone();
890
+ }
891
+ else {
892
+ M.literal[letter] = new fraction_1.Fraction(Math.min(m.literal[letter].value, M.literal[letter].value));
893
+ }
894
+ }
895
+ }
896
+ return M;
897
+ };
898
+ /**
899
+ * Multiply two monoms and return a NEW monom.
900
+ * @param monoms
901
+ */
902
+ Monom.xmultiply = (...monoms) => {
903
+ let M = new Monom().one();
904
+ for (let m of monoms) {
905
+ M.multiply(m);
906
+ }
907
+ return M;
908
+ };
909
909
  //# sourceMappingURL=monom.js.map