pimath 0.0.32 → 0.0.35

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 (127) hide show
  1. package/dist/pi.js +6537 -1
  2. package/dist/pi.js.map +1 -1
  3. package/dist/pi.min.js +2 -0
  4. package/dist/pi.min.js.map +1 -0
  5. package/docs/assets/search.js +1 -1
  6. package/docs/classes/algebra.Equation.html +9 -9
  7. package/docs/classes/algebra.LinearSystem.html +1 -1
  8. package/docs/classes/algebra.Logicalset.html +2 -2
  9. package/docs/classes/algebra.Monom.html +37 -37
  10. package/docs/classes/algebra.Polynom.html +10 -10
  11. package/docs/classes/algebra.PolynomExpFactor.html +1 -1
  12. package/docs/classes/algebra.PolynomExpProduct.html +1 -1
  13. package/docs/classes/algebra.Rational.html +2 -2
  14. package/docs/classes/coefficients.Fraction.html +4 -4
  15. package/docs/classes/coefficients.Nthroot.html +1 -1
  16. package/docs/classes/geometry.Circle.html +2 -2
  17. package/docs/classes/geometry.Line.html +2 -2
  18. package/docs/classes/geometry.Point.html +1 -1
  19. package/docs/classes/geometry.Triangle.html +5 -5
  20. package/docs/classes/geometry.Vector.html +1 -1
  21. package/docs/classes/numeric.Numeric.html +5 -5
  22. package/docs/classes/shutingyard.Shutingyard.html +4 -4
  23. package/docs/enums/geometry.LinePropriety.html +1 -0
  24. package/docs/enums/shutingyard.ShutingyardMode.html +1 -1
  25. package/docs/enums/shutingyard.ShutingyardType.html +1 -1
  26. package/docs/interfaces/geometry.remarquableLines.html +1 -1
  27. package/docs/modules/algebra.html +1 -1
  28. package/docs/modules/coefficients.html +1 -1
  29. package/docs/modules/geometry.html +1 -1
  30. package/docs/modules/random.Random.html +1 -1
  31. package/docs/modules/random.html +1 -1
  32. package/docs/modules/shutingyard.html +1 -1
  33. package/esm/main.d.ts +30 -1
  34. package/esm/main.js +4 -1
  35. package/esm/main.js.map +1 -1
  36. package/esm/maths/algebra/equation.d.ts +62 -17
  37. package/esm/maths/algebra/equation.js +597 -502
  38. package/esm/maths/algebra/equation.js.map +1 -1
  39. package/esm/maths/algebra/index.js +5 -1
  40. package/esm/maths/algebra/index.js.map +1 -1
  41. package/esm/maths/algebra/linearSystem.js +154 -101
  42. package/esm/maths/algebra/linearSystem.js.map +1 -1
  43. package/esm/maths/algebra/logicalset.d.ts +11 -0
  44. package/esm/maths/algebra/logicalset.js +18 -6
  45. package/esm/maths/algebra/logicalset.js.map +1 -1
  46. package/esm/maths/algebra/monom.d.ts +144 -0
  47. package/esm/maths/algebra/monom.js +626 -398
  48. package/esm/maths/algebra/monom.js.map +1 -1
  49. package/esm/maths/algebra/polynom.d.ts +49 -0
  50. package/esm/maths/algebra/polynom.js +995 -712
  51. package/esm/maths/algebra/polynom.js.map +1 -1
  52. package/esm/maths/algebra/rational.d.ts +12 -0
  53. package/esm/maths/algebra/rational.js +97 -82
  54. package/esm/maths/algebra/rational.js.map +1 -1
  55. package/esm/maths/coefficients/fraction.d.ts +18 -0
  56. package/esm/maths/coefficients/fraction.js +390 -332
  57. package/esm/maths/coefficients/fraction.js.map +1 -1
  58. package/esm/maths/coefficients/index.js +5 -1
  59. package/esm/maths/coefficients/index.js.map +1 -1
  60. package/esm/maths/coefficients/nthroot.d.ts +3 -0
  61. package/esm/maths/coefficients/nthroot.js +48 -33
  62. package/esm/maths/coefficients/nthroot.js.map +1 -1
  63. package/esm/maths/expressions/numexp.js +11 -3
  64. package/esm/maths/expressions/numexp.js.map +1 -1
  65. package/esm/maths/expressions/polynomexp.bkp.js +93 -93
  66. package/esm/maths/expressions/polynomexp.bkp.js.map +1 -1
  67. package/esm/maths/expressions/polynomexp.js +22 -9
  68. package/esm/maths/expressions/polynomexp.js.map +1 -1
  69. package/esm/maths/geometry/circle.d.ts +18 -6
  70. package/esm/maths/geometry/circle.js +139 -42
  71. package/esm/maths/geometry/circle.js.map +1 -1
  72. package/esm/maths/geometry/index.js +5 -1
  73. package/esm/maths/geometry/index.js.map +1 -1
  74. package/esm/maths/geometry/line.d.ts +9 -2
  75. package/esm/maths/geometry/line.js +245 -188
  76. package/esm/maths/geometry/line.js.map +1 -1
  77. package/esm/maths/geometry/point.d.ts +12 -0
  78. package/esm/maths/geometry/point.js +121 -73
  79. package/esm/maths/geometry/point.js.map +1 -1
  80. package/esm/maths/geometry/triangle.d.ts +23 -1
  81. package/esm/maths/geometry/triangle.js +197 -158
  82. package/esm/maths/geometry/triangle.js.map +1 -1
  83. package/esm/maths/geometry/vector.d.ts +5 -1
  84. package/esm/maths/geometry/vector.js +139 -115
  85. package/esm/maths/geometry/vector.js.map +1 -1
  86. package/esm/maths/numeric.d.ts +17 -0
  87. package/esm/maths/numeric.js +40 -0
  88. package/esm/maths/numeric.js.map +1 -1
  89. package/esm/maths/random/index.js +5 -1
  90. package/esm/maths/random/index.js.map +1 -1
  91. package/esm/maths/random/randomCore.js +15 -15
  92. package/esm/maths/random/randomCore.js.map +1 -1
  93. package/esm/maths/random/rndFraction.d.ts +3 -0
  94. package/esm/maths/random/rndFraction.js +19 -16
  95. package/esm/maths/random/rndFraction.js.map +1 -1
  96. package/esm/maths/random/rndHelpers.d.ts +17 -0
  97. package/esm/maths/random/rndHelpers.js +20 -0
  98. package/esm/maths/random/rndHelpers.js.map +1 -1
  99. package/esm/maths/random/rndMonom.d.ts +3 -0
  100. package/esm/maths/random/rndMonom.js +33 -26
  101. package/esm/maths/random/rndMonom.js.map +1 -1
  102. package/esm/maths/random/rndPolynom.d.ts +3 -0
  103. package/esm/maths/random/rndPolynom.js +49 -37
  104. package/esm/maths/random/rndPolynom.js.map +1 -1
  105. package/esm/maths/shutingyard.d.ts +21 -0
  106. package/esm/maths/shutingyard.js +86 -9
  107. package/esm/maths/shutingyard.js.map +1 -1
  108. package/package.json +2 -2
  109. package/public/index.html +47 -0
  110. package/src/main.ts +2 -2
  111. package/src/maths/algebra/equation.ts +142 -128
  112. package/src/maths/algebra/monom.ts +6 -2
  113. package/src/maths/algebra/polynom.ts +2 -7
  114. package/src/maths/geometry/circle.ts +168 -75
  115. package/src/maths/geometry/index.ts +1 -1
  116. package/src/maths/geometry/line.ts +1 -1
  117. package/src/maths/geometry/point.ts +25 -2
  118. package/src/maths/geometry/triangle.ts +1 -1
  119. package/src/maths/geometry/vector.ts +1 -1
  120. package/src/maths/numeric.ts +15 -0
  121. package/tests/algebra/polynom.test.ts +7 -0
  122. package/tests/geometry/circle.test.ts +33 -0
  123. package/tsconfig.json +2 -2
  124. package/webpack-production-min.config.js +26 -0
  125. package/webpack-production.config.js +1 -1
  126. package/dev/pi.js +0 -5392
  127. package/dev/pi.js.map +0 -1
