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.
- package/dist/pi.js +6537 -1
- package/dist/pi.js.map +1 -1
- package/dist/pi.min.js +2 -0
- package/dist/pi.min.js.map +1 -0
- 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 +37 -37
- package/docs/classes/algebra.Polynom.html +10 -10
- package/docs/classes/algebra.PolynomExpFactor.html +1 -1
- package/docs/classes/algebra.PolynomExpProduct.html +1 -1
- 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 +5 -5
- package/docs/classes/geometry.Vector.html +1 -1
- package/docs/classes/numeric.Numeric.html +5 -5
- package/docs/classes/shutingyard.Shutingyard.html +4 -4
- package/docs/enums/geometry.LinePropriety.html +1 -0
- package/docs/enums/shutingyard.ShutingyardMode.html +1 -1
- package/docs/enums/shutingyard.ShutingyardType.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/random.Random.html +1 -1
- package/docs/modules/random.html +1 -1
- package/docs/modules/shutingyard.html +1 -1
- package/esm/main.d.ts +30 -1
- package/esm/main.js +4 -1
- package/esm/main.js.map +1 -1
- package/esm/maths/algebra/equation.d.ts +62 -17
- package/esm/maths/algebra/equation.js +597 -502
- package/esm/maths/algebra/equation.js.map +1 -1
- package/esm/maths/algebra/index.js +5 -1
- package/esm/maths/algebra/index.js.map +1 -1
- package/esm/maths/algebra/linearSystem.js +154 -101
- package/esm/maths/algebra/linearSystem.js.map +1 -1
- package/esm/maths/algebra/logicalset.d.ts +11 -0
- package/esm/maths/algebra/logicalset.js +18 -6
- package/esm/maths/algebra/logicalset.js.map +1 -1
- package/esm/maths/algebra/monom.d.ts +144 -0
- package/esm/maths/algebra/monom.js +626 -398
- package/esm/maths/algebra/monom.js.map +1 -1
- package/esm/maths/algebra/polynom.d.ts +49 -0
- package/esm/maths/algebra/polynom.js +995 -712
- package/esm/maths/algebra/polynom.js.map +1 -1
- package/esm/maths/algebra/rational.d.ts +12 -0
- package/esm/maths/algebra/rational.js +97 -82
- package/esm/maths/algebra/rational.js.map +1 -1
- package/esm/maths/coefficients/fraction.d.ts +18 -0
- package/esm/maths/coefficients/fraction.js +390 -332
- package/esm/maths/coefficients/fraction.js.map +1 -1
- package/esm/maths/coefficients/index.js +5 -1
- package/esm/maths/coefficients/index.js.map +1 -1
- package/esm/maths/coefficients/nthroot.d.ts +3 -0
- package/esm/maths/coefficients/nthroot.js +48 -33
- package/esm/maths/coefficients/nthroot.js.map +1 -1
- package/esm/maths/expressions/numexp.js +11 -3
- package/esm/maths/expressions/numexp.js.map +1 -1
- package/esm/maths/expressions/polynomexp.bkp.js +93 -93
- package/esm/maths/expressions/polynomexp.bkp.js.map +1 -1
- package/esm/maths/expressions/polynomexp.js +22 -9
- package/esm/maths/expressions/polynomexp.js.map +1 -1
- package/esm/maths/geometry/circle.d.ts +18 -6
- package/esm/maths/geometry/circle.js +139 -42
- package/esm/maths/geometry/circle.js.map +1 -1
- package/esm/maths/geometry/index.js +5 -1
- package/esm/maths/geometry/index.js.map +1 -1
- package/esm/maths/geometry/line.d.ts +9 -2
- package/esm/maths/geometry/line.js +245 -188
- package/esm/maths/geometry/line.js.map +1 -1
- package/esm/maths/geometry/point.d.ts +12 -0
- package/esm/maths/geometry/point.js +121 -73
- package/esm/maths/geometry/point.js.map +1 -1
- package/esm/maths/geometry/triangle.d.ts +23 -1
- package/esm/maths/geometry/triangle.js +197 -158
- package/esm/maths/geometry/triangle.js.map +1 -1
- package/esm/maths/geometry/vector.d.ts +5 -1
- package/esm/maths/geometry/vector.js +139 -115
- package/esm/maths/geometry/vector.js.map +1 -1
- package/esm/maths/numeric.d.ts +17 -0
- package/esm/maths/numeric.js +40 -0
- package/esm/maths/numeric.js.map +1 -1
- package/esm/maths/random/index.js +5 -1
- package/esm/maths/random/index.js.map +1 -1
- package/esm/maths/random/randomCore.js +15 -15
- package/esm/maths/random/randomCore.js.map +1 -1
- package/esm/maths/random/rndFraction.d.ts +3 -0
- package/esm/maths/random/rndFraction.js +19 -16
- package/esm/maths/random/rndFraction.js.map +1 -1
- package/esm/maths/random/rndHelpers.d.ts +17 -0
- package/esm/maths/random/rndHelpers.js +20 -0
- package/esm/maths/random/rndHelpers.js.map +1 -1
- package/esm/maths/random/rndMonom.d.ts +3 -0
- package/esm/maths/random/rndMonom.js +33 -26
- package/esm/maths/random/rndMonom.js.map +1 -1
- package/esm/maths/random/rndPolynom.d.ts +3 -0
- package/esm/maths/random/rndPolynom.js +49 -37
- package/esm/maths/random/rndPolynom.js.map +1 -1
- package/esm/maths/shutingyard.d.ts +21 -0
- package/esm/maths/shutingyard.js +86 -9
- package/esm/maths/shutingyard.js.map +1 -1
- package/package.json +2 -2
- package/public/index.html +47 -0
- package/src/main.ts +2 -2
- package/src/maths/algebra/equation.ts +142 -128
- package/src/maths/algebra/monom.ts +6 -2
- package/src/maths/algebra/polynom.ts +2 -7
- package/src/maths/geometry/circle.ts +168 -75
- package/src/maths/geometry/index.ts +1 -1
- package/src/maths/geometry/line.ts +1 -1
- package/src/maths/geometry/point.ts +25 -2
- package/src/maths/geometry/triangle.ts +1 -1
- package/src/maths/geometry/vector.ts +1 -1
- package/src/maths/numeric.ts +15 -0
- package/tests/algebra/polynom.test.ts +7 -0
- package/tests/geometry/circle.test.ts +33 -0
- package/tsconfig.json +2 -2
- package/webpack-production-min.config.js +26 -0
- package/webpack-production.config.js +1 -1
- package/dev/pi.js +0 -5392
- package/dev/pi.js.map +0 -1
|
@@ -1,13 +1,938 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Polynom module contains everything necessary to handle polynoms.*
|
|
4
|
+
*/
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.Polynom = void 0;
|
|
4
7
|
const monom_1 = require("./monom");
|
|
5
8
|
const shutingyard_1 = require("../shutingyard");
|
|
6
9
|
const numeric_1 = require("../numeric");
|
|
7
10
|
const coefficients_1 = require("../coefficients");
|
|
11
|
+
/**
|
|
12
|
+
* Polynom class can handle polynoms, reorder, resolve, ...
|
|
13
|
+
* ```
|
|
14
|
+
* let P = new Polynom('3x-4')
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
8
17
|
class Polynom {
|
|
9
|
-
|
|
18
|
+
/**
|
|
19
|
+
*
|
|
20
|
+
* @param {string} polynomString (optional) Default polynom to parse on class creation
|
|
21
|
+
* @param values
|
|
22
|
+
*/
|
|
10
23
|
constructor(polynomString, ...values) {
|
|
24
|
+
// ------------------------------------------
|
|
25
|
+
/**
|
|
26
|
+
* Parse a string to a polynom.
|
|
27
|
+
* @param inputStr
|
|
28
|
+
* @param values: as string, numbers or fractions
|
|
29
|
+
*/
|
|
30
|
+
this.parse = (inputStr, ...values) => {
|
|
31
|
+
// Reset the main variables.
|
|
32
|
+
this._monoms = [];
|
|
33
|
+
this._factors = [];
|
|
34
|
+
if (typeof inputStr === 'string') {
|
|
35
|
+
return this._parseString(inputStr, ...values);
|
|
36
|
+
}
|
|
37
|
+
else if (typeof inputStr === 'number' || inputStr instanceof coefficients_1.Fraction || inputStr instanceof monom_1.Monom) {
|
|
38
|
+
this._monoms.push(new monom_1.Monom(inputStr));
|
|
39
|
+
}
|
|
40
|
+
else if (inputStr instanceof Polynom) {
|
|
41
|
+
for (const m of inputStr.monoms) {
|
|
42
|
+
this._monoms.push(m.clone());
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return this;
|
|
46
|
+
};
|
|
47
|
+
// ------------------------------------------
|
|
48
|
+
// Creation / parsing functions
|
|
49
|
+
/**
|
|
50
|
+
* Clone the polynom
|
|
51
|
+
*/
|
|
52
|
+
this.clone = () => {
|
|
53
|
+
const P = new Polynom();
|
|
54
|
+
const M = [];
|
|
55
|
+
for (const m of this._monoms) {
|
|
56
|
+
M.push(m.clone());
|
|
57
|
+
}
|
|
58
|
+
P.monoms = M;
|
|
59
|
+
return P;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Set the polynom to zero.
|
|
63
|
+
* @returns {this}
|
|
64
|
+
*/
|
|
65
|
+
this.zero = () => {
|
|
66
|
+
this._monoms = [];
|
|
67
|
+
this._monoms.push(new monom_1.Monom().zero());
|
|
68
|
+
this._rawString = '0';
|
|
69
|
+
return this;
|
|
70
|
+
};
|
|
71
|
+
this.one = () => {
|
|
72
|
+
this._monoms = [];
|
|
73
|
+
this._monoms.push(new monom_1.Monom().one());
|
|
74
|
+
this._rawString = '1';
|
|
75
|
+
return this;
|
|
76
|
+
};
|
|
77
|
+
this.empty = () => {
|
|
78
|
+
this._monoms = [];
|
|
79
|
+
this._rawString = '';
|
|
80
|
+
return this;
|
|
81
|
+
};
|
|
82
|
+
// ------------------------------------------
|
|
83
|
+
this.opposed = () => {
|
|
84
|
+
this._monoms = this._monoms.map(m => m.opposed());
|
|
85
|
+
return this;
|
|
86
|
+
};
|
|
87
|
+
this.add = (...values) => {
|
|
88
|
+
for (let value of values) {
|
|
89
|
+
if (value instanceof Polynom) {
|
|
90
|
+
this._monoms = this._monoms.concat(value.monoms);
|
|
91
|
+
}
|
|
92
|
+
else if (value instanceof monom_1.Monom) {
|
|
93
|
+
this._monoms.push(value.clone());
|
|
94
|
+
}
|
|
95
|
+
else if (Number.isSafeInteger(value)) {
|
|
96
|
+
this._monoms.push(new monom_1.Monom(value.toString()));
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
this._monoms.push(new monom_1.Monom(value));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return this.reduce();
|
|
103
|
+
};
|
|
104
|
+
// // -----------------------------------------------
|
|
105
|
+
// // Polynom generators and randomizers
|
|
106
|
+
// // -----------------------------------------------
|
|
107
|
+
// random(config?: randomPolynomConfig) {
|
|
108
|
+
// return Random.polynom(config);
|
|
109
|
+
// }
|
|
110
|
+
//
|
|
111
|
+
// private _randomizeDefaults: { [key: string]: number | string | boolean } = {
|
|
112
|
+
// degree: 2,
|
|
113
|
+
// unit: true,
|
|
114
|
+
// fractions: false,
|
|
115
|
+
// factorable: false,
|
|
116
|
+
// letters: 'x',
|
|
117
|
+
// allowNullMonom: false,
|
|
118
|
+
// numberOfMonoms: false
|
|
119
|
+
// };
|
|
120
|
+
// get randomizeDefaults(): { [key: string]: number | string | boolean } {
|
|
121
|
+
// return this._randomizeDefaults;
|
|
122
|
+
// }
|
|
123
|
+
//
|
|
124
|
+
// set randomizeDefaults(value) {
|
|
125
|
+
// this._randomizeDefaults = value;
|
|
126
|
+
// }
|
|
127
|
+
//
|
|
128
|
+
// randomize = (config: { [key: string]: number | string | boolean }): Polynom => {
|
|
129
|
+
// let P = new Polynom();
|
|
130
|
+
//
|
|
131
|
+
// // Check the config file and use the default values.
|
|
132
|
+
// if (config === undefined) {
|
|
133
|
+
// config = {};
|
|
134
|
+
// }
|
|
135
|
+
// for (let k in this._randomizeDefaults) {
|
|
136
|
+
// if (config[k] === undefined) {
|
|
137
|
+
// config[k] = this._randomizeDefaults[k];
|
|
138
|
+
// }
|
|
139
|
+
// }
|
|
140
|
+
//
|
|
141
|
+
// // TODO: Build a more robust randomize function
|
|
142
|
+
// return P;
|
|
143
|
+
// }
|
|
144
|
+
//
|
|
145
|
+
// rndFactorable = (degree: number = 2, unit: boolean | number = false, letters: string = 'x'): Polynom => {
|
|
146
|
+
// // TODO: Make rndFactorable polynom generator more user friendly
|
|
147
|
+
// this._factors = [];
|
|
148
|
+
// for (let i = 0; i < degree; i++) {
|
|
149
|
+
// let factorUnit = unit === true || i >= unit,
|
|
150
|
+
// p = Random.polynom({
|
|
151
|
+
// degree: 1,
|
|
152
|
+
// unit: factorUnit,
|
|
153
|
+
// fraction: false,
|
|
154
|
+
// letters
|
|
155
|
+
// });
|
|
156
|
+
// this._factors.push(p);
|
|
157
|
+
// }
|
|
158
|
+
//
|
|
159
|
+
// this.empty().monoms = this._factors[0].monoms;
|
|
160
|
+
// for (let i = 1; i < this._factors.length; i++) {
|
|
161
|
+
// this.multiply(this._factors[i]);
|
|
162
|
+
// }
|
|
163
|
+
// return this;
|
|
164
|
+
// };
|
|
165
|
+
// ------------------------------------------
|
|
166
|
+
// Mathematical operations
|
|
167
|
+
this.subtract = (...values) => {
|
|
168
|
+
for (let value of values) {
|
|
169
|
+
if (value instanceof Polynom) {
|
|
170
|
+
this._monoms = this._monoms.concat(value.clone().opposed().monoms);
|
|
171
|
+
}
|
|
172
|
+
else if (value instanceof monom_1.Monom) {
|
|
173
|
+
this._monoms.push(value.clone().opposed());
|
|
174
|
+
}
|
|
175
|
+
else if (Number.isSafeInteger(value)) {
|
|
176
|
+
this._monoms.push(new monom_1.Monom(value.toString()).opposed());
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
this._monoms.push(new monom_1.Monom(value).opposed());
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return this.reduce();
|
|
183
|
+
};
|
|
184
|
+
this.multiply = (value) => {
|
|
185
|
+
if (value instanceof Polynom) {
|
|
186
|
+
return this.multiplyByPolynom(value);
|
|
187
|
+
}
|
|
188
|
+
else if (value instanceof coefficients_1.Fraction) {
|
|
189
|
+
return this.multiplyByFraction(value);
|
|
190
|
+
}
|
|
191
|
+
else if (value instanceof monom_1.Monom) {
|
|
192
|
+
return this.multiplyByMonom(value);
|
|
193
|
+
}
|
|
194
|
+
else if (Number.isSafeInteger(value) && typeof value === 'number') {
|
|
195
|
+
return this.multiplyByInteger(value);
|
|
196
|
+
}
|
|
197
|
+
// Something went wrong...
|
|
198
|
+
return this;
|
|
199
|
+
};
|
|
200
|
+
/**
|
|
201
|
+
* Divide the current polynom by another polynom.
|
|
202
|
+
* @param P
|
|
203
|
+
* returns {quotient: Polynom, reminder: Polynom}
|
|
204
|
+
*/
|
|
205
|
+
this.euclidian = (P) => {
|
|
206
|
+
const letter = P.variables[0];
|
|
207
|
+
const quotient = new Polynom().zero();
|
|
208
|
+
const reminder = this.clone().reorder(letter);
|
|
209
|
+
// There is no variable !
|
|
210
|
+
if (P.variables.length === 0) {
|
|
211
|
+
return { quotient, reminder };
|
|
212
|
+
}
|
|
213
|
+
// Get at least a letter
|
|
214
|
+
const maxMP = P.monomByDegree(undefined, letter);
|
|
215
|
+
const degreeP = P.degree(letter);
|
|
216
|
+
let newM;
|
|
217
|
+
// Make the euclidian division of the two polynoms.
|
|
218
|
+
let MaxIteration = this.degree(letter).clone().multiply(2);
|
|
219
|
+
while (reminder.degree(letter).geq(degreeP) && MaxIteration.isPositive()) {
|
|
220
|
+
MaxIteration.subtract(1);
|
|
221
|
+
// Get the greatest monom divided by the max monom of the divider
|
|
222
|
+
newM = reminder.monomByDegree(undefined, letter).clone().divide(maxMP);
|
|
223
|
+
if (newM.isZero()) {
|
|
224
|
+
break;
|
|
225
|
+
}
|
|
226
|
+
// Get the new quotient and reminder.
|
|
227
|
+
quotient.add(newM);
|
|
228
|
+
reminder.subtract(P.clone().multiply(newM));
|
|
229
|
+
}
|
|
230
|
+
quotient.reduce();
|
|
231
|
+
reminder.reduce();
|
|
232
|
+
return { quotient, reminder };
|
|
233
|
+
};
|
|
234
|
+
this.divide = (value) => {
|
|
235
|
+
if (value instanceof coefficients_1.Fraction) {
|
|
236
|
+
return this.divideByFraction(value);
|
|
237
|
+
}
|
|
238
|
+
else if (typeof value === 'number' && Number.isSafeInteger(value)) {
|
|
239
|
+
return this.divideByInteger(value);
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
this.pow = (nb) => {
|
|
243
|
+
if (!Number.isSafeInteger(nb)) {
|
|
244
|
+
return this.zero();
|
|
245
|
+
}
|
|
246
|
+
if (nb < 0) {
|
|
247
|
+
return this.zero();
|
|
248
|
+
}
|
|
249
|
+
if (nb === 0) {
|
|
250
|
+
return new Polynom();
|
|
251
|
+
}
|
|
252
|
+
const P = this.clone();
|
|
253
|
+
for (let i = 1; i < nb; i++) {
|
|
254
|
+
this.multiply(P);
|
|
255
|
+
}
|
|
256
|
+
return this.reduce();
|
|
257
|
+
};
|
|
258
|
+
// ------------------------------------------
|
|
259
|
+
/**
|
|
260
|
+
* Compare the current coefficient with another coefficient
|
|
261
|
+
* @param P
|
|
262
|
+
* @param sign (string| default is =): authorized values: =, <, <=, >, >= with some variations.
|
|
263
|
+
*/
|
|
264
|
+
this.compare = (P, sign) => {
|
|
265
|
+
if (sign === undefined) {
|
|
266
|
+
sign = '=';
|
|
267
|
+
}
|
|
268
|
+
// Create clone version to reduce them without altering the original polynoms.
|
|
269
|
+
const cP1 = this.clone().reduce().reorder();
|
|
270
|
+
const cP2 = P.clone().reduce().reorder();
|
|
271
|
+
switch (sign) {
|
|
272
|
+
case '=':
|
|
273
|
+
// They must have the isSame length and the isSame degree
|
|
274
|
+
if (cP1.length !== cP2.length || cP1.degree().isNotEqual(cP2.degree())) {
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
277
|
+
// Check if the coefficients are the isSame.
|
|
278
|
+
for (const i in cP1.monoms) {
|
|
279
|
+
if (!cP1.monoms[i].isEqual(cP2.monoms[i])) {
|
|
280
|
+
return false;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return true;
|
|
284
|
+
case 'same':
|
|
285
|
+
// They must have the isSame length and the isSame degree
|
|
286
|
+
if (cP1.length !== cP2.length || cP1.degree() !== cP2.degree()) {
|
|
287
|
+
return false;
|
|
288
|
+
}
|
|
289
|
+
for (const i in cP1.monoms) {
|
|
290
|
+
if (!cP1.monoms[i].isSameAs(cP2.monoms[i])) {
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
return true;
|
|
295
|
+
default:
|
|
296
|
+
return false;
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
this.isEqual = (P) => {
|
|
300
|
+
return this.compare(P, '=');
|
|
301
|
+
};
|
|
302
|
+
this.isSameAs = (P) => {
|
|
303
|
+
return this.compare(P, 'same');
|
|
304
|
+
};
|
|
305
|
+
this.isOpposedAt = (P) => {
|
|
306
|
+
return this.compare(P.clone().opposed(), '=');
|
|
307
|
+
};
|
|
308
|
+
this.isFactorized = (polynomString) => {
|
|
309
|
+
let P;
|
|
310
|
+
// Check if polynom is complete...
|
|
311
|
+
if (polynomString.match(/\(/g).length !== polynomString.match(/\)/g).length) {
|
|
312
|
+
return false;
|
|
313
|
+
}
|
|
314
|
+
// Try to build the polynom
|
|
315
|
+
try {
|
|
316
|
+
P = new Polynom(polynomString);
|
|
317
|
+
}
|
|
318
|
+
catch (e) {
|
|
319
|
+
return false;
|
|
320
|
+
}
|
|
321
|
+
// Both polynom aren't the same (once developed and reduced => they cannot be equivalent)
|
|
322
|
+
if (!this.isEqual(P)) {
|
|
323
|
+
return false;
|
|
324
|
+
}
|
|
325
|
+
// Check if the provided (string) version is fully factorized.
|
|
326
|
+
// Run a regex on the string.
|
|
327
|
+
let polynomStringNormalized = polynomString.replaceAll('*', ''), polynomStringReduced = '' + polynomStringNormalized, factors = [];
|
|
328
|
+
for (let x of polynomStringNormalized.matchAll(/\(([a-z0-9+\-]+)\)(\^[0-9]*)?/g)) {
|
|
329
|
+
if (x[2] !== undefined) {
|
|
330
|
+
for (let i = 0; i < +x[2].substr(1); i++) {
|
|
331
|
+
factors.push(x[1]);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
factors.push(x[1]);
|
|
336
|
+
}
|
|
337
|
+
polynomStringReduced = polynomStringReduced.replaceAll(x[0], '');
|
|
338
|
+
}
|
|
339
|
+
if (polynomStringReduced !== '') {
|
|
340
|
+
factors.push(polynomStringReduced);
|
|
341
|
+
}
|
|
342
|
+
let polyFactors = factors.map(x => new Polynom(x));
|
|
343
|
+
// Factorize the current polynom.
|
|
344
|
+
this.factorize();
|
|
345
|
+
// Compare the given factors with the generated factors
|
|
346
|
+
let sign = 1;
|
|
347
|
+
for (let f of this.factors) {
|
|
348
|
+
for (let i = 0; i < polyFactors.length; i++) {
|
|
349
|
+
if (f.isEqual(polyFactors[i])) {
|
|
350
|
+
polyFactors.splice(i, 1);
|
|
351
|
+
break;
|
|
352
|
+
}
|
|
353
|
+
else if (f.isOpposedAt(polyFactors[i])) {
|
|
354
|
+
polyFactors.splice(i, 1);
|
|
355
|
+
sign = -sign;
|
|
356
|
+
break;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
// The polyfactors must be empty and the cumulative opposite factors must be 1.
|
|
361
|
+
return (polyFactors.length === 0 && sign === 1);
|
|
362
|
+
};
|
|
363
|
+
this.isDeveloped = (polynomString) => {
|
|
364
|
+
let P;
|
|
365
|
+
// There is at least one parenthese - it is not developed.
|
|
366
|
+
if (polynomString.match(/\(/g).length + polynomString.match(/\)/g).length) {
|
|
367
|
+
return false;
|
|
368
|
+
}
|
|
369
|
+
// Try to build the polynom
|
|
370
|
+
try {
|
|
371
|
+
// Build the polynom
|
|
372
|
+
P = new Polynom(polynomString);
|
|
373
|
+
}
|
|
374
|
+
catch (e) {
|
|
375
|
+
return false;
|
|
376
|
+
}
|
|
377
|
+
// Both polynom aren't the same (once developed and reduced => they cannot be equivalent)
|
|
378
|
+
if (!this.isEqual(P)) {
|
|
379
|
+
return false;
|
|
380
|
+
}
|
|
381
|
+
// Check that everything is completely developed. Actually, there are no parentheses... so it is fully developed
|
|
382
|
+
// maybe it wasn't reduced and not ordered...
|
|
383
|
+
// compare polynom string.
|
|
384
|
+
// normalize the string
|
|
385
|
+
let polynomStringNormalized = polynomString.replaceAll('[*\s]', '');
|
|
386
|
+
// Determine if it's the exact same string.
|
|
387
|
+
// TODO: Maybe it's enough to just make this test !
|
|
388
|
+
return polynomStringNormalized === P.reduce().reorder().display;
|
|
389
|
+
};
|
|
390
|
+
// ------------------------------------------
|
|
391
|
+
// Compare functions
|
|
392
|
+
// -------------------------------------
|
|
393
|
+
this.reduce = () => {
|
|
394
|
+
for (let i = 0; i < this._monoms.length; i++) {
|
|
395
|
+
for (let j = i + 1; j < this._monoms.length; j++) {
|
|
396
|
+
if (this._monoms[i].isSameAs(this.monoms[j])) {
|
|
397
|
+
this._monoms[i].add(this.monoms[j]);
|
|
398
|
+
this._monoms.splice(j, 1);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
// Remove all null monoms
|
|
403
|
+
this._monoms = this._monoms.filter((m) => {
|
|
404
|
+
return m.coefficient.value !== 0;
|
|
405
|
+
});
|
|
406
|
+
// Reduce all monoms coefficient.
|
|
407
|
+
for (const m of this._monoms) {
|
|
408
|
+
m.coefficient.reduce();
|
|
409
|
+
}
|
|
410
|
+
if (this.length === 0) {
|
|
411
|
+
return new Polynom().zero();
|
|
412
|
+
}
|
|
413
|
+
return this;
|
|
414
|
+
};
|
|
415
|
+
this.reorder = (letter = 'x') => {
|
|
416
|
+
// TODO: Must handle multiple setLetter reorder system
|
|
417
|
+
this._monoms.sort(function (a, b) {
|
|
418
|
+
return b.degree(letter).clone().subtract(a.degree(letter)).value;
|
|
419
|
+
});
|
|
420
|
+
return this.reduce();
|
|
421
|
+
};
|
|
422
|
+
this.degree = (letter) => {
|
|
423
|
+
let d = new coefficients_1.Fraction().zero();
|
|
424
|
+
for (const m of this._monoms) {
|
|
425
|
+
d = coefficients_1.Fraction.max(m.degree(letter).value, d);
|
|
426
|
+
}
|
|
427
|
+
return d;
|
|
428
|
+
};
|
|
429
|
+
this.letters = () => {
|
|
430
|
+
let L = [], S = new Set();
|
|
431
|
+
for (let m of this._monoms) {
|
|
432
|
+
S = new Set([...S, ...m.variables]);
|
|
433
|
+
}
|
|
434
|
+
// @ts-ignore
|
|
435
|
+
return [...S];
|
|
436
|
+
};
|
|
437
|
+
/**
|
|
438
|
+
* Replace a variable (letter) by a polynom.
|
|
439
|
+
* @param letter
|
|
440
|
+
* @param P
|
|
441
|
+
*/
|
|
442
|
+
this.replaceBy = (letter, P) => {
|
|
443
|
+
let pow;
|
|
444
|
+
const resultPolynom = new Polynom().zero();
|
|
445
|
+
for (const m of this.monoms) {
|
|
446
|
+
if (m.literal[letter] === undefined || m.literal[letter].isZero()) {
|
|
447
|
+
resultPolynom.add(m.clone());
|
|
448
|
+
}
|
|
449
|
+
else {
|
|
450
|
+
// We have found a setLetter.
|
|
451
|
+
// Get the power and reset it.
|
|
452
|
+
pow = m.literal[letter].clone();
|
|
453
|
+
delete m.literal[letter];
|
|
454
|
+
// TODO: replaceBy works only with positive and natural pow
|
|
455
|
+
resultPolynom.add(P.clone().pow(Math.abs(pow.numerator)).multiply(m));
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
this._monoms = resultPolynom.reduce().reorder().monoms;
|
|
459
|
+
return this;
|
|
460
|
+
};
|
|
461
|
+
// Evaluate a polynom.
|
|
462
|
+
this.evaluate = (values) => {
|
|
463
|
+
const r = new coefficients_1.Fraction().zero();
|
|
464
|
+
this._monoms.forEach(monom => {
|
|
465
|
+
//console.log('Evaluate polynom: ', monom.display, values, monom.evaluate(values).display);
|
|
466
|
+
r.add(monom.evaluate(values));
|
|
467
|
+
});
|
|
468
|
+
return r;
|
|
469
|
+
};
|
|
470
|
+
this.derivative = (letter) => {
|
|
471
|
+
let dP = new Polynom();
|
|
472
|
+
for (let m of this._monoms) {
|
|
473
|
+
dP.add(m.derivative(letter));
|
|
474
|
+
}
|
|
475
|
+
return dP;
|
|
476
|
+
};
|
|
477
|
+
this.primitive = (letter) => {
|
|
478
|
+
let dP = new Polynom();
|
|
479
|
+
for (let m of this._monoms) {
|
|
480
|
+
dP.add(m.primitive(letter));
|
|
481
|
+
}
|
|
482
|
+
return dP;
|
|
483
|
+
};
|
|
484
|
+
// ------------------------------------------
|
|
485
|
+
// Misc polynoms functions
|
|
486
|
+
this.integrate = (a, b, letter) => {
|
|
487
|
+
const primitive = this.primitive(letter);
|
|
488
|
+
if (letter === undefined) {
|
|
489
|
+
letter = 'x';
|
|
490
|
+
}
|
|
491
|
+
let valuesA = {}, valuesB = {};
|
|
492
|
+
valuesA[letter] = new coefficients_1.Fraction(a);
|
|
493
|
+
valuesB[letter] = new coefficients_1.Fraction(b);
|
|
494
|
+
return primitive.evaluate(valuesB).subtract(primitive.evaluate(valuesA));
|
|
495
|
+
};
|
|
496
|
+
// -------------------------------------
|
|
497
|
+
/**
|
|
498
|
+
* Factorize a polynom and store the best results in factors.
|
|
499
|
+
* @param maxValue Defines the greatest value to search to (default is 20).
|
|
500
|
+
*/
|
|
501
|
+
this.factorize = (letter) => {
|
|
502
|
+
let factors = [];
|
|
503
|
+
// Extract the common monom
|
|
504
|
+
let P = this.clone().reorder(), M = P.commonMonom(), tempPolynom;
|
|
505
|
+
// It has a common monom.
|
|
506
|
+
if (!M.isOne()) {
|
|
507
|
+
tempPolynom = new Polynom();
|
|
508
|
+
tempPolynom.monoms = [M];
|
|
509
|
+
factors = [tempPolynom.clone()];
|
|
510
|
+
P = P.euclidian(tempPolynom).quotient;
|
|
511
|
+
}
|
|
512
|
+
let securityLoop = P.degree().clone().multiply(2).value;
|
|
513
|
+
// securityLoop = 0
|
|
514
|
+
while (securityLoop >= 0) {
|
|
515
|
+
securityLoop--;
|
|
516
|
+
if (P.monoms.length < 2) {
|
|
517
|
+
if (!P.isOne()) {
|
|
518
|
+
factors.push(P.clone());
|
|
519
|
+
}
|
|
520
|
+
break;
|
|
521
|
+
}
|
|
522
|
+
else {
|
|
523
|
+
// Get the first and last monom.
|
|
524
|
+
let m1 = P.monoms[0].dividers, m2 = P.monoms[P.monoms.length - 1].dividers;
|
|
525
|
+
for (let m1d of m1) {
|
|
526
|
+
for (let m2d of m2) {
|
|
527
|
+
// if(m1d.degree()===m2d.degree()){continue}
|
|
528
|
+
let dividerPolynom = new Polynom(), result;
|
|
529
|
+
dividerPolynom.monoms = [m1d.clone(), m2d.clone()];
|
|
530
|
+
result = P.euclidian(dividerPolynom);
|
|
531
|
+
if (result.reminder.isZero()) {
|
|
532
|
+
P = result.quotient.clone();
|
|
533
|
+
factors.push(dividerPolynom);
|
|
534
|
+
continue;
|
|
535
|
+
}
|
|
536
|
+
dividerPolynom.monoms = [m1d.clone(), m2d.clone().opposed()];
|
|
537
|
+
result = P.euclidian(dividerPolynom);
|
|
538
|
+
if (result.reminder.isZero()) {
|
|
539
|
+
P = result.quotient.clone();
|
|
540
|
+
factors.push(dividerPolynom);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
this.factors = factors;
|
|
547
|
+
return factors;
|
|
548
|
+
};
|
|
549
|
+
// TODO: get zeroes for more than first degree and for more than natural degrees
|
|
550
|
+
this.getZeroes = () => {
|
|
551
|
+
const Z = [];
|
|
552
|
+
switch (this.degree().value) {
|
|
553
|
+
case 0:
|
|
554
|
+
if (this._monoms[0].coefficient.value === 0) {
|
|
555
|
+
return [true];
|
|
556
|
+
}
|
|
557
|
+
else {
|
|
558
|
+
return [false];
|
|
559
|
+
}
|
|
560
|
+
case 1:
|
|
561
|
+
// There is only one monoms,
|
|
562
|
+
if (this._monoms.length === 1) {
|
|
563
|
+
return [new coefficients_1.Fraction().zero()];
|
|
564
|
+
}
|
|
565
|
+
else {
|
|
566
|
+
const P = this.clone().reduce().reorder();
|
|
567
|
+
return [P.monoms[1].coefficient.opposed().divide(P.monoms[0].coefficient)];
|
|
568
|
+
}
|
|
569
|
+
// TODO: Determine the zeros of an equation of second degree.
|
|
570
|
+
//case 2:
|
|
571
|
+
default:
|
|
572
|
+
// Make sure the polynom is factorized.
|
|
573
|
+
if (this._factors.length === 0) {
|
|
574
|
+
this.factorize();
|
|
575
|
+
}
|
|
576
|
+
let zeroes = [], zeroesAsTex = [];
|
|
577
|
+
for (let P of this._factors) {
|
|
578
|
+
if (P.degree().greater(2)) {
|
|
579
|
+
// TODO: Handle other polynom.
|
|
580
|
+
}
|
|
581
|
+
else if (P.degree().value === 2) {
|
|
582
|
+
let A = P.monomByDegree(2).coefficient, B = P.monomByDegree(1).coefficient, C = P.monomByDegree(0).coefficient, D = B.clone().pow(2).subtract(A.clone().multiply(C).multiply(4));
|
|
583
|
+
if (D.value > 0) {
|
|
584
|
+
/*console.log('Two zeroes for ', P.tex); */
|
|
585
|
+
let x1 = (-(B.value) + Math.sqrt(D.value)) / (2 * A.value), x2 = (-(B.value) - Math.sqrt(D.value)) / (2 * A.value);
|
|
586
|
+
zeroes.push(new coefficients_1.Fraction(x1.toFixed(3)).reduce());
|
|
587
|
+
zeroes.push(new coefficients_1.Fraction(x2.toFixed(3)).reduce());
|
|
588
|
+
}
|
|
589
|
+
else if (D.value === 0) {
|
|
590
|
+
/*console.log('One zero for ', P.tex); */
|
|
591
|
+
}
|
|
592
|
+
else {
|
|
593
|
+
console.log('No zero for ', P.tex);
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
else {
|
|
597
|
+
for (let z of P.getZeroes()) {
|
|
598
|
+
// Check if the zero is already in the list.
|
|
599
|
+
if (z === false || z === true) {
|
|
600
|
+
continue;
|
|
601
|
+
}
|
|
602
|
+
if (zeroesAsTex.indexOf(z.frac) === -1) {
|
|
603
|
+
zeroes.push(z);
|
|
604
|
+
zeroesAsTex.push(z.frac);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
return zeroes;
|
|
610
|
+
}
|
|
611
|
+
return Z;
|
|
612
|
+
};
|
|
613
|
+
// TODO: analyse the next functions to determine if they are useful or not...
|
|
614
|
+
this.monomByDegree = (degree, letter) => {
|
|
615
|
+
if (degree === undefined) {
|
|
616
|
+
// return the highest degree monom.
|
|
617
|
+
return this.monomByDegree(this.degree(letter), letter);
|
|
618
|
+
}
|
|
619
|
+
// Reduce the polynom.
|
|
620
|
+
const M = this.clone().reduce();
|
|
621
|
+
for (const m of M._monoms) {
|
|
622
|
+
if (m.degree(letter).isEqual(degree)) {
|
|
623
|
+
return m.clone();
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
// Nothing was found - return the null monom.
|
|
627
|
+
return new monom_1.Monom().zero();
|
|
628
|
+
};
|
|
629
|
+
this.monomsByDegree = (degree, letter) => {
|
|
630
|
+
if (degree === undefined) {
|
|
631
|
+
// return the highest degree monom.
|
|
632
|
+
return this.monomsByDegree(this.degree(letter));
|
|
633
|
+
}
|
|
634
|
+
// Reduce the polynom.
|
|
635
|
+
let Ms = [];
|
|
636
|
+
const M = this.clone().reduce();
|
|
637
|
+
for (const m of M._monoms) {
|
|
638
|
+
if (m.degree(letter) === degree) {
|
|
639
|
+
Ms.push(m.clone());
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
return Ms;
|
|
643
|
+
// Nothing was found - retur
|
|
644
|
+
};
|
|
645
|
+
// Used in LinearSystem.tex
|
|
646
|
+
this.monomByLetter = (letter) => {
|
|
647
|
+
const M = this.clone().reduce();
|
|
648
|
+
for (const m of M._monoms) {
|
|
649
|
+
if (m.hasLetter(letter)) {
|
|
650
|
+
return m.clone();
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
return new monom_1.Monom().zero();
|
|
654
|
+
};
|
|
655
|
+
// Next functions are used for for commonMonom, which is used in the factorize method.
|
|
656
|
+
this.getDenominators = () => {
|
|
657
|
+
const denominators = [];
|
|
658
|
+
for (const m of this._monoms) {
|
|
659
|
+
denominators.push(m.coefficient.denominator);
|
|
660
|
+
}
|
|
661
|
+
return denominators;
|
|
662
|
+
};
|
|
663
|
+
this.getNumerators = () => {
|
|
664
|
+
const numerators = [];
|
|
665
|
+
for (const m of this._monoms) {
|
|
666
|
+
numerators.push(m.coefficient.numerator);
|
|
667
|
+
}
|
|
668
|
+
return numerators;
|
|
669
|
+
};
|
|
670
|
+
this.lcmDenominator = () => {
|
|
671
|
+
return numeric_1.Numeric.lcm(...this.getDenominators());
|
|
672
|
+
};
|
|
673
|
+
// ------------------------------------------
|
|
674
|
+
// Polynoms factorization functions
|
|
675
|
+
this.gcdDenominator = () => {
|
|
676
|
+
return numeric_1.Numeric.gcd(...this.getDenominators());
|
|
677
|
+
};
|
|
678
|
+
this.lcmNumerator = () => {
|
|
679
|
+
return numeric_1.Numeric.lcm(...this.getNumerators());
|
|
680
|
+
};
|
|
681
|
+
this.gcdNumerator = () => {
|
|
682
|
+
return numeric_1.Numeric.gcd(...this.getNumerators());
|
|
683
|
+
};
|
|
684
|
+
// ------------------------------------------
|
|
685
|
+
// Polynoms helpers functions
|
|
686
|
+
// -------------------------------------
|
|
687
|
+
this.commonMonom = () => {
|
|
688
|
+
let M = new monom_1.Monom().one(), numerator, denominator, degree = this.degree();
|
|
689
|
+
numerator = this.gcdNumerator();
|
|
690
|
+
denominator = this.gcdDenominator();
|
|
691
|
+
M.coefficient = new coefficients_1.Fraction(numerator, denominator);
|
|
692
|
+
for (let L of this.variables) {
|
|
693
|
+
// Initialize the setLetter with the max degree
|
|
694
|
+
M.setLetter(L, degree);
|
|
695
|
+
for (let m of this._monoms) {
|
|
696
|
+
M.setLetter(L, coefficients_1.Fraction.min(m.degree(L), M.degree(L)));
|
|
697
|
+
if (M.degree(L).isZero()) {
|
|
698
|
+
break;
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
return M;
|
|
703
|
+
};
|
|
704
|
+
this.genDisplay = (output, forceSign, wrapParentheses) => {
|
|
705
|
+
let P = '';
|
|
706
|
+
for (const k of this._monoms) {
|
|
707
|
+
if (k.coefficient.value === 0) {
|
|
708
|
+
continue;
|
|
709
|
+
}
|
|
710
|
+
P += `${(k.coefficient.sign() === 1 && (P !== '' || forceSign === true)) ? '+' : ''}${(output === 'tex') ? k.tex : k.display}`;
|
|
711
|
+
}
|
|
712
|
+
if (wrapParentheses === true && this.length > 1) {
|
|
713
|
+
if (output === 'tex') {
|
|
714
|
+
P = `\\left( ${P} \\right)`;
|
|
715
|
+
}
|
|
716
|
+
else {
|
|
717
|
+
P = `(${P})`;
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
if (P === '') {
|
|
721
|
+
P = '0';
|
|
722
|
+
}
|
|
723
|
+
return P;
|
|
724
|
+
};
|
|
725
|
+
/**
|
|
726
|
+
* Main parse using a shutting yard class
|
|
727
|
+
* @param inputStr
|
|
728
|
+
*/
|
|
729
|
+
this.shutingYardToReducedPolynom = (inputStr) => {
|
|
730
|
+
// Get the RPN array of the current expression
|
|
731
|
+
const SY = new shutingyard_1.Shutingyard().parse(inputStr);
|
|
732
|
+
const rpn = SY.rpn;
|
|
733
|
+
// New version for reducing shuting yard.
|
|
734
|
+
this.zero();
|
|
735
|
+
let stack = [], monom = new monom_1.Monom();
|
|
736
|
+
// Loop through the
|
|
737
|
+
for (const element of rpn) {
|
|
738
|
+
Polynom.addToken(stack, element);
|
|
739
|
+
}
|
|
740
|
+
if (stack.length === 1) {
|
|
741
|
+
this.add(stack[0]);
|
|
742
|
+
}
|
|
743
|
+
return this;
|
|
744
|
+
/**
|
|
745
|
+
let m1: Polynom;
|
|
746
|
+
let m2: Polynom;
|
|
747
|
+
|
|
748
|
+
let stack: Polynom[] = [],
|
|
749
|
+
previousToken: string = null,
|
|
750
|
+
tempPolynom
|
|
751
|
+
|
|
752
|
+
for (const element of rpn) {
|
|
753
|
+
if (element.tokenType === 'coefficient' || element.tokenType === 'variable') {
|
|
754
|
+
tempPolynom = new Polynom().zero();
|
|
755
|
+
tempPolynom.monoms = [new Monom(element.token)]
|
|
756
|
+
stack.push(tempPolynom.clone())
|
|
757
|
+
} else if (element.tokenType === 'operation') {
|
|
758
|
+
m2 = (stack.pop()) || new Polynom().zero();
|
|
759
|
+
m1 = (stack.pop()) || new Polynom().zero();
|
|
760
|
+
switch (element.token) {
|
|
761
|
+
case '+':
|
|
762
|
+
stack.push(m1.add(m2))
|
|
763
|
+
break;
|
|
764
|
+
case '-':
|
|
765
|
+
stack.push(m1.subtract(m2))
|
|
766
|
+
break;
|
|
767
|
+
case '*':
|
|
768
|
+
stack.push(m1.multiply(m2))
|
|
769
|
+
break;
|
|
770
|
+
case '^':
|
|
771
|
+
stack.push(m1.pow(+previousToken))
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
previousToken = element.token;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
this._monoms = stack[0].monoms;
|
|
778
|
+
return this;*/
|
|
779
|
+
};
|
|
780
|
+
this.multiplyByPolynom = (P) => {
|
|
781
|
+
const M = [];
|
|
782
|
+
for (const m1 of this._monoms) {
|
|
783
|
+
for (const m2 of P.monoms) {
|
|
784
|
+
M.push(monom_1.Monom.xmultiply(m1, m2));
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
this._monoms = M;
|
|
788
|
+
return this.reduce();
|
|
789
|
+
};
|
|
790
|
+
this.multiplyByFraction = (F) => {
|
|
791
|
+
for (const m of this._monoms) {
|
|
792
|
+
m.coefficient.multiply(F);
|
|
793
|
+
}
|
|
794
|
+
return this.reduce();
|
|
795
|
+
};
|
|
796
|
+
this.multiplyByInteger = (nb) => {
|
|
797
|
+
return this.multiplyByFraction(new coefficients_1.Fraction(nb));
|
|
798
|
+
};
|
|
799
|
+
this.multiplyByMonom = (M) => {
|
|
800
|
+
for (const m of this._monoms) {
|
|
801
|
+
m.multiply(M);
|
|
802
|
+
}
|
|
803
|
+
return this.reduce();
|
|
804
|
+
};
|
|
805
|
+
this.divideByInteger = (nb) => {
|
|
806
|
+
const nbF = new coefficients_1.Fraction(nb);
|
|
807
|
+
for (const m of this._monoms) {
|
|
808
|
+
m.coefficient.divide(nbF);
|
|
809
|
+
}
|
|
810
|
+
return this;
|
|
811
|
+
};
|
|
812
|
+
this.divideByFraction = (F) => {
|
|
813
|
+
for (const m of this._monoms) {
|
|
814
|
+
m.coefficient.divide(F);
|
|
815
|
+
}
|
|
816
|
+
return this;
|
|
817
|
+
};
|
|
818
|
+
this._factorize2ndDegree = (letter) => {
|
|
819
|
+
let P1, P2, a, b, c, delta, x1, x2, factor;
|
|
820
|
+
// One variable only
|
|
821
|
+
if (this.numberOfVars === 1) {
|
|
822
|
+
a = this.monomByDegree(2, letter).coefficient;
|
|
823
|
+
b = this.monomByDegree(1, letter).coefficient;
|
|
824
|
+
c = this.monomByDegree(0, letter).coefficient;
|
|
825
|
+
delta = b.clone().pow(2).subtract(a.clone().multiply(c).multiply(4));
|
|
826
|
+
if (delta.isZero()) {
|
|
827
|
+
x1 = b.clone().opposed().divide(a.clone().multiply(2));
|
|
828
|
+
P1 = new Polynom(letter).subtract(x1.display).multiply(x1.denominator);
|
|
829
|
+
P2 = new Polynom(letter).subtract(x1.display).multiply(x1.denominator);
|
|
830
|
+
factor = a.divide(x1.denominator).divide(x1.denominator);
|
|
831
|
+
if (!factor.isOne()) {
|
|
832
|
+
// TODO: Update new Polynom to accept anything...
|
|
833
|
+
return [new Polynom(factor.display), P1, P2];
|
|
834
|
+
}
|
|
835
|
+
else {
|
|
836
|
+
return [P1, P2];
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
else if (delta.isPositive() && delta.isSquare()) {
|
|
840
|
+
x1 = b.clone().opposed()
|
|
841
|
+
.add(delta.clone().sqrt())
|
|
842
|
+
.divide(a.clone().multiply(2));
|
|
843
|
+
x2 = b.clone().opposed()
|
|
844
|
+
.subtract(delta.clone().sqrt())
|
|
845
|
+
.divide(a.clone().multiply(2));
|
|
846
|
+
// (2x+5)(3x-2)
|
|
847
|
+
// 6x^2+11x-10
|
|
848
|
+
// a = 6, b = 11, c = -10
|
|
849
|
+
// delta = 121-4*6*(-10) = 361= 19^2
|
|
850
|
+
// x1 = (-11 + 19) / 12 = 8/12 = 2/3
|
|
851
|
+
// x2 = (-11 - 19) / 12 = -30/12 = -5/2
|
|
852
|
+
factor = a.divide(x1.denominator).divide(x2.denominator);
|
|
853
|
+
if (factor.isOne()) {
|
|
854
|
+
return [
|
|
855
|
+
new Polynom(letter).subtract(x1.display).multiply(x1.denominator),
|
|
856
|
+
new Polynom(letter).subtract(x2.display).multiply(x2.denominator),
|
|
857
|
+
];
|
|
858
|
+
}
|
|
859
|
+
else {
|
|
860
|
+
return [
|
|
861
|
+
new Polynom(factor.display),
|
|
862
|
+
new Polynom(letter).subtract(x1.display).multiply(x1.denominator),
|
|
863
|
+
new Polynom(letter).subtract(x2.display).multiply(x2.denominator),
|
|
864
|
+
];
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
else {
|
|
868
|
+
// No solution possible - return the complete value.
|
|
869
|
+
return [this.clone()];
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
else {
|
|
873
|
+
// If multiple variables, only handle perfect squares...
|
|
874
|
+
a = this.monomByDegree(2, letter);
|
|
875
|
+
b = this.monomByDegree(1, letter);
|
|
876
|
+
c = this.monomByDegree(0, letter);
|
|
877
|
+
if (a.isLiteralSquare() && c.isLiteralSquare()) {
|
|
878
|
+
// Check the middle item is same as...
|
|
879
|
+
if (b.clone().pow(2).isSameAs(a.clone().multiply(c))) {
|
|
880
|
+
// Determine if the coefficient values matches.
|
|
881
|
+
// Search 4 values (r, s, t, u) that matches:
|
|
882
|
+
// (r X + s Y)(t X + u Y) = rt X^2 + (ru + st) XY + su Y^2
|
|
883
|
+
let xPolynom = new Polynom('x', a.coefficient, b.coefficient, c.coefficient);
|
|
884
|
+
let xFactors = xPolynom._factorize2ndDegree('x');
|
|
885
|
+
let factors = [], xyzPolynom;
|
|
886
|
+
if (xFactors.length >= 2) {
|
|
887
|
+
for (let p of xFactors) {
|
|
888
|
+
if (p.degree().isZero()) {
|
|
889
|
+
factors.push(p.clone());
|
|
890
|
+
}
|
|
891
|
+
else {
|
|
892
|
+
xyzPolynom = p.clone();
|
|
893
|
+
xyzPolynom.monoms[0].literal = a.literalSqrt;
|
|
894
|
+
xyzPolynom.monoms[1].literal = c.literalSqrt;
|
|
895
|
+
factors.push(xyzPolynom.clone());
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
return factors;
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
return [this.clone()];
|
|
903
|
+
//
|
|
904
|
+
// console.log(a.tex, b.tex, c.tex)
|
|
905
|
+
// if (a.isSquare() && c.isSquare()) {
|
|
906
|
+
// console.log('A C squares')
|
|
907
|
+
// if (a.clone().sqrt().multiply(c.clone().sqrt()).multiplyByNumber(2).isSameAs(b)) {
|
|
908
|
+
// console.log('HERE')
|
|
909
|
+
// if (a.coefficient.sign() === b.coefficient.sign()) {
|
|
910
|
+
// return []
|
|
911
|
+
// }else{
|
|
912
|
+
// return []
|
|
913
|
+
// }
|
|
914
|
+
// }
|
|
915
|
+
// } else if(a.isLiteralSquare() && c.isLiteralSquare()) {
|
|
916
|
+
// console.log('A C litteral SQUARES')
|
|
917
|
+
// // Check that the middle element is the product of a and c.
|
|
918
|
+
//
|
|
919
|
+
// if(b.clone().pow(2).isSameAs(a.clone().multiply(c))){
|
|
920
|
+
// console.log('SAME')
|
|
921
|
+
//
|
|
922
|
+
// }else{
|
|
923
|
+
// console.log('NOT SAME')
|
|
924
|
+
// }
|
|
925
|
+
//
|
|
926
|
+
// return [this.clone()]
|
|
927
|
+
// } else {
|
|
928
|
+
// console.log('NOT SQUARES AT ALL !!!!')
|
|
929
|
+
// }
|
|
930
|
+
}
|
|
931
|
+
};
|
|
932
|
+
this._factorizeByGroups = () => {
|
|
933
|
+
// TODO: Factorize by groups.
|
|
934
|
+
return [];
|
|
935
|
+
};
|
|
11
936
|
this._monoms = [];
|
|
12
937
|
this._factors = [];
|
|
13
938
|
if (polynomString !== undefined) {
|
|
@@ -15,21 +940,19 @@ class Polynom {
|
|
|
15
940
|
}
|
|
16
941
|
return this;
|
|
17
942
|
}
|
|
18
|
-
|
|
943
|
+
// ------------------------------------------
|
|
19
944
|
get monoms() {
|
|
20
945
|
return this._monoms;
|
|
21
946
|
}
|
|
22
947
|
set monoms(M) {
|
|
23
948
|
this._monoms = M;
|
|
24
949
|
}
|
|
25
|
-
_factors;
|
|
26
950
|
get factors() {
|
|
27
951
|
return this._factors;
|
|
28
952
|
}
|
|
29
953
|
set factors(value) {
|
|
30
954
|
this._factors = value;
|
|
31
955
|
}
|
|
32
|
-
_texString;
|
|
33
956
|
get texString() {
|
|
34
957
|
return this._texString;
|
|
35
958
|
}
|
|
@@ -47,6 +970,7 @@ class Polynom {
|
|
|
47
970
|
return tex;
|
|
48
971
|
}
|
|
49
972
|
get length() {
|
|
973
|
+
// TODO: Must reduce the monoms list to remove the zero coefficient.
|
|
50
974
|
return this._monoms.length;
|
|
51
975
|
}
|
|
52
976
|
get display() {
|
|
@@ -72,44 +996,37 @@ class Polynom {
|
|
|
72
996
|
for (const m of this._monoms) {
|
|
73
997
|
V = V.concat(m.variables);
|
|
74
998
|
}
|
|
999
|
+
// Remove duplicates.
|
|
75
1000
|
V = [...new Set(V)];
|
|
76
1001
|
return V;
|
|
77
1002
|
}
|
|
78
1003
|
get numberOfVars() {
|
|
79
1004
|
return this.variables.length;
|
|
80
1005
|
}
|
|
81
|
-
parse = (inputStr, ...values) => {
|
|
82
|
-
this._monoms = [];
|
|
83
|
-
this._factors = [];
|
|
84
|
-
if (typeof inputStr === 'string') {
|
|
85
|
-
return this._parseString(inputStr, ...values);
|
|
86
|
-
}
|
|
87
|
-
else if (typeof inputStr === 'number' || inputStr instanceof coefficients_1.Fraction || inputStr instanceof monom_1.Monom) {
|
|
88
|
-
this._monoms.push(new monom_1.Monom(inputStr));
|
|
89
|
-
}
|
|
90
|
-
else if (inputStr instanceof Polynom) {
|
|
91
|
-
for (const m of inputStr.monoms) {
|
|
92
|
-
this._monoms.push(m.clone());
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
return this;
|
|
96
|
-
};
|
|
97
1006
|
_parseString(inputStr, ...values) {
|
|
98
1007
|
if (values === undefined || values.length === 0) {
|
|
99
1008
|
inputStr = '' + inputStr;
|
|
100
1009
|
this._rawString = inputStr;
|
|
1010
|
+
// Parse the polynom using the shutting yard algorithm
|
|
101
1011
|
if (inputStr !== '' && !isNaN(Number(inputStr))) {
|
|
102
1012
|
this.empty();
|
|
1013
|
+
// It's a simple number.
|
|
103
1014
|
let m = new monom_1.Monom(inputStr);
|
|
1015
|
+
// m.coefficient = new Fraction(inputStr);
|
|
1016
|
+
// m.literalStr = '';
|
|
104
1017
|
this.add(m);
|
|
105
1018
|
return this;
|
|
106
1019
|
}
|
|
1020
|
+
// Parse the string.
|
|
107
1021
|
return this.shutingYardToReducedPolynom(inputStr);
|
|
108
1022
|
}
|
|
109
1023
|
else if (/^[a-z]/.test(inputStr)) {
|
|
1024
|
+
// We assume the inputStr contains only letters.
|
|
110
1025
|
this.empty();
|
|
111
1026
|
let fractions = values.map(x => new coefficients_1.Fraction(x));
|
|
1027
|
+
// Multiple setLetter version
|
|
112
1028
|
if (inputStr.length > 1) {
|
|
1029
|
+
// TODO: check that the number of values given correspond to the letters (+1 eventually)
|
|
113
1030
|
let letters = inputStr.split(''), i = 0;
|
|
114
1031
|
for (let F of fractions) {
|
|
115
1032
|
let m = new monom_1.Monom();
|
|
@@ -119,6 +1036,7 @@ class Polynom {
|
|
|
119
1036
|
i++;
|
|
120
1037
|
}
|
|
121
1038
|
}
|
|
1039
|
+
// Single setLetter version
|
|
122
1040
|
else {
|
|
123
1041
|
let n = fractions.length - 1;
|
|
124
1042
|
for (let F of fractions) {
|
|
@@ -135,723 +1053,88 @@ class Polynom {
|
|
|
135
1053
|
return this.zero();
|
|
136
1054
|
}
|
|
137
1055
|
}
|
|
138
|
-
clone = () => {
|
|
139
|
-
const P = new Polynom();
|
|
140
|
-
const M = [];
|
|
141
|
-
for (const m of this._monoms) {
|
|
142
|
-
M.push(m.clone());
|
|
143
|
-
}
|
|
144
|
-
P.monoms = M;
|
|
145
|
-
return P;
|
|
146
|
-
};
|
|
147
|
-
zero = () => {
|
|
148
|
-
this._monoms = [];
|
|
149
|
-
this._monoms.push(new monom_1.Monom().zero());
|
|
150
|
-
this._rawString = '0';
|
|
151
|
-
return this;
|
|
152
|
-
};
|
|
153
|
-
one = () => {
|
|
154
|
-
this._monoms = [];
|
|
155
|
-
this._monoms.push(new monom_1.Monom().one());
|
|
156
|
-
this._rawString = '1';
|
|
157
|
-
return this;
|
|
158
|
-
};
|
|
159
|
-
empty = () => {
|
|
160
|
-
this._monoms = [];
|
|
161
|
-
this._rawString = '';
|
|
162
|
-
return this;
|
|
163
|
-
};
|
|
164
|
-
opposed = () => {
|
|
165
|
-
this._monoms = this._monoms.map(m => m.opposed());
|
|
166
|
-
return this;
|
|
167
|
-
};
|
|
168
|
-
add = (...values) => {
|
|
169
|
-
for (let value of values) {
|
|
170
|
-
if (value instanceof Polynom) {
|
|
171
|
-
this._monoms = this._monoms.concat(value.monoms);
|
|
172
|
-
}
|
|
173
|
-
else if (value instanceof monom_1.Monom) {
|
|
174
|
-
this._monoms.push(value.clone());
|
|
175
|
-
}
|
|
176
|
-
else if (Number.isSafeInteger(value)) {
|
|
177
|
-
this._monoms.push(new monom_1.Monom(value.toString()));
|
|
178
|
-
}
|
|
179
|
-
else {
|
|
180
|
-
this._monoms.push(new monom_1.Monom(value));
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
return this.reduce();
|
|
184
|
-
};
|
|
185
|
-
subtract = (...values) => {
|
|
186
|
-
for (let value of values) {
|
|
187
|
-
if (value instanceof Polynom) {
|
|
188
|
-
this._monoms = this._monoms.concat(value.clone().opposed().monoms);
|
|
189
|
-
}
|
|
190
|
-
else if (value instanceof monom_1.Monom) {
|
|
191
|
-
this._monoms.push(value.clone().opposed());
|
|
192
|
-
}
|
|
193
|
-
else if (Number.isSafeInteger(value)) {
|
|
194
|
-
this._monoms.push(new monom_1.Monom(value.toString()).opposed());
|
|
195
|
-
}
|
|
196
|
-
else {
|
|
197
|
-
this._monoms.push(new monom_1.Monom(value).opposed());
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
return this.reduce();
|
|
201
|
-
};
|
|
202
|
-
multiply = (value) => {
|
|
203
|
-
if (value instanceof Polynom) {
|
|
204
|
-
return this.multiplyByPolynom(value);
|
|
205
|
-
}
|
|
206
|
-
else if (value instanceof coefficients_1.Fraction) {
|
|
207
|
-
return this.multiplyByFraction(value);
|
|
208
|
-
}
|
|
209
|
-
else if (value instanceof monom_1.Monom) {
|
|
210
|
-
return this.multiplyByMonom(value);
|
|
211
|
-
}
|
|
212
|
-
else if (Number.isSafeInteger(value) && typeof value === 'number') {
|
|
213
|
-
return this.multiplyByInteger(value);
|
|
214
|
-
}
|
|
215
|
-
return this;
|
|
216
|
-
};
|
|
217
|
-
euclidian = (P) => {
|
|
218
|
-
const letter = P.variables[0];
|
|
219
|
-
const quotient = new Polynom().zero();
|
|
220
|
-
const reminder = this.clone().reorder(letter);
|
|
221
|
-
if (P.variables.length === 0) {
|
|
222
|
-
return { quotient, reminder };
|
|
223
|
-
}
|
|
224
|
-
const maxMP = P.monomByDegree(undefined, letter);
|
|
225
|
-
const degreeP = P.degree(letter);
|
|
226
|
-
let newM;
|
|
227
|
-
let MaxIteration = this.degree(letter).clone().multiply(2);
|
|
228
|
-
while (reminder.degree(letter).geq(degreeP) && MaxIteration.isPositive()) {
|
|
229
|
-
MaxIteration.subtract(1);
|
|
230
|
-
newM = reminder.monomByDegree(undefined, letter).clone().divide(maxMP);
|
|
231
|
-
if (newM.isZero()) {
|
|
232
|
-
break;
|
|
233
|
-
}
|
|
234
|
-
quotient.add(newM);
|
|
235
|
-
reminder.subtract(P.clone().multiply(newM));
|
|
236
|
-
}
|
|
237
|
-
quotient.reduce();
|
|
238
|
-
reminder.reduce();
|
|
239
|
-
return { quotient, reminder };
|
|
240
|
-
};
|
|
241
|
-
divide = (value) => {
|
|
242
|
-
if (value instanceof coefficients_1.Fraction) {
|
|
243
|
-
return this.divideByFraction(value);
|
|
244
|
-
}
|
|
245
|
-
else if (typeof value === 'number' && Number.isSafeInteger(value)) {
|
|
246
|
-
return this.divideByInteger(value);
|
|
247
|
-
}
|
|
248
|
-
};
|
|
249
|
-
pow = (nb) => {
|
|
250
|
-
if (!Number.isSafeInteger(nb)) {
|
|
251
|
-
return this.zero();
|
|
252
|
-
}
|
|
253
|
-
if (nb < 0) {
|
|
254
|
-
return this.zero();
|
|
255
|
-
}
|
|
256
|
-
if (nb === 0) {
|
|
257
|
-
return new Polynom();
|
|
258
|
-
}
|
|
259
|
-
const P = this.clone();
|
|
260
|
-
for (let i = 1; i < nb; i++) {
|
|
261
|
-
this.multiply(P);
|
|
262
|
-
}
|
|
263
|
-
return this.reduce();
|
|
264
|
-
};
|
|
265
|
-
compare = (P, sign) => {
|
|
266
|
-
if (sign === undefined) {
|
|
267
|
-
sign = '=';
|
|
268
|
-
}
|
|
269
|
-
const cP1 = this.clone().reduce().reorder();
|
|
270
|
-
const cP2 = P.clone().reduce().reorder();
|
|
271
|
-
switch (sign) {
|
|
272
|
-
case '=':
|
|
273
|
-
if (cP1.length !== cP2.length || cP1.degree().isNotEqual(cP2.degree())) {
|
|
274
|
-
return false;
|
|
275
|
-
}
|
|
276
|
-
for (const i in cP1.monoms) {
|
|
277
|
-
if (!cP1.monoms[i].isEqual(cP2.monoms[i])) {
|
|
278
|
-
return false;
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
return true;
|
|
282
|
-
case 'same':
|
|
283
|
-
if (cP1.length !== cP2.length || cP1.degree() !== cP2.degree()) {
|
|
284
|
-
return false;
|
|
285
|
-
}
|
|
286
|
-
for (const i in cP1.monoms) {
|
|
287
|
-
if (!cP1.monoms[i].isSameAs(cP2.monoms[i])) {
|
|
288
|
-
return false;
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
return true;
|
|
292
|
-
default:
|
|
293
|
-
return false;
|
|
294
|
-
}
|
|
295
|
-
};
|
|
296
1056
|
isZero() {
|
|
297
1057
|
return (this._monoms.length === 1 && this._monoms[0].coefficient.isZero()) || this._monoms.length === 0;
|
|
298
1058
|
}
|
|
299
1059
|
isOne() {
|
|
300
1060
|
return this._monoms.length === 1 && this._monoms[0].coefficient.isOne();
|
|
301
1061
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
}
|
|
322
|
-
if (!this.isEqual(P)) {
|
|
323
|
-
return false;
|
|
324
|
-
}
|
|
325
|
-
let polynomStringNormalized = polynomString.replaceAll('*', ''), polynomStringReduced = '' + polynomStringNormalized, factors = [];
|
|
326
|
-
for (let x of polynomStringNormalized.matchAll(/\(([a-z0-9+\-]+)\)(\^[0-9]*)?/g)) {
|
|
327
|
-
if (x[2] !== undefined) {
|
|
328
|
-
for (let i = 0; i < +x[2].substr(1); i++) {
|
|
329
|
-
factors.push(x[1]);
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
else {
|
|
333
|
-
factors.push(x[1]);
|
|
334
|
-
}
|
|
335
|
-
polynomStringReduced = polynomStringReduced.replaceAll(x[0], '');
|
|
336
|
-
}
|
|
337
|
-
if (polynomStringReduced !== '') {
|
|
338
|
-
factors.push(polynomStringReduced);
|
|
339
|
-
}
|
|
340
|
-
let polyFactors = factors.map(x => new Polynom(x));
|
|
341
|
-
this.factorize();
|
|
342
|
-
let sign = 1;
|
|
343
|
-
for (let f of this.factors) {
|
|
344
|
-
for (let i = 0; i < polyFactors.length; i++) {
|
|
345
|
-
if (f.isEqual(polyFactors[i])) {
|
|
346
|
-
polyFactors.splice(i, 1);
|
|
347
|
-
break;
|
|
348
|
-
}
|
|
349
|
-
else if (f.isOpposedAt(polyFactors[i])) {
|
|
350
|
-
polyFactors.splice(i, 1);
|
|
351
|
-
sign = -sign;
|
|
352
|
-
break;
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
return (polyFactors.length === 0 && sign === 1);
|
|
357
|
-
};
|
|
358
|
-
isDeveloped = (polynomString) => {
|
|
359
|
-
let P;
|
|
360
|
-
if (polynomString.match(/\(/g).length + polynomString.match(/\)/g).length) {
|
|
361
|
-
return false;
|
|
362
|
-
}
|
|
363
|
-
try {
|
|
364
|
-
P = new Polynom(polynomString);
|
|
365
|
-
}
|
|
366
|
-
catch (e) {
|
|
367
|
-
return false;
|
|
368
|
-
}
|
|
369
|
-
if (!this.isEqual(P)) {
|
|
370
|
-
return false;
|
|
371
|
-
}
|
|
372
|
-
let polynomStringNormalized = polynomString.replaceAll('[*\s]', '');
|
|
373
|
-
return polynomStringNormalized === P.reduce().reorder().display;
|
|
374
|
-
};
|
|
375
|
-
reduce = () => {
|
|
376
|
-
for (let i = 0; i < this._monoms.length; i++) {
|
|
377
|
-
for (let j = i + 1; j < this._monoms.length; j++) {
|
|
378
|
-
if (this._monoms[i].isSameAs(this.monoms[j])) {
|
|
379
|
-
this._monoms[i].add(this.monoms[j]);
|
|
380
|
-
this._monoms.splice(j, 1);
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
this._monoms = this._monoms.filter((m) => {
|
|
385
|
-
return m.coefficient.value !== 0;
|
|
386
|
-
});
|
|
387
|
-
for (const m of this._monoms) {
|
|
388
|
-
m.coefficient.reduce();
|
|
389
|
-
}
|
|
390
|
-
if (this.length === 0) {
|
|
391
|
-
return new Polynom().zero();
|
|
392
|
-
}
|
|
393
|
-
return this;
|
|
394
|
-
};
|
|
395
|
-
reorder = (letter = 'x') => {
|
|
396
|
-
this._monoms.sort(function (a, b) {
|
|
397
|
-
return b.degree(letter).clone().subtract(a.degree(letter)).value;
|
|
398
|
-
});
|
|
399
|
-
return this.reduce();
|
|
400
|
-
};
|
|
401
|
-
degree = (letter) => {
|
|
402
|
-
let d = new coefficients_1.Fraction().zero();
|
|
403
|
-
for (const m of this._monoms) {
|
|
404
|
-
d = coefficients_1.Fraction.max(m.degree(letter).value, d);
|
|
405
|
-
}
|
|
406
|
-
return d;
|
|
407
|
-
};
|
|
408
|
-
letters = () => {
|
|
409
|
-
let L = [], S = new Set();
|
|
410
|
-
for (let m of this._monoms) {
|
|
411
|
-
S = new Set([...S, ...m.variables]);
|
|
412
|
-
}
|
|
413
|
-
return [...S];
|
|
414
|
-
};
|
|
415
|
-
replaceBy = (letter, P) => {
|
|
416
|
-
let pow;
|
|
417
|
-
const resultPolynom = new Polynom().zero();
|
|
418
|
-
for (const m of this.monoms) {
|
|
419
|
-
if (m.literal[letter] === undefined || m.literal[letter].isZero()) {
|
|
420
|
-
resultPolynom.add(m.clone());
|
|
421
|
-
}
|
|
422
|
-
else {
|
|
423
|
-
pow = m.literal[letter].clone();
|
|
424
|
-
delete m.literal[letter];
|
|
425
|
-
resultPolynom.add(P.clone().pow(Math.abs(pow.numerator)).multiply(m));
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
this._monoms = resultPolynom.reduce().reorder().monoms;
|
|
429
|
-
return this;
|
|
430
|
-
};
|
|
431
|
-
evaluate = (values) => {
|
|
432
|
-
const r = new coefficients_1.Fraction().zero();
|
|
433
|
-
this._monoms.forEach(monom => {
|
|
434
|
-
r.add(monom.evaluate(values));
|
|
435
|
-
});
|
|
436
|
-
return r;
|
|
437
|
-
};
|
|
438
|
-
derivative = (letter) => {
|
|
439
|
-
let dP = new Polynom();
|
|
440
|
-
for (let m of this._monoms) {
|
|
441
|
-
dP.add(m.derivative(letter));
|
|
442
|
-
}
|
|
443
|
-
return dP;
|
|
444
|
-
};
|
|
445
|
-
primitive = (letter) => {
|
|
446
|
-
let dP = new Polynom();
|
|
447
|
-
for (let m of this._monoms) {
|
|
448
|
-
dP.add(m.primitive(letter));
|
|
449
|
-
}
|
|
450
|
-
return dP;
|
|
451
|
-
};
|
|
452
|
-
integrate = (a, b, letter) => {
|
|
453
|
-
const primitive = this.primitive(letter);
|
|
454
|
-
if (letter === undefined) {
|
|
455
|
-
letter = 'x';
|
|
456
|
-
}
|
|
457
|
-
let valuesA = {}, valuesB = {};
|
|
458
|
-
valuesA[letter] = new coefficients_1.Fraction(a);
|
|
459
|
-
valuesB[letter] = new coefficients_1.Fraction(b);
|
|
460
|
-
return primitive.evaluate(valuesB).subtract(primitive.evaluate(valuesA));
|
|
461
|
-
};
|
|
462
|
-
factorize = (letter) => {
|
|
463
|
-
let factors = [];
|
|
464
|
-
let P = this.clone().reorder(), M = P.commonMonom(), tempPolynom;
|
|
465
|
-
if (!M.isOne()) {
|
|
466
|
-
tempPolynom = new Polynom();
|
|
467
|
-
tempPolynom.monoms = [M];
|
|
468
|
-
factors = [tempPolynom.clone()];
|
|
469
|
-
P = P.euclidian(tempPolynom).quotient;
|
|
470
|
-
}
|
|
471
|
-
let securityLoop = P.degree().clone().multiply(2).value;
|
|
472
|
-
while (securityLoop >= 0) {
|
|
473
|
-
securityLoop--;
|
|
474
|
-
if (P.monoms.length < 2) {
|
|
475
|
-
if (!P.isOne()) {
|
|
476
|
-
factors.push(P.clone());
|
|
477
|
-
}
|
|
478
|
-
break;
|
|
479
|
-
}
|
|
480
|
-
else {
|
|
481
|
-
let m1 = P.monoms[0].dividers, m2 = P.monoms[P.monoms.length - 1].dividers;
|
|
482
|
-
for (let m1d of m1) {
|
|
483
|
-
for (let m2d of m2) {
|
|
484
|
-
let dividerPolynom = new Polynom(), result;
|
|
485
|
-
dividerPolynom.monoms = [m1d.clone(), m2d.clone()];
|
|
486
|
-
result = P.euclidian(dividerPolynom);
|
|
487
|
-
if (result.reminder.isZero()) {
|
|
488
|
-
P = result.quotient.clone();
|
|
489
|
-
factors.push(dividerPolynom);
|
|
490
|
-
continue;
|
|
491
|
-
}
|
|
492
|
-
dividerPolynom.monoms = [m1d.clone(), m2d.clone().opposed()];
|
|
493
|
-
result = P.euclidian(dividerPolynom);
|
|
494
|
-
if (result.reminder.isZero()) {
|
|
495
|
-
P = result.quotient.clone();
|
|
496
|
-
factors.push(dividerPolynom);
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
this.factors = factors;
|
|
503
|
-
return factors;
|
|
504
|
-
};
|
|
505
|
-
getZeroes = () => {
|
|
506
|
-
const Z = [];
|
|
507
|
-
switch (this.degree().value) {
|
|
508
|
-
case 0:
|
|
509
|
-
if (this._monoms[0].coefficient.value === 0) {
|
|
510
|
-
return [true];
|
|
511
|
-
}
|
|
512
|
-
else {
|
|
513
|
-
return [false];
|
|
514
|
-
}
|
|
515
|
-
case 1:
|
|
516
|
-
if (this._monoms.length === 1) {
|
|
517
|
-
return [new coefficients_1.Fraction().zero()];
|
|
1062
|
+
}
|
|
1063
|
+
exports.Polynom = Polynom;
|
|
1064
|
+
Polynom.addToken = (stack, element) => {
|
|
1065
|
+
switch (element.tokenType) {
|
|
1066
|
+
case shutingyard_1.ShutingyardType.COEFFICIENT:
|
|
1067
|
+
stack.push(new Polynom(element.token));
|
|
1068
|
+
break;
|
|
1069
|
+
case shutingyard_1.ShutingyardType.VARIABLE:
|
|
1070
|
+
stack.push(new Polynom().add(new monom_1.Monom(element.token)));
|
|
1071
|
+
break;
|
|
1072
|
+
case shutingyard_1.ShutingyardType.CONSTANT:
|
|
1073
|
+
// TODO: add constant support to Polynom parsing.
|
|
1074
|
+
console.log('Actually, not supported - will be added later !');
|
|
1075
|
+
break;
|
|
1076
|
+
case shutingyard_1.ShutingyardType.OPERATION:
|
|
1077
|
+
if (stack.length >= 2) {
|
|
1078
|
+
const b = stack.pop(), a = stack.pop();
|
|
1079
|
+
if (element.token === '+') {
|
|
1080
|
+
stack.push(a.add(b));
|
|
518
1081
|
}
|
|
519
|
-
else {
|
|
520
|
-
|
|
521
|
-
return [P.monoms[1].coefficient.opposed().divide(P.monoms[0].coefficient)];
|
|
1082
|
+
else if (element.token === '-') {
|
|
1083
|
+
stack.push(a.subtract(b));
|
|
522
1084
|
}
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
this.factorize();
|
|
1085
|
+
else if (element.token === '*') {
|
|
1086
|
+
stack.push(a.multiply(b));
|
|
526
1087
|
}
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
}
|
|
531
|
-
else if (P.degree().value === 2) {
|
|
532
|
-
let A = P.monomByDegree(2).coefficient, B = P.monomByDegree(1).coefficient, C = P.monomByDegree(0).coefficient, D = B.clone().pow(2).subtract(A.clone().multiply(C).multiply(4));
|
|
533
|
-
if (D.value > 0) {
|
|
534
|
-
let x1 = (-(B.value) + Math.sqrt(D.value)) / (2 * A.value), x2 = (-(B.value) - Math.sqrt(D.value)) / (2 * A.value);
|
|
535
|
-
zeroes.push(new coefficients_1.Fraction(x1.toFixed(3)).reduce());
|
|
536
|
-
zeroes.push(new coefficients_1.Fraction(x2.toFixed(3)).reduce());
|
|
537
|
-
}
|
|
538
|
-
else if (D.value === 0) {
|
|
539
|
-
}
|
|
540
|
-
else {
|
|
541
|
-
console.log('No zero for ', P.tex);
|
|
542
|
-
}
|
|
1088
|
+
else if (element.token === '/') {
|
|
1089
|
+
if (b.degree().isStrictlyPositive()) {
|
|
1090
|
+
console.log('divide by a polynom -> should create a rational polynom !');
|
|
543
1091
|
}
|
|
544
1092
|
else {
|
|
545
|
-
|
|
546
|
-
if (z === false || z === true) {
|
|
547
|
-
continue;
|
|
548
|
-
}
|
|
549
|
-
if (zeroesAsTex.indexOf(z.frac) === -1) {
|
|
550
|
-
zeroes.push(z);
|
|
551
|
-
zeroesAsTex.push(z.frac);
|
|
552
|
-
}
|
|
553
|
-
}
|
|
1093
|
+
stack.push(a.divide(b.monoms[0].coefficient));
|
|
554
1094
|
}
|
|
555
1095
|
}
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
};
|
|
560
|
-
monomByDegree = (degree, letter) => {
|
|
561
|
-
if (degree === undefined) {
|
|
562
|
-
return this.monomByDegree(this.degree(letter), letter);
|
|
563
|
-
}
|
|
564
|
-
const M = this.clone().reduce();
|
|
565
|
-
for (const m of M._monoms) {
|
|
566
|
-
if (m.degree(letter).isEqual(degree)) {
|
|
567
|
-
return m.clone();
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
return new monom_1.Monom().zero();
|
|
571
|
-
};
|
|
572
|
-
monomsByDegree = (degree, letter) => {
|
|
573
|
-
if (degree === undefined) {
|
|
574
|
-
return this.monomsByDegree(this.degree(letter));
|
|
575
|
-
}
|
|
576
|
-
let Ms = [];
|
|
577
|
-
const M = this.clone().reduce();
|
|
578
|
-
for (const m of M._monoms) {
|
|
579
|
-
if (m.degree(letter) === degree) {
|
|
580
|
-
Ms.push(m.clone());
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
return Ms;
|
|
584
|
-
};
|
|
585
|
-
monomByLetter = (letter) => {
|
|
586
|
-
const M = this.clone().reduce();
|
|
587
|
-
for (const m of M._monoms) {
|
|
588
|
-
if (m.hasLetter(letter)) {
|
|
589
|
-
return m.clone();
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
return new monom_1.Monom().zero();
|
|
593
|
-
};
|
|
594
|
-
getDenominators = () => {
|
|
595
|
-
const denominators = [];
|
|
596
|
-
for (const m of this._monoms) {
|
|
597
|
-
denominators.push(m.coefficient.denominator);
|
|
598
|
-
}
|
|
599
|
-
return denominators;
|
|
600
|
-
};
|
|
601
|
-
getNumerators = () => {
|
|
602
|
-
const numerators = [];
|
|
603
|
-
for (const m of this._monoms) {
|
|
604
|
-
numerators.push(m.coefficient.numerator);
|
|
605
|
-
}
|
|
606
|
-
return numerators;
|
|
607
|
-
};
|
|
608
|
-
lcmDenominator = () => {
|
|
609
|
-
return numeric_1.Numeric.lcm(...this.getDenominators());
|
|
610
|
-
};
|
|
611
|
-
gcdDenominator = () => {
|
|
612
|
-
return numeric_1.Numeric.gcd(...this.getDenominators());
|
|
613
|
-
};
|
|
614
|
-
lcmNumerator = () => {
|
|
615
|
-
return numeric_1.Numeric.lcm(...this.getNumerators());
|
|
616
|
-
};
|
|
617
|
-
gcdNumerator = () => {
|
|
618
|
-
return numeric_1.Numeric.gcd(...this.getNumerators());
|
|
619
|
-
};
|
|
620
|
-
commonMonom = () => {
|
|
621
|
-
let M = new monom_1.Monom().one(), numerator, denominator, degree = this.degree();
|
|
622
|
-
numerator = this.gcdNumerator();
|
|
623
|
-
denominator = this.gcdDenominator();
|
|
624
|
-
M.coefficient = new coefficients_1.Fraction(numerator, denominator);
|
|
625
|
-
for (let L of this.variables) {
|
|
626
|
-
M.setLetter(L, degree);
|
|
627
|
-
for (let m of this._monoms) {
|
|
628
|
-
M.setLetter(L, coefficients_1.Fraction.min(m.degree(L), M.degree(L)));
|
|
629
|
-
if (M.degree(L).isZero()) {
|
|
630
|
-
break;
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
|
-
return M;
|
|
635
|
-
};
|
|
636
|
-
genDisplay = (output, forceSign, wrapParentheses) => {
|
|
637
|
-
let P = '';
|
|
638
|
-
for (const k of this._monoms) {
|
|
639
|
-
if (k.coefficient.value === 0) {
|
|
640
|
-
continue;
|
|
641
|
-
}
|
|
642
|
-
P += `${(k.coefficient.sign() === 1 && (P !== '' || forceSign === true)) ? '+' : ''}${(output === 'tex') ? k.tex : k.display}`;
|
|
643
|
-
}
|
|
644
|
-
if (wrapParentheses === true && this.length > 1) {
|
|
645
|
-
if (output === 'tex') {
|
|
646
|
-
P = `\\left( ${P} \\right)`;
|
|
647
|
-
}
|
|
648
|
-
else {
|
|
649
|
-
P = `(${P})`;
|
|
650
|
-
}
|
|
651
|
-
}
|
|
652
|
-
if (P === '') {
|
|
653
|
-
P = '0';
|
|
654
|
-
}
|
|
655
|
-
return P;
|
|
656
|
-
};
|
|
657
|
-
static addToken = (stack, element) => {
|
|
658
|
-
switch (element.tokenType) {
|
|
659
|
-
case shutingyard_1.ShutingyardType.COEFFICIENT:
|
|
660
|
-
stack.push(new Polynom(element.token));
|
|
661
|
-
break;
|
|
662
|
-
case shutingyard_1.ShutingyardType.VARIABLE:
|
|
663
|
-
stack.push(new Polynom().add(new monom_1.Monom(element.token)));
|
|
664
|
-
break;
|
|
665
|
-
case shutingyard_1.ShutingyardType.CONSTANT:
|
|
666
|
-
console.log('Actually, not supported - will be added later !');
|
|
667
|
-
break;
|
|
668
|
-
case shutingyard_1.ShutingyardType.OPERATION:
|
|
669
|
-
if (stack.length >= 2) {
|
|
670
|
-
const b = stack.pop(), a = stack.pop();
|
|
671
|
-
if (element.token === '+') {
|
|
672
|
-
stack.push(a.add(b));
|
|
673
|
-
}
|
|
674
|
-
else if (element.token === '-') {
|
|
675
|
-
stack.push(a.subtract(b));
|
|
676
|
-
}
|
|
677
|
-
else if (element.token === '*') {
|
|
678
|
-
stack.push(a.multiply(b));
|
|
679
|
-
}
|
|
680
|
-
else if (element.token === '/') {
|
|
681
|
-
if (b.degree().isStrictlyPositive()) {
|
|
682
|
-
console.log('divide by a polynom -> should create a rational polynom !');
|
|
683
|
-
}
|
|
684
|
-
else {
|
|
685
|
-
stack.push(a.divide(b.monoms[0].coefficient));
|
|
686
|
-
}
|
|
1096
|
+
else if (element.token === '^') {
|
|
1097
|
+
if (b.degree().isStrictlyPositive()) {
|
|
1098
|
+
console.error('Cannot elevate a polynom with another polynom !');
|
|
687
1099
|
}
|
|
688
|
-
else
|
|
689
|
-
if (b.
|
|
690
|
-
|
|
1100
|
+
else {
|
|
1101
|
+
if (b.monoms[0].coefficient.isRelative()) {
|
|
1102
|
+
// Integer power
|
|
1103
|
+
stack.push(a.pow(b.monoms[0].coefficient.value));
|
|
691
1104
|
}
|
|
692
1105
|
else {
|
|
693
|
-
if
|
|
694
|
-
|
|
1106
|
+
// Only allow power if the previous polynom is only a monom, without coefficient.
|
|
1107
|
+
if (a.monoms.length === 1 && a.monoms[0].coefficient.isOne()) {
|
|
1108
|
+
for (let letter in a.monoms[0].literal) {
|
|
1109
|
+
a.monoms[0].literal[letter].multiply(b.monoms[0].coefficient);
|
|
1110
|
+
}
|
|
1111
|
+
stack.push(a);
|
|
695
1112
|
}
|
|
696
1113
|
else {
|
|
697
|
-
|
|
698
|
-
for (let letter in a.monoms[0].literal) {
|
|
699
|
-
a.monoms[0].literal[letter].multiply(b.monoms[0].coefficient);
|
|
700
|
-
}
|
|
701
|
-
stack.push(a);
|
|
702
|
-
}
|
|
703
|
-
else {
|
|
704
|
-
console.error('Cannot have power with fraction');
|
|
705
|
-
}
|
|
1114
|
+
console.error('Cannot have power with fraction');
|
|
706
1115
|
}
|
|
707
1116
|
}
|
|
708
1117
|
}
|
|
709
1118
|
}
|
|
710
|
-
else {
|
|
711
|
-
console.log('Stack size: ', stack.length);
|
|
712
|
-
if (element.token === '-') {
|
|
713
|
-
stack.push(stack.pop().opposed());
|
|
714
|
-
}
|
|
715
|
-
else {
|
|
716
|
-
console.log('While parsing, cannot apply ', element.token, 'to', stack[0].tex);
|
|
717
|
-
}
|
|
718
|
-
}
|
|
719
|
-
break;
|
|
720
|
-
case shutingyard_1.ShutingyardType.MONOM:
|
|
721
|
-
console.error('The monom token should not appear here');
|
|
722
|
-
break;
|
|
723
|
-
case shutingyard_1.ShutingyardType.FUNCTION:
|
|
724
|
-
console.log('The function token should not appear here - might be introduced later.');
|
|
725
|
-
break;
|
|
726
|
-
}
|
|
727
|
-
};
|
|
728
|
-
shutingYardToReducedPolynom = (inputStr) => {
|
|
729
|
-
const SY = new shutingyard_1.Shutingyard().parse(inputStr);
|
|
730
|
-
const rpn = SY.rpn;
|
|
731
|
-
this.zero();
|
|
732
|
-
let stack = [], monom = new monom_1.Monom();
|
|
733
|
-
for (const element of rpn) {
|
|
734
|
-
Polynom.addToken(stack, element);
|
|
735
|
-
}
|
|
736
|
-
if (stack.length === 1) {
|
|
737
|
-
this.add(stack[0]);
|
|
738
|
-
}
|
|
739
|
-
return this;
|
|
740
|
-
};
|
|
741
|
-
multiplyByPolynom = (P) => {
|
|
742
|
-
const M = [];
|
|
743
|
-
for (const m1 of this._monoms) {
|
|
744
|
-
for (const m2 of P.monoms) {
|
|
745
|
-
M.push(monom_1.Monom.xmultiply(m1, m2));
|
|
746
1119
|
}
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
multiplyByFraction = (F) => {
|
|
752
|
-
for (const m of this._monoms) {
|
|
753
|
-
m.coefficient.multiply(F);
|
|
754
|
-
}
|
|
755
|
-
return this.reduce();
|
|
756
|
-
};
|
|
757
|
-
multiplyByInteger = (nb) => {
|
|
758
|
-
return this.multiplyByFraction(new coefficients_1.Fraction(nb));
|
|
759
|
-
};
|
|
760
|
-
multiplyByMonom = (M) => {
|
|
761
|
-
for (const m of this._monoms) {
|
|
762
|
-
m.multiply(M);
|
|
763
|
-
}
|
|
764
|
-
return this.reduce();
|
|
765
|
-
};
|
|
766
|
-
divideByInteger = (nb) => {
|
|
767
|
-
const nbF = new coefficients_1.Fraction(nb);
|
|
768
|
-
for (const m of this._monoms) {
|
|
769
|
-
m.coefficient.divide(nbF);
|
|
770
|
-
}
|
|
771
|
-
return this;
|
|
772
|
-
};
|
|
773
|
-
divideByFraction = (F) => {
|
|
774
|
-
for (const m of this._monoms) {
|
|
775
|
-
m.coefficient.divide(F);
|
|
776
|
-
}
|
|
777
|
-
return this;
|
|
778
|
-
};
|
|
779
|
-
_factorize2ndDegree = (letter) => {
|
|
780
|
-
let P1, P2, a, b, c, delta, x1, x2, factor;
|
|
781
|
-
if (this.numberOfVars === 1) {
|
|
782
|
-
a = this.monomByDegree(2, letter).coefficient;
|
|
783
|
-
b = this.monomByDegree(1, letter).coefficient;
|
|
784
|
-
c = this.monomByDegree(0, letter).coefficient;
|
|
785
|
-
delta = b.clone().pow(2).subtract(a.clone().multiply(c).multiply(4));
|
|
786
|
-
if (delta.isZero()) {
|
|
787
|
-
x1 = b.clone().opposed().divide(a.clone().multiply(2));
|
|
788
|
-
P1 = new Polynom(letter).subtract(x1.display).multiply(x1.denominator);
|
|
789
|
-
P2 = new Polynom(letter).subtract(x1.display).multiply(x1.denominator);
|
|
790
|
-
factor = a.divide(x1.denominator).divide(x1.denominator);
|
|
791
|
-
if (!factor.isOne()) {
|
|
792
|
-
return [new Polynom(factor.display), P1, P2];
|
|
793
|
-
}
|
|
794
|
-
else {
|
|
795
|
-
return [P1, P2];
|
|
796
|
-
}
|
|
797
|
-
}
|
|
798
|
-
else if (delta.isPositive() && delta.isSquare()) {
|
|
799
|
-
x1 = b.clone().opposed()
|
|
800
|
-
.add(delta.clone().sqrt())
|
|
801
|
-
.divide(a.clone().multiply(2));
|
|
802
|
-
x2 = b.clone().opposed()
|
|
803
|
-
.subtract(delta.clone().sqrt())
|
|
804
|
-
.divide(a.clone().multiply(2));
|
|
805
|
-
factor = a.divide(x1.denominator).divide(x2.denominator);
|
|
806
|
-
if (factor.isOne()) {
|
|
807
|
-
return [
|
|
808
|
-
new Polynom(letter).subtract(x1.display).multiply(x1.denominator),
|
|
809
|
-
new Polynom(letter).subtract(x2.display).multiply(x2.denominator),
|
|
810
|
-
];
|
|
1120
|
+
else {
|
|
1121
|
+
console.log('Stack size: ', stack.length);
|
|
1122
|
+
if (element.token === '-') {
|
|
1123
|
+
stack.push(stack.pop().opposed());
|
|
811
1124
|
}
|
|
812
1125
|
else {
|
|
813
|
-
|
|
814
|
-
new Polynom(factor.display),
|
|
815
|
-
new Polynom(letter).subtract(x1.display).multiply(x1.denominator),
|
|
816
|
-
new Polynom(letter).subtract(x2.display).multiply(x2.denominator),
|
|
817
|
-
];
|
|
818
|
-
}
|
|
819
|
-
}
|
|
820
|
-
else {
|
|
821
|
-
return [this.clone()];
|
|
822
|
-
}
|
|
823
|
-
}
|
|
824
|
-
else {
|
|
825
|
-
a = this.monomByDegree(2, letter);
|
|
826
|
-
b = this.monomByDegree(1, letter);
|
|
827
|
-
c = this.monomByDegree(0, letter);
|
|
828
|
-
if (a.isLiteralSquare() && c.isLiteralSquare()) {
|
|
829
|
-
if (b.clone().pow(2).isSameAs(a.clone().multiply(c))) {
|
|
830
|
-
let xPolynom = new Polynom('x', a.coefficient, b.coefficient, c.coefficient);
|
|
831
|
-
let xFactors = xPolynom._factorize2ndDegree('x');
|
|
832
|
-
let factors = [], xyzPolynom;
|
|
833
|
-
if (xFactors.length >= 2) {
|
|
834
|
-
for (let p of xFactors) {
|
|
835
|
-
if (p.degree().isZero()) {
|
|
836
|
-
factors.push(p.clone());
|
|
837
|
-
}
|
|
838
|
-
else {
|
|
839
|
-
xyzPolynom = p.clone();
|
|
840
|
-
xyzPolynom.monoms[0].literal = a.literalSqrt;
|
|
841
|
-
xyzPolynom.monoms[1].literal = c.literalSqrt;
|
|
842
|
-
factors.push(xyzPolynom.clone());
|
|
843
|
-
}
|
|
844
|
-
}
|
|
845
|
-
return factors;
|
|
846
|
-
}
|
|
1126
|
+
console.log('While parsing, cannot apply ', element.token, 'to', stack[0].tex);
|
|
847
1127
|
}
|
|
848
1128
|
}
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
1129
|
+
break;
|
|
1130
|
+
case shutingyard_1.ShutingyardType.MONOM:
|
|
1131
|
+
// Should never appear.
|
|
1132
|
+
console.error('The monom token should not appear here');
|
|
1133
|
+
break;
|
|
1134
|
+
case shutingyard_1.ShutingyardType.FUNCTION:
|
|
1135
|
+
// Should never appear.
|
|
1136
|
+
console.log('The function token should not appear here - might be introduced later.');
|
|
1137
|
+
break;
|
|
1138
|
+
}
|
|
1139
|
+
};
|
|
857
1140
|
//# sourceMappingURL=polynom.js.map
|