pimath 0.0.28 → 0.0.32
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.
- package/dev/pi.js +864 -487
- package/dev/pi.js.map +1 -1
- package/dist/pi.js +1 -1
- package/dist/pi.js.map +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/algebra.Equation.html +9 -9
- package/docs/classes/algebra.LinearSystem.html +1 -1
- package/docs/classes/algebra.Logicalset.html +2 -2
- package/docs/classes/algebra.Monom.html +42 -40
- package/docs/classes/algebra.Polynom.html +10 -10
- package/docs/classes/algebra.PolynomExpFactor.html +1 -0
- package/docs/classes/algebra.PolynomExpProduct.html +1 -0
- package/docs/classes/algebra.Rational.html +2 -2
- package/docs/classes/coefficients.Fraction.html +4 -4
- package/docs/classes/coefficients.Nthroot.html +1 -1
- package/docs/classes/geometry.Circle.html +2 -2
- package/docs/classes/geometry.Line.html +2 -2
- package/docs/classes/geometry.Point.html +1 -1
- package/docs/classes/geometry.Triangle.html +6 -6
- package/docs/classes/geometry.Vector.html +1 -1
- package/docs/classes/numeric.Numeric.html +5 -5
- package/docs/classes/shutingyard.Shutingyard.html +7 -8
- package/docs/enums/shutingyard.ShutingyardMode.html +1 -0
- package/docs/enums/shutingyard.ShutingyardType.html +1 -0
- package/docs/index.html +1 -1
- package/docs/interfaces/geometry.remarquableLines.html +1 -1
- package/docs/modules/algebra.html +1 -1
- package/docs/modules/coefficients.html +1 -1
- package/docs/modules/geometry.html +1 -1
- package/docs/modules/numeric.html +1 -1
- package/docs/modules/random.Random.html +1 -1
- package/docs/modules/random.html +1 -1
- package/docs/modules/shutingyard.html +1 -1
- package/docs/modules.html +1 -1
- package/esm/main.js +3 -1
- package/esm/main.js.map +1 -1
- package/esm/maths/algebra/equation.js +1 -1
- package/esm/maths/algebra/equation.js.map +1 -1
- package/esm/maths/algebra/index.d.ts +1 -0
- package/esm/maths/algebra/index.js +1 -0
- package/esm/maths/algebra/index.js.map +1 -1
- package/esm/maths/algebra/monom.d.ts +4 -1
- package/esm/maths/algebra/monom.js +52 -37
- package/esm/maths/algebra/monom.js.map +1 -1
- package/esm/maths/algebra/polynom.d.ts +19 -15
- package/esm/maths/algebra/polynom.js +242 -174
- package/esm/maths/algebra/polynom.js.map +1 -1
- package/esm/maths/coefficients/fraction.d.ts +3 -0
- package/esm/maths/coefficients/fraction.js +21 -8
- package/esm/maths/coefficients/fraction.js.map +1 -1
- package/esm/maths/{numexp.d.ts → expressions/numexp.d.ts} +3 -0
- package/esm/maths/{numexp.js → expressions/numexp.js} +46 -15
- package/esm/maths/expressions/numexp.js.map +1 -0
- package/esm/maths/expressions/polynomexp.bkp.d.ts +33 -0
- package/esm/maths/expressions/polynomexp.bkp.js +186 -0
- package/esm/maths/expressions/polynomexp.bkp.js.map +1 -0
- package/esm/maths/expressions/polynomexp.d.ts +52 -0
- package/esm/maths/expressions/polynomexp.js +233 -0
- package/esm/maths/expressions/polynomexp.js.map +1 -0
- package/esm/maths/geometry/line.d.ts +4 -2
- package/esm/maths/geometry/line.js +6 -2
- package/esm/maths/geometry/line.js.map +1 -1
- package/esm/maths/geometry/vector.js +7 -2
- package/esm/maths/geometry/vector.js.map +1 -1
- package/esm/maths/shutingyard.d.ts +7 -7
- package/esm/maths/shutingyard.js +5 -7
- package/esm/maths/shutingyard.js.map +1 -1
- package/package.json +1 -1
- package/{dev → public}/demo.css +0 -0
- package/{dev → public}/index.html +48 -14
- package/{dev → public}/playground.html +1 -1
- package/src/main.ts +13 -2
- package/src/maths/algebra/equation.ts +1 -1
- package/src/maths/algebra/index.ts +2 -1
- package/src/maths/algebra/monom.ts +71 -49
- package/src/maths/algebra/polynom.ts +432 -309
- package/src/maths/coefficients/fraction.ts +28 -11
- package/src/maths/{numexp.ts → expressions/numexp.ts} +42 -20
- package/src/maths/expressions/polynomexp.bkp.ts +223 -0
- package/src/maths/expressions/polynomexp.ts +309 -0
- package/src/maths/geometry/line.ts +7 -2
- package/src/maths/geometry/vector.ts +10 -2
- package/src/maths/shutingyard.ts +15 -64
- package/tests/algebra/monom.test.ts +12 -8
- package/tests/algebra/polynom.test.ts +28 -2
- package/tests/numexp.test.ts +34 -0
- package/tests/polynomexp.test.ts +15 -0
- package/tests/shutingyard.test.ts +4 -4
- package/tsconfig.json +0 -1
- package/esm/docs.d.ts +0 -6
- package/esm/docs.js +0 -7
- package/esm/docs.js.map +0 -1
- package/esm/maths/numexp.js.map +0 -1
- package/esm/maths/random/random.d.ts +0 -13
- package/esm/maths/random/random.js +0 -27
- package/esm/maths/random/random.js.map +0 -1
|
@@ -3,11 +3,12 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import {literalType, Monom} from './monom';
|
|
6
|
-
import {Shutingyard} from '../shutingyard';
|
|
6
|
+
import {Shutingyard, ShutingyardType, Token} from '../shutingyard';
|
|
7
7
|
import {Numeric} from '../numeric';
|
|
8
|
-
import {Random, randomPolynomConfig} from "../random";
|
|
9
8
|
import {Fraction} from "../coefficients";
|
|
9
|
+
import {log} from "util";
|
|
10
10
|
|
|
11
|
+
export type PolynomParsingType = string|Polynom|number|Fraction|Monom
|
|
11
12
|
/**
|
|
12
13
|
* Polynom class can handle polynoms, reorder, resolve, ...
|
|
13
14
|
* ```
|
|
@@ -16,16 +17,13 @@ import {Fraction} from "../coefficients";
|
|
|
16
17
|
*/
|
|
17
18
|
export class Polynom {
|
|
18
19
|
private _rawString: string;
|
|
19
|
-
private _monoms: Monom[];
|
|
20
|
-
private _factors: Polynom[];
|
|
21
|
-
private _texString: string;
|
|
22
20
|
|
|
23
21
|
/**
|
|
24
22
|
*
|
|
25
23
|
* @param {string} polynomString (optional) Default polynom to parse on class creation
|
|
26
24
|
* @param values
|
|
27
25
|
*/
|
|
28
|
-
constructor(polynomString?:
|
|
26
|
+
constructor(polynomString?: PolynomParsingType, ...values: unknown[]) {
|
|
29
27
|
this._monoms = [];
|
|
30
28
|
this._factors = [];
|
|
31
29
|
if (polynomString !== undefined) {
|
|
@@ -34,8 +32,8 @@ export class Polynom {
|
|
|
34
32
|
return this;
|
|
35
33
|
}
|
|
36
34
|
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
private _monoms: Monom[];
|
|
36
|
+
|
|
39
37
|
// ------------------------------------------
|
|
40
38
|
get monoms() {
|
|
41
39
|
return this._monoms;
|
|
@@ -45,6 +43,11 @@ export class Polynom {
|
|
|
45
43
|
this._monoms = M;
|
|
46
44
|
}
|
|
47
45
|
|
|
46
|
+
// ------------------------------------------
|
|
47
|
+
// Getter and setter
|
|
48
|
+
|
|
49
|
+
private _factors: Polynom[];
|
|
50
|
+
|
|
48
51
|
get factors(): Polynom[] {
|
|
49
52
|
return this._factors;
|
|
50
53
|
}
|
|
@@ -53,6 +56,12 @@ export class Polynom {
|
|
|
53
56
|
this._factors = value;
|
|
54
57
|
}
|
|
55
58
|
|
|
59
|
+
private _texString: string;
|
|
60
|
+
|
|
61
|
+
get texString(): string {
|
|
62
|
+
return this._texString;
|
|
63
|
+
}
|
|
64
|
+
|
|
56
65
|
get texFactors(): string {
|
|
57
66
|
this.factorize()
|
|
58
67
|
|
|
@@ -67,10 +76,6 @@ export class Polynom {
|
|
|
67
76
|
return tex;
|
|
68
77
|
}
|
|
69
78
|
|
|
70
|
-
get texString(): string {
|
|
71
|
-
return this._texString;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
79
|
get length() {
|
|
75
80
|
// TODO: Must reduce the monoms list to remove the zero coefficient.
|
|
76
81
|
return this._monoms.length;
|
|
@@ -115,47 +120,36 @@ export class Polynom {
|
|
|
115
120
|
return this.variables.length;
|
|
116
121
|
}
|
|
117
122
|
|
|
118
|
-
private genDisplay = (output?: string, forceSign?: boolean, wrapParentheses?: boolean): string => {
|
|
119
|
-
let P: string = '';
|
|
120
|
-
|
|
121
|
-
for (const k of this._monoms) {
|
|
122
|
-
if (k.coefficient.value === 0) {
|
|
123
|
-
continue;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
P += `${(k.coefficient.sign() === 1 && (P !== '' || forceSign === true)) ? '+' : ''}${(output === 'tex') ? k.tex : k.display}`;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
if (wrapParentheses === true && this.length > 1) {
|
|
130
|
-
if (output === 'tex') {
|
|
131
|
-
P = `\\left( ${P} \\right)`;
|
|
132
|
-
} else {
|
|
133
|
-
P = `(${P})`;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
if (P === '') {
|
|
138
|
-
P = '0';
|
|
139
|
-
}
|
|
140
|
-
return P;
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
// ------------------------------------------
|
|
145
|
-
// Creation / parsing functions
|
|
146
123
|
// ------------------------------------------
|
|
147
124
|
/**
|
|
148
125
|
* Parse a string to a polynom.
|
|
149
126
|
* @param inputStr
|
|
150
127
|
* @param values: as string, numbers or fractions
|
|
151
128
|
*/
|
|
152
|
-
parse = (inputStr:
|
|
129
|
+
parse = (inputStr: PolynomParsingType, ...values: unknown[]): Polynom => {
|
|
130
|
+
// Reset the main variables.
|
|
131
|
+
this._monoms = []
|
|
132
|
+
this._factors = []
|
|
133
|
+
|
|
134
|
+
if(typeof inputStr === 'string') {
|
|
135
|
+
return this._parseString(inputStr, ...values)
|
|
136
|
+
}else if(typeof inputStr === 'number' || inputStr instanceof Fraction || inputStr instanceof Monom){
|
|
137
|
+
this._monoms.push(new Monom(inputStr))
|
|
138
|
+
}else if(inputStr instanceof Polynom){
|
|
139
|
+
for(const m of inputStr.monoms){
|
|
140
|
+
this._monoms.push(m.clone())
|
|
141
|
+
}
|
|
142
|
+
}
|
|
153
143
|
|
|
144
|
+
return this
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
private _parseString(inputStr: string, ...values:unknown[]): Polynom{
|
|
154
148
|
if (values === undefined || values.length === 0) {
|
|
155
149
|
inputStr = '' + inputStr;
|
|
156
150
|
this._rawString = inputStr;
|
|
157
151
|
|
|
158
|
-
// Parse the polynom using the
|
|
152
|
+
// Parse the polynom using the shutting yard algorithm
|
|
159
153
|
if (inputStr !== '' && !isNaN(Number(inputStr))) {
|
|
160
154
|
this.empty();
|
|
161
155
|
// It's a simple number.
|
|
@@ -201,52 +195,11 @@ export class Polynom {
|
|
|
201
195
|
} else {
|
|
202
196
|
return this.zero();
|
|
203
197
|
}
|
|
198
|
+
}
|
|
204
199
|
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Main parse using a shutting yard class
|
|
209
|
-
* @param inputStr
|
|
210
|
-
*/
|
|
211
|
-
private shutingYardToReducedPolynom = (inputStr: string): Polynom => {
|
|
212
|
-
// Get the RPN array of the current expression
|
|
213
|
-
const SY: Shutingyard = new Shutingyard().parse(inputStr);
|
|
214
|
-
const rpn: { token: string, tokenType: string }[] = SY.rpn;
|
|
215
|
-
let m1: Polynom;
|
|
216
|
-
let m2: Polynom;
|
|
217
|
-
|
|
218
|
-
let stack: Polynom[] = [],
|
|
219
|
-
previousToken: string = null,
|
|
220
|
-
tempPolynom
|
|
221
|
-
|
|
222
|
-
for (const element of rpn) {
|
|
223
|
-
if (element.tokenType === 'coefficient' || element.tokenType === 'variable') {
|
|
224
|
-
tempPolynom = new Polynom().zero();
|
|
225
|
-
tempPolynom.monoms = [new Monom(element.token)]
|
|
226
|
-
stack.push(tempPolynom.clone())
|
|
227
|
-
} else if (element.tokenType === 'operation') {
|
|
228
|
-
m2 = (stack.pop()) || new Polynom().zero();
|
|
229
|
-
m1 = (stack.pop()) || new Polynom().zero();
|
|
230
|
-
switch (element.token) {
|
|
231
|
-
case '+':
|
|
232
|
-
stack.push(m1.add(m2))
|
|
233
|
-
break;
|
|
234
|
-
case '-':
|
|
235
|
-
stack.push(m1.subtract(m2))
|
|
236
|
-
break;
|
|
237
|
-
case '*':
|
|
238
|
-
stack.push(m1.multiply(m2))
|
|
239
|
-
break;
|
|
240
|
-
case '^':
|
|
241
|
-
stack.push(m1.pow(+previousToken))
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
previousToken = element.token;
|
|
245
|
-
}
|
|
246
200
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
}
|
|
201
|
+
// ------------------------------------------
|
|
202
|
+
// Creation / parsing functions
|
|
250
203
|
|
|
251
204
|
/**
|
|
252
205
|
* Clone the polynom
|
|
@@ -287,6 +240,29 @@ export class Polynom {
|
|
|
287
240
|
return this;
|
|
288
241
|
};
|
|
289
242
|
|
|
243
|
+
// ------------------------------------------
|
|
244
|
+
opposed = (): Polynom => {
|
|
245
|
+
this._monoms = this._monoms.map(m => m.opposed());
|
|
246
|
+
return this;
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
add = (...values: unknown[]): Polynom => {
|
|
250
|
+
|
|
251
|
+
for (let value of values) {
|
|
252
|
+
if (value instanceof Polynom) {
|
|
253
|
+
this._monoms = this._monoms.concat(value.monoms);
|
|
254
|
+
} else if (value instanceof Monom) {
|
|
255
|
+
this._monoms.push(value.clone());
|
|
256
|
+
} else if (Number.isSafeInteger(value)) {
|
|
257
|
+
this._monoms.push(new Monom(value.toString()));
|
|
258
|
+
} else {
|
|
259
|
+
this._monoms.push(new Monom(value));
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return this.reduce();
|
|
264
|
+
};
|
|
265
|
+
|
|
290
266
|
// // -----------------------------------------------
|
|
291
267
|
// // Polynom generators and randomizers
|
|
292
268
|
// // -----------------------------------------------
|
|
@@ -351,28 +327,6 @@ export class Polynom {
|
|
|
351
327
|
|
|
352
328
|
// ------------------------------------------
|
|
353
329
|
// Mathematical operations
|
|
354
|
-
// ------------------------------------------
|
|
355
|
-
opposed = (): Polynom => {
|
|
356
|
-
this._monoms = this._monoms.map(m => m.opposed());
|
|
357
|
-
return this;
|
|
358
|
-
};
|
|
359
|
-
|
|
360
|
-
add = (...values: unknown[]): Polynom => {
|
|
361
|
-
|
|
362
|
-
for (let value of values) {
|
|
363
|
-
if (value instanceof Polynom) {
|
|
364
|
-
this._monoms = this._monoms.concat(value.monoms);
|
|
365
|
-
} else if (value instanceof Monom) {
|
|
366
|
-
this._monoms.push(value.clone());
|
|
367
|
-
} else if (Number.isSafeInteger(value)) {
|
|
368
|
-
this._monoms.push(new Monom(value.toString()));
|
|
369
|
-
} else {
|
|
370
|
-
this._monoms.push(new Monom(value));
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
return this.reduce();
|
|
375
|
-
};
|
|
376
330
|
|
|
377
331
|
subtract = (...values: unknown[]): Polynom => {
|
|
378
332
|
|
|
@@ -398,7 +352,7 @@ export class Polynom {
|
|
|
398
352
|
return this.multiplyByFraction(value);
|
|
399
353
|
} else if (value instanceof Monom) {
|
|
400
354
|
return this.multiplyByMonom(value);
|
|
401
|
-
} else if (Number.isSafeInteger(value) && typeof value==='number') {
|
|
355
|
+
} else if (Number.isSafeInteger(value) && typeof value === 'number') {
|
|
402
356
|
return this.multiplyByInteger(value);
|
|
403
357
|
}
|
|
404
358
|
|
|
@@ -406,37 +360,6 @@ export class Polynom {
|
|
|
406
360
|
return this;
|
|
407
361
|
}
|
|
408
362
|
|
|
409
|
-
private multiplyByPolynom = (P: Polynom): Polynom => {
|
|
410
|
-
const M: Monom[] = [];
|
|
411
|
-
for (const m1 of this._monoms) {
|
|
412
|
-
for (const m2 of P.monoms) {
|
|
413
|
-
M.push(Monom.xmultiply(m1, m2));
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
this._monoms = M;
|
|
418
|
-
return this.reduce();
|
|
419
|
-
};
|
|
420
|
-
|
|
421
|
-
private multiplyByFraction = (F: Fraction): Polynom => {
|
|
422
|
-
for (const m of this._monoms) {
|
|
423
|
-
m.coefficient.multiply(F);
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
return this.reduce();
|
|
427
|
-
};
|
|
428
|
-
|
|
429
|
-
private multiplyByInteger = (nb: number): Polynom => {
|
|
430
|
-
return this.multiplyByFraction(new Fraction(nb));
|
|
431
|
-
};
|
|
432
|
-
|
|
433
|
-
private multiplyByMonom = (M: Monom): Polynom => {
|
|
434
|
-
for (const m of this._monoms) {
|
|
435
|
-
m.multiply(M)
|
|
436
|
-
}
|
|
437
|
-
return this.reduce();
|
|
438
|
-
};
|
|
439
|
-
|
|
440
363
|
/**
|
|
441
364
|
* Divide the current polynom by another polynom.
|
|
442
365
|
* @param P
|
|
@@ -476,31 +399,19 @@ export class Polynom {
|
|
|
476
399
|
reminder.subtract(P.clone().multiply(newM));
|
|
477
400
|
}
|
|
478
401
|
|
|
402
|
+
quotient.reduce()
|
|
403
|
+
reminder.reduce()
|
|
479
404
|
return {quotient, reminder};
|
|
480
405
|
};
|
|
481
406
|
|
|
482
407
|
divide = (value: unknown): Polynom => {
|
|
483
408
|
if (value instanceof Fraction) {
|
|
484
|
-
this.divideByFraction(value);
|
|
485
|
-
} else if (typeof value==='number' && Number.isSafeInteger(value)) {
|
|
409
|
+
return this.divideByFraction(value);
|
|
410
|
+
} else if (typeof value === 'number' && Number.isSafeInteger(value)) {
|
|
486
411
|
return this.divideByInteger(value);
|
|
487
412
|
}
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
private divideByInteger = (nb: number): Polynom => {
|
|
491
|
-
const nbF = new Fraction(nb);
|
|
492
|
-
for (const m of this._monoms) {
|
|
493
|
-
m.coefficient.divide(nbF);
|
|
494
|
-
}
|
|
495
|
-
return this;
|
|
496
|
-
};
|
|
497
413
|
|
|
498
|
-
|
|
499
|
-
for (const m of this._monoms) {
|
|
500
|
-
m.coefficient.divide(F);
|
|
501
|
-
}
|
|
502
|
-
return this;
|
|
503
|
-
};
|
|
414
|
+
}
|
|
504
415
|
|
|
505
416
|
pow = (nb: number): Polynom => {
|
|
506
417
|
if (!Number.isSafeInteger(nb)) {
|
|
@@ -520,9 +431,6 @@ export class Polynom {
|
|
|
520
431
|
return this.reduce();
|
|
521
432
|
};
|
|
522
433
|
|
|
523
|
-
|
|
524
|
-
// ------------------------------------------
|
|
525
|
-
// Compare functions
|
|
526
434
|
// ------------------------------------------
|
|
527
435
|
/**
|
|
528
436
|
* Compare the current coefficient with another coefficient
|
|
@@ -686,8 +594,11 @@ export class Polynom {
|
|
|
686
594
|
// TODO: Maybe it's enough to just make this test !
|
|
687
595
|
return polynomStringNormalized === P.reduce().reorder().display
|
|
688
596
|
}
|
|
597
|
+
|
|
598
|
+
|
|
689
599
|
// ------------------------------------------
|
|
690
|
-
//
|
|
600
|
+
// Compare functions
|
|
601
|
+
|
|
691
602
|
// -------------------------------------
|
|
692
603
|
reduce = (): Polynom => {
|
|
693
604
|
for (let i = 0; i < this._monoms.length; i++) {
|
|
@@ -777,6 +688,7 @@ export class Polynom {
|
|
|
777
688
|
//console.log('Evaluate polynom: ', monom.display, values, monom.evaluate(values).display);
|
|
778
689
|
r.add(monom.evaluate(values));
|
|
779
690
|
});
|
|
691
|
+
|
|
780
692
|
return r;
|
|
781
693
|
};
|
|
782
694
|
|
|
@@ -798,6 +710,8 @@ export class Polynom {
|
|
|
798
710
|
}
|
|
799
711
|
return dP
|
|
800
712
|
}
|
|
713
|
+
// ------------------------------------------
|
|
714
|
+
// Misc polynoms functions
|
|
801
715
|
|
|
802
716
|
integrate = (a: Fraction | number, b: Fraction | number, letter?: string): Fraction => {
|
|
803
717
|
const primitive = this.primitive(letter)
|
|
@@ -813,8 +727,7 @@ export class Polynom {
|
|
|
813
727
|
|
|
814
728
|
return primitive.evaluate(valuesB).subtract(primitive.evaluate(valuesA))
|
|
815
729
|
}
|
|
816
|
-
|
|
817
|
-
// Polynoms factorization functions
|
|
730
|
+
|
|
818
731
|
// -------------------------------------
|
|
819
732
|
/**
|
|
820
733
|
* Factorize a polynom and store the best results in factors.
|
|
@@ -886,151 +799,21 @@ export class Polynom {
|
|
|
886
799
|
return factors;
|
|
887
800
|
}
|
|
888
801
|
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
// One variable only
|
|
894
|
-
if (this.numberOfVars === 1) {
|
|
895
|
-
a = this.monomByDegree(2, letter).coefficient;
|
|
896
|
-
b = this.monomByDegree(1, letter).coefficient;
|
|
897
|
-
c = this.monomByDegree(0, letter).coefficient;
|
|
898
|
-
delta = b.clone().pow(2).subtract(a.clone().multiply(c).multiply(4));
|
|
899
|
-
|
|
900
|
-
if (delta.isZero()) {
|
|
901
|
-
x1 = b.clone().opposed().divide(a.clone().multiply(2))
|
|
902
|
-
P1 = new Polynom(letter).subtract(x1.display).multiply(x1.denominator)
|
|
903
|
-
P2 = new Polynom(letter).subtract(x1.display).multiply(x1.denominator)
|
|
904
|
-
factor = a.divide(x1.denominator).divide(x1.denominator);
|
|
802
|
+
// TODO: get zeroes for more than first degree and for more than natural degrees
|
|
803
|
+
getZeroes = (): (Fraction | boolean)[] => {
|
|
804
|
+
const Z: Fraction[] = [];
|
|
905
805
|
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
806
|
+
switch (this.degree().value) {
|
|
807
|
+
case 0:
|
|
808
|
+
if (this._monoms[0].coefficient.value === 0) {
|
|
809
|
+
return [true];
|
|
909
810
|
} else {
|
|
910
|
-
return [
|
|
811
|
+
return [false];
|
|
911
812
|
}
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
x2 = b.clone().opposed()
|
|
917
|
-
.subtract(delta.clone().sqrt())
|
|
918
|
-
.divide(a.clone().multiply(2))
|
|
919
|
-
|
|
920
|
-
// (2x+5)(3x-2)
|
|
921
|
-
// 6x^2+11x-10
|
|
922
|
-
// a = 6, b = 11, c = -10
|
|
923
|
-
// delta = 121-4*6*(-10) = 361= 19^2
|
|
924
|
-
// x1 = (-11 + 19) / 12 = 8/12 = 2/3
|
|
925
|
-
// x2 = (-11 - 19) / 12 = -30/12 = -5/2
|
|
926
|
-
factor = a.divide(x1.denominator).divide(x2.denominator);
|
|
927
|
-
if (factor.isOne()) {
|
|
928
|
-
return [
|
|
929
|
-
new Polynom(letter).subtract(x1.display).multiply(x1.denominator),
|
|
930
|
-
new Polynom(letter).subtract(x2.display).multiply(x2.denominator),
|
|
931
|
-
]
|
|
932
|
-
} else {
|
|
933
|
-
return [
|
|
934
|
-
new Polynom(factor.display),
|
|
935
|
-
new Polynom(letter).subtract(x1.display).multiply(x1.denominator),
|
|
936
|
-
new Polynom(letter).subtract(x2.display).multiply(x2.denominator),
|
|
937
|
-
]
|
|
938
|
-
|
|
939
|
-
}
|
|
940
|
-
} else {
|
|
941
|
-
// No solution possible - return the complete value.
|
|
942
|
-
return [this.clone()]
|
|
943
|
-
}
|
|
944
|
-
} else {
|
|
945
|
-
// If multiple variables, only handle perfect squares...
|
|
946
|
-
a = this.monomByDegree(2, letter);
|
|
947
|
-
b = this.monomByDegree(1, letter);
|
|
948
|
-
c = this.monomByDegree(0, letter);
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
if (a.isLiteralSquare() && c.isLiteralSquare()) {
|
|
952
|
-
// Check the middle item is same as...
|
|
953
|
-
if (b.clone().pow(2).isSameAs(a.clone().multiply(c))) {
|
|
954
|
-
// Determine if the coefficient values matches.
|
|
955
|
-
|
|
956
|
-
// Search 4 values (r, s, t, u) that matches:
|
|
957
|
-
// (r X + s Y)(t X + u Y) = rt X^2 + (ru + st) XY + su Y^2
|
|
958
|
-
|
|
959
|
-
let xPolynom = new Polynom('x', a.coefficient, b.coefficient, c.coefficient);
|
|
960
|
-
let xFactors = xPolynom._factorize2ndDegree('x');
|
|
961
|
-
|
|
962
|
-
let factors = [], xyzPolynom: Polynom;
|
|
963
|
-
|
|
964
|
-
if (xFactors.length >= 2) {
|
|
965
|
-
for (let p of xFactors) {
|
|
966
|
-
if (p.degree().isZero()) {
|
|
967
|
-
factors.push(p.clone())
|
|
968
|
-
} else {
|
|
969
|
-
xyzPolynom = p.clone();
|
|
970
|
-
xyzPolynom.monoms[0].literal = a.literalSqrt
|
|
971
|
-
xyzPolynom.monoms[1].literal = c.literalSqrt
|
|
972
|
-
factors.push(xyzPolynom.clone())
|
|
973
|
-
}
|
|
974
|
-
}
|
|
975
|
-
return factors
|
|
976
|
-
}
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
|
|
980
|
-
return [this.clone()]
|
|
981
|
-
//
|
|
982
|
-
// console.log(a.tex, b.tex, c.tex)
|
|
983
|
-
// if (a.isSquare() && c.isSquare()) {
|
|
984
|
-
// console.log('A C squares')
|
|
985
|
-
// if (a.clone().sqrt().multiply(c.clone().sqrt()).multiplyByNumber(2).isSameAs(b)) {
|
|
986
|
-
// console.log('HERE')
|
|
987
|
-
// if (a.coefficient.sign() === b.coefficient.sign()) {
|
|
988
|
-
// return []
|
|
989
|
-
// }else{
|
|
990
|
-
// return []
|
|
991
|
-
// }
|
|
992
|
-
// }
|
|
993
|
-
// } else if(a.isLiteralSquare() && c.isLiteralSquare()) {
|
|
994
|
-
// console.log('A C litteral SQUARES')
|
|
995
|
-
// // Check that the middle element is the product of a and c.
|
|
996
|
-
//
|
|
997
|
-
// if(b.clone().pow(2).isSameAs(a.clone().multiply(c))){
|
|
998
|
-
// console.log('SAME')
|
|
999
|
-
//
|
|
1000
|
-
// }else{
|
|
1001
|
-
// console.log('NOT SAME')
|
|
1002
|
-
// }
|
|
1003
|
-
//
|
|
1004
|
-
// return [this.clone()]
|
|
1005
|
-
// } else {
|
|
1006
|
-
// console.log('NOT SQUARES AT ALL !!!!')
|
|
1007
|
-
// }
|
|
1008
|
-
|
|
1009
|
-
}
|
|
1010
|
-
}
|
|
1011
|
-
|
|
1012
|
-
private _factorizeByGroups = (): Polynom[] => {
|
|
1013
|
-
// TODO: Factorize by groups.
|
|
1014
|
-
return [];
|
|
1015
|
-
}
|
|
1016
|
-
// ------------------------------------------
|
|
1017
|
-
// Polynoms helpers functions
|
|
1018
|
-
// -------------------------------------
|
|
1019
|
-
// TODO: get zeroes for more than first degree and for more than natural degrees
|
|
1020
|
-
getZeroes = (): (Fraction | boolean)[] => {
|
|
1021
|
-
const Z: Fraction[] = [];
|
|
1022
|
-
|
|
1023
|
-
switch (this.degree().value) {
|
|
1024
|
-
case 0:
|
|
1025
|
-
if (this._monoms[0].coefficient.value === 0) {
|
|
1026
|
-
return [true];
|
|
1027
|
-
} else {
|
|
1028
|
-
return [false];
|
|
1029
|
-
}
|
|
1030
|
-
case 1:
|
|
1031
|
-
// There is only one monoms,
|
|
1032
|
-
if (this._monoms.length === 1) {
|
|
1033
|
-
return [new Fraction().zero()];
|
|
813
|
+
case 1:
|
|
814
|
+
// There is only one monoms,
|
|
815
|
+
if (this._monoms.length === 1) {
|
|
816
|
+
return [new Fraction().zero()];
|
|
1034
817
|
} else {
|
|
1035
818
|
const P = this.clone().reduce().reorder();
|
|
1036
819
|
return [P.monoms[1].coefficient.opposed().divide(P.monoms[0].coefficient)];
|
|
@@ -1085,9 +868,8 @@ export class Polynom {
|
|
|
1085
868
|
return Z;
|
|
1086
869
|
};
|
|
1087
870
|
|
|
1088
|
-
|
|
1089
871
|
// TODO: analyse the next functions to determine if they are useful or not...
|
|
1090
|
-
monomByDegree = (degree?: Fraction|number, letter?: string): Monom => {
|
|
872
|
+
monomByDegree = (degree?: Fraction | number, letter?: string): Monom => {
|
|
1091
873
|
if (degree === undefined) {
|
|
1092
874
|
// return the highest degree monom.
|
|
1093
875
|
return this.monomByDegree(this.degree(letter), letter);
|
|
@@ -1105,7 +887,7 @@ export class Polynom {
|
|
|
1105
887
|
return new Monom().zero();
|
|
1106
888
|
};
|
|
1107
889
|
|
|
1108
|
-
monomsByDegree = (degree?: number|Fraction, letter?: string): Monom[] => {
|
|
890
|
+
monomsByDegree = (degree?: number | Fraction, letter?: string): Monom[] => {
|
|
1109
891
|
if (degree === undefined) {
|
|
1110
892
|
// return the highest degree monom.
|
|
1111
893
|
return this.monomsByDegree(this.degree(letter));
|
|
@@ -1137,7 +919,6 @@ export class Polynom {
|
|
|
1137
919
|
return new Monom().zero();
|
|
1138
920
|
};
|
|
1139
921
|
|
|
1140
|
-
|
|
1141
922
|
// Next functions are used for for commonMonom, which is used in the factorize method.
|
|
1142
923
|
getDenominators = (): number[] => {
|
|
1143
924
|
const denominators: number[] = [];
|
|
@@ -1158,6 +939,8 @@ export class Polynom {
|
|
|
1158
939
|
lcmDenominator = (): number => {
|
|
1159
940
|
return Numeric.lcm(...this.getDenominators());
|
|
1160
941
|
};
|
|
942
|
+
// ------------------------------------------
|
|
943
|
+
// Polynoms factorization functions
|
|
1161
944
|
|
|
1162
945
|
gcdDenominator = (): number => {
|
|
1163
946
|
return Numeric.gcd(...this.getDenominators());
|
|
@@ -1170,6 +953,9 @@ export class Polynom {
|
|
|
1170
953
|
gcdNumerator = (): number => {
|
|
1171
954
|
return Numeric.gcd(...this.getNumerators());
|
|
1172
955
|
};
|
|
956
|
+
// ------------------------------------------
|
|
957
|
+
// Polynoms helpers functions
|
|
958
|
+
// -------------------------------------
|
|
1173
959
|
|
|
1174
960
|
commonMonom = (): Monom => {
|
|
1175
961
|
let M = new Monom().one(), numerator: number, denominator: number, degree = this.degree();
|
|
@@ -1190,4 +976,341 @@ export class Polynom {
|
|
|
1190
976
|
}
|
|
1191
977
|
return M;
|
|
1192
978
|
}
|
|
979
|
+
|
|
980
|
+
private genDisplay = (output?: string, forceSign?: boolean, wrapParentheses?: boolean): string => {
|
|
981
|
+
let P: string = '';
|
|
982
|
+
|
|
983
|
+
for (const k of this._monoms) {
|
|
984
|
+
if (k.coefficient.value === 0) {
|
|
985
|
+
continue;
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
P += `${(k.coefficient.sign() === 1 && (P !== '' || forceSign === true)) ? '+' : ''}${(output === 'tex') ? k.tex : k.display}`;
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
if (wrapParentheses === true && this.length > 1) {
|
|
992
|
+
if (output === 'tex') {
|
|
993
|
+
P = `\\left( ${P} \\right)`;
|
|
994
|
+
} else {
|
|
995
|
+
P = `(${P})`;
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
if (P === '') {
|
|
1000
|
+
P = '0';
|
|
1001
|
+
}
|
|
1002
|
+
return P;
|
|
1003
|
+
};
|
|
1004
|
+
|
|
1005
|
+
|
|
1006
|
+
static addToken = (stack: Polynom[], element: Token): void => {
|
|
1007
|
+
|
|
1008
|
+
switch(element.tokenType){
|
|
1009
|
+
case ShutingyardType.COEFFICIENT:
|
|
1010
|
+
stack.push(new Polynom( element.token ))
|
|
1011
|
+
break
|
|
1012
|
+
|
|
1013
|
+
case ShutingyardType.VARIABLE:
|
|
1014
|
+
stack.push(new Polynom().add(new Monom(element.token)))
|
|
1015
|
+
break
|
|
1016
|
+
|
|
1017
|
+
case ShutingyardType.CONSTANT:
|
|
1018
|
+
// TODO: add constant support to Polynom parsing.
|
|
1019
|
+
console.log('Actually, not supported - will be added later !')
|
|
1020
|
+
break
|
|
1021
|
+
|
|
1022
|
+
case ShutingyardType.OPERATION:
|
|
1023
|
+
if(stack.length>=2){
|
|
1024
|
+
const b = stack.pop(),
|
|
1025
|
+
a = stack.pop()
|
|
1026
|
+
|
|
1027
|
+
if(element.token === '+'){
|
|
1028
|
+
stack.push(a.add(b))
|
|
1029
|
+
}else if(element.token === '-'){
|
|
1030
|
+
stack.push(a.subtract(b))
|
|
1031
|
+
}else if(element.token === '*'){
|
|
1032
|
+
stack.push(a.multiply(b))
|
|
1033
|
+
}else if(element.token === '/'){
|
|
1034
|
+
if(b.degree().isStrictlyPositive()){
|
|
1035
|
+
console.log('divide by a polynom -> should create a rational polynom !')
|
|
1036
|
+
}else {
|
|
1037
|
+
stack.push(a.divide(b.monoms[0].coefficient))
|
|
1038
|
+
|
|
1039
|
+
}
|
|
1040
|
+
}else if(element.token === '^'){
|
|
1041
|
+
if(b.degree().isStrictlyPositive()) {
|
|
1042
|
+
console.error('Cannot elevate a polynom with another polynom !')
|
|
1043
|
+
}else {
|
|
1044
|
+
if(b.monoms[0].coefficient.isRelative()) {
|
|
1045
|
+
// Integer power
|
|
1046
|
+
stack.push(a.pow(b.monoms[0].coefficient.value))
|
|
1047
|
+
}else{
|
|
1048
|
+
// Only allow power if the previous polynom is only a monom, without coefficient.
|
|
1049
|
+
if(a.monoms.length===1 && a.monoms[0].coefficient.isOne()){
|
|
1050
|
+
for (let letter in a.monoms[0].literal) {
|
|
1051
|
+
a.monoms[0].literal[letter].multiply(b.monoms[0].coefficient)
|
|
1052
|
+
}
|
|
1053
|
+
stack.push(a)
|
|
1054
|
+
}else {
|
|
1055
|
+
console.error('Cannot have power with fraction')
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
}else{
|
|
1061
|
+
console.log('Stack size: ', stack.length)
|
|
1062
|
+
if(element.token === '-'){
|
|
1063
|
+
stack.push(stack.pop().opposed())
|
|
1064
|
+
}else{
|
|
1065
|
+
console.log('While parsing, cannot apply ', element.token, 'to', stack[0].tex)
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
break
|
|
1069
|
+
|
|
1070
|
+
case ShutingyardType.MONOM:
|
|
1071
|
+
// Should never appear.
|
|
1072
|
+
console.error('The monom token should not appear here')
|
|
1073
|
+
break;
|
|
1074
|
+
|
|
1075
|
+
case ShutingyardType.FUNCTION:
|
|
1076
|
+
// Should never appear.
|
|
1077
|
+
console.log('The function token should not appear here - might be introduced later.')
|
|
1078
|
+
break;
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
/**
|
|
1082
|
+
* Main parse using a shutting yard class
|
|
1083
|
+
* @param inputStr
|
|
1084
|
+
*/
|
|
1085
|
+
private shutingYardToReducedPolynom = (inputStr: string): Polynom => {
|
|
1086
|
+
// Get the RPN array of the current expression
|
|
1087
|
+
const SY: Shutingyard = new Shutingyard().parse(inputStr);
|
|
1088
|
+
const rpn: { token: string, tokenType: string }[] = SY.rpn;
|
|
1089
|
+
|
|
1090
|
+
// New version for reducing shuting yard.
|
|
1091
|
+
this.zero()
|
|
1092
|
+
|
|
1093
|
+
let stack: Polynom[] = [],
|
|
1094
|
+
monom: Monom = new Monom()
|
|
1095
|
+
|
|
1096
|
+
// Loop through the
|
|
1097
|
+
for (const element of rpn) {
|
|
1098
|
+
Polynom.addToken(stack, element);
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
if (stack.length === 1) {
|
|
1102
|
+
this.add(stack[0])
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
return this
|
|
1106
|
+
/**
|
|
1107
|
+
let m1: Polynom;
|
|
1108
|
+
let m2: Polynom;
|
|
1109
|
+
|
|
1110
|
+
let stack: Polynom[] = [],
|
|
1111
|
+
previousToken: string = null,
|
|
1112
|
+
tempPolynom
|
|
1113
|
+
|
|
1114
|
+
for (const element of rpn) {
|
|
1115
|
+
if (element.tokenType === 'coefficient' || element.tokenType === 'variable') {
|
|
1116
|
+
tempPolynom = new Polynom().zero();
|
|
1117
|
+
tempPolynom.monoms = [new Monom(element.token)]
|
|
1118
|
+
stack.push(tempPolynom.clone())
|
|
1119
|
+
} else if (element.tokenType === 'operation') {
|
|
1120
|
+
m2 = (stack.pop()) || new Polynom().zero();
|
|
1121
|
+
m1 = (stack.pop()) || new Polynom().zero();
|
|
1122
|
+
switch (element.token) {
|
|
1123
|
+
case '+':
|
|
1124
|
+
stack.push(m1.add(m2))
|
|
1125
|
+
break;
|
|
1126
|
+
case '-':
|
|
1127
|
+
stack.push(m1.subtract(m2))
|
|
1128
|
+
break;
|
|
1129
|
+
case '*':
|
|
1130
|
+
stack.push(m1.multiply(m2))
|
|
1131
|
+
break;
|
|
1132
|
+
case '^':
|
|
1133
|
+
stack.push(m1.pow(+previousToken))
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
previousToken = element.token;
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
this._monoms = stack[0].monoms;
|
|
1140
|
+
return this;*/
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
private multiplyByPolynom = (P: Polynom): Polynom => {
|
|
1144
|
+
const M: Monom[] = [];
|
|
1145
|
+
for (const m1 of this._monoms) {
|
|
1146
|
+
for (const m2 of P.monoms) {
|
|
1147
|
+
M.push(Monom.xmultiply(m1, m2));
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
this._monoms = M;
|
|
1152
|
+
return this.reduce();
|
|
1153
|
+
};
|
|
1154
|
+
|
|
1155
|
+
private multiplyByFraction = (F: Fraction): Polynom => {
|
|
1156
|
+
for (const m of this._monoms) {
|
|
1157
|
+
m.coefficient.multiply(F);
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
return this.reduce();
|
|
1161
|
+
};
|
|
1162
|
+
|
|
1163
|
+
private multiplyByInteger = (nb: number): Polynom => {
|
|
1164
|
+
return this.multiplyByFraction(new Fraction(nb));
|
|
1165
|
+
};
|
|
1166
|
+
|
|
1167
|
+
private multiplyByMonom = (M: Monom): Polynom => {
|
|
1168
|
+
for (const m of this._monoms) {
|
|
1169
|
+
m.multiply(M)
|
|
1170
|
+
}
|
|
1171
|
+
return this.reduce();
|
|
1172
|
+
};
|
|
1173
|
+
|
|
1174
|
+
private divideByInteger = (nb: number): Polynom => {
|
|
1175
|
+
const nbF = new Fraction(nb);
|
|
1176
|
+
for (const m of this._monoms) {
|
|
1177
|
+
m.coefficient.divide(nbF);
|
|
1178
|
+
}
|
|
1179
|
+
return this;
|
|
1180
|
+
};
|
|
1181
|
+
|
|
1182
|
+
private divideByFraction = (F: Fraction): Polynom => {
|
|
1183
|
+
for (const m of this._monoms) {
|
|
1184
|
+
m.coefficient.divide(F);
|
|
1185
|
+
}
|
|
1186
|
+
return this;
|
|
1187
|
+
};
|
|
1188
|
+
|
|
1189
|
+
private _factorize2ndDegree = (letter: string): Polynom[] => {
|
|
1190
|
+
let P1: Polynom, P2: Polynom,
|
|
1191
|
+
a, b, c, delta, x1, x2, factor;
|
|
1192
|
+
|
|
1193
|
+
// One variable only
|
|
1194
|
+
if (this.numberOfVars === 1) {
|
|
1195
|
+
a = this.monomByDegree(2, letter).coefficient;
|
|
1196
|
+
b = this.monomByDegree(1, letter).coefficient;
|
|
1197
|
+
c = this.monomByDegree(0, letter).coefficient;
|
|
1198
|
+
delta = b.clone().pow(2).subtract(a.clone().multiply(c).multiply(4));
|
|
1199
|
+
|
|
1200
|
+
if (delta.isZero()) {
|
|
1201
|
+
x1 = b.clone().opposed().divide(a.clone().multiply(2))
|
|
1202
|
+
P1 = new Polynom(letter).subtract(x1.display).multiply(x1.denominator)
|
|
1203
|
+
P2 = new Polynom(letter).subtract(x1.display).multiply(x1.denominator)
|
|
1204
|
+
factor = a.divide(x1.denominator).divide(x1.denominator);
|
|
1205
|
+
|
|
1206
|
+
if (!factor.isOne()) {
|
|
1207
|
+
// TODO: Update new Polynom to accept anything...
|
|
1208
|
+
return [new Polynom(factor.display), P1, P2]
|
|
1209
|
+
} else {
|
|
1210
|
+
return [P1, P2]
|
|
1211
|
+
}
|
|
1212
|
+
} else if (delta.isPositive() && delta.isSquare()) {
|
|
1213
|
+
x1 = b.clone().opposed()
|
|
1214
|
+
.add(delta.clone().sqrt())
|
|
1215
|
+
.divide(a.clone().multiply(2))
|
|
1216
|
+
x2 = b.clone().opposed()
|
|
1217
|
+
.subtract(delta.clone().sqrt())
|
|
1218
|
+
.divide(a.clone().multiply(2))
|
|
1219
|
+
|
|
1220
|
+
// (2x+5)(3x-2)
|
|
1221
|
+
// 6x^2+11x-10
|
|
1222
|
+
// a = 6, b = 11, c = -10
|
|
1223
|
+
// delta = 121-4*6*(-10) = 361= 19^2
|
|
1224
|
+
// x1 = (-11 + 19) / 12 = 8/12 = 2/3
|
|
1225
|
+
// x2 = (-11 - 19) / 12 = -30/12 = -5/2
|
|
1226
|
+
factor = a.divide(x1.denominator).divide(x2.denominator);
|
|
1227
|
+
if (factor.isOne()) {
|
|
1228
|
+
return [
|
|
1229
|
+
new Polynom(letter).subtract(x1.display).multiply(x1.denominator),
|
|
1230
|
+
new Polynom(letter).subtract(x2.display).multiply(x2.denominator),
|
|
1231
|
+
]
|
|
1232
|
+
} else {
|
|
1233
|
+
return [
|
|
1234
|
+
new Polynom(factor.display),
|
|
1235
|
+
new Polynom(letter).subtract(x1.display).multiply(x1.denominator),
|
|
1236
|
+
new Polynom(letter).subtract(x2.display).multiply(x2.denominator),
|
|
1237
|
+
]
|
|
1238
|
+
|
|
1239
|
+
}
|
|
1240
|
+
} else {
|
|
1241
|
+
// No solution possible - return the complete value.
|
|
1242
|
+
return [this.clone()]
|
|
1243
|
+
}
|
|
1244
|
+
} else {
|
|
1245
|
+
// If multiple variables, only handle perfect squares...
|
|
1246
|
+
a = this.monomByDegree(2, letter);
|
|
1247
|
+
b = this.monomByDegree(1, letter);
|
|
1248
|
+
c = this.monomByDegree(0, letter);
|
|
1249
|
+
|
|
1250
|
+
|
|
1251
|
+
if (a.isLiteralSquare() && c.isLiteralSquare()) {
|
|
1252
|
+
// Check the middle item is same as...
|
|
1253
|
+
if (b.clone().pow(2).isSameAs(a.clone().multiply(c))) {
|
|
1254
|
+
// Determine if the coefficient values matches.
|
|
1255
|
+
|
|
1256
|
+
// Search 4 values (r, s, t, u) that matches:
|
|
1257
|
+
// (r X + s Y)(t X + u Y) = rt X^2 + (ru + st) XY + su Y^2
|
|
1258
|
+
|
|
1259
|
+
let xPolynom = new Polynom('x', a.coefficient, b.coefficient, c.coefficient);
|
|
1260
|
+
let xFactors = xPolynom._factorize2ndDegree('x');
|
|
1261
|
+
|
|
1262
|
+
let factors = [], xyzPolynom: Polynom;
|
|
1263
|
+
|
|
1264
|
+
if (xFactors.length >= 2) {
|
|
1265
|
+
for (let p of xFactors) {
|
|
1266
|
+
if (p.degree().isZero()) {
|
|
1267
|
+
factors.push(p.clone())
|
|
1268
|
+
} else {
|
|
1269
|
+
xyzPolynom = p.clone();
|
|
1270
|
+
xyzPolynom.monoms[0].literal = a.literalSqrt
|
|
1271
|
+
xyzPolynom.monoms[1].literal = c.literalSqrt
|
|
1272
|
+
factors.push(xyzPolynom.clone())
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
return factors
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1280
|
+
return [this.clone()]
|
|
1281
|
+
//
|
|
1282
|
+
// console.log(a.tex, b.tex, c.tex)
|
|
1283
|
+
// if (a.isSquare() && c.isSquare()) {
|
|
1284
|
+
// console.log('A C squares')
|
|
1285
|
+
// if (a.clone().sqrt().multiply(c.clone().sqrt()).multiplyByNumber(2).isSameAs(b)) {
|
|
1286
|
+
// console.log('HERE')
|
|
1287
|
+
// if (a.coefficient.sign() === b.coefficient.sign()) {
|
|
1288
|
+
// return []
|
|
1289
|
+
// }else{
|
|
1290
|
+
// return []
|
|
1291
|
+
// }
|
|
1292
|
+
// }
|
|
1293
|
+
// } else if(a.isLiteralSquare() && c.isLiteralSquare()) {
|
|
1294
|
+
// console.log('A C litteral SQUARES')
|
|
1295
|
+
// // Check that the middle element is the product of a and c.
|
|
1296
|
+
//
|
|
1297
|
+
// if(b.clone().pow(2).isSameAs(a.clone().multiply(c))){
|
|
1298
|
+
// console.log('SAME')
|
|
1299
|
+
//
|
|
1300
|
+
// }else{
|
|
1301
|
+
// console.log('NOT SAME')
|
|
1302
|
+
// }
|
|
1303
|
+
//
|
|
1304
|
+
// return [this.clone()]
|
|
1305
|
+
// } else {
|
|
1306
|
+
// console.log('NOT SQUARES AT ALL !!!!')
|
|
1307
|
+
// }
|
|
1308
|
+
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1312
|
+
private _factorizeByGroups = (): Polynom[] => {
|
|
1313
|
+
// TODO: Factorize by groups.
|
|
1314
|
+
return [];
|
|
1315
|
+
}
|
|
1193
1316
|
}
|