pimath 0.0.64 → 0.0.67
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 +236 -56
- 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 +9 -5
- package/esm/maths/algebra/study/rationalStudy.d.ts +1 -2
- package/esm/maths/algebra/study/rationalStudy.js +32 -20
- package/esm/maths/algebra/study/rationalStudy.js.map +1 -1
- package/esm/maths/algebra/study.d.ts +16 -24
- package/esm/maths/algebra/study.js +65 -24
- 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 +26 -12
- package/src/maths/algebra/study.ts +48 -5
- 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 +29 -4
- 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() ? '\\[' : '\\]'}${v};+\\infty\\right\\[`;
|
|
437
|
+
s = `\\left${this.isAlsoEqual() ? '\\[' : '\\]'}${v.tex};+\\infty\\right\\[`;
|
|
438
438
|
}
|
|
439
439
|
else {
|
|
440
|
-
s = `\\left\\]-\\infty;${v} \\right\\${this.isAlsoEqual() ? '\\]' : '\\['}`;
|
|
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
|
}
|
|
@@ -3444,6 +3445,7 @@ exports.Rational = Rational;
|
|
|
3444
3445
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
3445
3446
|
exports.Study = exports.TABLE_OF_SIGNS = exports.FUNCTION_EXTREMA = exports.ASYMPTOTE = exports.ZEROTYPE = void 0;
|
|
3446
3447
|
const fraction_1 = __webpack_require__(506);
|
|
3448
|
+
const numexp_1 = __webpack_require__(735);
|
|
3447
3449
|
var ZEROTYPE;
|
|
3448
3450
|
(function (ZEROTYPE) {
|
|
3449
3451
|
ZEROTYPE["ZERO"] = "z";
|
|
@@ -3466,9 +3468,9 @@ var FUNCTION_EXTREMA;
|
|
|
3466
3468
|
})(FUNCTION_EXTREMA = exports.FUNCTION_EXTREMA || (exports.FUNCTION_EXTREMA = {}));
|
|
3467
3469
|
var TABLE_OF_SIGNS;
|
|
3468
3470
|
(function (TABLE_OF_SIGNS) {
|
|
3469
|
-
TABLE_OF_SIGNS[
|
|
3470
|
-
TABLE_OF_SIGNS[
|
|
3471
|
-
TABLE_OF_SIGNS[
|
|
3471
|
+
TABLE_OF_SIGNS["SIGNS"] = "signs";
|
|
3472
|
+
TABLE_OF_SIGNS["GROWS"] = "grows";
|
|
3473
|
+
TABLE_OF_SIGNS["VARIATIONS"] = "variatins";
|
|
3472
3474
|
})(TABLE_OF_SIGNS = exports.TABLE_OF_SIGNS || (exports.TABLE_OF_SIGNS = {}));
|
|
3473
3475
|
/**
|
|
3474
3476
|
* The study class is a "function study" class that will get:
|
|
@@ -3572,6 +3574,8 @@ class Study {
|
|
|
3572
3574
|
if (resultLine[pos] === 'z') {
|
|
3573
3575
|
// It's a zero. Get the coordinates
|
|
3574
3576
|
let x, y, zero = zeroes[i].exact, pt, xTex, yTex, pointType;
|
|
3577
|
+
// TODO: NumExp should parse something that isn't yet plotFunction
|
|
3578
|
+
let exp = new numexp_1.NumExp(this.fx.plotFunction);
|
|
3575
3579
|
if (zero instanceof fraction_1.Fraction) {
|
|
3576
3580
|
let value = zero, evalY = this.fx.evaluate(value);
|
|
3577
3581
|
x = zero.value;
|
|
@@ -3581,7 +3585,7 @@ class Study {
|
|
|
3581
3585
|
}
|
|
3582
3586
|
else {
|
|
3583
3587
|
x = zeroes[i].value;
|
|
3584
|
-
y =
|
|
3588
|
+
y = exp.evaluate({ x });
|
|
3585
3589
|
xTex = x.toFixed(2);
|
|
3586
3590
|
yTex = y.toFixed(2);
|
|
3587
3591
|
}
|
|
@@ -3653,6 +3657,39 @@ class Study {
|
|
|
3653
3657
|
tex += `\n\\end{tikzpicture}`;
|
|
3654
3658
|
return tex;
|
|
3655
3659
|
};
|
|
3660
|
+
this.drawCode = () => {
|
|
3661
|
+
// Function as string
|
|
3662
|
+
let code = `f(x)=${this.fx.plotFunction}`;
|
|
3663
|
+
// Asymptotes
|
|
3664
|
+
let i = 1;
|
|
3665
|
+
this.asymptotes.forEach(asymptote => {
|
|
3666
|
+
if (asymptote.type === ASYMPTOTE.VERTICAL) {
|
|
3667
|
+
code += `\nav_${i}=line x=${asymptote.zero.value}->red,dash`;
|
|
3668
|
+
i++;
|
|
3669
|
+
}
|
|
3670
|
+
else if (asymptote.type === ASYMPTOTE.HORIZONTAL) {
|
|
3671
|
+
code += `\nah=line y=${asymptote.fx.monoms[0].coefficient.value}->orange,dash`;
|
|
3672
|
+
}
|
|
3673
|
+
else if (asymptote.type === ASYMPTOTE.SLOPE) {
|
|
3674
|
+
code += `\nao=line y=${asymptote.fx.plotFunction}->red,dash`;
|
|
3675
|
+
}
|
|
3676
|
+
i++;
|
|
3677
|
+
});
|
|
3678
|
+
// Extremes
|
|
3679
|
+
for (let zero in this.derivative.extremes) {
|
|
3680
|
+
let extreme = this.derivative.extremes[zero];
|
|
3681
|
+
code += `\nM_${i}(${extreme.value.x},${extreme.value.y})*`;
|
|
3682
|
+
i++;
|
|
3683
|
+
}
|
|
3684
|
+
// Zeroes
|
|
3685
|
+
this.zeroes.forEach(zero => {
|
|
3686
|
+
if (zero.type === ZEROTYPE.ZERO) {
|
|
3687
|
+
code += `\nZ_${i}(${zero.value},0)*`;
|
|
3688
|
+
i++;
|
|
3689
|
+
}
|
|
3690
|
+
});
|
|
3691
|
+
return code;
|
|
3692
|
+
};
|
|
3656
3693
|
this.fx = fx;
|
|
3657
3694
|
this.makeStudy();
|
|
3658
3695
|
return this;
|
|
@@ -3687,7 +3724,7 @@ class Study {
|
|
|
3687
3724
|
;
|
|
3688
3725
|
makeSigns() {
|
|
3689
3726
|
return {
|
|
3690
|
-
type: TABLE_OF_SIGNS.
|
|
3727
|
+
type: TABLE_OF_SIGNS.SIGNS,
|
|
3691
3728
|
fx: null,
|
|
3692
3729
|
factors: [],
|
|
3693
3730
|
zeroes: [],
|
|
@@ -3752,13 +3789,13 @@ exports.RationalStudy = void 0;
|
|
|
3752
3789
|
const study_1 = __webpack_require__(996);
|
|
3753
3790
|
const rational_1 = __webpack_require__(107);
|
|
3754
3791
|
const fraction_1 = __webpack_require__(506);
|
|
3792
|
+
const polynom_1 = __webpack_require__(38);
|
|
3755
3793
|
class RationalStudy extends study_1.Study {
|
|
3756
3794
|
constructor(fx) {
|
|
3757
3795
|
super(fx);
|
|
3758
3796
|
return this;
|
|
3759
3797
|
}
|
|
3760
3798
|
makeZeroes() {
|
|
3761
|
-
console.log('GETTING ZEROES');
|
|
3762
3799
|
return this._getZeroes(this.fx);
|
|
3763
3800
|
}
|
|
3764
3801
|
;
|
|
@@ -3788,44 +3825,52 @@ class RationalStudy extends study_1.Study {
|
|
|
3788
3825
|
}
|
|
3789
3826
|
}
|
|
3790
3827
|
asymptotes.push({
|
|
3828
|
+
fx: null,
|
|
3791
3829
|
type: Ztype,
|
|
3792
3830
|
tex: tex,
|
|
3793
3831
|
zero: zero,
|
|
3794
3832
|
limits: `\\lim_{x\\to${zero.tex} }\\ f(x) = \\pm\\infty`,
|
|
3795
|
-
deltaX: null
|
|
3833
|
+
deltaX: null,
|
|
3834
|
+
tableOfSign: null
|
|
3796
3835
|
});
|
|
3797
3836
|
});
|
|
3798
3837
|
// Sloped asymptote
|
|
3799
3838
|
let NDegree = this.fx.numerator.degree(), DDegree = this.fx.denominator.degree();
|
|
3800
3839
|
if (NDegree.isEqual(DDegree)) {
|
|
3801
|
-
let H = this.fx.numerator.monomByDegree().coefficient.clone().divide(this.fx.denominator.monomByDegree().coefficient).tex;
|
|
3802
|
-
let { reminder } = reduced.euclidian();
|
|
3840
|
+
let H = this.fx.numerator.monomByDegree().coefficient.clone().divide(this.fx.denominator.monomByDegree().coefficient), Htex = H.tex;
|
|
3841
|
+
let { reminder } = reduced.euclidian(), deltaX = new rational_1.Rational(reminder, reduced.denominator);
|
|
3803
3842
|
asymptotes.push({
|
|
3843
|
+
fx: new polynom_1.Polynom(H),
|
|
3804
3844
|
type: study_1.ASYMPTOTE.HORIZONTAL,
|
|
3805
|
-
tex: `y=${
|
|
3845
|
+
tex: `y=${Htex}`,
|
|
3806
3846
|
zero: null,
|
|
3807
|
-
limits: `\\lim_{x\\to\\infty}\\ f(x) = ${
|
|
3808
|
-
deltaX
|
|
3847
|
+
limits: `\\lim_{x\\to\\infty}\\ f(x) = ${Htex}`,
|
|
3848
|
+
deltaX,
|
|
3849
|
+
tableOfSign: this._getSigns(deltaX)
|
|
3809
3850
|
});
|
|
3810
3851
|
}
|
|
3811
3852
|
else if (DDegree.greater(NDegree)) {
|
|
3812
3853
|
asymptotes.push({
|
|
3854
|
+
fx: new polynom_1.Polynom('0'),
|
|
3813
3855
|
type: study_1.ASYMPTOTE.HORIZONTAL,
|
|
3814
3856
|
tex: `y=0`,
|
|
3815
3857
|
zero: null,
|
|
3816
3858
|
limits: `\\lim_{x\\to\\infty}\\ f(x) = ${0}`,
|
|
3817
|
-
deltaX: null
|
|
3859
|
+
deltaX: null,
|
|
3860
|
+
tableOfSign: null
|
|
3818
3861
|
});
|
|
3819
3862
|
}
|
|
3820
3863
|
else if (NDegree.value - 1 === DDegree.value) {
|
|
3821
3864
|
// Calculate the slope
|
|
3822
|
-
let { quotient, reminder } = reduced.euclidian();
|
|
3865
|
+
let { quotient, reminder } = reduced.euclidian(), deltaX = new rational_1.Rational(reminder, reduced.denominator);
|
|
3823
3866
|
asymptotes.push({
|
|
3867
|
+
fx: quotient.clone(),
|
|
3824
3868
|
type: study_1.ASYMPTOTE.SLOPE,
|
|
3825
3869
|
tex: `y=${quotient.tex}`,
|
|
3826
3870
|
zero: null,
|
|
3827
3871
|
limits: ``,
|
|
3828
|
-
deltaX: new rational_1.Rational(reminder, reduced.denominator)
|
|
3872
|
+
deltaX: new rational_1.Rational(reminder, reduced.denominator),
|
|
3873
|
+
tableOfSign: this._getSigns(deltaX)
|
|
3829
3874
|
});
|
|
3830
3875
|
}
|
|
3831
3876
|
return asymptotes;
|
|
@@ -3833,7 +3878,6 @@ class RationalStudy extends study_1.Study {
|
|
|
3833
3878
|
;
|
|
3834
3879
|
makeDerivative() {
|
|
3835
3880
|
let dx = this.fx.clone().derivative(), tos = this._getSigns(dx, this._getZeroes(dx), study_1.TABLE_OF_SIGNS.GROWS);
|
|
3836
|
-
console.log(tos.factors.length, tos.signs.length);
|
|
3837
3881
|
let result = this.makeGrowsResult(tos);
|
|
3838
3882
|
tos.signs.push(result.growsLine);
|
|
3839
3883
|
tos.extremes = result.extremes;
|
|
@@ -3885,6 +3929,9 @@ class RationalStudy extends study_1.Study {
|
|
|
3885
3929
|
_getSigns(fx, zeroes, typeOfTable) {
|
|
3886
3930
|
// Factorize the rational
|
|
3887
3931
|
let signs = [], factors = [];
|
|
3932
|
+
if (zeroes === undefined) {
|
|
3933
|
+
zeroes = this._getZeroes(fx);
|
|
3934
|
+
}
|
|
3888
3935
|
fx.numerator.factors.forEach(factor => {
|
|
3889
3936
|
signs.push(this.makeOneLineForSigns(factor, zeroes, study_1.ZEROTYPE.ZERO));
|
|
3890
3937
|
factors.push(factor.clone());
|
|
@@ -3924,8 +3971,12 @@ const numeric_1 = __webpack_require__(956);
|
|
|
3924
3971
|
*/
|
|
3925
3972
|
class Fraction {
|
|
3926
3973
|
constructor(value, denominatorOrPeriodic) {
|
|
3927
|
-
|
|
3928
|
-
|
|
3974
|
+
this.isApproximative = () => {
|
|
3975
|
+
return this._numerator.toString().length >= 15 && this._denominator.toString().length >= 15;
|
|
3976
|
+
};
|
|
3977
|
+
this.isExact = () => {
|
|
3978
|
+
return !this.isApproximative();
|
|
3979
|
+
};
|
|
3929
3980
|
// ------------------------------------------
|
|
3930
3981
|
/**
|
|
3931
3982
|
* Parse the value to get the numerator and denominator
|
|
@@ -3942,15 +3993,15 @@ class Fraction {
|
|
|
3942
3993
|
}
|
|
3943
3994
|
switch (typeof value) {
|
|
3944
3995
|
case "string":
|
|
3945
|
-
// Split the
|
|
3996
|
+
// Split the string value in two parts: Numerator/Denominator
|
|
3946
3997
|
S = value.split('/');
|
|
3947
3998
|
// Security checks
|
|
3948
3999
|
if (S.length > 2)
|
|
3949
|
-
throw "
|
|
4000
|
+
throw value + " has too many divide signs";
|
|
3950
4001
|
if (S.map(x => x === '' || isNaN(Number(x))).includes(true))
|
|
3951
|
-
throw "
|
|
4002
|
+
throw value + " is not a valid number";
|
|
3952
4003
|
if (S.length === 1) {
|
|
3953
|
-
// No divide sign
|
|
4004
|
+
// No divide sign - it's a number
|
|
3954
4005
|
return this.parse(+S[0]);
|
|
3955
4006
|
}
|
|
3956
4007
|
else if (S.length === 2) {
|
|
@@ -3967,6 +4018,7 @@ class Fraction {
|
|
|
3967
4018
|
}
|
|
3968
4019
|
else {
|
|
3969
4020
|
// More than one divide sign ?
|
|
4021
|
+
// This is impossible
|
|
3970
4022
|
this._numerator = NaN;
|
|
3971
4023
|
this._denominator = 1;
|
|
3972
4024
|
}
|
|
@@ -4007,6 +4059,8 @@ class Fraction {
|
|
|
4007
4059
|
}
|
|
4008
4060
|
return this;
|
|
4009
4061
|
};
|
|
4062
|
+
// ------------------------------------------
|
|
4063
|
+
// Mathematical operations
|
|
4010
4064
|
this.clone = () => {
|
|
4011
4065
|
let F = new Fraction();
|
|
4012
4066
|
F.numerator = +this._numerator;
|
|
@@ -4034,8 +4088,6 @@ class Fraction {
|
|
|
4034
4088
|
return this;
|
|
4035
4089
|
};
|
|
4036
4090
|
// ------------------------------------------
|
|
4037
|
-
// Mathematical operations
|
|
4038
|
-
// ------------------------------------------
|
|
4039
4091
|
this.opposed = () => {
|
|
4040
4092
|
this._numerator = -this._numerator;
|
|
4041
4093
|
return this;
|
|
@@ -4314,22 +4366,32 @@ class Fraction {
|
|
|
4314
4366
|
if (this.isInfinity()) {
|
|
4315
4367
|
return `${this.sign() === 1 ? '+' : '-'}\\infty`;
|
|
4316
4368
|
}
|
|
4317
|
-
if (this.
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
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
|
+
}
|
|
4322
4379
|
}
|
|
4323
4380
|
else {
|
|
4324
|
-
return
|
|
4381
|
+
return this.value.toFixed(3);
|
|
4325
4382
|
}
|
|
4326
4383
|
}
|
|
4327
4384
|
get display() {
|
|
4328
|
-
if (this.
|
|
4329
|
-
|
|
4385
|
+
if (this.isExact()) {
|
|
4386
|
+
if (this._denominator === 1) {
|
|
4387
|
+
return `${this._numerator}`;
|
|
4388
|
+
}
|
|
4389
|
+
else {
|
|
4390
|
+
return `${this._numerator}/${this._denominator}`;
|
|
4391
|
+
}
|
|
4330
4392
|
}
|
|
4331
4393
|
else {
|
|
4332
|
-
return
|
|
4394
|
+
return this.value.toFixed(3);
|
|
4333
4395
|
}
|
|
4334
4396
|
}
|
|
4335
4397
|
// Helper function to display fractions
|
|
@@ -4364,6 +4426,8 @@ Fraction.min = (...fractions) => {
|
|
|
4364
4426
|
}
|
|
4365
4427
|
return M;
|
|
4366
4428
|
};
|
|
4429
|
+
// ------------------------------------------
|
|
4430
|
+
// Creation / parsing functions
|
|
4367
4431
|
Fraction.average = (...fractions) => {
|
|
4368
4432
|
let M = new Fraction().zero();
|
|
4369
4433
|
for (let f of fractions) {
|
|
@@ -6785,6 +6849,7 @@ var ShutingyardType;
|
|
|
6785
6849
|
})(ShutingyardType = exports.ShutingyardType || (exports.ShutingyardType = {}));
|
|
6786
6850
|
var ShutingyardMode;
|
|
6787
6851
|
(function (ShutingyardMode) {
|
|
6852
|
+
ShutingyardMode["EXPRESSION"] = "expression";
|
|
6788
6853
|
ShutingyardMode["POLYNOM"] = "polynom";
|
|
6789
6854
|
ShutingyardMode["SET"] = "set";
|
|
6790
6855
|
ShutingyardMode["NUMERIC"] = "numeric";
|
|
@@ -6800,6 +6865,9 @@ class Shutingyard {
|
|
|
6800
6865
|
// console.log(this._rpn)
|
|
6801
6866
|
return this._rpn;
|
|
6802
6867
|
}
|
|
6868
|
+
get rpnToken() {
|
|
6869
|
+
return this._rpn.map(x => x.token);
|
|
6870
|
+
}
|
|
6803
6871
|
/**
|
|
6804
6872
|
* Determin if the token is a defined operation
|
|
6805
6873
|
* Defined operations: + - * / ^ sin cos tan
|
|
@@ -6841,6 +6909,22 @@ class Shutingyard {
|
|
|
6841
6909
|
};
|
|
6842
6910
|
this._uniformize = false;
|
|
6843
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
|
+
}
|
|
6844
6928
|
else {
|
|
6845
6929
|
this._tokenConfig = {
|
|
6846
6930
|
'^': { precedence: 4, associative: 'right', type: ShutingyardType.OPERATION },
|
|
@@ -6848,10 +6932,6 @@ class Shutingyard {
|
|
|
6848
6932
|
'/': { precedence: 3, associative: 'left', type: ShutingyardType.OPERATION },
|
|
6849
6933
|
'+': { precedence: 2, associative: 'left', type: ShutingyardType.OPERATION },
|
|
6850
6934
|
'-': { precedence: 2, associative: 'left', type: ShutingyardType.OPERATION },
|
|
6851
|
-
// '%': {precedence: 3, associative: 'right', type: ShutingyardType.OPERATION},
|
|
6852
|
-
// 'sin': {precedence: 4, associative: 'right', type: ShutingyardType.FUNCTION},
|
|
6853
|
-
// 'cos': {precedence: 4, associative: 'right', type: ShutingyardType.FUNCTION},
|
|
6854
|
-
// 'tan': {precedence: 4, associative: 'right', type: ShutingyardType.FUNCTION},
|
|
6855
6935
|
};
|
|
6856
6936
|
this._uniformize = true;
|
|
6857
6937
|
}
|
|
@@ -6883,9 +6963,6 @@ class Shutingyard {
|
|
|
6883
6963
|
tokenType = 'function-argument';
|
|
6884
6964
|
}
|
|
6885
6965
|
else {
|
|
6886
|
-
// Order token keys by token characters length (descending)
|
|
6887
|
-
// TODO: this is done each time ! SHould be done once !
|
|
6888
|
-
// const keys = Object.keys(this._tokenConfig).sort((a,b)=>b.length-a.length)
|
|
6889
6966
|
// Extract operation and function tokens
|
|
6890
6967
|
for (let key of this._tokenKeys) {
|
|
6891
6968
|
if (expr.substring(start, start + key.length) === key) {
|
|
@@ -6907,7 +6984,7 @@ class Shutingyard {
|
|
|
6907
6984
|
if (expr[start].match(/[0-9]/)) {
|
|
6908
6985
|
if (this._mode === ShutingyardMode.POLYNOM && false) {}
|
|
6909
6986
|
else {
|
|
6910
|
-
token = expr.substring(start).match(/^([0-9
|
|
6987
|
+
token = expr.substring(start).match(/^([0-9.]+)/)[0];
|
|
6911
6988
|
}
|
|
6912
6989
|
tokenType = ShutingyardType.COEFFICIENT;
|
|
6913
6990
|
}
|
|
@@ -6924,19 +7001,114 @@ class Shutingyard {
|
|
|
6924
7001
|
}
|
|
6925
7002
|
return [token, start + token.length, tokenType];
|
|
6926
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
|
+
}
|
|
6927
7082
|
/**
|
|
6928
7083
|
* Sanitize an expression by adding missing common operation (multiplication between parentheseses)
|
|
6929
7084
|
* @param expr
|
|
6930
7085
|
* @constructor
|
|
6931
7086
|
*/
|
|
6932
7087
|
Uniformizer(expr) {
|
|
7088
|
+
// TODO: Delete this old version
|
|
7089
|
+
// Prefere "normalize", much more robust !
|
|
6933
7090
|
// Determiner if need to be uniformized
|
|
6934
7091
|
if (!this._uniformize) {
|
|
6935
7092
|
return expr;
|
|
6936
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));
|
|
6937
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");
|
|
6938
7110
|
// Replace missing multiplication between two parenthese
|
|
6939
|
-
expr2 =
|
|
7111
|
+
expr2 = expr2.replace(/\)\(/g, ')*(');
|
|
6940
7112
|
// Replace missing multiplication between number or setLetter and parenthese.
|
|
6941
7113
|
// 3x(x-4) => 3x*(x-4)
|
|
6942
7114
|
expr2 = expr2.replace(/([\da-zA-Z])(\()/g, "$1*$2");
|
|
@@ -6946,14 +7118,24 @@ class Shutingyard {
|
|
|
6946
7118
|
// 3x => 3*x
|
|
6947
7119
|
expr2 = expr2.replace(/([0-9])([a-zA-Z])/g, "$1*$2");
|
|
6948
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
|
+
// }
|
|
6949
7126
|
// Add multiplication between letters ?
|
|
6950
|
-
|
|
6951
|
-
expr2 = expr2.replace(/([
|
|
6952
|
-
// Restore operation auto
|
|
6953
|
-
|
|
6954
|
-
|
|
6955
|
-
|
|
6956
|
-
|
|
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
|
+
}
|
|
6957
7139
|
}
|
|
6958
7140
|
return expr2;
|
|
6959
7141
|
}
|
|
@@ -6967,7 +7149,9 @@ class Shutingyard {
|
|
|
6967
7149
|
let outQueue = [], // Output queue
|
|
6968
7150
|
opStack = [], // Operation queue
|
|
6969
7151
|
token = '', tokenPos = 0, tokenType = '', previousOpStatckLength = 0;
|
|
6970
|
-
|
|
7152
|
+
// Normalize the input if required.
|
|
7153
|
+
if (this._uniformize)
|
|
7154
|
+
expr = this.normalize(expr);
|
|
6971
7155
|
let securityLoopLvl1 = 50, securityLoopLvl2_default = 50, securityLoopLvl2;
|
|
6972
7156
|
while (tokenPos < expr.length) {
|
|
6973
7157
|
securityLoopLvl1--;
|
|
@@ -6986,10 +7170,6 @@ class Shutingyard {
|
|
|
6986
7170
|
token,
|
|
6987
7171
|
tokenType
|
|
6988
7172
|
});
|
|
6989
|
-
// if(previousOpStatckLength == opStack.length && outQueue.length>=2){
|
|
6990
|
-
// console.log('opStatckLength', outQueue, opStack.length)
|
|
6991
|
-
// outQueue.push('*')
|
|
6992
|
-
// }
|
|
6993
7173
|
break;
|
|
6994
7174
|
case 'operation':
|
|
6995
7175
|
previousOpStatckLength = opStack.length;
|