pimath 0.0.13 → 0.0.17

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