@@ -5,14 +5,579 @@ const polynom_1 = require("./polynom");
5
5
  const numeric_1 = require("../numeric");
6
6
  const coefficients_1 = require("../coefficients");
7
7
  class Equation {
8
- _left;
9
- _right;
10
- _sign;
11
- _polynom;
12
- _solutions;
13
- _varnothing = '\\varnothing';
14
- _real = '\\mathbb{R}';
8
+ /**
9
+ * Create an Equation using two polynoms.
10
+ * Markdown *support* is cool
11
+ * @param equations
12
+ */
15
13
  constructor(...equations) {
14
+ // Undetermined texSolutions.
15
+ this._varnothing = '\\varnothing';
16
+ this._real = '\\mathbb{R}';
17
+ // ------------------------------------------
18
+ // Creation / parsing functions
19
+ // -----------------------------------------------
20
+ this._randomizeDefaults = {
21
+ degree: 2
22
+ };
23
+ // ------------------------------------------
24
+ this.parse = (equationString) => {
25
+ let pStr, strSign;
26
+ // Find the string separator
27
+ strSign = this._findSign(equationString);
28
+ if (strSign === false) {
29
+ console.error('The equation is not valid (no sign found)');
30
+ return;
31
+ }
32
+ // The StrSign is found
33
+ pStr = equationString.split(strSign);
34
+ return this.create(new polynom_1.Polynom(pStr[0]), new polynom_1.Polynom(pStr[1]), this._formatSign(strSign));
35
+ };
36
+ this.create = (left, right, sign) => {
37
+ this._left = left;
38
+ this._right = right;
39
+ this._sign = this._formatSign(sign);
40
+ return this;
41
+ };
42
+ this.clone = () => {
43
+ return new Equation().create(this._left.clone(), this._right.clone(), this._sign + '');
44
+ };
45
+ // -----------------------------------------------
46
+ // Equations generators and randomizers
47
+ this.randomize = (opts, sign) => {
48
+ // TODO: Generate equations randomly, using config.
49
+ return new Equation().create(new polynom_1.Polynom(), new polynom_1.Polynom(), sign);
50
+ };
51
+ // -----------------------------------------------
52
+ /**
53
+ * Reorder will move all monoms containing a letter on the left, all the other on the right.
54
+ */
55
+ this.moveLeft = () => {
56
+ this._left = this._left.clone().subtract(this._right);
57
+ this._right.zero();
58
+ return this;
59
+ };
60
+ this.reorder = (allLeft) => {
61
+ // Move all monoms of degree greater than 0 to the left.
62
+ // and all zero degree monoms to the right.
63
+ this._left.subtract(this._right);
64
+ this._right.zero();
65
+ if (allLeft) {
66
+ return this.moveLeft();
67
+ }
68
+ let mMove;
69
+ for (let m of this._left.monoms) {
70
+ if (m.degree().isZero()) {
71
+ mMove = m.clone();
72
+ this._left.subtract(mMove);
73
+ this._right.subtract(mMove);
74
+ }
75
+ }
76
+ // Reorder the left and right polynoms
77
+ this._left.reorder();
78
+ this._right.reorder();
79
+ return this;
80
+ };
81
+ /**
82
+ * Multiply by the lcm denominator and divide by the gcm numerators.
83
+ */
84
+ this.simplify = () => {
85
+ this.multiply(numeric_1.Numeric.lcm(...this._left.getDenominators(), ...this._right.getDenominators()));
86
+ this.divide(numeric_1.Numeric.gcd(...this._left.getNumerators(), ...this._right.getNumerators()));
87
+ return this;
88
+ };
89
+ // -----------------------------------------------
90
+ // Equations operations
91
+ /**
92
+ * Reorder the polynom to have only one letter on the left, the rest on the right.
93
+ * @param letter
94
+ */
95
+ this.isolate = (letter) => {
96
+ // Determine if we can isolate the variables.
97
+ // Both part of the equations must be of the first degree.
98
+ //TODO: handle equations of degree two or more ?
99
+ if (!this.degree(letter).isOne()) {
100
+ return false;
101
+ }
102
+ // Modify the equation to isolate the asked variable.
103
+ // TODO: must handle equations like 3xy+5y=4 => y = 4/(3x-5)
104
+ if (this.isMultiVariable()) {
105
+ return false;
106
+ }
107
+ // Isolate the letter.
108
+ let mMove, cMove;
109
+ // Start by moving everything to the left.
110
+ this._left.subtract(this._right);
111
+ this._right.zero();
112
+ for (let m of this._left.monoms) {
113
+ if (!m.hasLetter(letter)) {
114
+ mMove = m.clone();
115
+ this._left.add(mMove.clone().opposed());
116
+ this._right.add(mMove.clone().opposed());
117
+ }
118
+ }
119
+ // In theory, we should have only one item on the left.
120
+ if (this._left.length !== 1) {
121
+ return false;
122
+ }
123
+ cMove = this._left.monoms[0].coefficient.clone();
124
+ this._left.divide(cMove);
125
+ this._right.divide(cMove);
126
+ return this;
127
+ };
128
+ this.replaceBy = (letter, P) => {
129
+ this._left.replaceBy(letter, P);
130
+ this._right.replaceBy(letter, P);
131
+ return this;
132
+ };
133
+ /**
134
+ * Multiple an equation by a fraction value.
135
+ * @param value
136
+ */
137
+ this.multiply = (value) => {
138
+ // Make sure we have a fraction.
139
+ let F = new coefficients_1.Fraction(value);
140
+ // Multiply each part of the equation by the fraction
141
+ this._left.multiply(F);
142
+ this._right.multiply(F);
143
+ // The sign of the inequation must be changed.
144
+ if (this._sign !== '=' && F.sign() === -1) {
145
+ this._reverseSign();
146
+ }
147
+ return this;
148
+ };
149
+ /**
150
+ * divide an equation by a given value (transformed as a fraction)
151
+ *
152
+ * ```
153
+ * 8x+10=6x \vert 2
154
+ * 4x+5=3x
155
+ * ```
156
+ *
157
+ * |>Alternatively with $3x-4$ maybe it's working ?
158
+ * $$\frac{3x}{5}$$
159
+ *
160
+ * @param value
161
+ * @returns {Equation}
162
+ */
163
+ this.divide = (value) => {
164
+ // Make sure we have a fraction.
165
+ let F = new coefficients_1.Fraction(value);
166
+ if (F.isZero()) {
167
+ return this;
168
+ }
169
+ else {
170
+ return this.multiply(F.invert());
171
+ }
172
+ };
173
+ /**
174
+ * Get the degree of the equation
175
+ * @param letter
176
+ */
177
+ this.degree = (letter) => {
178
+ return coefficients_1.Fraction.max(this._left.degree(letter), this._right.degree(letter));
179
+ };
180
+ /**
181
+ * Determine if the equation contains more than one letter/variable.
182
+ */
183
+ this.isMultiVariable = () => {
184
+ return this._left.isMultiVariable || this._right.isMultiVariable;
185
+ };
186
+ this.letters = () => {
187
+ // @ts-ignore
188
+ return [...new Set([...this._left.letters(), ...this._right.letters()])];
189
+ };
190
+ // -----------------------------------------------
191
+ // Equations helpers
192
+ // -----------------------------------------------
193
+ // -----------------------------------------------
194
+ this.solve = () => {
195
+ // Initialise the variables:
196
+ this._solutions = [];
197
+ // TODO: consolidate solving equations (inequations vs equations)
198
+ // TODO: work with not natural degrees ?
199
+ this._polynom = this._left.clone().subtract(this._right);
200
+ switch (this._polynom.degree().value) {
201
+ case 0:
202
+ case 1:
203
+ this._solveDegree1();
204
+ break;
205
+ case 2:
206
+ this._solveDegree2();
207
+ break;
208
+ default:
209
+ this._solveDegree3plus();
210
+ }
211
+ return this;
212
+ };
213
+ this.test = (values) => {
214
+ return this.left.evaluate(values).isEqual(this.right.evaluate(values));
215
+ };
216
+ this._findSign = (equationString) => {
217
+ let strSign = '';
218
+ if (equationString.includes('geq')) {
219
+ return (equationString.includes('\\geq')) ? '\\geq' : 'geq';
220
+ }
221
+ else if (equationString.includes('leq')) {
222
+ return (equationString.includes('\\leq')) ? '\\leq' : 'leq';
223
+ }
224
+ else if (equationString.includes('>=')) {
225
+ return '>=';
226
+ }
227
+ else if (equationString.includes('=>')) {
228
+ return '=>';
229
+ }
230
+ else if (equationString.includes('>')) {
231
+ return '>';
232
+ }
233
+ else if (equationString.includes('<=')) {
234
+ return '<=';
235
+ }
236
+ else if (equationString.includes('=<')) {
237
+ return '=<';
238
+ }
239
+ else if (equationString.includes('<')) {
240
+ return '<';
241
+ }
242
+ else if (equationString.includes('=')) {
243
+ return '=';
244
+ }
245
+ if (strSign === '') {
246
+ console.log('Equation: parse string : sign not found');
247
+ return false;
248
+ }
249
+ };
250
+ // -----------------------------------------------
251
+ // Equations solving algorithms
252
+ this._formatSign = (signStr) => {
253
+ if (signStr === undefined) {
254
+ return '=';
255
+ }
256
+ if (signStr.includes('geq')) {
257
+ return '>=';
258
+ }
259
+ else if (signStr.includes('>=')) {
260
+ return '>=';
261
+ }
262
+ else if (signStr.includes('=>')) {
263
+ return '>=';
264
+ }
265
+ else if (signStr.includes('>')) {
266
+ return '>';
267
+ }
268
+ else if (signStr.includes('leq')) {
269
+ return '<=';
270
+ }
271
+ else if (signStr.includes('<=')) {
272
+ return '<=';
273
+ }
274
+ else if (signStr.includes('=<')) {
275
+ return '<=';
276
+ }
277
+ else if (signStr.includes('<')) {
278
+ return '<';
279
+ }
280
+ else {
281
+ return '=';
282
+ }
283
+ };
284
+ this._reverseSign = () => {
285
+ if (this._sign === '=') {
286
+ return this;
287
+ }
288
+ if (this._sign.includes('<')) {
289
+ this._sign.replace('<', '>');
290
+ return this;
291
+ }
292
+ if (this._sign.includes('>')) {
293
+ this._sign.replace('>', '<');
294
+ return this;
295
+ }
296
+ return this;
297
+ };
298
+ this.isGreater = () => {
299
+ if (this._sign.indexOf('>') !== -1) {
300
+ return true;
301
+ }
302
+ return this._sign.indexOf('geq') !== -1;
303
+ };
304
+ this.isStrictEqual = () => {
305
+ return this._sign === '=';
306
+ };
307
+ this.isAlsoEqual = () => {
308
+ if (this._sign.indexOf('=') !== -1) {
309
+ return true;
310
+ }
311
+ if (this._sign.indexOf('geq') !== -1) {
312
+ return true;
313
+ }
314
+ if (this._sign.indexOf('leq') !== -1) {
315
+ return true;
316
+ }
317
+ };
318
+ this._solveDegree1 = (letter) => {
319
+ const m1 = this._polynom.monomByDegree(1, letter).coefficient, m0 = this._polynom.monomByDegree(0, letter).coefficient, v = m0.clone().opposed().divide(m1);
320
+ let s;
321
+ if (this.isStrictEqual()) {
322
+ if (m1.value === 0) {
323
+ // In this case, the coefficient of the x variable is zero.
324
+ if (m0.value === 0) {
325
+ this._solutions = [{
326
+ tex: this._real,
327
+ value: NaN,
328
+ exact: false
329
+ }];
330
+ }
331
+ else {
332
+ this._solutions = [{
333
+ tex: this._varnothing,
334
+ value: NaN,
335
+ exact: false
336
+ }];
337
+ }
338
+ }
339
+ else {
340
+ this._solutions = [{
341
+ tex: v.display,
342
+ value: v.value,
343
+ exact: v
344
+ }];
345
+ }
346
+ }
347
+ else {
348
+ if (m1.value === 0) {
349
+ // In this case, the coefficient of the x variable is zero.
350
+ if (m0.value === 0 && this.isAlsoEqual()) {
351
+ s = '\\mathbb{R}';
352
+ }
353
+ else {
354
+ if (m0.value > 0) {
355
+ s = this.isGreater() ? this._real : this._varnothing;
356
+ }
357
+ else {
358
+ s = !this.isGreater() ? this._real : this._varnothing;
359
+ }
360
+ }
361
+ }
362
+ else {
363
+ // Must handle the case if the m1 monom is negative.
364
+ if ((this.isGreater() && m1.sign() === 1) || (!this.isGreater() && m1.sign() === -1)) {
365
+ s = `\\left${this.isAlsoEqual() ? '\\[' : '\\]'}${v};+\\infty\\right\\[`;
366
+ }
367
+ else {
368
+ s = `\\left\\]-\\infty;${v} \\right\\${this.isAlsoEqual() ? '\\]' : '\\['}`;
369
+ }
370
+ }
371
+ this._solutions = [{
372
+ tex: s,
373
+ value: NaN,
374
+ exact: false
375
+ }];
376
+ }
377
+ return this._solutions;
378
+ };
379
+ this._solveDegree2 = (letter) => {
380
+ let aF = this._polynom.monomByDegree(2, letter).coefficient, bF = this._polynom.monomByDegree(1, letter).coefficient, cF = this._polynom.monomByDegree(0, letter).coefficient, delta, nthDelta, lcm = numeric_1.Numeric.lcm(aF.denominator, bF.denominator, cF.denominator), a = aF.multiply(lcm).value, b = bF.multiply(lcm).value, c = cF.multiply(lcm).value, realX1, realX2, sX1, sX2;
381
+ delta = b * b - 4 * a * c;
382
+ if (delta > 0) {
383
+ realX1 = (-b - Math.sqrt(delta)) / (2 * a);
384
+ realX2 = (-b + Math.sqrt(delta)) / (2 * a);
385
+ if (delta > 1.0e5) {
386
+ // The delta is too big to be parsed !
387
+ this._solutions = [
388
+ {
389
+ tex: ((-b - Math.sqrt(delta)) / (2 * a)).toFixed(5),
390
+ value: realX1,
391
+ exact: false
392
+ },
393
+ {
394
+ tex: ((-b + Math.sqrt(delta)) / (2 * a)).toFixed(5),
395
+ value: realX2,
396
+ exact: false
397
+ }
398
+ ];
399
+ }
400
+ else {
401
+ nthDelta = new coefficients_1.Nthroot(delta).reduce();
402
+ if (nthDelta.hasRadical()) {
403
+ // -b +- coeff\sqrt{radical}
404
+ // -------------------------
405
+ // 2a
406
+ let gcd = numeric_1.Numeric.gcd(b, 2 * a, nthDelta.coefficient);
407
+ nthDelta.coefficient = nthDelta.coefficient / gcd;
408
+ // TODO: Can i delete the next line ?
409
+ // let deltaC = nthDelta.coefficient, deltaR = nthDelta.radical;
410
+ if (b !== 0) {
411
+ if (2 * a / gcd === 1) {
412
+ this._solutions = [
413
+ {
414
+ tex: `${-b / gcd} - ${nthDelta.tex}`,
415
+ value: realX1,
416
+ exact: false // TODO: implement exact value with nthroot
417
+ },
418
+ {
419
+ tex: `${-b / gcd} + ${nthDelta.tex}`,
420
+ value: realX2,
421
+ exact: false
422
+ },
423
+ ];
424
+ }
425
+ else {
426
+ this._solutions = [
427
+ {
428
+ tex: `\\dfrac{${-b / gcd} - ${nthDelta.tex} }{ ${2 * a / gcd} }`,
429
+ value: realX1,
430
+ exact: false
431
+ },
432
+ {
433
+ tex: `\\dfrac{${-b / gcd} + ${nthDelta.tex} }{ ${2 * a / gcd} }`,
434
+ value: realX2,
435
+ exact: false
436
+ },
437
+ ];
438
+ }
439
+ }
440
+ else {
441
+ if (2 * a / gcd === 1) {
442
+ this._solutions = [
443
+ {
444
+ tex: `- ${nthDelta.tex}`,
445
+ value: realX1,
446
+ exact: false
447
+ },
448
+ {
449
+ tex: `${nthDelta.tex}`,
450
+ value: realX2,
451
+ exact: false
452
+ },
453
+ ];
454
+ }
455
+ else {
456
+ this._solutions = [
457
+ {
458
+ tex: `\\dfrac{- ${nthDelta.tex} }{ ${2 * a / gcd} }`,
459
+ value: realX1,
460
+ exact: false
461
+ },
462
+ {
463
+ tex: `\\dfrac{${nthDelta.tex} }{ ${2 * a / gcd} }`,
464
+ value: realX2,
465
+ exact: false
466
+ },
467
+ ];
468
+ }
469
+ }
470
+ }
471
+ else {
472
+ // -b +- d / 2a
473
+ const S1 = new coefficients_1.Fraction(-b - nthDelta.coefficient, 2 * a).reduce(), S2 = new coefficients_1.Fraction(-b + nthDelta.coefficient, 2 * a).reduce();
474
+ this._solutions = [
475
+ {
476
+ tex: S1.dfrac,
477
+ value: realX1,
478
+ exact: S1
479
+ },
480
+ {
481
+ tex: S2.dfrac,
482
+ value: realX2,
483
+ exact: S2
484
+ }
485
+ ];
486
+ }
487
+ }
488
+ }
489
+ else if (delta === 0) {
490
+ const sol = new coefficients_1.Fraction(-b, 2 * a).reduce();
491
+ this._solutions = [{
492
+ tex: sol.dfrac,
493
+ value: sol.value,
494
+ exact: sol
495
+ }];
496
+ }
497
+ else {
498
+ this._solutions = [{
499
+ tex: this._varnothing,
500
+ value: NaN,
501
+ exact: false
502
+ }];
503
+ }
504
+ // Handle now the inequations.
505
+ if (!this.isStrictEqual()) {
506
+ if (this._solutions.length === 2) {
507
+ sX1 = (realX1 < realX2) ? this._solutions[0].tex : this._solutions[1].tex;
508
+ sX2 = (realX1 < realX2) ? this._solutions[1].tex : this._solutions[0].tex;
509
+ if ((this.isGreater() && aF.sign() === 1) || (!this.isGreater() && aF.sign() === -1)) {
510
+ this._solutions = [{
511
+ tex: `\\left]-\\infty ; ${sX1}\\right${this.isAlsoEqual() ? ']' : '['} \\cup \\left${this.isAlsoEqual() ? '[' : ']'}${sX2};+\\infty\\right[`,
512
+ value: NaN,
513
+ exact: false
514
+ }
515
+ ];
516
+ }
517
+ else {
518
+ this._solutions = [{
519
+ tex: `\\left${this.isAlsoEqual() ? '[' : ']'}${sX1} ; ${sX2}\\right${this.isAlsoEqual() ? ']' : '['}`,
520
+ value: NaN,
521
+ exact: false
522
+ }];
523
+ }
524
+ }
525
+ else if (this._solutions.length === 1 && this._solutions[0].tex !== this._varnothing) {
526
+ if (!this.isAlsoEqual()) {
527
+ if ((this.isGreater() && aF.sign() === 1) || (!this.isGreater() && aF.sign() === -1)) {
528
+ this._solutions = [{
529
+ tex: `\\left]-\\infty ; ${this._solutions[0].tex}\\right[ \\cup \\left]${this._solutions[0].tex};+\\infty\\right[`,
530
+ value: NaN,
531
+ exact: false
532
+ }
533
+ ];
534
+ }
535
+ else {
536
+ this._solutions = [{
537
+ tex: this._varnothing,
538
+ value: NaN,
539
+ exact: false
540
+ }];
541
+ }
542
+ }
543
+ else {
544
+ if ((this.isGreater() && aF.sign() === 1) || (!this.isGreater() && aF.sign() === -1)) {
545
+ this._solutions = [{
546
+ tex: this._real,
547
+ value: NaN,
548
+ exact: false
549
+ }];
550
+ }
551
+ else {
552
+ // this._texSolutions = [ this._texSolutions[0] ];
553
+ }
554
+ }
555
+ }
556
+ else {
557
+ if (this.isGreater()) {
558
+ this._solutions = [{
559
+ tex: aF.sign() === 1 ? this._real : this._varnothing,
560
+ value: NaN,
561
+ exact: false
562
+ }];
563
+ }
564
+ else {
565
+ this._solutions = [{
566
+ tex: aF.sign() === -1 ? this._real : this._varnothing,
567
+ value: NaN,
568
+ exact: false
569
+ }];
570
+ }
571
+ }
572
+ }
573
+ return this._solutions;
574
+ };
575
+ this._solveDegree3plus = () => {
576
+ // TODO: try to resolve equations with a degree superior than 2.
577
+ this._solutions = [{ tex: 'solve x - not yet handled', value: NaN, exact: false }]; // ESLint remove system :(
578
+ return this._solutions;
579
+ };
580
+ // Default equation
16
581
  this._left = new polynom_1.Polynom().zero();
17
582
  this._right = new polynom_1.Polynom().zero();
18
583
  this._sign = '=';
@@ -39,16 +604,39 @@ class Equation {
39
604
  }
40
605
  }
41
606
  else {
607
+ // Return default empty equation
42
608
  return this;
43
609
  }
44
610
  return this;
45
611
  }
