pimath 0.0.58 → 0.0.61
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 +164 -259
- package/dist/pi.js.map +1 -1
- package/dist/pi.min.js +1 -1
- package/dist/pi.min.js.map +1 -1
- package/esm/maths/algebra/monom.d.ts +1 -0
- package/esm/maths/algebra/monom.js +15 -0
- package/esm/maths/algebra/monom.js.map +1 -1
- package/esm/maths/algebra/polynom.d.ts +23 -4
- package/esm/maths/algebra/polynom.js +142 -257
- package/esm/maths/algebra/polynom.js.map +1 -1
- package/esm/maths/algebra/rational.d.ts +2 -0
- package/esm/maths/algebra/rational.js +7 -2
- package/esm/maths/algebra/rational.js.map +1 -1
- package/package.json +1 -1
- package/src/maths/algebra/monom.ts +16 -0
- package/src/maths/algebra/polynom.ts +180 -270
- package/src/maths/algebra/rational.ts +12 -2
- package/tests/algebra/monom.test.ts +2 -5
- package/tests/algebra/polynom.test.ts +2 -3
- package/tests/numexp.test.ts +1 -1
|
@@ -10,6 +10,7 @@ import {Equation, ISolution} from "./equation";
|
|
|
10
10
|
|
|
11
11
|
export type PolynomParsingType = string | Polynom | number | Fraction | Monom
|
|
12
12
|
|
|
13
|
+
interface IEuclidian{ quotient: Polynom, reminder: Polynom }
|
|
13
14
|
/**
|
|
14
15
|
* Polynom class can handle polynoms, reorder, resolve, ...
|
|
15
16
|
* ```
|
|
@@ -19,6 +20,15 @@ export type PolynomParsingType = string | Polynom | number | Fraction | Monom
|
|
|
19
20
|
export class Polynom {
|
|
20
21
|
private _rawString: string;
|
|
21
22
|
|
|
23
|
+
private _euclidianCache: {[Key:string]:IEuclidian}
|
|
24
|
+
get euclidianCache(): { [p: string]: IEuclidian } {
|
|
25
|
+
return this._euclidianCache;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
set euclidianCache(value: { [p: string]: IEuclidian }) {
|
|
29
|
+
this._euclidianCache = value;
|
|
30
|
+
}
|
|
31
|
+
|
|
22
32
|
/**
|
|
23
33
|
*
|
|
24
34
|
* @param {string} polynomString (optional) Default polynom to parse on class creation
|
|
@@ -27,12 +37,36 @@ export class Polynom {
|
|
|
27
37
|
constructor(polynomString?: PolynomParsingType, ...values: unknown[]) {
|
|
28
38
|
this._monoms = [];
|
|
29
39
|
this._factors = [];
|
|
40
|
+
this.mark_as_dirty()
|
|
41
|
+
|
|
30
42
|
if (polynomString !== undefined) {
|
|
31
43
|
this.parse(polynomString, ...values);
|
|
32
44
|
}
|
|
33
45
|
return this;
|
|
34
46
|
}
|
|
35
47
|
|
|
48
|
+
// Getter and setter
|
|
49
|
+
private _dirty_zeroes: boolean
|
|
50
|
+
|
|
51
|
+
get dirty_zeroes(): boolean {
|
|
52
|
+
return this._dirty_zeroes;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
set dirty_zeroes(value: boolean) {
|
|
56
|
+
this._dirty_zeroes = value;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
private _dirty_factors: boolean
|
|
60
|
+
|
|
61
|
+
// ------------------------------------------
|
|
62
|
+
get dirty_factors(): boolean {
|
|
63
|
+
return this._dirty_factors;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
set dirty_factors(value: boolean) {
|
|
67
|
+
this._dirty_factors = value;
|
|
68
|
+
}
|
|
69
|
+
|
|
36
70
|
private _monoms: Monom[];
|
|
37
71
|
|
|
38
72
|
// ------------------------------------------
|
|
@@ -44,8 +78,11 @@ export class Polynom {
|
|
|
44
78
|
this._monoms = M;
|
|
45
79
|
}
|
|
46
80
|
|
|
47
|
-
|
|
48
|
-
|
|
81
|
+
private _zeroes: ISolution[]
|
|
82
|
+
|
|
83
|
+
get zeroes(): ISolution[] {
|
|
84
|
+
return this.getZeroes()
|
|
85
|
+
}
|
|
49
86
|
|
|
50
87
|
private _factors: Polynom[];
|
|
51
88
|
|
|
@@ -54,6 +91,7 @@ export class Polynom {
|
|
|
54
91
|
}
|
|
55
92
|
|
|
56
93
|
set factors(value: Polynom[]) {
|
|
94
|
+
this.mark_as_dirty()
|
|
57
95
|
this._factors = value;
|
|
58
96
|
}
|
|
59
97
|
|
|
@@ -128,8 +166,13 @@ export class Polynom {
|
|
|
128
166
|
return this.genDisplay('tex', false, false, true)
|
|
129
167
|
}
|
|
130
168
|
|
|
131
|
-
|
|
169
|
+
mark_as_dirty = (): void => {
|
|
170
|
+
this.dirty_factors = true
|
|
171
|
+
this.dirty_zeroes = true
|
|
172
|
+
this.euclidianCache = {}
|
|
173
|
+
}
|
|
132
174
|
|
|
175
|
+
addToken = (stack: Polynom[], element: Token): void => {
|
|
133
176
|
switch (element.tokenType) {
|
|
134
177
|
case ShutingyardType.COEFFICIENT:
|
|
135
178
|
stack.push(new Polynom(element.token))
|
|
@@ -217,6 +260,7 @@ export class Polynom {
|
|
|
217
260
|
// Reset the main variables.
|
|
218
261
|
this._monoms = []
|
|
219
262
|
this._factors = []
|
|
263
|
+
this.mark_as_dirty()
|
|
220
264
|
|
|
221
265
|
if (typeof inputStr === 'string') {
|
|
222
266
|
return this._parseString(inputStr, ...values)
|
|
@@ -251,6 +295,7 @@ export class Polynom {
|
|
|
251
295
|
}
|
|
252
296
|
|
|
253
297
|
P.monoms = M;
|
|
298
|
+
|
|
254
299
|
return P;
|
|
255
300
|
};
|
|
256
301
|
|
|
@@ -262,6 +307,7 @@ export class Polynom {
|
|
|
262
307
|
this._monoms = [];
|
|
263
308
|
this._monoms.push(new Monom().zero());
|
|
264
309
|
this._rawString = '0';
|
|
310
|
+
this.mark_as_dirty()
|
|
265
311
|
return this;
|
|
266
312
|
};
|
|
267
313
|
|
|
@@ -269,87 +315,30 @@ export class Polynom {
|
|
|
269
315
|
this._monoms = [];
|
|
270
316
|
this._monoms.push(new Monom().one());
|
|
271
317
|
this._rawString = '1';
|
|
318
|
+
this.mark_as_dirty()
|
|
272
319
|
return this;
|
|
273
320
|
}
|
|
274
321
|
|
|
275
322
|
empty = (): Polynom => {
|
|
276
323
|
this._monoms = [];
|
|
277
324
|
this._rawString = '';
|
|
325
|
+
this.mark_as_dirty()
|
|
278
326
|
return this;
|
|
279
327
|
};
|
|
280
328
|
|
|
281
329
|
// ------------------------------------------
|
|
282
330
|
opposed = (): Polynom => {
|
|
283
331
|
this._monoms = this._monoms.map(m => m.opposed());
|
|
332
|
+
this.mark_as_dirty()
|
|
284
333
|
return this;
|
|
285
334
|
};
|
|
286
335
|
|
|
287
|
-
// // -----------------------------------------------
|
|
288
|
-
// // Polynom generators and randomizers
|
|
289
|
-
// // -----------------------------------------------
|
|
290
|
-
// random(config?: randomPolynomConfig) {
|
|
291
|
-
// return Random.polynom(config);
|
|
292
|
-
// }
|
|
293
|
-
//
|
|
294
|
-
// private _randomizeDefaults: { [key: string]: number | string | boolean } = {
|
|
295
|
-
// degree: 2,
|
|
296
|
-
// unit: true,
|
|
297
|
-
// fractions: false,
|
|
298
|
-
// factorable: false,
|
|
299
|
-
// letters: 'x',
|
|
300
|
-
// allowNullMonom: false,
|
|
301
|
-
// numberOfMonoms: false
|
|
302
|
-
// };
|
|
303
|
-
// get randomizeDefaults(): { [key: string]: number | string | boolean } {
|
|
304
|
-
// return this._randomizeDefaults;
|
|
305
|
-
// }
|
|
306
|
-
//
|
|
307
|
-
// set randomizeDefaults(value) {
|
|
308
|
-
// this._randomizeDefaults = value;
|
|
309
|
-
// }
|
|
310
|
-
//
|
|
311
|
-
// randomize = (config: { [key: string]: number | string | boolean }): Polynom => {
|
|
312
|
-
// let P = new Polynom();
|
|
313
|
-
//
|
|
314
|
-
// // Check the config file and use the default values.
|
|
315
|
-
// if (config === undefined) {
|
|
316
|
-
// config = {};
|
|
317
|
-
// }
|
|
318
|
-
// for (let k in this._randomizeDefaults) {
|
|
319
|
-
// if (config[k] === undefined) {
|
|
320
|
-
// config[k] = this._randomizeDefaults[k];
|
|
321
|
-
// }
|
|
322
|
-
// }
|
|
323
|
-
//
|
|
324
|
-
// // TODO: Build a more robust randomize function
|
|
325
|
-
// return P;
|
|
326
|
-
// }
|
|
327
|
-
//
|
|
328
|
-
// rndFactorable = (degree: number = 2, unit: boolean | number = false, letters: string = 'x'): Polynom => {
|
|
329
|
-
// // TODO: Make rndFactorable polynom generator more user friendly
|
|
330
|
-
// this._factors = [];
|
|
331
|
-
// for (let i = 0; i < degree; i++) {
|
|
332
|
-
// let factorUnit = unit === true || i >= unit,
|
|
333
|
-
// p = Random.polynom({
|
|
334
|
-
// degree: 1,
|
|
335
|
-
// unit: factorUnit,
|
|
336
|
-
// fraction: false,
|
|
337
|
-
// letters
|
|
338
|
-
// });
|
|
339
|
-
// this._factors.push(p);
|
|
340
|
-
// }
|
|
341
|
-
//
|
|
342
|
-
// this.empty().monoms = this._factors[0].monoms;
|
|
343
|
-
// for (let i = 1; i < this._factors.length; i++) {
|
|
344
|
-
// this.multiply(this._factors[i]);
|
|
345
|
-
// }
|
|
346
|
-
// return this;
|
|
347
|
-
// };
|
|
348
336
|
|
|
349
337
|
// ------------------------------------------
|
|
350
338
|
// Mathematical operations
|
|
351
339
|
|
|
352
340
|
add = (...values: unknown[]): Polynom => {
|
|
341
|
+
this.mark_as_dirty()
|
|
353
342
|
|
|
354
343
|
for (let value of values) {
|
|
355
344
|
if (value instanceof Polynom) {
|
|
@@ -367,6 +356,7 @@ export class Polynom {
|
|
|
367
356
|
};
|
|
368
357
|
|
|
369
358
|
subtract = (...values: unknown[]): Polynom => {
|
|
359
|
+
this.mark_as_dirty()
|
|
370
360
|
|
|
371
361
|
for (let value of values) {
|
|
372
362
|
if (value instanceof Polynom) {
|
|
@@ -384,6 +374,8 @@ export class Polynom {
|
|
|
384
374
|
};
|
|
385
375
|
|
|
386
376
|
multiply = (value: unknown): Polynom => {
|
|
377
|
+
this.mark_as_dirty()
|
|
378
|
+
|
|
387
379
|
if (value instanceof Polynom) {
|
|
388
380
|
return this.multiplyByPolynom(value);
|
|
389
381
|
} else if (value instanceof Fraction) {
|
|
@@ -403,7 +395,12 @@ export class Polynom {
|
|
|
403
395
|
* @param P
|
|
404
396
|
* returns {quotient: Polynom, reminder: Polynom}
|
|
405
397
|
*/
|
|
406
|
-
euclidian = (P: Polynom):
|
|
398
|
+
euclidian = (P: Polynom): IEuclidian => {
|
|
399
|
+
|
|
400
|
+
if(this.euclidianCache[P.tex]!==undefined){
|
|
401
|
+
return this.euclidianCache[P.tex]
|
|
402
|
+
}
|
|
403
|
+
|
|
407
404
|
const letter: string = P.variables[0];
|
|
408
405
|
const quotient: Polynom = new Polynom().zero();
|
|
409
406
|
const reminder: Polynom = this.clone().reorder(letter);
|
|
@@ -448,6 +445,8 @@ export class Polynom {
|
|
|
448
445
|
};
|
|
449
446
|
|
|
450
447
|
divide = (value: unknown): Polynom => {
|
|
448
|
+
this.mark_as_dirty()
|
|
449
|
+
|
|
451
450
|
if (value instanceof Fraction) {
|
|
452
451
|
return this.divideByFraction(value);
|
|
453
452
|
} else if (typeof value === 'number' && Number.isSafeInteger(value)) {
|
|
@@ -460,6 +459,8 @@ export class Polynom {
|
|
|
460
459
|
}
|
|
461
460
|
|
|
462
461
|
pow = (nb: number): Polynom => {
|
|
462
|
+
this.mark_as_dirty()
|
|
463
|
+
|
|
463
464
|
if (!Number.isSafeInteger(nb)) {
|
|
464
465
|
return this.zero();
|
|
465
466
|
}
|
|
@@ -705,6 +706,8 @@ export class Polynom {
|
|
|
705
706
|
* @param P
|
|
706
707
|
*/
|
|
707
708
|
replaceBy = (letter: string, P: Polynom): Polynom => {
|
|
709
|
+
this.mark_as_dirty()
|
|
710
|
+
|
|
708
711
|
let pow: Fraction;
|
|
709
712
|
const resultPolynom: Polynom = new Polynom().zero();
|
|
710
713
|
|
|
@@ -780,157 +783,124 @@ export class Polynom {
|
|
|
780
783
|
* @param maxValue Defines the greatest value to search to (default is 20).
|
|
781
784
|
*/
|
|
782
785
|
factorize = (letter?: string): Polynom[] => {
|
|
783
|
-
|
|
786
|
+
if (this.dirty_factors) {
|
|
784
787
|
|
|
785
|
-
|
|
786
|
-
let P = this.clone().reorder(),
|
|
787
|
-
M = P.commonMonom(),
|
|
788
|
-
tempPolynom: Polynom
|
|
789
|
-
|
|
790
|
-
// It has a common monom.
|
|
791
|
-
if (!M.isOne()) {
|
|
792
|
-
tempPolynom = new Polynom(M)
|
|
793
|
-
factors = [tempPolynom.clone()]
|
|
794
|
-
P = P.euclidian(tempPolynom).quotient;
|
|
795
|
-
}
|
|
788
|
+
let factors: Polynom[] = [];
|
|
796
789
|
|
|
797
|
-
|
|
798
|
-
let result
|
|
799
|
-
// securityLoop = 0
|
|
790
|
+
let P = this.clone().reorder()
|
|
800
791
|
|
|
801
|
-
|
|
802
|
-
|
|
792
|
+
// Extract the common monom
|
|
793
|
+
// 2x^3+6x^2 => 2x^2
|
|
794
|
+
let M = P.commonMonom()
|
|
795
|
+
if (!M.isOne()) {
|
|
796
|
+
let tempPolynom: Polynom = new Polynom(M)
|
|
797
|
+
factors = [tempPolynom.clone()]
|
|
798
|
+
P = P.euclidian(tempPolynom).quotient;
|
|
799
|
+
}
|
|
803
800
|
|
|
804
|
-
|
|
805
|
-
|
|
801
|
+
// Main loop
|
|
802
|
+
let securityLoop = P.degree().clone().multiply(2).value,
|
|
803
|
+
maxDegree = 1
|
|
804
|
+
while (securityLoop >= 0) {
|
|
805
|
+
securityLoop--
|
|
806
|
+
|
|
807
|
+
if (P.monoms.length < 2) {
|
|
808
|
+
// The polynom has only one monom => 7x^2
|
|
809
|
+
// No need to continue.
|
|
810
|
+
if (!P.isOne()) {
|
|
811
|
+
factors.push(P.clone())
|
|
812
|
+
P.one()
|
|
813
|
+
}
|
|
814
|
+
break
|
|
815
|
+
} else if (P.degree(letter).isOne()) {
|
|
816
|
+
// The polynom is a first degree polynom => 3x-5
|
|
817
|
+
// No need to continue
|
|
806
818
|
factors.push(P.clone())
|
|
807
819
|
P.one()
|
|
820
|
+
break
|
|
821
|
+
} else {
|
|
822
|
+
// Create the list of all "potential" polynom dividers.
|
|
823
|
+
let allDividers: Polynom[] = this._getAllPotentialFactors(P, maxDegree, letter)
|
|
824
|
+
maxDegree = P.degree(letter).value
|
|
825
|
+
|
|
826
|
+
|
|
827
|
+
// Actually: 100ms
|
|
828
|
+
while (allDividers.length > 0) {
|
|
829
|
+
let div = allDividers[0]
|
|
830
|
+
|
|
831
|
+
if (!P.isDividableBy(div)) {
|
|
832
|
+
// Not dividable. Remove it from the list
|
|
833
|
+
allDividers.shift()
|
|
834
|
+
} else {
|
|
835
|
+
// Add the factor
|
|
836
|
+
factors.push(div)
|
|
837
|
+
|
|
838
|
+
// It's dividable - so make the division
|
|
839
|
+
let result = P.euclidian(div)
|
|
840
|
+
|
|
841
|
+
// As it's dividable, get the quotient.
|
|
842
|
+
P = result.quotient.clone()
|
|
843
|
+
|
|
844
|
+
// filter all dividers that are no more suitable.
|
|
845
|
+
allDividers = allDividers.filter(x => {
|
|
846
|
+
let pX = P.monoms[0],
|
|
847
|
+
pC = P.monoms[P.monoms.length - 1],
|
|
848
|
+
dX = x.monoms[0],
|
|
849
|
+
dC = x.monoms[x.monoms.length - 1]
|
|
850
|
+
|
|
851
|
+
// Check last item (degree zero)
|
|
852
|
+
if(!pC.isDivisible(dC)){return false}
|
|
853
|
+
|
|
854
|
+
// Check the first item (degree max)
|
|
855
|
+
if(!pX.isDivisible(dX)){return false}
|
|
856
|
+
|
|
857
|
+
return true
|
|
858
|
+
})
|
|
859
|
+
}
|
|
860
|
+
}
|
|
808
861
|
}
|
|
809
|
-
|
|
810
|
-
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
// Maybe there is still something in the Polynom (not everything was possible to factorize)
|
|
865
|
+
if (!P.isOne()) {
|
|
811
866
|
factors.push(P.clone())
|
|
812
|
-
P.one()
|
|
813
|
-
break
|
|
814
|
-
} else {
|
|
815
|
-
// Get the first and last monom and build all their dividers.
|
|
816
|
-
// let m1 = P.monoms[0].dividers,
|
|
817
|
-
// m2 = P.monoms[P.monoms.length - 1].dividers
|
|
818
|
-
|
|
819
|
-
// Create the list of all "potential" polynom dividers.
|
|
820
|
-
let allDividers: Polynom[] = this._getAllPotentialFactors(P, letter)
|
|
821
|
-
|
|
822
|
-
allDividers.every(div => {
|
|
823
|
-
result = P.euclidian(div)
|
|
824
|
-
if (result.reminder.isZero()) {
|
|
825
|
-
P = result.quotient.clone()
|
|
826
|
-
factors.push(div)
|
|
827
|
-
return false
|
|
828
|
-
}
|
|
829
|
-
return true
|
|
830
|
-
})
|
|
831
867
|
}
|
|
832
|
-
}
|
|
833
868
|
|
|
834
|
-
|
|
835
|
-
factors
|
|
869
|
+
// Save the factors
|
|
870
|
+
this.factors = factors
|
|
871
|
+
|
|
872
|
+
// The factors list is no more dirty
|
|
873
|
+
this.dirty_factors = false
|
|
836
874
|
}
|
|
837
875
|
|
|
838
|
-
this.factors
|
|
839
|
-
return factors;
|
|
876
|
+
return this.factors;
|
|
840
877
|
}
|
|
841
878
|
|
|
879
|
+
isDividableBy = (div: Polynom): boolean => {
|
|
880
|
+
// Quick evaluation.
|
|
881
|
+
if (div.degree().isOne()) {
|
|
882
|
+
let zero = div.getZeroes()[0]
|
|
883
|
+
|
|
884
|
+
if (zero.exact instanceof Fraction) {
|
|
885
|
+
return this.evaluate(zero.exact).isZero()
|
|
886
|
+
} else {
|
|
887
|
+
return false
|
|
888
|
+
}
|
|
889
|
+
} else {
|
|
890
|
+
this.euclidianCache[div.tex] = this.euclidian(div)
|
|
891
|
+
return this.euclidianCache[div.tex].reminder.isZero()
|
|
892
|
+
}
|
|
893
|
+
}
|
|
842
894
|
// TODO: get zeroes for more than first degree and for more than natural degrees
|
|
843
895
|
getZeroes = (): ISolution[] => {
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
//
|
|
853
|
-
// switch (this.degree().value) {
|
|
854
|
-
// case 0:
|
|
855
|
-
// if (this._monoms[0].coefficient.value === 0) {
|
|
856
|
-
// return [{
|
|
857
|
-
// tex: '\\mathbb{R}',
|
|
858
|
-
// value: NaN,
|
|
859
|
-
// exact: false
|
|
860
|
-
// }];
|
|
861
|
-
// } else {
|
|
862
|
-
// return [{
|
|
863
|
-
// tex: '\\varnothing',
|
|
864
|
-
// value: NaN,
|
|
865
|
-
// exact: false
|
|
866
|
-
// }];
|
|
867
|
-
// }
|
|
868
|
-
// case 1:
|
|
869
|
-
// // There is only one monoms,
|
|
870
|
-
// if (this._monoms.length === 1) {
|
|
871
|
-
// return [{
|
|
872
|
-
// tex: '0',
|
|
873
|
-
// value: 0,
|
|
874
|
-
// exact: new Fraction().zero()
|
|
875
|
-
// }];
|
|
876
|
-
// } else {
|
|
877
|
-
// const P = this.clone().reduce().reorder();
|
|
878
|
-
// const coeff = P.monoms[1].coefficient.opposed().divide(P.monoms[0].coefficient)
|
|
879
|
-
// return [{
|
|
880
|
-
// tex: coeff.tex,
|
|
881
|
-
// value: coeff.value,
|
|
882
|
-
// exact: coeff
|
|
883
|
-
// }];
|
|
884
|
-
// }
|
|
885
|
-
// // TODO: Determine the zeros of an equation of second degree.
|
|
886
|
-
// //case 2:
|
|
887
|
-
// default:
|
|
888
|
-
// // Make sure the polynom is factorized.
|
|
889
|
-
// if (this._factors.length === 0) {
|
|
890
|
-
// this.factorize()
|
|
891
|
-
// }
|
|
892
|
-
//
|
|
893
|
-
// let zeroes:Fraction[] = [], zeroesAsTex = [];
|
|
894
|
-
// for (let P of this._factors) {
|
|
895
|
-
// if (P.degree().greater(2)) {
|
|
896
|
-
// // TODO: get zeroes of polynom with a degree greater than 2.
|
|
897
|
-
//
|
|
898
|
-
// } else if (P.degree().value === 2) {
|
|
899
|
-
// let A = P.monomByDegree(2).coefficient,
|
|
900
|
-
// B = P.monomByDegree(1).coefficient,
|
|
901
|
-
// C = P.monomByDegree(0).coefficient,
|
|
902
|
-
// D = B.clone().pow(2).subtract(A.clone().multiply(C).multiply(4));
|
|
903
|
-
//
|
|
904
|
-
// if (D.value > 0) {
|
|
905
|
-
// /*console.log('Two zeroes for ', P.tex); */
|
|
906
|
-
// let x1 = (-(B.value) + Math.sqrt(D.value)) / (2 * A.value),
|
|
907
|
-
// x2 = (-(B.value) - Math.sqrt(D.value)) / (2 * A.value);
|
|
908
|
-
//
|
|
909
|
-
// zeroes.push(new Fraction(x1.toFixed(3)).reduce());
|
|
910
|
-
// zeroes.push(new Fraction(x2.toFixed(3)).reduce());
|
|
911
|
-
// } else if (D.value === 0) {
|
|
912
|
-
// /*console.log('One zero for ', P.tex); */
|
|
913
|
-
// } else {
|
|
914
|
-
// console.log('No zero for ', P.tex);
|
|
915
|
-
// }
|
|
916
|
-
// } else {
|
|
917
|
-
// for (let z of P.getZeroes()) {
|
|
918
|
-
// // Check if the zero is already in the list.
|
|
919
|
-
// // if (z === false || z === true) {
|
|
920
|
-
// // continue;
|
|
921
|
-
// // }
|
|
922
|
-
// if (zeroesAsTex.indexOf(z.frac) === -1) {
|
|
923
|
-
// zeroes.push(z);
|
|
924
|
-
// zeroesAsTex.push(z.frac);
|
|
925
|
-
// }
|
|
926
|
-
// }
|
|
927
|
-
// }
|
|
928
|
-
// }
|
|
929
|
-
//
|
|
930
|
-
//
|
|
931
|
-
// return zeroes;
|
|
932
|
-
// }
|
|
933
|
-
// return Z;
|
|
896
|
+
if (this.dirty_zeroes) {
|
|
897
|
+
let equ = new Equation(this.clone(), 0)
|
|
898
|
+
equ.solve()
|
|
899
|
+
this._zeroes = equ.solutions
|
|
900
|
+
this.dirty_zeroes = false
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
return this._zeroes
|
|
934
904
|
};
|
|
935
905
|
|
|
936
906
|
// TODO: analyse the next functions to determine if they are useful or not...
|
|
@@ -1071,18 +1041,21 @@ export class Polynom {
|
|
|
1071
1041
|
return (new Fraction()).zero()
|
|
1072
1042
|
}
|
|
1073
1043
|
|
|
1074
|
-
private _getAllPotentialFactors = (P: Polynom, letter
|
|
1044
|
+
private _getAllPotentialFactors = (P: Polynom, maxDegree: number, letter: string): Polynom[] => {
|
|
1075
1045
|
let m1 = P.monoms[0].dividers,
|
|
1076
1046
|
m2 = P.monoms[P.monoms.length - 1].dividers
|
|
1077
1047
|
|
|
1078
1048
|
let allDividers: Polynom[] = []
|
|
1079
1049
|
m1.forEach(m1d => {
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1050
|
+
// Get only polynom that has a degree less than a specific value
|
|
1051
|
+
if(m1d.degree(letter).leq(maxDegree)) {
|
|
1052
|
+
m2.forEach(m2d => {
|
|
1053
|
+
if (m1d.degree(letter).isNotEqual(m2d.degree(letter))) {
|
|
1054
|
+
allDividers.push(new Polynom(m1d, m2d))
|
|
1055
|
+
allDividers.push(new Polynom(m1d, m2d.clone().opposed()))
|
|
1056
|
+
}
|
|
1057
|
+
})
|
|
1058
|
+
}
|
|
1086
1059
|
})
|
|
1087
1060
|
|
|
1088
1061
|
return allDividers
|
|
@@ -1200,41 +1173,6 @@ export class Polynom {
|
|
|
1200
1173
|
}
|
|
1201
1174
|
|
|
1202
1175
|
return this
|
|
1203
|
-
/**
|
|
1204
|
-
let m1: Polynom;
|
|
1205
|
-
let m2: Polynom;
|
|
1206
|
-
|
|
1207
|
-
let stack: Polynom[] = [],
|
|
1208
|
-
previousToken: string = null,
|
|
1209
|
-
tempPolynom
|
|
1210
|
-
|
|
1211
|
-
for (const element of rpn) {
|
|
1212
|
-
if (element.tokenType === 'coefficient' || element.tokenType === 'variable') {
|
|
1213
|
-
tempPolynom = new Polynom().zero();
|
|
1214
|
-
tempPolynom.monoms = [new Monom(element.token)]
|
|
1215
|
-
stack.push(tempPolynom.clone())
|
|
1216
|
-
} else if (element.tokenType === 'operation') {
|
|
1217
|
-
m2 = (stack.pop()) || new Polynom().zero();
|
|
1218
|
-
m1 = (stack.pop()) || new Polynom().zero();
|
|
1219
|
-
switch (element.token) {
|
|
1220
|
-
case '+':
|
|
1221
|
-
stack.push(m1.add(m2))
|
|
1222
|
-
break;
|
|
1223
|
-
case '-':
|
|
1224
|
-
stack.push(m1.subtract(m2))
|
|
1225
|
-
break;
|
|
1226
|
-
case '*':
|
|
1227
|
-
stack.push(m1.multiply(m2))
|
|
1228
|
-
break;
|
|
1229
|
-
case '^':
|
|
1230
|
-
stack.push(m1.pow(+previousToken))
|
|
1231
|
-
}
|
|
1232
|
-
}
|
|
1233
|
-
previousToken = element.token;
|
|
1234
|
-
}
|
|
1235
|
-
|
|
1236
|
-
this._monoms = stack[0].monoms;
|
|
1237
|
-
return this;*/
|
|
1238
1176
|
}
|
|
1239
1177
|
|
|
1240
1178
|
private multiplyByPolynom = (P: Polynom): Polynom => {
|
|
@@ -1375,34 +1313,6 @@ export class Polynom {
|
|
|
1375
1313
|
}
|
|
1376
1314
|
|
|
1377
1315
|
return [this.clone()]
|
|
1378
|
-
//
|
|
1379
|
-
// console.log(a.tex, b.tex, c.tex)
|
|
1380
|
-
// if (a.isSquare() && c.isSquare()) {
|
|
1381
|
-
// console.log('A C squares')
|
|
1382
|
-
// if (a.clone().sqrt().multiply(c.clone().sqrt()).multiplyByNumber(2).isSameAs(b)) {
|
|
1383
|
-
// console.log('HERE')
|
|
1384
|
-
// if (a.coefficient.sign() === b.coefficient.sign()) {
|
|
1385
|
-
// return []
|
|
1386
|
-
// }else{
|
|
1387
|
-
// return []
|
|
1388
|
-
// }
|
|
1389
|
-
// }
|
|
1390
|
-
// } else if(a.isLiteralSquare() && c.isLiteralSquare()) {
|
|
1391
|
-
// console.log('A C litteral SQUARES')
|
|
1392
|
-
// // Check that the middle element is the product of a and c.
|
|
1393
|
-
//
|
|
1394
|
-
// if(b.clone().pow(2).isSameAs(a.clone().multiply(c))){
|
|
1395
|
-
// console.log('SAME')
|
|
1396
|
-
//
|
|
1397
|
-
// }else{
|
|
1398
|
-
// console.log('NOT SAME')
|
|
1399
|
-
// }
|
|
1400
|
-
//
|
|
1401
|
-
// return [this.clone()]
|
|
1402
|
-
// } else {
|
|
1403
|
-
// console.log('NOT SQUARES AT ALL !!!!')
|
|
1404
|
-
// }
|
|
1405
|
-
|
|
1406
1316
|
}
|
|
1407
1317
|
}
|
|
1408
1318
|
|
|
@@ -67,10 +67,11 @@ export class Rational {
|
|
|
67
67
|
|
|
68
68
|
domain = (): string => {
|
|
69
69
|
let zeroes = this._denominator.getZeroes();
|
|
70
|
+
|
|
70
71
|
if (zeroes.length === 0 || zeroes[0].tex === PARTICULAR_SOLUTION.real) {
|
|
71
|
-
return PARTICULAR_SOLUTION.real
|
|
72
|
-
} else if (zeroes[0].tex === PARTICULAR_SOLUTION.varnothing) {
|
|
73
72
|
return PARTICULAR_SOLUTION.varnothing
|
|
73
|
+
} else if (zeroes[0].tex === PARTICULAR_SOLUTION.varnothing) {
|
|
74
|
+
return PARTICULAR_SOLUTION.real
|
|
74
75
|
} else {
|
|
75
76
|
return '\\mathbb{R}\\setminus\\left\\{' +
|
|
76
77
|
zeroes.map(x => x.tex).join(';') + '\\right\\}'
|
|
@@ -312,4 +313,13 @@ export class Rational {
|
|
|
312
313
|
get plotFunction():string {
|
|
313
314
|
return `(${this._numerator.plotFunction})/(${this._denominator.plotFunction})`
|
|
314
315
|
}
|
|
316
|
+
|
|
317
|
+
evaluate = (values: literalType | Fraction | number): Fraction => {
|
|
318
|
+
const r = new Fraction().zero();
|
|
319
|
+
|
|
320
|
+
let N = this._numerator.evaluate(values),
|
|
321
|
+
D = this._numerator.evaluate(values)
|
|
322
|
+
|
|
323
|
+
return N.divide(D)
|
|
324
|
+
};
|
|
315
325
|
}
|
|
@@ -18,7 +18,7 @@ describe('Monom with integer power', () => {
|
|
|
18
18
|
expect(M1.tex).to.be.equal('3x^{5}')
|
|
19
19
|
|
|
20
20
|
const M2 = new Monom('2/3x^2yz^3y^4')
|
|
21
|
-
expect(M2.display).to.be.equal('2/3x^
|
|
21
|
+
expect(M2.display).to.be.equal('2/3x^(2)y^(5)z^(3)')
|
|
22
22
|
|
|
23
23
|
const M3 = new Monom('-3x^(-2)')
|
|
24
24
|
expect(M3.tex).to.be.equal('-3x^{-2}')
|
|
@@ -49,7 +49,7 @@ describe('Monom with integer power', () => {
|
|
|
49
49
|
|
|
50
50
|
it('integrate', () => { // the single test
|
|
51
51
|
const options = new Monom('7x^3'); // this will be your class
|
|
52
|
-
expect(options.primitive().display).to.be.equal('7/4x^4');
|
|
52
|
+
expect(options.primitive().display).to.be.equal('7/4x^(4)');
|
|
53
53
|
});
|
|
54
54
|
|
|
55
55
|
it('randomize', function () {
|
|
@@ -73,9 +73,6 @@ describe('Monom with fraction power', () => {
|
|
|
73
73
|
|
|
74
74
|
M.multiply(N.clone())
|
|
75
75
|
|
|
76
|
-
console.log(M.tex)
|
|
77
|
-
|
|
78
|
-
// TODO: Problem while displaying numerical expression
|
|
79
76
|
expect(M.tex).to.be.equal('-\\frac{ 7 }{ 5 }x^{\\tfrac{ 22 }{ 15 }}')
|
|
80
77
|
})
|
|
81
78
|
})
|