pimath 0.0.104 → 0.0.106
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 +120 -70
- 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/polynom.d.ts +1 -1
- package/esm/maths/algebra/polynom.js +42 -6
- package/esm/maths/algebra/polynom.js.map +1 -1
- package/esm/maths/expressions/numexp.js +1 -1
- package/esm/maths/expressions/numexp.js.map +1 -1
- package/esm/maths/shutingyard.d.ts +2 -8
- package/esm/maths/shutingyard.js +77 -63
- package/esm/maths/shutingyard.js.map +1 -1
- package/package.json +1 -1
- package/src/maths/algebra/polynom.ts +79 -33
- package/src/maths/expressions/numexp.ts +1 -1
- package/src/maths/shutingyard.ts +77 -80
- package/tests/algebra/polynom.test.ts +25 -6
- package/tests/numexp.test.ts +6 -2
- package/dev/pi.js +0 -7866
- package/dev/pi.js.map +0 -1
package/dist/pi.js
CHANGED
|
@@ -2495,10 +2495,23 @@ class Polynom {
|
|
|
2495
2495
|
else if (typeof value === 'number' && Number.isSafeInteger(value)) {
|
|
2496
2496
|
return this.divideByInteger(value);
|
|
2497
2497
|
}
|
|
2498
|
+
else if (value instanceof monom_1.Monom) {
|
|
2499
|
+
return this.divide(new Polynom(value));
|
|
2500
|
+
}
|
|
2498
2501
|
else if (value instanceof Polynom) {
|
|
2499
2502
|
if (value.monoms.length === 1 && value.variables.length === 0) {
|
|
2500
2503
|
return this.divideByFraction(value.monoms[0].coefficient);
|
|
2501
2504
|
}
|
|
2505
|
+
else {
|
|
2506
|
+
let { quotient, reminder } = this.euclidian(value);
|
|
2507
|
+
if (reminder.isZero()) {
|
|
2508
|
+
return quotient;
|
|
2509
|
+
}
|
|
2510
|
+
else {
|
|
2511
|
+
console.log(`${this.tex} is not divideable by ${value.tex}`);
|
|
2512
|
+
return new Polynom().zero();
|
|
2513
|
+
}
|
|
2514
|
+
}
|
|
2502
2515
|
}
|
|
2503
2516
|
};
|
|
2504
2517
|
this.pow = (nb) => {
|
|
@@ -2568,7 +2581,7 @@ class Polynom {
|
|
|
2568
2581
|
this.isOpposedAt = (P) => {
|
|
2569
2582
|
return this.compare(P.clone().opposed(), '=');
|
|
2570
2583
|
};
|
|
2571
|
-
this.isFactorized = (polynomString) => {
|
|
2584
|
+
this.isFactorized = (polynomString, soft) => {
|
|
2572
2585
|
let P;
|
|
2573
2586
|
// Check if polynom is complete...
|
|
2574
2587
|
if (polynomString.split('(').length !== polynomString.split(')').length) {
|
|
@@ -2590,44 +2603,67 @@ class Polynom {
|
|
|
2590
2603
|
let polynomStringNormalized = polynomString.replaceAll('*', ''), polynomStringReduced = '' + polynomStringNormalized, factors = [];
|
|
2591
2604
|
for (let x of polynomStringNormalized.matchAll(/\(([a-z0-9+\-]+)\)(\^[0-9]*)?/g)) {
|
|
2592
2605
|
if (x[2] !== undefined) {
|
|
2606
|
+
// if there is an exponential value, add it multiple times
|
|
2593
2607
|
for (let i = 0; i < +x[2].substring(1); i++) {
|
|
2594
2608
|
factors.push(x[1]);
|
|
2595
2609
|
}
|
|
2596
2610
|
}
|
|
2597
2611
|
else {
|
|
2612
|
+
// no power - add it once.
|
|
2598
2613
|
factors.push(x[1]);
|
|
2599
2614
|
}
|
|
2615
|
+
// Remove the current polynom
|
|
2600
2616
|
polynomStringReduced = polynomStringReduced.replaceAll(x[0], '');
|
|
2601
2617
|
}
|
|
2602
2618
|
if (polynomStringReduced !== '') {
|
|
2603
2619
|
factors.push(polynomStringReduced);
|
|
2604
2620
|
}
|
|
2605
2621
|
let polyFactors = factors.map(x => new Polynom(x));
|
|
2622
|
+
// polyFactors contain all polynoms.
|
|
2623
|
+
let checkPolyFactors = polyFactors.filter(x => x.degree().geq(1) && !x.commonMonom().isOne());
|
|
2624
|
+
// Some polynoms are not completely factorized.
|
|
2625
|
+
if (checkPolyFactors.length > 0 && !soft) {
|
|
2626
|
+
return false;
|
|
2627
|
+
}
|
|
2628
|
+
if (checkPolyFactors.length > 0 && soft) {
|
|
2629
|
+
polyFactors = polyFactors.filter(x => x.commonMonom().isOne());
|
|
2630
|
+
let FactorizedConstant = new fraction_1.Fraction().one();
|
|
2631
|
+
for (let p of checkPolyFactors) {
|
|
2632
|
+
let k = p.commonMonom(), pFactor = p.clone().divide(k);
|
|
2633
|
+
if (k.degree().isZero()) {
|
|
2634
|
+
FactorizedConstant.multiply(k.coefficient);
|
|
2635
|
+
polyFactors.push(pFactor.clone());
|
|
2636
|
+
}
|
|
2637
|
+
}
|
|
2638
|
+
}
|
|
2606
2639
|
// Factorize the current polynom.
|
|
2607
2640
|
this.factorize();
|
|
2608
|
-
// console.log('RESULT BEFORE COMPARE')
|
|
2609
|
-
// console.log(polynomString, polynomStringNormalized)
|
|
2610
|
-
// console.log(factors)
|
|
2611
|
-
// console.log(this.factors.map(x=>x.display))
|
|
2612
2641
|
// Compare the given factors with the generated factors
|
|
2613
|
-
let sign = 1;
|
|
2642
|
+
let sign = 1, notFoundedFactors = [];
|
|
2614
2643
|
for (let f of this.factors) {
|
|
2644
|
+
// The factor is just a coefficient. Might be opposed
|
|
2615
2645
|
if (f.degree().isZero()) {
|
|
2616
2646
|
if (f.monoms[0].coefficient.isNegativeOne()) {
|
|
2617
2647
|
sign = -sign;
|
|
2618
2648
|
}
|
|
2619
2649
|
}
|
|
2650
|
+
let factorFound = false;
|
|
2620
2651
|
for (let i = 0; i < polyFactors.length; i++) {
|
|
2621
2652
|
if (f.isEqual(polyFactors[i])) {
|
|
2622
2653
|
polyFactors.splice(i, 1);
|
|
2654
|
+
factorFound = true;
|
|
2623
2655
|
break;
|
|
2624
2656
|
}
|
|
2625
2657
|
else if (f.isOpposedAt(polyFactors[i])) {
|
|
2626
2658
|
polyFactors.splice(i, 1);
|
|
2627
2659
|
sign = -sign;
|
|
2660
|
+
factorFound = true;
|
|
2628
2661
|
break;
|
|
2629
2662
|
}
|
|
2630
2663
|
}
|
|
2664
|
+
if (!factorFound) {
|
|
2665
|
+
notFoundedFactors.push(f.clone());
|
|
2666
|
+
}
|
|
2631
2667
|
}
|
|
2632
2668
|
// The polyfactors must be empty and the cumulative opposite factors must be 1.
|
|
2633
2669
|
return (polyFactors.length === 0 && sign === 1);
|
|
@@ -4954,7 +4990,7 @@ const fraction_1 = __webpack_require__(506);
|
|
|
4954
4990
|
class NumExp {
|
|
4955
4991
|
constructor(value, uniformize) {
|
|
4956
4992
|
this._expression = value;
|
|
4957
|
-
this._rpn = new shutingyard_1.Shutingyard(shutingyard_1.ShutingyardMode.NUMERIC).parse(value).rpn;
|
|
4993
|
+
this._rpn = new shutingyard_1.Shutingyard(shutingyard_1.ShutingyardMode.NUMERIC).parse(value, uniformize).rpn;
|
|
4958
4994
|
}
|
|
4959
4995
|
get rpn() {
|
|
4960
4996
|
return this._rpn;
|
|
@@ -7572,78 +7608,92 @@ class Shutingyard {
|
|
|
7572
7608
|
// add the last token
|
|
7573
7609
|
return normalizedExpr + nextToken;
|
|
7574
7610
|
}
|
|
7575
|
-
/**
|
|
7576
|
-
|
|
7577
|
-
|
|
7578
|
-
|
|
7579
|
-
|
|
7580
|
-
Uniformizer(expr) {
|
|
7581
|
-
|
|
7582
|
-
|
|
7583
|
-
|
|
7584
|
-
|
|
7585
|
-
|
|
7586
|
-
|
|
7587
|
-
|
|
7588
|
-
|
|
7589
|
-
|
|
7590
|
-
|
|
7591
|
-
|
|
7592
|
-
|
|
7593
|
-
|
|
7594
|
-
|
|
7595
|
-
|
|
7596
|
-
|
|
7597
|
-
|
|
7598
|
-
|
|
7599
|
-
|
|
7600
|
-
|
|
7601
|
-
|
|
7602
|
-
|
|
7603
|
-
|
|
7604
|
-
|
|
7605
|
-
|
|
7606
|
-
|
|
7607
|
-
|
|
7608
|
-
|
|
7609
|
-
|
|
7610
|
-
|
|
7611
|
-
|
|
7612
|
-
|
|
7613
|
-
|
|
7614
|
-
|
|
7615
|
-
|
|
7616
|
-
|
|
7617
|
-
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
|
|
7621
|
-
|
|
7622
|
-
|
|
7623
|
-
|
|
7624
|
-
|
|
7625
|
-
|
|
7626
|
-
|
|
7627
|
-
|
|
7628
|
-
|
|
7629
|
-
|
|
7630
|
-
|
|
7631
|
-
|
|
7632
|
-
|
|
7633
|
-
|
|
7634
|
-
|
|
7611
|
+
// /**
|
|
7612
|
+
// * Sanitize an expression by adding missing common operation (multiplication between parentheseses)
|
|
7613
|
+
// * @param expr
|
|
7614
|
+
// * @constructor
|
|
7615
|
+
// */
|
|
7616
|
+
// Uniformizer(expr: string): string {
|
|
7617
|
+
// // TODO: Delete this old version
|
|
7618
|
+
// // Prefere "normalize", much more robust !
|
|
7619
|
+
// // Determiner if need to be uniformized
|
|
7620
|
+
// if (!this._uniformize) {
|
|
7621
|
+
// return expr
|
|
7622
|
+
// }
|
|
7623
|
+
//
|
|
7624
|
+
// // Generate the list of function token.
|
|
7625
|
+
// let fnToken: string[] = []
|
|
7626
|
+
// for (let token in this._tokenConfig) {
|
|
7627
|
+
// if (this._tokenConfig[token].type === ShutingyardType.FUNCTION) {
|
|
7628
|
+
// fnToken.push(token)
|
|
7629
|
+
// }
|
|
7630
|
+
// }
|
|
7631
|
+
// // sort if from the lengthy to the smallest function
|
|
7632
|
+
// fnToken.sort((a, b) => b.length - a.length)
|
|
7633
|
+
// let tokenRegExp = new RegExp(`(${fnToken.join('|')})`, 'g')
|
|
7634
|
+
// let functionTokenOrder = Array.from(expr.matchAll(tokenRegExp))
|
|
7635
|
+
//
|
|
7636
|
+
//
|
|
7637
|
+
// let expr2;
|
|
7638
|
+
//
|
|
7639
|
+
// // Replace all function by @
|
|
7640
|
+
// expr2 = expr.replace(tokenRegExp, '@')
|
|
7641
|
+
// // Add * before @ (functionn)
|
|
7642
|
+
// expr2 = expr2.replace(/([\da-zA-Z])(@)/g, "$1*$2");
|
|
7643
|
+
//
|
|
7644
|
+
// // Replace missing multiplication between two parenthese
|
|
7645
|
+
// expr2 = expr2.replace(/\)\(/g, ')*(');
|
|
7646
|
+
//
|
|
7647
|
+
// // Replace missing multiplication between number or setLetter and parenthese.
|
|
7648
|
+
//
|
|
7649
|
+
// // 3x(x-4) => 3x*(x-4)
|
|
7650
|
+
// expr2 = expr2.replace(/([\da-zA-Z])(\()/g, "$1*$2");
|
|
7651
|
+
//
|
|
7652
|
+
// // (x-4)3x => (x-4)*3x
|
|
7653
|
+
// expr2 = expr2.replace(/(\))([\da-zA-Z])/g, "$1*$2");
|
|
7654
|
+
//
|
|
7655
|
+
// // Add multiplication between number and letters.
|
|
7656
|
+
// // 3x => 3*x
|
|
7657
|
+
// expr2 = expr2.replace(/([0-9])([a-zA-Z])/g, "$1*$2");
|
|
7658
|
+
// expr2 = expr2.replace(/([a-zA-Z])([0-9])/g, "$1*$2");
|
|
7659
|
+
//
|
|
7660
|
+
// // Remove letter between function token and it's parenthese.
|
|
7661
|
+
// // for (let token of fnToken) {
|
|
7662
|
+
// // // Remove
|
|
7663
|
+
// // expr2 = expr2.replace(new RegExp(token + '\\*', 'g'), token);
|
|
7664
|
+
// // }
|
|
7665
|
+
// // Add multiplication between letters ?
|
|
7666
|
+
// expr2 = expr2.replace(/([a-zA-Z])([a-zA-Z])/g, "$1*$2");
|
|
7667
|
+
// expr2 = expr2.replace(/([a-zA-Z])([a-zA-Z])/g, "$1*$2");
|
|
7668
|
+
//
|
|
7669
|
+
// // Restore operation auto formatting (prevent adding the multiplication star)
|
|
7670
|
+
// let exprAsArray = expr2.split('@')
|
|
7671
|
+
//
|
|
7672
|
+
// if (exprAsArray.length > 0) {
|
|
7673
|
+
// expr2 = ""
|
|
7674
|
+
// for (let idx in exprAsArray) {
|
|
7675
|
+
// }
|
|
7676
|
+
// for (let token of fnToken) {
|
|
7677
|
+
// // Remove
|
|
7678
|
+
//
|
|
7679
|
+
// // expr2 = expr2.replace(new RegExp(token + '\\*', 'g'), token);
|
|
7680
|
+
// }
|
|
7681
|
+
// }
|
|
7682
|
+
//
|
|
7683
|
+
// return expr2;
|
|
7684
|
+
// }
|
|
7635
7685
|
/**
|
|
7636
7686
|
* Parse an expression using the shutting yard tree algorithms
|
|
7637
7687
|
* @param expr (string) Expression to analyse
|
|
7638
7688
|
* Returns a RPN list of items.
|
|
7639
|
-
* @param
|
|
7689
|
+
* @param uniformize
|
|
7640
7690
|
*/
|
|
7641
|
-
parse(expr,
|
|
7691
|
+
parse(expr, uniformize) {
|
|
7642
7692
|
let outQueue = [], // Output queue
|
|
7643
7693
|
opStack = [], // Operation queue
|
|
7644
7694
|
token = '', tokenPos = 0, tokenType = '', previousOpStatckLength = 0;
|
|
7645
7695
|
// Normalize the input if required.
|
|
7646
|
-
if (this._uniformize)
|
|
7696
|
+
if (uniformize || this._uniformize)
|
|
7647
7697
|
expr = this.normalize(expr);
|
|
7648
7698
|
let securityLoopLvl1 = 50, securityLoopLvl2_default = 50, securityLoopLvl2;
|
|
7649
7699
|
while (tokenPos < expr.length) {
|