46
- get isEquation() {
47
- return true;
612
+ get left() {
613
+ return this._left;
48
614
  }
615
+ set left(value) {
616
+ this._left = value;
617
+ }
618
+ get right() {
619
+ return this._right;
620
+ }
621
+ // ------------------------------------------
622
+ // Getter and setter
623
+ set right(value) {
624
+ this._right = value;
625
+ }
626
+ get sign() {
627
+ return this._sign;
628
+ }
629
+ set sign(value) {
630
+ // Set the sign value as formatted.
631
+ this._sign = this._formatSign(value);
632
+ }
633
+ // ------------------------------------------
49
634
  get solutions() {
50
635
  return this._solutions;
51
636
  }
637
+ get isEquation() {
638
+ return true;
639
+ }
52
640
  get solution() {
53
641
  if (this._solutions.length === 1
54
642
  &&
@@ -95,505 +683,12 @@ class Equation {
95
683
  get numberOfVars() {
96
684
  return this.variables.length;
97
685
  }
98
- get left() {
99
- return this._left;
100
- }
101
- set left(value) {
102
- this._left = value;
103
- }
104
- get right() {
105
- return this._right;
106
- }
107
- set right(value) {
108
- this._right = value;
109
- }
110
- get sign() {
111
- return this._sign;
112
- }
113
- set sign(value) {
114
- this._sign = this._formatSign(value);
115
- }
116
- parse = (equationString) => {
117
- let pStr, strSign;
118
- strSign = this._findSign(equationString);
119
- if (strSign === false) {
120
- console.error('The equation is not valid (no sign found)');
121
- return;
122
- }
123
- pStr = equationString.split(strSign);
124
- return this.create(new polynom_1.Polynom(pStr[0]), new polynom_1.Polynom(pStr[1]), this._formatSign(strSign));
125
- };
126
- _findSign = (equationString) => {
127
- let strSign = '';
128
- if (equationString.includes('geq')) {
129
- return (equationString.includes('\\geq')) ? '\\geq' : 'geq';
130
- }
131
- else if (equationString.includes('leq')) {
132
- return (equationString.includes('\\leq')) ? '\\leq' : 'leq';
133
- }
134
- else if (equationString.includes('>=')) {
135
- return '>=';
136
- }
137
- else if (equationString.includes('=>')) {
138
- return '=>';
139
- }
140
- else if (equationString.includes('>')) {
141
- return '>';
142
- }
143
- else if (equationString.includes('<=')) {
144
- return '<=';
145
- }
146
- else if (equationString.includes('=<')) {
147
- return '=<';
148
- }
149
- else if (equationString.includes('<')) {
150
- return '<';
151
- }
152
- else if (equationString.includes('=')) {
153
- return '=';
154
- }
155
- if (strSign === '') {
156
- console.log('Equation: parse string : sign not found');
157
- return false;
158
- }
159
- };
160
- _formatSign = (signStr) => {
161
- if (signStr === undefined) {
162
- return '=';
163
- }
164
- if (signStr.includes('geq')) {
165
- return '>=';
166
- }
167
- else if (signStr.includes('>=')) {
168
- return '>=';
169
- }
170
- else if (signStr.includes('=>')) {
171
- return '>=';
172
- }
173
- else if (signStr.includes('>')) {
174
- return '>';
175
- }
176
- else if (signStr.includes('leq')) {
177
- return '<=';
178
- }
179
- else if (signStr.includes('<=')) {
180
- return '<=';
181
- }
182
- else if (signStr.includes('=<')) {
183
- return '<=';
184
- }
185
- else if (signStr.includes('<')) {
186
- return '<';
187
- }
188
- else {
189
- return '=';
190
- }
191
- };
192
- _reverseSign = () => {
193
- if (this._sign === '=') {
194
- return this;
195
- }
196
- if (this._sign.includes('<')) {
197
- this._sign.replace('<', '>');
198
- return this;
199
- }
200
- if (this._sign.includes('>')) {
201
- this._sign.replace('>', '<');
202
- return this;
203
- }
204
- return this;
205
- };
206
- create = (left, right, sign) => {
207
- this._left = left;
208
- this._right = right;
209
- this._sign = this._formatSign(sign);
210
- return this;
211
- };
212
- clone = () => {
213
- return new Equation().create(this._left.clone(), this._right.clone(), this._sign + '');
214
- };
215
- _randomizeDefaults = {
216
- degree: 2
217
- };
218
686
  get randomizeDefaults() {
219
687
  return this._randomizeDefaults;
220
688
  }
221
689
  set randomizeDefaults(value) {
222
690
  this._randomizeDefaults = value;
223
691
  }
224
- randomize = (opts, sign) => {
225
- return new Equation().create(new polynom_1.Polynom(), new polynom_1.Polynom(), sign);
226
- };
227
- moveLeft = () => {
228
- this._left = this._left.clone().subtract(this._right);
229
- this._right.zero();
230
- return this;
231
- };
232
- reorder = (allLeft) => {
233
- this._left.subtract(this._right);
234
- this._right.zero();
235
- if (allLeft) {
236
- return this.moveLeft();
237
- }
238
- let mMove;
239
- for (let m of this._left.monoms) {
240
- if (m.degree().isZero()) {
241
- mMove = m.clone();
242
- this._left.subtract(mMove);
243
- this._right.subtract(mMove);
244
- }
245
- }
246
- this._left.reorder();
247
- this._right.reorder();
248
- return this;
249
- };
250
- simplify = () => {
251
- this.multiply(numeric_1.Numeric.lcm(...this._left.getDenominators(), ...this._right.getDenominators()));
252
- this.divide(numeric_1.Numeric.gcd(...this._left.getNumerators(), ...this._right.getNumerators()));
253
- return this;
254
- };
255
- isolate = (letter) => {
256
- if (!this.degree(letter).isOne()) {
257
- return false;
258
- }
259
- if (this.isMultiVariable()) {
260
- return false;
261
- }
262
- let mMove, cMove;
263
- this._left.subtract(this._right);
264
- this._right.zero();
265
- for (let m of this._left.monoms) {
266
- if (!m.hasLetter(letter)) {
267
- mMove = m.clone();
268
- this._left.add(mMove.clone().opposed());
269
- this._right.add(mMove.clone().opposed());
270
- }
271
- }
272
- if (this._left.length !== 1) {
273
- return false;
274
- }
275
- cMove = this._left.monoms[0].coefficient.clone();
276
- this._left.divide(cMove);
277
- this._right.divide(cMove);
278
- return this;
279
- };
280
- replaceBy = (letter, P) => {
281
- this._left.replaceBy(letter, P);
282
- this._right.replaceBy(letter, P);
283
- return this;
284
- };
285
- multiply = (value) => {
286
- let F = new coefficients_1.Fraction(value);
287
- this._left.multiply(F);
288
- this._right.multiply(F);
289
- if (this._sign !== '=' && F.sign() === -1) {
290
- this._reverseSign();
291
- }
292
- return this;
293
- };
294
- divide = (value) => {
295
- let F = new coefficients_1.Fraction(value);
296
- if (F.isZero()) {
297
- return this;
298
- }
299
- else {
300
- return this.multiply(F.invert());
301
- }
302
- };
303
- degree = (letter) => {
304
- return coefficients_1.Fraction.max(this._left.degree(letter), this._right.degree(letter));
305
- };
306
- isMultiVariable = () => {
307
- return this._left.isMultiVariable || this._right.isMultiVariable;
308
- };
309
- letters = () => {
310
- return [...new Set([...this._left.letters(), ...this._right.letters()])];
311
- };
312
- solve = () => {
313
- this._solutions = [];
314
- this._polynom = this._left.clone().subtract(this._right);
315
- switch (this._polynom.degree().value) {
316
- case 0:
317
- case 1:
318
- this._solveDegree1();
319
- break;
320
- case 2:
321
- this._solveDegree2();
322
- break;
323
- default:
324
- this._solveDegree3plus();
325
- }
326
- return this;
327
- };
328
- isGreater = () => {
329
- if (this._sign.indexOf('>') !== -1) {
330
- return true;
331
- }
332
- return this._sign.indexOf('geq') !== -1;
333
- };
334
- isStrictEqual = () => {
335
- return this._sign === '=';
336
- };
337
- isAlsoEqual = () => {
338
- if (this._sign.indexOf('=') !== -1) {
339
- return true;
340
- }
341
- if (this._sign.indexOf('geq') !== -1) {
342
- return true;
343
- }
344
- if (this._sign.indexOf('leq') !== -1) {
345
- return true;
346
- }
347
- };
348
- _solveDegree1 = (letter) => {
349
- const m1 = this._polynom.monomByDegree(1, letter).coefficient, m0 = this._polynom.monomByDegree(0, letter).coefficient, v = m0.clone().opposed().divide(m1);
350
- let s;
351
- if (this.isStrictEqual()) {
352
- if (m1.value === 0) {
353
- if (m0.value === 0) {
354
- this._solutions = [{
355
- tex: this._real,
356
- value: NaN,
357
- exact: false
358
- }];
359
- }
360
- else {
361
- this._solutions = [{
362
- tex: this._varnothing,
363
- value: NaN,
364
- exact: false
365
- }];
366
- }
367
- }
368
- else {
369
- this._solutions = [{
370
- tex: v.display,
371
- value: v.value,
372
- exact: v
373
- }];
374
- }
375
- }
376
- else {
377
- if (m1.value === 0) {
378
- if (m0.value === 0 && this.isAlsoEqual()) {
379
- s = '\\mathbb{R}';
380
- }
381
- else {
382
- if (m0.value > 0) {
383
- s = this.isGreater() ? this._real : this._varnothing;
384
- }
385
- else {
386
- s = !this.isGreater() ? this._real : this._varnothing;
387
- }
388
- }
389
- }
390
- else {
391
- if ((this.isGreater() && m1.sign() === 1) || (!this.isGreater() && m1.sign() === -1)) {
392
- s = `\\left${this.isAlsoEqual() ? '\\[' : '\\]'}${v};+\\infty\\right\\[`;
393
- }
394
- else {
395
- s = `\\left\\]-\\infty;${v} \\right\\${this.isAlsoEqual() ? '\\]' : '\\['}`;
396
- }
397
- }
398
- this._solutions = [{
399
- tex: s,
400
- value: NaN,
401
- exact: false
402
- }];
403
- }
404
- return this._solutions;
405
- };
406
- _solveDegree2 = (letter) => {
407
- let aF = this._polynom.monomByDegree(2, letter).coefficient, bF = this._polynom.monomByDegree(1, letter).coefficient, cF = this._polynom.monomByDegree(0, letter).coefficient, delta, nthDelta, lcm = numeric_1.Numeric.lcm(aF.denominator, bF.denominator, cF.denominator), a = aF.multiply(lcm).value, b = bF.multiply(lcm).value, c = cF.multiply(lcm).value, realX1, realX2, sX1, sX2;
408
- delta = b * b - 4 * a * c;
409
- if (delta > 0) {
410
- realX1 = (-b - Math.sqrt(delta)) / (2 * a);
411
- realX2 = (-b + Math.sqrt(delta)) / (2 * a);
412
- if (delta > 1.0e5) {
413
- this._solutions = [
414
- {
415
- tex: ((-b - Math.sqrt(delta)) / (2 * a)).toFixed(5),
416
- value: realX1,
417
- exact: false
418
- },
419
- {
420
- tex: ((-b + Math.sqrt(delta)) / (2 * a)).toFixed(5),
421
- value: realX2,
422
- exact: false
423
- }
424
- ];
425
- }
426
- else {
427
- nthDelta = new coefficients_1.Nthroot(delta).reduce();
428
- if (nthDelta.hasRadical()) {
429
- let gcd = numeric_1.Numeric.gcd(b, 2 * a, nthDelta.coefficient);
430
- nthDelta.coefficient = nthDelta.coefficient / gcd;
431
- if (b !== 0) {
432
- if (2 * a / gcd === 1) {
433
- this._solutions = [
434
- {
435
- tex: `${-b / gcd} - ${nthDelta.tex}`,
436
- value: realX1,
437
- exact: false
438
- },
439
- {
440
- tex: `${-b / gcd} + ${nthDelta.tex}`,
441
- value: realX2,
442
- exact: false
443
- },
444
- ];
445
- }
446
- else {
447
- this._solutions = [
448
- {
449
- tex: `\\dfrac{${-b / gcd} - ${nthDelta.tex} }{ ${2 * a / gcd} }`,
450
- value: realX1,
451
- exact: false
452
- },
453
- {
454
- tex: `\\dfrac{${-b / gcd} + ${nthDelta.tex} }{ ${2 * a / gcd} }`,
455
- value: realX2,
456
- exact: false
457
- },
458
- ];
459
- }
460
- }
461
- else {
462
- if (2 * a / gcd === 1) {
463
- this._solutions = [
464
- {
465
- tex: `- ${nthDelta.tex}`,
466
- value: realX1,
467
- exact: false
468
- },
469
- {
470
- tex: `${nthDelta.tex}`,
471
- value: realX2,
472
- exact: false
473
- },
474
- ];
475
- }
476
- else {
477
- this._solutions = [
478
- {
479
- tex: `\\dfrac{- ${nthDelta.tex} }{ ${2 * a / gcd} }`,
480
- value: realX1,
481
- exact: false
482
- },
483
- {
484
- tex: `\\dfrac{${nthDelta.tex} }{ ${2 * a / gcd} }`,
485
- value: realX2,
486
- exact: false
487
- },
488
- ];
489
- }
490
- }
491
- }
492
- else {
493
- const S1 = new coefficients_1.Fraction(-b - nthDelta.coefficient, 2 * a).reduce(), S2 = new coefficients_1.Fraction(-b + nthDelta.coefficient, 2 * a).reduce();
494
- this._solutions = [
495
- {
496
- tex: S1.dfrac,
497
- value: realX1,
498
- exact: S1
499
- },
500
- {
501
- tex: S2.dfrac,
502
- value: realX2,
503
- exact: S2
504
- }
505
- ];
506
- }
507
- }
508
- }
509
- else if (delta === 0) {
510
- const sol = new coefficients_1.Fraction(-b, 2 * a).reduce();
511
- this._solutions = [{
512
- tex: sol.dfrac,
513
- value: sol.value,
514
- exact: sol
515
- }];
516
- }
517
- else {
518
- this._solutions = [{
519
- tex: this._varnothing,
520
- value: NaN,
521
- exact: false
522
- }];
523
- }
524
- if (!this.isStrictEqual()) {
525
- if (this._solutions.length === 2) {
526
- sX1 = (realX1 < realX2) ? this._solutions[0].tex : this._solutions[1].tex;
527
- sX2 = (realX1 < realX2) ? this._solutions[1].tex : this._solutions[0].tex;
528
- if ((this.isGreater() && aF.sign() === 1) || (!this.isGreater() && aF.sign() === -1)) {
529
- this._solutions = [{
530
- tex: `\\left]-\\infty ; ${sX1}\\right${this.isAlsoEqual() ? ']' : '['} \\cup \\left${this.isAlsoEqual() ? '[' : ']'}${sX2};+\\infty\\right[`,
531
- value: NaN,
532
- exact: false
533
- }
534
- ];
535
- }
536
- else {
537
- this._solutions = [{
538
- tex: `\\left${this.isAlsoEqual() ? '[' : ']'}${sX1} ; ${sX2}\\right${this.isAlsoEqual() ? ']' : '['}`,
539
- value: NaN,
540
- exact: false
541
- }];
542
- }
543
- }
544
- else if (this._solutions.length === 1 && this._solutions[0].tex !== this._varnothing) {
545
- if (!this.isAlsoEqual()) {
546
- if ((this.isGreater() && aF.sign() === 1) || (!this.isGreater() && aF.sign() === -1)) {
547
- this._solutions = [{
548
- tex: `\\left]-\\infty ; ${this._solutions[0].tex}\\right[ \\cup \\left]${this._solutions[0].tex};+\\infty\\right[`,
549
- value: NaN,
550
- exact: false
551
- }
552
- ];
553
- }
554
- else {
555
- this._solutions = [{
556
- tex: this._varnothing,
557
- value: NaN,
558
- exact: false
559
- }];
560
- }
561
- }
562
- else {
563
- if ((this.isGreater() && aF.sign() === 1) || (!this.isGreater() && aF.sign() === -1)) {
564
- this._solutions = [{
565
- tex: this._real,
566
- value: NaN,
567
- exact: false
568
- }];
569
- }
570
- else {
571
- }
572
- }
573
- }
574
- else {
575
- if (this.isGreater()) {
576
- this._solutions = [{
577
- tex: aF.sign() === 1 ? this._real : this._varnothing,
578
- value: NaN,
579
- exact: false
580
- }];
581
- }
582
- else {
583
- this._solutions = [{
584
- tex: aF.sign() === -1 ? this._real : this._varnothing,
585
- value: NaN,
586
- exact: false
587
- }];
588
- }
589
- }
590
- }
591
- return this._solutions;
592
- };
593
- _solveDegree3plus = () => {
594
- this._solutions = [{ tex: 'solve x - not yet handled', value: NaN, exact: false }];
595
- return this._solutions;
596
- };
597
692
  }
598
693
  exports.Equation = Equation;
599
694
  //# sourceMappingURL=equation.js.map