pimath 0.0.65 → 0.0.68
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/.eslintrc.js +23 -23
- package/dist/pi.js +191 -50
- package/dist/pi.js.map +1 -1
- package/dist/pi.min.js +1 -1
- package/dist/pi.min.js.map +1 -1
- package/docs/assets/highlight.css +78 -78
- package/docs/assets/main.js +52 -52
- package/docs/assets/style.css +1413 -1413
- package/docs/classes/Logicalset.Logicalset-1.html +4 -4
- package/docs/classes/Polynom.Rational.html +3 -3
- package/docs/classes/algebra_equation.Equation.html +25 -25
- package/docs/classes/algebra_monom.Monom.html +113 -113
- package/docs/classes/algebra_polynom.Polynom.html +29 -29
- package/docs/classes/coefficients_fraction.Fraction.html +18 -18
- package/docs/classes/coefficients_nthroot.NthRoot.html +2 -2
- package/docs/classes/geometry_circle.Circle.html +2 -2
- package/docs/classes/geometry_line.Line.html +2 -2
- package/docs/classes/geometry_triangle.Triangle.html +16 -16
- package/docs/classes/numeric.Numeric.html +13 -13
- package/docs/classes/shutingyard.Shutingyard.html +17 -17
- package/docs/index.html +10 -10
- package/docs/interfaces/algebra_equation.ISolution.html +2 -2
- package/docs/modules/Logicalset.html +2 -2
- package/docs/modules/Polynom.html +2 -2
- package/docs/modules/Vector.html +2 -2
- package/esm/maths/algebra/equation.js +2 -2
- package/esm/maths/algebra/equation.js.map +1 -1
- package/esm/maths/algebra/polynom.d.ts +4 -5
- package/esm/maths/algebra/polynom.js +2 -2
- package/esm/maths/algebra/polynom.js.map +1 -1
- package/esm/maths/algebra/rational.d.ts +8 -10
- package/esm/maths/algebra/rational.js +11 -6
- package/esm/maths/algebra/study/rationalStudy.d.ts +1 -2
- package/esm/maths/algebra/study/rationalStudy.js +25 -17
- package/esm/maths/algebra/study/rationalStudy.js.map +1 -1
- package/esm/maths/algebra/study.d.ts +13 -30
- package/esm/maths/algebra/study.js +33 -23
- package/esm/maths/algebra/study.js.map +1 -1
- package/esm/maths/coefficients/fraction.d.ts +8 -6
- package/esm/maths/coefficients/fraction.js +34 -17
- package/esm/maths/coefficients/fraction.js.map +1 -1
- package/esm/maths/expressions/expression.d.ts +21 -0
- package/esm/maths/expressions/expression.js +161 -0
- package/esm/maths/expressions/expression.js.map +1 -0
- package/esm/maths/expressions/expressionFactor.d.ts +29 -0
- package/esm/maths/expressions/expressionFactor.js +109 -0
- package/esm/maths/expressions/expressionFactor.js.map +1 -0
- package/esm/maths/expressions/expressionMember.d.ts +16 -0
- package/esm/maths/expressions/expressionMember.js +90 -0
- package/esm/maths/expressions/expressionMember.js.map +1 -0
- package/esm/maths/expressions/expressionOperators.d.ts +8 -0
- package/esm/maths/expressions/expressionOperators.js +42 -0
- package/esm/maths/expressions/expressionOperators.js.map +1 -0
- package/esm/maths/expressions/expressionParser.d.ts +12 -0
- package/esm/maths/expressions/expressionParser.js +219 -0
- package/esm/maths/expressions/expressionParser.js.map +1 -0
- package/esm/maths/expressions/factors/ExpFactor.d.ts +7 -0
- package/esm/maths/expressions/factors/ExpFactor.js +22 -0
- package/esm/maths/expressions/factors/ExpFactor.js.map +1 -0
- package/esm/maths/expressions/factors/ExpFactorConstant.d.ts +13 -0
- package/esm/maths/expressions/factors/ExpFactorConstant.js +49 -0
- package/esm/maths/expressions/factors/ExpFactorConstant.js.map +1 -0
- package/esm/maths/expressions/factors/ExpFactorExponential.d.ts +7 -0
- package/esm/maths/expressions/factors/ExpFactorExponential.js +18 -0
- package/esm/maths/expressions/factors/ExpFactorExponential.js.map +1 -0
- package/esm/maths/expressions/factors/ExpFactorNumber.d.ts +13 -0
- package/esm/maths/expressions/factors/ExpFactorNumber.js +36 -0
- package/esm/maths/expressions/factors/ExpFactorNumber.js.map +1 -0
- package/esm/maths/expressions/factors/ExpFactorPower.d.ts +9 -0
- package/esm/maths/expressions/factors/ExpFactorPower.js +22 -0
- package/esm/maths/expressions/factors/ExpFactorPower.js.map +1 -0
- package/esm/maths/expressions/factors/ExpFactorSin.d.ts +7 -0
- package/esm/maths/expressions/factors/ExpFactorSin.js +22 -0
- package/esm/maths/expressions/factors/ExpFactorSin.js.map +1 -0
- package/esm/maths/expressions/factors/ExpFactorTrigo.d.ts +19 -0
- package/esm/maths/expressions/factors/ExpFactorTrigo.js +40 -0
- package/esm/maths/expressions/factors/ExpFactorTrigo.js.map +1 -0
- package/esm/maths/expressions/factors/ExpFactorVariable.d.ts +12 -0
- package/esm/maths/expressions/factors/ExpFactorVariable.js +33 -0
- package/esm/maths/expressions/factors/ExpFactorVariable.js.map +1 -0
- package/esm/maths/expressions/internals.d.ts +12 -0
- package/esm/maths/expressions/internals.js +29 -0
- package/esm/maths/expressions/internals.js.map +1 -0
- package/esm/maths/shutingyard.d.ts +4 -1
- package/esm/maths/shutingyard.js +137 -21
- package/esm/maths/shutingyard.js.map +1 -1
- package/graph.svg +1033 -0
- package/package.json +1 -1
- package/src/maths/algebra/equation.ts +2 -2
- package/src/maths/algebra/polynom.ts +1 -0
- package/src/maths/algebra/study/rationalStudy.ts +18 -7
- package/src/maths/algebra/study.ts +5 -4
- package/src/maths/coefficients/fraction.ts +111 -86
- package/src/maths/expressions/expression.ts +191 -0
- package/src/maths/expressions/expressionFactor.ts +138 -0
- package/src/maths/expressions/expressionMember.ts +114 -0
- package/src/maths/expressions/expressionOperators.ts +49 -0
- package/src/maths/expressions/expressionParser.ts +249 -0
- package/src/maths/expressions/factors/ExpFactor.ts +26 -0
- package/src/maths/expressions/factors/ExpFactorConstant.ts +56 -0
- package/src/maths/expressions/factors/ExpFactorExponential.ts +19 -0
- package/src/maths/expressions/factors/ExpFactorNumber.ts +44 -0
- package/src/maths/expressions/factors/ExpFactorPower.ts +24 -0
- package/src/maths/expressions/factors/ExpFactorTrigo.ts +44 -0
- package/src/maths/expressions/factors/ExpFactorVariable.ts +40 -0
- package/src/maths/expressions/internals.ts +14 -0
- package/src/maths/shutingyard.ts +156 -26
- package/tests/algebra/study.test.ts +11 -5
- package/tests/coefficients/fraction.test.ts +17 -0
- package/tests/expressions/expressions.test.ts +124 -0
- package/tests/shutingyard.test.ts +22 -0
- package/.idea/shelf/Uncommitted_changes_before_Update_at_17_04_2022_12_40_[Changes]/shelved.patch +0 -21
- package/.idea/shelf/Uncommitted_changes_before_Update_at_17_04_2022_12_40__Changes_.xml +0 -4
package/.eslintrc.js
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
"env": {
|
|
3
|
-
"browser": true,
|
|
4
|
-
"es6": true
|
|
5
|
-
},
|
|
6
|
-
"extends": [
|
|
7
|
-
"eslint:recommended",
|
|
8
|
-
"plugin:@typescript-eslint/eslint-recommended"
|
|
9
|
-
],
|
|
10
|
-
"globals": {
|
|
11
|
-
"Atomics": "readonly",
|
|
12
|
-
"SharedArrayBuffer": "readonly"
|
|
13
|
-
},
|
|
14
|
-
"parser": "@typescript-eslint/parser",
|
|
15
|
-
"parserOptions": {
|
|
16
|
-
"ecmaVersion": 2018,
|
|
17
|
-
"sourceType": "module"
|
|
18
|
-
},
|
|
19
|
-
"plugins": [
|
|
20
|
-
"@typescript-eslint"
|
|
21
|
-
],
|
|
22
|
-
"rules": {
|
|
23
|
-
}
|
|
1
|
+
module.exports = {
|
|
2
|
+
"env": {
|
|
3
|
+
"browser": true,
|
|
4
|
+
"es6": true
|
|
5
|
+
},
|
|
6
|
+
"extends": [
|
|
7
|
+
"eslint:recommended",
|
|
8
|
+
"plugin:@typescript-eslint/eslint-recommended"
|
|
9
|
+
],
|
|
10
|
+
"globals": {
|
|
11
|
+
"Atomics": "readonly",
|
|
12
|
+
"SharedArrayBuffer": "readonly"
|
|
13
|
+
},
|
|
14
|
+
"parser": "@typescript-eslint/parser",
|
|
15
|
+
"parserOptions": {
|
|
16
|
+
"ecmaVersion": 2018,
|
|
17
|
+
"sourceType": "module"
|
|
18
|
+
},
|
|
19
|
+
"plugins": [
|
|
20
|
+
"@typescript-eslint"
|
|
21
|
+
],
|
|
22
|
+
"rules": {
|
|
23
|
+
}
|
|
24
24
|
};
|
package/dist/pi.js
CHANGED
|
@@ -434,10 +434,10 @@ class Equation {
|
|
|
434
434
|
else {
|
|
435
435
|
// Must handle the case if the m1 monom is negative.
|
|
436
436
|
if ((this.isGreater() && m1.sign() === 1) || (!this.isGreater() && m1.sign() === -1)) {
|
|
437
|
-
s = `\\left${this.isAlsoEqual() ? '
|
|
437
|
+
s = `\\left${this.isAlsoEqual() ? '[' : ']'}${v.tex};+\\infty\\right[`;
|
|
438
438
|
}
|
|
439
439
|
else {
|
|
440
|
-
s = `\\left
|
|
440
|
+
s = `\\left]-\\infty;${v.tex} \\right\\${this.isAlsoEqual() ? ']' : '['}`;
|
|
441
441
|
}
|
|
442
442
|
}
|
|
443
443
|
this._solutions = [{
|
|
@@ -2245,6 +2245,7 @@ class Polynom {
|
|
|
2245
2245
|
this._monoms = [];
|
|
2246
2246
|
this._factors = [];
|
|
2247
2247
|
this.mark_as_dirty();
|
|
2248
|
+
// TODO: allow to enter a liste of Fraction (a, b, c, ...) to make a polynom ax^n + bx^(n-1) + cx^(n-2) + ...
|
|
2248
2249
|
if (typeof inputStr === 'string') {
|
|
2249
2250
|
return this._parseString(inputStr, ...values);
|
|
2250
2251
|
}
|
|
@@ -3467,9 +3468,9 @@ var FUNCTION_EXTREMA;
|
|
|
3467
3468
|
})(FUNCTION_EXTREMA = exports.FUNCTION_EXTREMA || (exports.FUNCTION_EXTREMA = {}));
|
|
3468
3469
|
var TABLE_OF_SIGNS;
|
|
3469
3470
|
(function (TABLE_OF_SIGNS) {
|
|
3470
|
-
TABLE_OF_SIGNS[
|
|
3471
|
-
TABLE_OF_SIGNS[
|
|
3472
|
-
TABLE_OF_SIGNS[
|
|
3471
|
+
TABLE_OF_SIGNS["SIGNS"] = "signs";
|
|
3472
|
+
TABLE_OF_SIGNS["GROWS"] = "grows";
|
|
3473
|
+
TABLE_OF_SIGNS["VARIATIONS"] = "variatins";
|
|
3473
3474
|
})(TABLE_OF_SIGNS = exports.TABLE_OF_SIGNS || (exports.TABLE_OF_SIGNS = {}));
|
|
3474
3475
|
/**
|
|
3475
3476
|
* The study class is a "function study" class that will get:
|
|
@@ -3723,7 +3724,7 @@ class Study {
|
|
|
3723
3724
|
;
|
|
3724
3725
|
makeSigns() {
|
|
3725
3726
|
return {
|
|
3726
|
-
type: TABLE_OF_SIGNS.
|
|
3727
|
+
type: TABLE_OF_SIGNS.SIGNS,
|
|
3727
3728
|
fx: null,
|
|
3728
3729
|
factors: [],
|
|
3729
3730
|
zeroes: [],
|
|
@@ -3829,21 +3830,23 @@ class RationalStudy extends study_1.Study {
|
|
|
3829
3830
|
tex: tex,
|
|
3830
3831
|
zero: zero,
|
|
3831
3832
|
limits: `\\lim_{x\\to${zero.tex} }\\ f(x) = \\pm\\infty`,
|
|
3832
|
-
deltaX: null
|
|
3833
|
+
deltaX: null,
|
|
3834
|
+
tableOfSign: null
|
|
3833
3835
|
});
|
|
3834
3836
|
});
|
|
3835
3837
|
// Sloped asymptote
|
|
3836
3838
|
let NDegree = this.fx.numerator.degree(), DDegree = this.fx.denominator.degree();
|
|
3837
3839
|
if (NDegree.isEqual(DDegree)) {
|
|
3838
3840
|
let H = this.fx.numerator.monomByDegree().coefficient.clone().divide(this.fx.denominator.monomByDegree().coefficient), Htex = H.tex;
|
|
3839
|
-
let { reminder } = reduced.euclidian();
|
|
3841
|
+
let { reminder } = reduced.euclidian(), deltaX = new rational_1.Rational(reminder, reduced.denominator);
|
|
3840
3842
|
asymptotes.push({
|
|
3841
3843
|
fx: new polynom_1.Polynom(H),
|
|
3842
3844
|
type: study_1.ASYMPTOTE.HORIZONTAL,
|
|
3843
3845
|
tex: `y=${Htex}`,
|
|
3844
3846
|
zero: null,
|
|
3845
3847
|
limits: `\\lim_{x\\to\\infty}\\ f(x) = ${Htex}`,
|
|
3846
|
-
deltaX
|
|
3848
|
+
deltaX,
|
|
3849
|
+
tableOfSign: this._getSigns(deltaX)
|
|
3847
3850
|
});
|
|
3848
3851
|
}
|
|
3849
3852
|
else if (DDegree.greater(NDegree)) {
|
|
@@ -3853,19 +3856,21 @@ class RationalStudy extends study_1.Study {
|
|
|
3853
3856
|
tex: `y=0`,
|
|
3854
3857
|
zero: null,
|
|
3855
3858
|
limits: `\\lim_{x\\to\\infty}\\ f(x) = ${0}`,
|
|
3856
|
-
deltaX: null
|
|
3859
|
+
deltaX: null,
|
|
3860
|
+
tableOfSign: null
|
|
3857
3861
|
});
|
|
3858
3862
|
}
|
|
3859
3863
|
else if (NDegree.value - 1 === DDegree.value) {
|
|
3860
3864
|
// Calculate the slope
|
|
3861
|
-
let { quotient, reminder } = reduced.euclidian();
|
|
3865
|
+
let { quotient, reminder } = reduced.euclidian(), deltaX = new rational_1.Rational(reminder, reduced.denominator);
|
|
3862
3866
|
asymptotes.push({
|
|
3863
3867
|
fx: quotient.clone(),
|
|
3864
3868
|
type: study_1.ASYMPTOTE.SLOPE,
|
|
3865
3869
|
tex: `y=${quotient.tex}`,
|
|
3866
3870
|
zero: null,
|
|
3867
3871
|
limits: ``,
|
|
3868
|
-
deltaX: new rational_1.Rational(reminder, reduced.denominator)
|
|
3872
|
+
deltaX: new rational_1.Rational(reminder, reduced.denominator),
|
|
3873
|
+
tableOfSign: this._getSigns(deltaX)
|
|
3869
3874
|
});
|
|
3870
3875
|
}
|
|
3871
3876
|
return asymptotes;
|
|
@@ -3924,6 +3929,9 @@ class RationalStudy extends study_1.Study {
|
|
|
3924
3929
|
_getSigns(fx, zeroes, typeOfTable) {
|
|
3925
3930
|
// Factorize the rational
|
|
3926
3931
|
let signs = [], factors = [];
|
|
3932
|
+
if (zeroes === undefined) {
|
|
3933
|
+
zeroes = this._getZeroes(fx);
|
|
3934
|
+
}
|
|
3927
3935
|
fx.numerator.factors.forEach(factor => {
|
|
3928
3936
|
signs.push(this.makeOneLineForSigns(factor, zeroes, study_1.ZEROTYPE.ZERO));
|
|
3929
3937
|
factors.push(factor.clone());
|
|
@@ -3963,8 +3971,12 @@ const numeric_1 = __webpack_require__(956);
|
|
|
3963
3971
|
*/
|
|
3964
3972
|
class Fraction {
|
|
3965
3973
|
constructor(value, denominatorOrPeriodic) {
|
|
3966
|
-
|
|
3967
|
-
|
|
3974
|
+
this.isApproximative = () => {
|
|
3975
|
+
return this._numerator.toString().length >= 15 && this._denominator.toString().length >= 15;
|
|
3976
|
+
};
|
|
3977
|
+
this.isExact = () => {
|
|
3978
|
+
return !this.isApproximative();
|
|
3979
|
+
};
|
|
3968
3980
|
// ------------------------------------------
|
|
3969
3981
|
/**
|
|
3970
3982
|
* Parse the value to get the numerator and denominator
|
|
@@ -3981,15 +3993,15 @@ class Fraction {
|
|
|
3981
3993
|
}
|
|
3982
3994
|
switch (typeof value) {
|
|
3983
3995
|
case "string":
|
|
3984
|
-
// Split the
|
|
3996
|
+
// Split the string value in two parts: Numerator/Denominator
|
|
3985
3997
|
S = value.split('/');
|
|
3986
3998
|
// Security checks
|
|
3987
3999
|
if (S.length > 2)
|
|
3988
|
-
throw "
|
|
4000
|
+
throw value + " has too many divide signs";
|
|
3989
4001
|
if (S.map(x => x === '' || isNaN(Number(x))).includes(true))
|
|
3990
|
-
throw "
|
|
4002
|
+
throw value + " is not a valid number";
|
|
3991
4003
|
if (S.length === 1) {
|
|
3992
|
-
// No divide sign
|
|
4004
|
+
// No divide sign - it's a number
|
|
3993
4005
|
return this.parse(+S[0]);
|
|
3994
4006
|
}
|
|
3995
4007
|
else if (S.length === 2) {
|
|
@@ -4006,6 +4018,7 @@ class Fraction {
|
|
|
4006
4018
|
}
|
|
4007
4019
|
else {
|
|
4008
4020
|
// More than one divide sign ?
|
|
4021
|
+
// This is impossible
|
|
4009
4022
|
this._numerator = NaN;
|
|
4010
4023
|
this._denominator = 1;
|
|
4011
4024
|
}
|
|
@@ -4046,6 +4059,8 @@ class Fraction {
|
|
|
4046
4059
|
}
|
|
4047
4060
|
return this;
|
|
4048
4061
|
};
|
|
4062
|
+
// ------------------------------------------
|
|
4063
|
+
// Mathematical operations
|
|
4049
4064
|
this.clone = () => {
|
|
4050
4065
|
let F = new Fraction();
|
|
4051
4066
|
F.numerator = +this._numerator;
|
|
@@ -4073,8 +4088,6 @@ class Fraction {
|
|
|
4073
4088
|
return this;
|
|
4074
4089
|
};
|
|
4075
4090
|
// ------------------------------------------
|
|
4076
|
-
// Mathematical operations
|
|
4077
|
-
// ------------------------------------------
|
|
4078
4091
|
this.opposed = () => {
|
|
4079
4092
|
this._numerator = -this._numerator;
|
|
4080
4093
|
return this;
|
|
@@ -4353,22 +4366,32 @@ class Fraction {
|
|
|
4353
4366
|
if (this.isInfinity()) {
|
|
4354
4367
|
return `${this.sign() === 1 ? '+' : '-'}\\infty`;
|
|
4355
4368
|
}
|
|
4356
|
-
if (this.
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
|
|
4369
|
+
if (this.isExact()) {
|
|
4370
|
+
if (this._denominator === 1) {
|
|
4371
|
+
return `${this._numerator}`;
|
|
4372
|
+
}
|
|
4373
|
+
else if (this._numerator < 0) {
|
|
4374
|
+
return `-\\frac{ ${-this._numerator} }{ ${this._denominator} }`;
|
|
4375
|
+
}
|
|
4376
|
+
else {
|
|
4377
|
+
return `\\frac{ ${this._numerator} }{ ${this._denominator} }`;
|
|
4378
|
+
}
|
|
4361
4379
|
}
|
|
4362
4380
|
else {
|
|
4363
|
-
return
|
|
4381
|
+
return this.value.toFixed(3);
|
|
4364
4382
|
}
|
|
4365
4383
|
}
|
|
4366
4384
|
get display() {
|
|
4367
|
-
if (this.
|
|
4368
|
-
|
|
4385
|
+
if (this.isExact()) {
|
|
4386
|
+
if (this._denominator === 1) {
|
|
4387
|
+
return `${this._numerator}`;
|
|
4388
|
+
}
|
|
4389
|
+
else {
|
|
4390
|
+
return `${this._numerator}/${this._denominator}`;
|
|
4391
|
+
}
|
|
4369
4392
|
}
|
|
4370
4393
|
else {
|
|
4371
|
-
return
|
|
4394
|
+
return this.value.toFixed(3);
|
|
4372
4395
|
}
|
|
4373
4396
|
}
|
|
4374
4397
|
// Helper function to display fractions
|
|
@@ -4403,6 +4426,8 @@ Fraction.min = (...fractions) => {
|
|
|
4403
4426
|
}
|
|
4404
4427
|
return M;
|
|
4405
4428
|
};
|
|
4429
|
+
// ------------------------------------------
|
|
4430
|
+
// Creation / parsing functions
|
|
4406
4431
|
Fraction.average = (...fractions) => {
|
|
4407
4432
|
let M = new Fraction().zero();
|
|
4408
4433
|
for (let f of fractions) {
|
|
@@ -6824,6 +6849,7 @@ var ShutingyardType;
|
|
|
6824
6849
|
})(ShutingyardType = exports.ShutingyardType || (exports.ShutingyardType = {}));
|
|
6825
6850
|
var ShutingyardMode;
|
|
6826
6851
|
(function (ShutingyardMode) {
|
|
6852
|
+
ShutingyardMode["EXPRESSION"] = "expression";
|
|
6827
6853
|
ShutingyardMode["POLYNOM"] = "polynom";
|
|
6828
6854
|
ShutingyardMode["SET"] = "set";
|
|
6829
6855
|
ShutingyardMode["NUMERIC"] = "numeric";
|
|
@@ -6839,6 +6865,9 @@ class Shutingyard {
|
|
|
6839
6865
|
// console.log(this._rpn)
|
|
6840
6866
|
return this._rpn;
|
|
6841
6867
|
}
|
|
6868
|
+
get rpnToken() {
|
|
6869
|
+
return this._rpn.map(x => x.token);
|
|
6870
|
+
}
|
|
6842
6871
|
/**
|
|
6843
6872
|
* Determin if the token is a defined operation
|
|
6844
6873
|
* Defined operations: + - * / ^ sin cos tan
|
|
@@ -6880,6 +6909,22 @@ class Shutingyard {
|
|
|
6880
6909
|
};
|
|
6881
6910
|
this._uniformize = false;
|
|
6882
6911
|
}
|
|
6912
|
+
else if (this._mode === ShutingyardMode.EXPRESSION) {
|
|
6913
|
+
this._tokenConfig = {
|
|
6914
|
+
'^': { precedence: 4, associative: 'right', type: ShutingyardType.OPERATION },
|
|
6915
|
+
'*': { precedence: 3, associative: 'left', type: ShutingyardType.OPERATION },
|
|
6916
|
+
'/': { precedence: 3, associative: 'left', type: ShutingyardType.OPERATION },
|
|
6917
|
+
'+': { precedence: 2, associative: 'left', type: ShutingyardType.OPERATION },
|
|
6918
|
+
'-': { precedence: 2, associative: 'left', type: ShutingyardType.OPERATION },
|
|
6919
|
+
'%': { precedence: 3, associative: 'right', type: ShutingyardType.OPERATION },
|
|
6920
|
+
'sin': { precedence: 4, associative: 'right', type: ShutingyardType.FUNCTION },
|
|
6921
|
+
'cos': { precedence: 4, associative: 'right', type: ShutingyardType.FUNCTION },
|
|
6922
|
+
'tan': { precedence: 4, associative: 'right', type: ShutingyardType.FUNCTION },
|
|
6923
|
+
'sqrt': { precedence: 4, associative: 'right', type: ShutingyardType.FUNCTION },
|
|
6924
|
+
'nthrt': { precedence: 4, associative: 'right', type: ShutingyardType.FUNCTION },
|
|
6925
|
+
};
|
|
6926
|
+
this._uniformize = true;
|
|
6927
|
+
}
|
|
6883
6928
|
else {
|
|
6884
6929
|
this._tokenConfig = {
|
|
6885
6930
|
'^': { precedence: 4, associative: 'right', type: ShutingyardType.OPERATION },
|
|
@@ -6887,10 +6932,6 @@ class Shutingyard {
|
|
|
6887
6932
|
'/': { precedence: 3, associative: 'left', type: ShutingyardType.OPERATION },
|
|
6888
6933
|
'+': { precedence: 2, associative: 'left', type: ShutingyardType.OPERATION },
|
|
6889
6934
|
'-': { precedence: 2, associative: 'left', type: ShutingyardType.OPERATION },
|
|
6890
|
-
// '%': {precedence: 3, associative: 'right', type: ShutingyardType.OPERATION},
|
|
6891
|
-
// 'sin': {precedence: 4, associative: 'right', type: ShutingyardType.FUNCTION},
|
|
6892
|
-
// 'cos': {precedence: 4, associative: 'right', type: ShutingyardType.FUNCTION},
|
|
6893
|
-
// 'tan': {precedence: 4, associative: 'right', type: ShutingyardType.FUNCTION},
|
|
6894
6935
|
};
|
|
6895
6936
|
this._uniformize = true;
|
|
6896
6937
|
}
|
|
@@ -6922,9 +6963,6 @@ class Shutingyard {
|
|
|
6922
6963
|
tokenType = 'function-argument';
|
|
6923
6964
|
}
|
|
6924
6965
|
else {
|
|
6925
|
-
// Order token keys by token characters length (descending)
|
|
6926
|
-
// TODO: this is done each time ! SHould be done once !
|
|
6927
|
-
// const keys = Object.keys(this._tokenConfig).sort((a,b)=>b.length-a.length)
|
|
6928
6966
|
// Extract operation and function tokens
|
|
6929
6967
|
for (let key of this._tokenKeys) {
|
|
6930
6968
|
if (expr.substring(start, start + key.length) === key) {
|
|
@@ -6946,7 +6984,7 @@ class Shutingyard {
|
|
|
6946
6984
|
if (expr[start].match(/[0-9]/)) {
|
|
6947
6985
|
if (this._mode === ShutingyardMode.POLYNOM && false) {}
|
|
6948
6986
|
else {
|
|
6949
|
-
token = expr.substring(start).match(/^([0-9
|
|
6987
|
+
token = expr.substring(start).match(/^([0-9.]+)/)[0];
|
|
6950
6988
|
}
|
|
6951
6989
|
tokenType = ShutingyardType.COEFFICIENT;
|
|
6952
6990
|
}
|
|
@@ -6963,19 +7001,114 @@ class Shutingyard {
|
|
|
6963
7001
|
}
|
|
6964
7002
|
return [token, start + token.length, tokenType];
|
|
6965
7003
|
}
|
|
7004
|
+
normalize(expr) {
|
|
7005
|
+
// Get the list of function token.
|
|
7006
|
+
let fnToken = [], kToken = [];
|
|
7007
|
+
for (let token in this._tokenConfig) {
|
|
7008
|
+
if (this._tokenConfig[token].type === ShutingyardType.FUNCTION) {
|
|
7009
|
+
fnToken.push(token);
|
|
7010
|
+
}
|
|
7011
|
+
}
|
|
7012
|
+
// sort if from the lengthy to the smallest function
|
|
7013
|
+
fnToken.sort((a, b) => b.length - a.length);
|
|
7014
|
+
for (let token in exports.tokenConstant) {
|
|
7015
|
+
kToken.push(token);
|
|
7016
|
+
}
|
|
7017
|
+
// sort if from the lengthy to the smallest function
|
|
7018
|
+
kToken.sort((a, b) => b.length - a.length);
|
|
7019
|
+
let normalizedExpr = "", i = 0, crtToken, nextToken;
|
|
7020
|
+
while (i < expr.length - 1) {
|
|
7021
|
+
// Check if we have a function token.
|
|
7022
|
+
// The function MUST have an open parentheses
|
|
7023
|
+
let tokenIdx = 0;
|
|
7024
|
+
while (tokenIdx < fnToken.length) {
|
|
7025
|
+
let token = fnToken[tokenIdx];
|
|
7026
|
+
if (expr.slice(i, i + token.length + 1) === token + '(') {
|
|
7027
|
+
normalizedExpr += token + '(';
|
|
7028
|
+
i += token.length + 1;
|
|
7029
|
+
// Restart the scan for the function token
|
|
7030
|
+
tokenIdx = 0;
|
|
7031
|
+
}
|
|
7032
|
+
else {
|
|
7033
|
+
// scan for a next function token
|
|
7034
|
+
tokenIdx++;
|
|
7035
|
+
}
|
|
7036
|
+
}
|
|
7037
|
+
// Check for a constant
|
|
7038
|
+
tokenIdx = 0;
|
|
7039
|
+
while (tokenIdx < kToken.length) {
|
|
7040
|
+
let token = kToken[tokenIdx];
|
|
7041
|
+
if (expr.slice(i, i + token.length) === token) {
|
|
7042
|
+
// We have found a constant.
|
|
7043
|
+
// add it, but with remove the last letter
|
|
7044
|
+
normalizedExpr += token.slice(0, -1);
|
|
7045
|
+
i += token.length - 1;
|
|
7046
|
+
// Exit the loop
|
|
7047
|
+
break;
|
|
7048
|
+
}
|
|
7049
|
+
tokenIdx++;
|
|
7050
|
+
}
|
|
7051
|
+
// The function token are solved.
|
|
7052
|
+
crtToken = expr[i];
|
|
7053
|
+
nextToken = expr[i + 1];
|
|
7054
|
+
normalizedExpr += crtToken;
|
|
7055
|
+
if (crtToken.match(/[a-zA-Z]/g)) {
|
|
7056
|
+
// Current element is a letter.
|
|
7057
|
+
// if the next element is a letter, a number or an opening parentheses, add the multiplication sign.
|
|
7058
|
+
if (nextToken.match(/[a-zA-Z\d(]/)) {
|
|
7059
|
+
normalizedExpr += '*';
|
|
7060
|
+
}
|
|
7061
|
+
}
|
|
7062
|
+
else if (crtToken.match(/\d/)) {
|
|
7063
|
+
// Current element is a number.
|
|
7064
|
+
// if the next element is a letter or a parentheses, add the multiplication sign.
|
|
7065
|
+
if (nextToken.match(/[a-zA-Z(]/)) {
|
|
7066
|
+
normalizedExpr += '*';
|
|
7067
|
+
}
|
|
7068
|
+
}
|
|
7069
|
+
else if (crtToken === ')') {
|
|
7070
|
+
// Current element is a closing parentheses.
|
|
7071
|
+
// if the next element is a letter, a number or an opening parentheses, add the multiplication sign
|
|
7072
|
+
if (nextToken.match(/[a-zA-Z\d(]/)) {
|
|
7073
|
+
normalizedExpr += '*';
|
|
7074
|
+
}
|
|
7075
|
+
}
|
|
7076
|
+
// Go to next token
|
|
7077
|
+
i++;
|
|
7078
|
+
}
|
|
7079
|
+
// add the last token
|
|
7080
|
+
return normalizedExpr + nextToken;
|
|
7081
|
+
}
|
|
6966
7082
|
/**
|
|
6967
7083
|
* Sanitize an expression by adding missing common operation (multiplication between parentheseses)
|
|
6968
7084
|
* @param expr
|
|
6969
7085
|
* @constructor
|
|
6970
7086
|
*/
|
|
6971
7087
|
Uniformizer(expr) {
|
|
7088
|
+
// TODO: Delete this old version
|
|
7089
|
+
// Prefere "normalize", much more robust !
|
|
6972
7090
|
// Determiner if need to be uniformized
|
|
6973
7091
|
if (!this._uniformize) {
|
|
6974
7092
|
return expr;
|
|
6975
7093
|
}
|
|
7094
|
+
// Generate the list of function token.
|
|
7095
|
+
let fnToken = [];
|
|
7096
|
+
for (let token in this._tokenConfig) {
|
|
7097
|
+
if (this._tokenConfig[token].type === ShutingyardType.FUNCTION) {
|
|
7098
|
+
fnToken.push(token);
|
|
7099
|
+
}
|
|
7100
|
+
}
|
|
7101
|
+
// sort if from the lengthy to the smallest function
|
|
7102
|
+
fnToken.sort((a, b) => b.length - a.length);
|
|
7103
|
+
let tokenRegExp = new RegExp(`(${fnToken.join('|')})`, 'g');
|
|
7104
|
+
let functionTokenOrder = Array.from(expr.matchAll(tokenRegExp));
|
|
6976
7105
|
let expr2;
|
|
7106
|
+
// Replace all function by @
|
|
7107
|
+
expr2 = expr.replace(tokenRegExp, '@');
|
|
7108
|
+
// Add * before @ (functionn)
|
|
7109
|
+
expr2 = expr2.replace(/([\da-zA-Z])(@)/g, "$1*$2");
|
|
6977
7110
|
// Replace missing multiplication between two parenthese
|
|
6978
|
-
expr2 =
|
|
7111
|
+
expr2 = expr2.replace(/\)\(/g, ')*(');
|
|
6979
7112
|
// Replace missing multiplication between number or setLetter and parenthese.
|
|
6980
7113
|
// 3x(x-4) => 3x*(x-4)
|
|
6981
7114
|
expr2 = expr2.replace(/([\da-zA-Z])(\()/g, "$1*$2");
|
|
@@ -6985,14 +7118,24 @@ class Shutingyard {
|
|
|
6985
7118
|
// 3x => 3*x
|
|
6986
7119
|
expr2 = expr2.replace(/([0-9])([a-zA-Z])/g, "$1*$2");
|
|
6987
7120
|
expr2 = expr2.replace(/([a-zA-Z])([0-9])/g, "$1*$2");
|
|
7121
|
+
// Remove letter between function token and it's parenthese.
|
|
7122
|
+
// for (let token of fnToken) {
|
|
7123
|
+
// // Remove
|
|
7124
|
+
// expr2 = expr2.replace(new RegExp(token + '\\*', 'g'), token);
|
|
7125
|
+
// }
|
|
6988
7126
|
// Add multiplication between letters ?
|
|
6989
|
-
|
|
6990
|
-
expr2 = expr2.replace(/([
|
|
6991
|
-
// Restore operation auto
|
|
6992
|
-
|
|
6993
|
-
|
|
6994
|
-
|
|
6995
|
-
|
|
7127
|
+
expr2 = expr2.replace(/([a-zA-Z])([a-zA-Z])/g, "$1*$2");
|
|
7128
|
+
expr2 = expr2.replace(/([a-zA-Z])([a-zA-Z])/g, "$1*$2");
|
|
7129
|
+
// Restore operation auto formatting (prevent adding the multiplication star)
|
|
7130
|
+
let exprAsArray = expr2.split('@');
|
|
7131
|
+
if (exprAsArray.length > 0) {
|
|
7132
|
+
expr2 = "";
|
|
7133
|
+
for (let idx in exprAsArray) {
|
|
7134
|
+
}
|
|
7135
|
+
for (let token of fnToken) {
|
|
7136
|
+
// Remove
|
|
7137
|
+
// expr2 = expr2.replace(new RegExp(token + '\\*', 'g'), token);
|
|
7138
|
+
}
|
|
6996
7139
|
}
|
|
6997
7140
|
return expr2;
|
|
6998
7141
|
}
|
|
@@ -7006,7 +7149,9 @@ class Shutingyard {
|
|
|
7006
7149
|
let outQueue = [], // Output queue
|
|
7007
7150
|
opStack = [], // Operation queue
|
|
7008
7151
|
token = '', tokenPos = 0, tokenType = '', previousOpStatckLength = 0;
|
|
7009
|
-
|
|
7152
|
+
// Normalize the input if required.
|
|
7153
|
+
if (this._uniformize)
|
|
7154
|
+
expr = this.normalize(expr);
|
|
7010
7155
|
let securityLoopLvl1 = 50, securityLoopLvl2_default = 50, securityLoopLvl2;
|
|
7011
7156
|
while (tokenPos < expr.length) {
|
|
7012
7157
|
securityLoopLvl1--;
|
|
@@ -7025,10 +7170,6 @@ class Shutingyard {
|
|
|
7025
7170
|
token,
|
|
7026
7171
|
tokenType
|
|
7027
7172
|
});
|
|
7028
|
-
// if(previousOpStatckLength == opStack.length && outQueue.length>=2){
|
|
7029
|
-
// console.log('opStatckLength', outQueue, opStack.length)
|
|
7030
|
-
// outQueue.push('*')
|
|
7031
|
-
// }
|
|
7032
7173
|
break;
|
|
7033
7174
|
case 'operation':
|
|
7034
7175
|
previousOpStatckLength = opStack.length;
|