pimath 0.0.60 → 0.0.63
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/.idea/misc.xml +5 -0
- package/.idea/php.xml +1 -1
- package/.idea/shelf/Uncommitted_changes_before_Update_at_17_04_2022_12_40_[Changes]/shelved.patch +21 -0
- package/.idea/shelf/Uncommitted_changes_before_Update_at_17_04_2022_12_40__Changes_.xml +4 -0
- package/dist/pi.js +638 -351
- 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/linearSystem.js +0 -1
- package/esm/maths/algebra/linearSystem.js.map +1 -1
- package/esm/maths/algebra/monom.d.ts +1 -0
- package/esm/maths/algebra/monom.js +18 -0
- package/esm/maths/algebra/monom.js.map +1 -1
- package/esm/maths/algebra/polynom.d.ts +30 -11
- package/esm/maths/algebra/polynom.js +144 -258
- package/esm/maths/algebra/polynom.js.map +1 -1
- package/esm/maths/algebra/rational.d.ts +12 -15
- package/esm/maths/algebra/rational.js +14 -103
- package/esm/maths/algebra/rational.js.map +1 -1
- package/esm/maths/algebra/study/rationalStudy.d.ts +33 -0
- package/esm/maths/algebra/study/rationalStudy.js +174 -0
- package/esm/maths/algebra/study/rationalStudy.js.map +1 -0
- package/esm/maths/algebra/study.d.ts +133 -0
- package/esm/maths/algebra/study.js +275 -0
- package/esm/maths/algebra/study.js.map +1 -0
- package/package.json +1 -1
- package/src/maths/algebra/linearSystem.ts +0 -1
- package/src/maths/algebra/monom.ts +19 -0
- package/src/maths/algebra/polynom.ts +185 -278
- package/src/maths/algebra/rational.ts +24 -132
- package/src/maths/algebra/study/rationalStudy.ts +208 -0
- package/src/maths/algebra/study.ts +384 -0
- package/tests/algebra/monom.test.ts +2 -5
- package/tests/algebra/polynom.test.ts +2 -3
- package/tests/algebra/rationnal.test.ts +0 -43
- package/tests/algebra/study.test.ts +18 -0
- package/tests/numexp.test.ts +1 -1
package/dist/pi.js
CHANGED
|
@@ -932,7 +932,6 @@ class LinearSystem {
|
|
|
932
932
|
this.log = () => {
|
|
933
933
|
let str = '';
|
|
934
934
|
for (let E of this._equations) {
|
|
935
|
-
console.log(E.tex);
|
|
936
935
|
str += `${E.tex}\\n}`;
|
|
937
936
|
}
|
|
938
937
|
return str;
|
|
@@ -1673,6 +1672,9 @@ class Monom {
|
|
|
1673
1672
|
return this.evaluate(tmpValues);
|
|
1674
1673
|
}
|
|
1675
1674
|
if (typeof values === 'object') {
|
|
1675
|
+
if (this.variables.length === 0) {
|
|
1676
|
+
return this.coefficient;
|
|
1677
|
+
}
|
|
1676
1678
|
for (let L in this._literal) {
|
|
1677
1679
|
if (values[L] === undefined) {
|
|
1678
1680
|
return new fraction_1.Fraction().zero();
|
|
@@ -1760,6 +1762,21 @@ class Monom {
|
|
|
1760
1762
|
// All checks passed.
|
|
1761
1763
|
return true;
|
|
1762
1764
|
};
|
|
1765
|
+
this.isDivisible = (div) => {
|
|
1766
|
+
// For all variables (letters), the current monom must have a degree higher than the divider
|
|
1767
|
+
if (div.degree().isStrictlyPositive()) {
|
|
1768
|
+
for (let letter of div.variables) {
|
|
1769
|
+
if (!this.degree(letter).geq(div.degree(letter))) {
|
|
1770
|
+
return false;
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
}
|
|
1774
|
+
// If the coefficient is rational, we suppose we don't need to check the division by the coefficient.
|
|
1775
|
+
if (this.coefficient.isRational() || div.coefficient.isRational()) {
|
|
1776
|
+
return true;
|
|
1777
|
+
}
|
|
1778
|
+
return this.coefficient.clone().divide(div.coefficient).isRelative();
|
|
1779
|
+
};
|
|
1763
1780
|
this.zero();
|
|
1764
1781
|
if (value !== undefined) {
|
|
1765
1782
|
// A string is given - try to parse the value.
|
|
@@ -2135,6 +2152,11 @@ class Polynom {
|
|
|
2135
2152
|
* @param values
|
|
2136
2153
|
*/
|
|
2137
2154
|
constructor(polynomString, ...values) {
|
|
2155
|
+
this.mark_as_dirty = () => {
|
|
2156
|
+
this.dirty_factors = true;
|
|
2157
|
+
this.dirty_zeroes = true;
|
|
2158
|
+
this.euclidianCache = {};
|
|
2159
|
+
};
|
|
2138
2160
|
this.addToken = (stack, element) => {
|
|
2139
2161
|
switch (element.tokenType) {
|
|
2140
2162
|
case shutingyard_1.ShutingyardType.COEFFICIENT:
|
|
@@ -2222,6 +2244,7 @@ class Polynom {
|
|
|
2222
2244
|
// Reset the main variables.
|
|
2223
2245
|
this._monoms = [];
|
|
2224
2246
|
this._factors = [];
|
|
2247
|
+
this.mark_as_dirty();
|
|
2225
2248
|
if (typeof inputStr === 'string') {
|
|
2226
2249
|
return this._parseString(inputStr, ...values);
|
|
2227
2250
|
}
|
|
@@ -2262,88 +2285,32 @@ class Polynom {
|
|
|
2262
2285
|
this._monoms = [];
|
|
2263
2286
|
this._monoms.push(new monom_1.Monom().zero());
|
|
2264
2287
|
this._rawString = '0';
|
|
2288
|
+
this.mark_as_dirty();
|
|
2265
2289
|
return this;
|
|
2266
2290
|
};
|
|
2267
2291
|
this.one = () => {
|
|
2268
2292
|
this._monoms = [];
|
|
2269
2293
|
this._monoms.push(new monom_1.Monom().one());
|
|
2270
2294
|
this._rawString = '1';
|
|
2295
|
+
this.mark_as_dirty();
|
|
2271
2296
|
return this;
|
|
2272
2297
|
};
|
|
2273
2298
|
this.empty = () => {
|
|
2274
2299
|
this._monoms = [];
|
|
2275
2300
|
this._rawString = '';
|
|
2301
|
+
this.mark_as_dirty();
|
|
2276
2302
|
return this;
|
|
2277
2303
|
};
|
|
2278
2304
|
// ------------------------------------------
|
|
2279
2305
|
this.opposed = () => {
|
|
2280
2306
|
this._monoms = this._monoms.map(m => m.opposed());
|
|
2307
|
+
this.mark_as_dirty();
|
|
2281
2308
|
return this;
|
|
2282
2309
|
};
|
|
2283
|
-
// // -----------------------------------------------
|
|
2284
|
-
// // Polynom generators and randomizers
|
|
2285
|
-
// // -----------------------------------------------
|
|
2286
|
-
// random(config?: randomPolynomConfig) {
|
|
2287
|
-
// return Random.polynom(config);
|
|
2288
|
-
// }
|
|
2289
|
-
//
|
|
2290
|
-
// private _randomizeDefaults: { [key: string]: number | string | boolean } = {
|
|
2291
|
-
// degree: 2,
|
|
2292
|
-
// unit: true,
|
|
2293
|
-
// fractions: false,
|
|
2294
|
-
// factorable: false,
|
|
2295
|
-
// letters: 'x',
|
|
2296
|
-
// allowNullMonom: false,
|
|
2297
|
-
// numberOfMonoms: false
|
|
2298
|
-
// };
|
|
2299
|
-
// get randomizeDefaults(): { [key: string]: number | string | boolean } {
|
|
2300
|
-
// return this._randomizeDefaults;
|
|
2301
|
-
// }
|
|
2302
|
-
//
|
|
2303
|
-
// set randomizeDefaults(value) {
|
|
2304
|
-
// this._randomizeDefaults = value;
|
|
2305
|
-
// }
|
|
2306
|
-
//
|
|
2307
|
-
// randomize = (config: { [key: string]: number | string | boolean }): Polynom => {
|
|
2308
|
-
// let P = new Polynom();
|
|
2309
|
-
//
|
|
2310
|
-
// // Check the config file and use the default values.
|
|
2311
|
-
// if (config === undefined) {
|
|
2312
|
-
// config = {};
|
|
2313
|
-
// }
|
|
2314
|
-
// for (let k in this._randomizeDefaults) {
|
|
2315
|
-
// if (config[k] === undefined) {
|
|
2316
|
-
// config[k] = this._randomizeDefaults[k];
|
|
2317
|
-
// }
|
|
2318
|
-
// }
|
|
2319
|
-
//
|
|
2320
|
-
// // TODO: Build a more robust randomize function
|
|
2321
|
-
// return P;
|
|
2322
|
-
// }
|
|
2323
|
-
//
|
|
2324
|
-
// rndFactorable = (degree: number = 2, unit: boolean | number = false, letters: string = 'x'): Polynom => {
|
|
2325
|
-
// // TODO: Make rndFactorable polynom generator more user friendly
|
|
2326
|
-
// this._factors = [];
|
|
2327
|
-
// for (let i = 0; i < degree; i++) {
|
|
2328
|
-
// let factorUnit = unit === true || i >= unit,
|
|
2329
|
-
// p = Random.polynom({
|
|
2330
|
-
// degree: 1,
|
|
2331
|
-
// unit: factorUnit,
|
|
2332
|
-
// fraction: false,
|
|
2333
|
-
// letters
|
|
2334
|
-
// });
|
|
2335
|
-
// this._factors.push(p);
|
|
2336
|
-
// }
|
|
2337
|
-
//
|
|
2338
|
-
// this.empty().monoms = this._factors[0].monoms;
|
|
2339
|
-
// for (let i = 1; i < this._factors.length; i++) {
|
|
2340
|
-
// this.multiply(this._factors[i]);
|
|
2341
|
-
// }
|
|
2342
|
-
// return this;
|
|
2343
|
-
// };
|
|
2344
2310
|
// ------------------------------------------
|
|
2345
2311
|
// Mathematical operations
|
|
2346
2312
|
this.add = (...values) => {
|
|
2313
|
+
this.mark_as_dirty();
|
|
2347
2314
|
for (let value of values) {
|
|
2348
2315
|
if (value instanceof Polynom) {
|
|
2349
2316
|
this._monoms = this._monoms.concat(value.monoms);
|
|
@@ -2361,6 +2328,7 @@ class Polynom {
|
|
|
2361
2328
|
return this.reduce();
|
|
2362
2329
|
};
|
|
2363
2330
|
this.subtract = (...values) => {
|
|
2331
|
+
this.mark_as_dirty();
|
|
2364
2332
|
for (let value of values) {
|
|
2365
2333
|
if (value instanceof Polynom) {
|
|
2366
2334
|
this._monoms = this._monoms.concat(value.clone().opposed().monoms);
|
|
@@ -2378,6 +2346,7 @@ class Polynom {
|
|
|
2378
2346
|
return this.reduce();
|
|
2379
2347
|
};
|
|
2380
2348
|
this.multiply = (value) => {
|
|
2349
|
+
this.mark_as_dirty();
|
|
2381
2350
|
if (value instanceof Polynom) {
|
|
2382
2351
|
return this.multiplyByPolynom(value);
|
|
2383
2352
|
}
|
|
@@ -2399,6 +2368,9 @@ class Polynom {
|
|
|
2399
2368
|
* returns {quotient: Polynom, reminder: Polynom}
|
|
2400
2369
|
*/
|
|
2401
2370
|
this.euclidian = (P) => {
|
|
2371
|
+
if (this.euclidianCache[P.tex] !== undefined) {
|
|
2372
|
+
return this.euclidianCache[P.tex];
|
|
2373
|
+
}
|
|
2402
2374
|
const letter = P.variables[0];
|
|
2403
2375
|
const quotient = new Polynom().zero();
|
|
2404
2376
|
const reminder = this.clone().reorder(letter);
|
|
@@ -2432,6 +2404,7 @@ class Polynom {
|
|
|
2432
2404
|
return { quotient, reminder };
|
|
2433
2405
|
};
|
|
2434
2406
|
this.divide = (value) => {
|
|
2407
|
+
this.mark_as_dirty();
|
|
2435
2408
|
if (value instanceof fraction_1.Fraction) {
|
|
2436
2409
|
return this.divideByFraction(value);
|
|
2437
2410
|
}
|
|
@@ -2445,6 +2418,7 @@ class Polynom {
|
|
|
2445
2418
|
}
|
|
2446
2419
|
};
|
|
2447
2420
|
this.pow = (nb) => {
|
|
2421
|
+
this.mark_as_dirty();
|
|
2448
2422
|
if (!Number.isSafeInteger(nb)) {
|
|
2449
2423
|
return this.zero();
|
|
2450
2424
|
}
|
|
@@ -2645,6 +2619,7 @@ class Polynom {
|
|
|
2645
2619
|
* @param P
|
|
2646
2620
|
*/
|
|
2647
2621
|
this.replaceBy = (letter, P) => {
|
|
2622
|
+
this.mark_as_dirty();
|
|
2648
2623
|
let pow;
|
|
2649
2624
|
const resultPolynom = new Polynom().zero();
|
|
2650
2625
|
for (const m of this.monoms) {
|
|
@@ -2704,146 +2679,108 @@ class Polynom {
|
|
|
2704
2679
|
* @param maxValue Defines the greatest value to search to (default is 20).
|
|
2705
2680
|
*/
|
|
2706
2681
|
this.factorize = (letter) => {
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
securityLoop
|
|
2721
|
-
|
|
2722
|
-
if (
|
|
2682
|
+
if (this.dirty_factors) {
|
|
2683
|
+
let factors = [];
|
|
2684
|
+
let P = this.clone().reorder();
|
|
2685
|
+
// Extract the common monom
|
|
2686
|
+
// 2x^3+6x^2 => 2x^2
|
|
2687
|
+
let M = P.commonMonom();
|
|
2688
|
+
if (!M.isOne()) {
|
|
2689
|
+
let tempPolynom = new Polynom(M);
|
|
2690
|
+
factors = [tempPolynom.clone()];
|
|
2691
|
+
P = P.euclidian(tempPolynom).quotient;
|
|
2692
|
+
}
|
|
2693
|
+
// Main loop
|
|
2694
|
+
let securityLoop = P.degree().clone().multiply(2).value, maxDegree = 1;
|
|
2695
|
+
while (securityLoop >= 0) {
|
|
2696
|
+
securityLoop--;
|
|
2697
|
+
if (P.monoms.length < 2) {
|
|
2698
|
+
// The polynom has only one monom => 7x^2
|
|
2699
|
+
// No need to continue.
|
|
2700
|
+
if (!P.isOne()) {
|
|
2701
|
+
factors.push(P.clone());
|
|
2702
|
+
P.one();
|
|
2703
|
+
}
|
|
2704
|
+
break;
|
|
2705
|
+
}
|
|
2706
|
+
else if (P.degree(letter).isOne()) {
|
|
2707
|
+
// The polynom is a first degree polynom => 3x-5
|
|
2708
|
+
// No need to continue
|
|
2723
2709
|
factors.push(P.clone());
|
|
2724
2710
|
P.one();
|
|
2711
|
+
break;
|
|
2712
|
+
}
|
|
2713
|
+
else {
|
|
2714
|
+
// Create the list of all "potential" polynom dividers.
|
|
2715
|
+
let allDividers = this._getAllPotentialFactors(P, maxDegree, letter);
|
|
2716
|
+
maxDegree = P.degree(letter).value;
|
|
2717
|
+
// Actually: 100ms
|
|
2718
|
+
while (allDividers.length > 0) {
|
|
2719
|
+
let div = allDividers[0];
|
|
2720
|
+
if (!P.isDividableBy(div)) {
|
|
2721
|
+
// Not dividable. Remove it from the list
|
|
2722
|
+
allDividers.shift();
|
|
2723
|
+
}
|
|
2724
|
+
else {
|
|
2725
|
+
// It's dividable - so make the division
|
|
2726
|
+
let result = P.euclidian(div);
|
|
2727
|
+
// Add the factor
|
|
2728
|
+
factors.push(div);
|
|
2729
|
+
// As it's dividable, get the quotient.
|
|
2730
|
+
P = result.quotient.clone();
|
|
2731
|
+
// filter all dividers that are no more suitable.
|
|
2732
|
+
allDividers = allDividers.filter(x => {
|
|
2733
|
+
let pX = P.monoms[0], pC = P.monoms[P.monoms.length - 1], dX = x.monoms[0], dC = x.monoms[x.monoms.length - 1];
|
|
2734
|
+
// Check last item (degree zero)
|
|
2735
|
+
if (!pC.isDivisible(dC)) {
|
|
2736
|
+
return false;
|
|
2737
|
+
}
|
|
2738
|
+
// Check the first item (degree max)
|
|
2739
|
+
if (!pX.isDivisible(dX)) {
|
|
2740
|
+
return false;
|
|
2741
|
+
}
|
|
2742
|
+
return true;
|
|
2743
|
+
});
|
|
2744
|
+
}
|
|
2745
|
+
}
|
|
2725
2746
|
}
|
|
2726
|
-
break;
|
|
2727
2747
|
}
|
|
2728
|
-
|
|
2748
|
+
// Maybe there is still something in the Polynom (not everything was possible to factorize)
|
|
2749
|
+
if (!P.isOne()) {
|
|
2729
2750
|
factors.push(P.clone());
|
|
2730
|
-
|
|
2731
|
-
|
|
2751
|
+
}
|
|
2752
|
+
// Save the factors
|
|
2753
|
+
this._factors = factors;
|
|
2754
|
+
// The factors list is no more dirty
|
|
2755
|
+
this.dirty_factors = false;
|
|
2756
|
+
}
|
|
2757
|
+
return this._factors;
|
|
2758
|
+
};
|
|
2759
|
+
this.isDividableBy = (div) => {
|
|
2760
|
+
// Quick evaluation.
|
|
2761
|
+
if (div.degree().isOne()) {
|
|
2762
|
+
let zero = div.getZeroes()[0];
|
|
2763
|
+
if (zero.exact instanceof fraction_1.Fraction) {
|
|
2764
|
+
return this.evaluate(zero.exact).isZero();
|
|
2732
2765
|
}
|
|
2733
2766
|
else {
|
|
2734
|
-
|
|
2735
|
-
// let m1 = P.monoms[0].dividers,
|
|
2736
|
-
// m2 = P.monoms[P.monoms.length - 1].dividers
|
|
2737
|
-
// Create the list of all "potential" polynom dividers.
|
|
2738
|
-
let allDividers = this._getAllPotentialFactors(P, letter);
|
|
2739
|
-
allDividers.every(div => {
|
|
2740
|
-
result = P.euclidian(div);
|
|
2741
|
-
if (result.reminder.isZero()) {
|
|
2742
|
-
P = result.quotient.clone();
|
|
2743
|
-
factors.push(div);
|
|
2744
|
-
return false;
|
|
2745
|
-
}
|
|
2746
|
-
return true;
|
|
2747
|
-
});
|
|
2767
|
+
return false;
|
|
2748
2768
|
}
|
|
2749
2769
|
}
|
|
2750
|
-
|
|
2751
|
-
|
|
2770
|
+
else {
|
|
2771
|
+
this.euclidianCache[div.tex] = this.euclidian(div);
|
|
2772
|
+
return this.euclidianCache[div.tex].reminder.isZero();
|
|
2752
2773
|
}
|
|
2753
|
-
this.factors = factors;
|
|
2754
|
-
return factors;
|
|
2755
2774
|
};
|
|
2756
2775
|
// TODO: get zeroes for more than first degree and for more than natural degrees
|
|
2757
2776
|
this.getZeroes = () => {
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
//
|
|
2766
|
-
// switch (this.degree().value) {
|
|
2767
|
-
// case 0:
|
|
2768
|
-
// if (this._monoms[0].coefficient.value === 0) {
|
|
2769
|
-
// return [{
|
|
2770
|
-
// tex: '\\mathbb{R}',
|
|
2771
|
-
// value: NaN,
|
|
2772
|
-
// exact: false
|
|
2773
|
-
// }];
|
|
2774
|
-
// } else {
|
|
2775
|
-
// return [{
|
|
2776
|
-
// tex: '\\varnothing',
|
|
2777
|
-
// value: NaN,
|
|
2778
|
-
// exact: false
|
|
2779
|
-
// }];
|
|
2780
|
-
// }
|
|
2781
|
-
// case 1:
|
|
2782
|
-
// // There is only one monoms,
|
|
2783
|
-
// if (this._monoms.length === 1) {
|
|
2784
|
-
// return [{
|
|
2785
|
-
// tex: '0',
|
|
2786
|
-
// value: 0,
|
|
2787
|
-
// exact: new Fraction().zero()
|
|
2788
|
-
// }];
|
|
2789
|
-
// } else {
|
|
2790
|
-
// const P = this.clone().reduce().reorder();
|
|
2791
|
-
// const coeff = P.monoms[1].coefficient.opposed().divide(P.monoms[0].coefficient)
|
|
2792
|
-
// return [{
|
|
2793
|
-
// tex: coeff.tex,
|
|
2794
|
-
// value: coeff.value,
|
|
2795
|
-
// exact: coeff
|
|
2796
|
-
// }];
|
|
2797
|
-
// }
|
|
2798
|
-
// // TODO: Determine the zeros of an equation of second degree.
|
|
2799
|
-
// //case 2:
|
|
2800
|
-
// default:
|
|
2801
|
-
// // Make sure the polynom is factorized.
|
|
2802
|
-
// if (this._factors.length === 0) {
|
|
2803
|
-
// this.factorize()
|
|
2804
|
-
// }
|
|
2805
|
-
//
|
|
2806
|
-
// let zeroes:Fraction[] = [], zeroesAsTex = [];
|
|
2807
|
-
// for (let P of this._factors) {
|
|
2808
|
-
// if (P.degree().greater(2)) {
|
|
2809
|
-
// // TODO: get zeroes of polynom with a degree greater than 2.
|
|
2810
|
-
//
|
|
2811
|
-
// } else if (P.degree().value === 2) {
|
|
2812
|
-
// let A = P.monomByDegree(2).coefficient,
|
|
2813
|
-
// B = P.monomByDegree(1).coefficient,
|
|
2814
|
-
// C = P.monomByDegree(0).coefficient,
|
|
2815
|
-
// D = B.clone().pow(2).subtract(A.clone().multiply(C).multiply(4));
|
|
2816
|
-
//
|
|
2817
|
-
// if (D.value > 0) {
|
|
2818
|
-
// /*console.log('Two zeroes for ', P.tex); */
|
|
2819
|
-
// let x1 = (-(B.value) + Math.sqrt(D.value)) / (2 * A.value),
|
|
2820
|
-
// x2 = (-(B.value) - Math.sqrt(D.value)) / (2 * A.value);
|
|
2821
|
-
//
|
|
2822
|
-
// zeroes.push(new Fraction(x1.toFixed(3)).reduce());
|
|
2823
|
-
// zeroes.push(new Fraction(x2.toFixed(3)).reduce());
|
|
2824
|
-
// } else if (D.value === 0) {
|
|
2825
|
-
// /*console.log('One zero for ', P.tex); */
|
|
2826
|
-
// } else {
|
|
2827
|
-
// console.log('No zero for ', P.tex);
|
|
2828
|
-
// }
|
|
2829
|
-
// } else {
|
|
2830
|
-
// for (let z of P.getZeroes()) {
|
|
2831
|
-
// // Check if the zero is already in the list.
|
|
2832
|
-
// // if (z === false || z === true) {
|
|
2833
|
-
// // continue;
|
|
2834
|
-
// // }
|
|
2835
|
-
// if (zeroesAsTex.indexOf(z.frac) === -1) {
|
|
2836
|
-
// zeroes.push(z);
|
|
2837
|
-
// zeroesAsTex.push(z.frac);
|
|
2838
|
-
// }
|
|
2839
|
-
// }
|
|
2840
|
-
// }
|
|
2841
|
-
// }
|
|
2842
|
-
//
|
|
2843
|
-
//
|
|
2844
|
-
// return zeroes;
|
|
2845
|
-
// }
|
|
2846
|
-
// return Z;
|
|
2777
|
+
if (this.dirty_zeroes) {
|
|
2778
|
+
let equ = new equation_1.Equation(this.clone(), 0);
|
|
2779
|
+
equ.solve();
|
|
2780
|
+
this._zeroes = equ.solutions;
|
|
2781
|
+
this.dirty_zeroes = false;
|
|
2782
|
+
}
|
|
2783
|
+
return this._zeroes;
|
|
2847
2784
|
};
|
|
2848
2785
|
// TODO: analyse the next functions to determine if they are useful or not...
|
|
2849
2786
|
this.monomByDegree = (degree, letter) => {
|
|
@@ -2958,16 +2895,19 @@ class Polynom {
|
|
|
2958
2895
|
// Any other cases
|
|
2959
2896
|
return (new fraction_1.Fraction()).zero();
|
|
2960
2897
|
};
|
|
2961
|
-
this._getAllPotentialFactors = (P, letter) => {
|
|
2898
|
+
this._getAllPotentialFactors = (P, maxDegree, letter) => {
|
|
2962
2899
|
let m1 = P.monoms[0].dividers, m2 = P.monoms[P.monoms.length - 1].dividers;
|
|
2963
2900
|
let allDividers = [];
|
|
2964
2901
|
m1.forEach(m1d => {
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2902
|
+
// Get only polynom that has a degree less than a specific value
|
|
2903
|
+
if (m1d.degree(letter).leq(maxDegree)) {
|
|
2904
|
+
m2.forEach(m2d => {
|
|
2905
|
+
if (m1d.degree(letter).isNotEqual(m2d.degree(letter))) {
|
|
2906
|
+
allDividers.push(new Polynom(m1d, m2d));
|
|
2907
|
+
allDividers.push(new Polynom(m1d, m2d.clone().opposed()));
|
|
2908
|
+
}
|
|
2909
|
+
});
|
|
2910
|
+
}
|
|
2971
2911
|
});
|
|
2972
2912
|
return allDividers;
|
|
2973
2913
|
};
|
|
@@ -3019,41 +2959,6 @@ class Polynom {
|
|
|
3019
2959
|
this.add(stack[0]);
|
|
3020
2960
|
}
|
|
3021
2961
|
return this;
|
|
3022
|
-
/**
|
|
3023
|
-
let m1: Polynom;
|
|
3024
|
-
let m2: Polynom;
|
|
3025
|
-
|
|
3026
|
-
let stack: Polynom[] = [],
|
|
3027
|
-
previousToken: string = null,
|
|
3028
|
-
tempPolynom
|
|
3029
|
-
|
|
3030
|
-
for (const element of rpn) {
|
|
3031
|
-
if (element.tokenType === 'coefficient' || element.tokenType === 'variable') {
|
|
3032
|
-
tempPolynom = new Polynom().zero();
|
|
3033
|
-
tempPolynom.monoms = [new Monom(element.token)]
|
|
3034
|
-
stack.push(tempPolynom.clone())
|
|
3035
|
-
} else if (element.tokenType === 'operation') {
|
|
3036
|
-
m2 = (stack.pop()) || new Polynom().zero();
|
|
3037
|
-
m1 = (stack.pop()) || new Polynom().zero();
|
|
3038
|
-
switch (element.token) {
|
|
3039
|
-
case '+':
|
|
3040
|
-
stack.push(m1.add(m2))
|
|
3041
|
-
break;
|
|
3042
|
-
case '-':
|
|
3043
|
-
stack.push(m1.subtract(m2))
|
|
3044
|
-
break;
|
|
3045
|
-
case '*':
|
|
3046
|
-
stack.push(m1.multiply(m2))
|
|
3047
|
-
break;
|
|
3048
|
-
case '^':
|
|
3049
|
-
stack.push(m1.pow(+previousToken))
|
|
3050
|
-
}
|
|
3051
|
-
}
|
|
3052
|
-
previousToken = element.token;
|
|
3053
|
-
}
|
|
3054
|
-
|
|
3055
|
-
this._monoms = stack[0].monoms;
|
|
3056
|
-
return this;*/
|
|
3057
2962
|
};
|
|
3058
2963
|
this.multiplyByPolynom = (P) => {
|
|
3059
2964
|
const M = [];
|
|
@@ -3178,33 +3083,6 @@ class Polynom {
|
|
|
3178
3083
|
}
|
|
3179
3084
|
}
|
|
3180
3085
|
return [this.clone()];
|
|
3181
|
-
//
|
|
3182
|
-
// console.log(a.tex, b.tex, c.tex)
|
|
3183
|
-
// if (a.isSquare() && c.isSquare()) {
|
|
3184
|
-
// console.log('A C squares')
|
|
3185
|
-
// if (a.clone().sqrt().multiply(c.clone().sqrt()).multiplyByNumber(2).isSameAs(b)) {
|
|
3186
|
-
// console.log('HERE')
|
|
3187
|
-
// if (a.coefficient.sign() === b.coefficient.sign()) {
|
|
3188
|
-
// return []
|
|
3189
|
-
// }else{
|
|
3190
|
-
// return []
|
|
3191
|
-
// }
|
|
3192
|
-
// }
|
|
3193
|
-
// } else if(a.isLiteralSquare() && c.isLiteralSquare()) {
|
|
3194
|
-
// console.log('A C litteral SQUARES')
|
|
3195
|
-
// // Check that the middle element is the product of a and c.
|
|
3196
|
-
//
|
|
3197
|
-
// if(b.clone().pow(2).isSameAs(a.clone().multiply(c))){
|
|
3198
|
-
// console.log('SAME')
|
|
3199
|
-
//
|
|
3200
|
-
// }else{
|
|
3201
|
-
// console.log('NOT SAME')
|
|
3202
|
-
// }
|
|
3203
|
-
//
|
|
3204
|
-
// return [this.clone()]
|
|
3205
|
-
// } else {
|
|
3206
|
-
// console.log('NOT SQUARES AT ALL !!!!')
|
|
3207
|
-
// }
|
|
3208
3086
|
}
|
|
3209
3087
|
};
|
|
3210
3088
|
this._factorizeByGroups = () => {
|
|
@@ -3213,11 +3091,31 @@ class Polynom {
|
|
|
3213
3091
|
};
|
|
3214
3092
|
this._monoms = [];
|
|
3215
3093
|
this._factors = [];
|
|
3094
|
+
this.mark_as_dirty();
|
|
3216
3095
|
if (polynomString !== undefined) {
|
|
3217
3096
|
this.parse(polynomString, ...values);
|
|
3218
3097
|
}
|
|
3219
3098
|
return this;
|
|
3220
3099
|
}
|
|
3100
|
+
get euclidianCache() {
|
|
3101
|
+
return this._euclidianCache;
|
|
3102
|
+
}
|
|
3103
|
+
set euclidianCache(value) {
|
|
3104
|
+
this._euclidianCache = value;
|
|
3105
|
+
}
|
|
3106
|
+
get dirty_zeroes() {
|
|
3107
|
+
return this._dirty_zeroes;
|
|
3108
|
+
}
|
|
3109
|
+
set dirty_zeroes(value) {
|
|
3110
|
+
this._dirty_zeroes = value;
|
|
3111
|
+
}
|
|
3112
|
+
// ------------------------------------------
|
|
3113
|
+
get dirty_factors() {
|
|
3114
|
+
return this._dirty_factors;
|
|
3115
|
+
}
|
|
3116
|
+
set dirty_factors(value) {
|
|
3117
|
+
this._dirty_factors = value;
|
|
3118
|
+
}
|
|
3221
3119
|
// ------------------------------------------
|
|
3222
3120
|
get monoms() {
|
|
3223
3121
|
return this._monoms;
|
|
@@ -3225,10 +3123,14 @@ class Polynom {
|
|
|
3225
3123
|
set monoms(M) {
|
|
3226
3124
|
this._monoms = M;
|
|
3227
3125
|
}
|
|
3126
|
+
get zeroes() {
|
|
3127
|
+
return this.getZeroes();
|
|
3128
|
+
}
|
|
3228
3129
|
get factors() {
|
|
3229
|
-
return this.
|
|
3130
|
+
return this.factorize();
|
|
3230
3131
|
}
|
|
3231
3132
|
set factors(value) {
|
|
3133
|
+
this.mark_as_dirty();
|
|
3232
3134
|
this._factors = value;
|
|
3233
3135
|
}
|
|
3234
3136
|
get texString() {
|
|
@@ -3362,6 +3264,7 @@ exports.Rational = void 0;
|
|
|
3362
3264
|
const polynom_1 = __webpack_require__(38);
|
|
3363
3265
|
const fraction_1 = __webpack_require__(506);
|
|
3364
3266
|
const equation_1 = __webpack_require__(760);
|
|
3267
|
+
const rationalStudy_1 = __webpack_require__(572);
|
|
3365
3268
|
/**
|
|
3366
3269
|
* Rational class can handle rational polynoms
|
|
3367
3270
|
*/
|
|
@@ -3373,9 +3276,7 @@ class Rational {
|
|
|
3373
3276
|
*/
|
|
3374
3277
|
constructor(numerator, denominator) {
|
|
3375
3278
|
this.clone = () => {
|
|
3376
|
-
this._numerator
|
|
3377
|
-
this._denominator = this._denominator.clone();
|
|
3378
|
-
return this;
|
|
3279
|
+
return new Rational(this._numerator.clone(), this._denominator.clone());
|
|
3379
3280
|
};
|
|
3380
3281
|
this.domain = () => {
|
|
3381
3282
|
let zeroes = this._denominator.getZeroes();
|
|
@@ -3440,6 +3341,10 @@ class Rational {
|
|
|
3440
3341
|
this.subtract = (R) => {
|
|
3441
3342
|
return this.add(R.clone().opposed());
|
|
3442
3343
|
};
|
|
3344
|
+
this.euclidian = () => {
|
|
3345
|
+
return this._numerator.euclidian(this._denominator);
|
|
3346
|
+
};
|
|
3347
|
+
// TODO : where and how is used limits ?
|
|
3443
3348
|
this.limits = (value, offset, letter) => {
|
|
3444
3349
|
if (value === Infinity || value === -Infinity) {
|
|
3445
3350
|
let { quotient, reminder } = this._numerator.clone().euclidian(this._denominator);
|
|
@@ -3480,26 +3385,151 @@ class Rational {
|
|
|
3480
3385
|
}
|
|
3481
3386
|
}
|
|
3482
3387
|
};
|
|
3483
|
-
this.
|
|
3484
|
-
|
|
3485
|
-
this._numerator.
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3388
|
+
this.evaluate = (values) => {
|
|
3389
|
+
const r = new fraction_1.Fraction().zero();
|
|
3390
|
+
let N = this._numerator.evaluate(values), D = this._denominator.evaluate(values);
|
|
3391
|
+
return N.divide(D);
|
|
3392
|
+
};
|
|
3393
|
+
this.study = () => {
|
|
3394
|
+
return new rationalStudy_1.RationalStudy(this);
|
|
3395
|
+
};
|
|
3396
|
+
if (numerator instanceof polynom_1.Polynom) {
|
|
3397
|
+
this._numerator = numerator.clone();
|
|
3398
|
+
}
|
|
3399
|
+
else if (typeof numerator === 'string') {
|
|
3400
|
+
this._numerator = new polynom_1.Polynom(numerator);
|
|
3401
|
+
}
|
|
3402
|
+
else {
|
|
3403
|
+
this._numerator = new polynom_1.Polynom();
|
|
3404
|
+
}
|
|
3405
|
+
if (denominator instanceof polynom_1.Polynom) {
|
|
3406
|
+
this._denominator = denominator.clone();
|
|
3407
|
+
}
|
|
3408
|
+
else if (typeof denominator === 'string') {
|
|
3409
|
+
this._denominator = new polynom_1.Polynom(denominator);
|
|
3410
|
+
}
|
|
3411
|
+
else {
|
|
3412
|
+
this._denominator = new polynom_1.Polynom();
|
|
3413
|
+
}
|
|
3414
|
+
}
|
|
3415
|
+
get numerator() {
|
|
3416
|
+
return this._numerator;
|
|
3417
|
+
}
|
|
3418
|
+
get denominator() {
|
|
3419
|
+
return this._denominator;
|
|
3420
|
+
}
|
|
3421
|
+
get tex() {
|
|
3422
|
+
return `\\frac{ ${this._numerator.tex} }{ ${this._denominator.tex} }`;
|
|
3423
|
+
}
|
|
3424
|
+
get texFactors() {
|
|
3425
|
+
return `\\frac{ ${this._numerator.texFactors} }{ ${this._denominator.texFactors} }`;
|
|
3426
|
+
}
|
|
3427
|
+
get plotFunction() {
|
|
3428
|
+
return `(${this._numerator.plotFunction})/(${this._denominator.plotFunction})`;
|
|
3429
|
+
}
|
|
3430
|
+
}
|
|
3431
|
+
exports.Rational = Rational;
|
|
3432
|
+
|
|
3433
|
+
|
|
3434
|
+
/***/ }),
|
|
3435
|
+
|
|
3436
|
+
/***/ 996:
|
|
3437
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
3438
|
+
|
|
3439
|
+
|
|
3440
|
+
/**
|
|
3441
|
+
* Rational polynom module contains everything necessary to handle rational polynoms.
|
|
3442
|
+
* @module Polynom
|
|
3443
|
+
*/
|
|
3444
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
3445
|
+
exports.Study = exports.TABLE_OF_SIGNS = exports.FUNCTION_EXTREMA = exports.ASYMPTOTE = exports.ZEROTYPE = void 0;
|
|
3446
|
+
const fraction_1 = __webpack_require__(506);
|
|
3447
|
+
var ZEROTYPE;
|
|
3448
|
+
(function (ZEROTYPE) {
|
|
3449
|
+
ZEROTYPE["ZERO"] = "z";
|
|
3450
|
+
ZEROTYPE["DEFENCE"] = "d";
|
|
3451
|
+
ZEROTYPE["NOTHING"] = "t";
|
|
3452
|
+
})(ZEROTYPE = exports.ZEROTYPE || (exports.ZEROTYPE = {}));
|
|
3453
|
+
var ASYMPTOTE;
|
|
3454
|
+
(function (ASYMPTOTE) {
|
|
3455
|
+
ASYMPTOTE["VERTICAL"] = "av";
|
|
3456
|
+
ASYMPTOTE["HORIZONTAL"] = "ah";
|
|
3457
|
+
ASYMPTOTE["SLOPE"] = "ao";
|
|
3458
|
+
ASYMPTOTE["HOLE"] = "hole";
|
|
3459
|
+
})(ASYMPTOTE = exports.ASYMPTOTE || (exports.ASYMPTOTE = {}));
|
|
3460
|
+
var FUNCTION_EXTREMA;
|
|
3461
|
+
(function (FUNCTION_EXTREMA) {
|
|
3462
|
+
FUNCTION_EXTREMA["MIN"] = "min";
|
|
3463
|
+
FUNCTION_EXTREMA["MAX"] = "max";
|
|
3464
|
+
FUNCTION_EXTREMA["FLAT"] = "flat";
|
|
3465
|
+
FUNCTION_EXTREMA["NOTHING"] = "";
|
|
3466
|
+
})(FUNCTION_EXTREMA = exports.FUNCTION_EXTREMA || (exports.FUNCTION_EXTREMA = {}));
|
|
3467
|
+
var TABLE_OF_SIGNS;
|
|
3468
|
+
(function (TABLE_OF_SIGNS) {
|
|
3469
|
+
TABLE_OF_SIGNS[TABLE_OF_SIGNS["DEFAULT"] = 0] = "DEFAULT";
|
|
3470
|
+
TABLE_OF_SIGNS[TABLE_OF_SIGNS["GROWS"] = 1] = "GROWS";
|
|
3471
|
+
TABLE_OF_SIGNS[TABLE_OF_SIGNS["VARIATIONS"] = 2] = "VARIATIONS";
|
|
3472
|
+
})(TABLE_OF_SIGNS = exports.TABLE_OF_SIGNS || (exports.TABLE_OF_SIGNS = {}));
|
|
3473
|
+
/**
|
|
3474
|
+
* The study class is a "function study" class that will get:
|
|
3475
|
+
* fx : get the function
|
|
3476
|
+
* domain : string
|
|
3477
|
+
* zeroes : Object (tex, IZero)
|
|
3478
|
+
* signs : table of signs + tex output using tkz-tab
|
|
3479
|
+
* av : vertical asymptotic
|
|
3480
|
+
* ah : horizontal asymptotic
|
|
3481
|
+
* ao : obliques
|
|
3482
|
+
* deltaX : position relative
|
|
3483
|
+
* dx : derivative
|
|
3484
|
+
* grows : growing table + tex output using tkz-tab
|
|
3485
|
+
* ddx : dérivée seconde
|
|
3486
|
+
* variations : variation table + tex output using tkz-tab
|
|
3487
|
+
*/
|
|
3488
|
+
class Study {
|
|
3489
|
+
constructor(fx) {
|
|
3490
|
+
this.makeStudy = () => {
|
|
3491
|
+
this._zeroes = this.makeZeroes();
|
|
3492
|
+
this._signs = this.makeSigns();
|
|
3493
|
+
this._asymptotes = this.makeAsymptotes();
|
|
3494
|
+
this._derivative = this.makeDerivative();
|
|
3495
|
+
this._variations = this.makeVariation();
|
|
3496
|
+
};
|
|
3497
|
+
this.indexOfZero = (zeroes, zero) => {
|
|
3498
|
+
for (let i = 0; i < zeroes.length; i++) {
|
|
3499
|
+
if (zeroes[i].tex === zero.tex) {
|
|
3500
|
+
return i;
|
|
3501
|
+
}
|
|
3502
|
+
}
|
|
3503
|
+
return -1;
|
|
3504
|
+
};
|
|
3505
|
+
this.makeOneLineForSigns = (factor, zeroes, zeroSign) => {
|
|
3506
|
+
let oneLine = [], currentZero = factor.getZeroes().map(x => x.tex);
|
|
3507
|
+
// First +/- sign, before the first zero
|
|
3508
|
+
oneLine.push('');
|
|
3509
|
+
if (factor.degree().isZero()) {
|
|
3510
|
+
oneLine.push(factor.monoms[0].coefficient.sign() === 1 ? '+' : '-');
|
|
3511
|
+
}
|
|
3512
|
+
else {
|
|
3513
|
+
oneLine.push(factor.evaluate(zeroes[0].value - 1).sign() === 1 ? '+' : '-');
|
|
3514
|
+
}
|
|
3515
|
+
for (let i = 0; i < zeroes.length; i++) {
|
|
3516
|
+
// Add the zero if it's the current one
|
|
3517
|
+
oneLine.push(currentZero.includes(zeroes[i].tex) ? zeroSign : ZEROTYPE.NOTHING);
|
|
3518
|
+
// + / - sign after the current zero
|
|
3519
|
+
if (i < zeroes.length - 1) {
|
|
3520
|
+
oneLine.push(factor.evaluate((zeroes[i].value + zeroes[i + 1].value) / 2).sign() === 1 ? '+' : '-');
|
|
3501
3521
|
}
|
|
3502
|
-
if (
|
|
3522
|
+
else if (i === zeroes.length - 1) {
|
|
3523
|
+
oneLine.push(factor.evaluate(zeroes[i].value + 1).sign() === 1 ? '+' : '-');
|
|
3524
|
+
}
|
|
3525
|
+
}
|
|
3526
|
+
oneLine.push('');
|
|
3527
|
+
return oneLine;
|
|
3528
|
+
};
|
|
3529
|
+
this.makeSignsResult = (signs) => {
|
|
3530
|
+
// Initialize the result line with the first line of the signs table
|
|
3531
|
+
let resultLine = signs[0].map((x, index) => {
|
|
3532
|
+
if (index === 0 || index === signs[0].length - 1) {
|
|
3503
3533
|
return '';
|
|
3504
3534
|
}
|
|
3505
3535
|
if (index % 2 === 0) {
|
|
@@ -3507,7 +3537,8 @@ class Rational {
|
|
|
3507
3537
|
}
|
|
3508
3538
|
return '+';
|
|
3509
3539
|
});
|
|
3510
|
-
|
|
3540
|
+
// Go through each lines (except the first)
|
|
3541
|
+
for (let current of signs) {
|
|
3511
3542
|
for (let i = 0; i < current.length; i++) {
|
|
3512
3543
|
if (i % 2 === 0) {
|
|
3513
3544
|
// t, z or d
|
|
@@ -3526,93 +3557,349 @@ class Rational {
|
|
|
3526
3557
|
}
|
|
3527
3558
|
}
|
|
3528
3559
|
}
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3560
|
+
return resultLine;
|
|
3561
|
+
};
|
|
3562
|
+
this.makeGrowsResult = (fx, tos) => {
|
|
3563
|
+
// Use the last line (=> resultLine) to grab the necessary information
|
|
3564
|
+
let signsAsArray = Object.values(tos.signs), resultLine = signsAsArray[signsAsArray.length - 1], growsLine = [], extremes = {}, zeroes = tos.zeroes;
|
|
3565
|
+
// Get the extremes
|
|
3566
|
+
for (let i = 0; i < zeroes.length; i++) {
|
|
3567
|
+
// Get the corresponding item in the resultLine.
|
|
3568
|
+
let pos = 2 * i + 2;
|
|
3569
|
+
if (resultLine[pos] === 'z') {
|
|
3570
|
+
// It's a zero. Get the coordinates
|
|
3571
|
+
let x, y, zero = zeroes[i].exact, pt, xTex, yTex, pointType;
|
|
3572
|
+
if (zero instanceof fraction_1.Fraction) {
|
|
3573
|
+
let value = zero, evalY = fx.evaluate(value);
|
|
3574
|
+
x = zero.value;
|
|
3575
|
+
y = evalY.value;
|
|
3576
|
+
xTex = zero.tex;
|
|
3577
|
+
yTex = evalY.tex;
|
|
3578
|
+
}
|
|
3579
|
+
else {
|
|
3580
|
+
x = zeroes[i].value;
|
|
3581
|
+
y = fx.evaluate(zeroes[i].value).value;
|
|
3582
|
+
xTex = x.toFixed(2);
|
|
3583
|
+
yTex = y.toFixed(2);
|
|
3584
|
+
}
|
|
3585
|
+
// Determine the type of the zero.
|
|
3586
|
+
if (resultLine[pos - 1] === resultLine[pos + 1]) {
|
|
3587
|
+
pointType = FUNCTION_EXTREMA.FLAT;
|
|
3588
|
+
}
|
|
3589
|
+
else if (resultLine[pos - 1] === '+') {
|
|
3590
|
+
pointType = FUNCTION_EXTREMA.MAX;
|
|
3591
|
+
}
|
|
3592
|
+
else {
|
|
3593
|
+
pointType = FUNCTION_EXTREMA.MIN;
|
|
3594
|
+
}
|
|
3595
|
+
// Add the point to the list
|
|
3596
|
+
extremes[zeroes[i].tex] = {
|
|
3597
|
+
type: pointType,
|
|
3598
|
+
tex: { x: xTex, y: yTex },
|
|
3599
|
+
value: { x, y }
|
|
3600
|
+
};
|
|
3601
|
+
}
|
|
3602
|
+
}
|
|
3603
|
+
// Create the grows line, based on tkz-tab
|
|
3604
|
+
// \tkzTabLine{ , + , z , - , d , - , z , + , }
|
|
3605
|
+
// \tkzTabVar{ -/ , +/$3$ , -D+/ , -/$1$ , +/ }
|
|
3606
|
+
growsLine.push(resultLine[1] === '+' ? '-/' : '+/');
|
|
3607
|
+
for (let i = 1; i < resultLine.length - 1; i++) {
|
|
3608
|
+
if (resultLine[i] === "z") {
|
|
3609
|
+
let extr = extremes[zeroes[(i - 2) / 2].tex];
|
|
3610
|
+
growsLine.push(`${resultLine[i - 1]}/\\(${extr.type}(${extr.tex.x};${extr.tex.y})\\)`);
|
|
3611
|
+
}
|
|
3612
|
+
else if (resultLine[i] === 'd') {
|
|
3613
|
+
growsLine.push(`${resultLine[i - 1]}D${resultLine[i + 1] === '+' ? '-' : '+'}/`);
|
|
3614
|
+
}
|
|
3615
|
+
}
|
|
3616
|
+
growsLine.push(`${resultLine[resultLine.length - 2]}/`);
|
|
3617
|
+
return { growsLine, extremes };
|
|
3618
|
+
};
|
|
3619
|
+
this.makeVariationsResult = (fx, tos) => {
|
|
3620
|
+
// TODO: make variations result is not yet implemented.
|
|
3621
|
+
let extremes = {}, varsLine = [];
|
|
3622
|
+
return { varsLine, extremes };
|
|
3540
3623
|
};
|
|
3541
3624
|
this._makeTexFromTableOfSigns = (tos) => {
|
|
3625
|
+
let factors = tos.factors.map(x => `\\(${x.tex}\\)/1`), factorsFx = "\\(fx\\)/1.2", zeroes = tos.zeroes;
|
|
3626
|
+
// Add the last lines "label"
|
|
3627
|
+
if (tos.type === TABLE_OF_SIGNS.GROWS) {
|
|
3628
|
+
factorsFx = "\\(f'(x)\\)/1.2,\\(f(x)\\)/2";
|
|
3629
|
+
}
|
|
3630
|
+
else if (tos.type === TABLE_OF_SIGNS.VARIATIONS) {
|
|
3631
|
+
factorsFx = "\\(f''(x)\\)/1.2,\\(f(x)\\)/2";
|
|
3632
|
+
}
|
|
3633
|
+
// Create the tikzPicture header
|
|
3542
3634
|
let tex = `\\begin{tikzpicture}
|
|
3543
|
-
\\tkzTabInit[lgt=3,espcl=2,deltacl=0]{/1.2
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3635
|
+
\\tkzTabInit[lgt=3,espcl=2,deltacl=0]{/1.2,${factors.join(',')},/.1,${factorsFx} }{{\\scriptsize \\hspace{1cm} \\(-\\infty\\)},\\(${zeroes.map(x => x.tex).join('\\),\\(')}\\),{\\scriptsize \\hspace{-1cm} \\(+\\infty\\)}}`;
|
|
3636
|
+
let pos;
|
|
3637
|
+
for (pos = 0; pos < tos.factors.length; pos++) {
|
|
3638
|
+
tex += (`\n\\tkzTabLine{${tos.signs[pos].join(',')}}`);
|
|
3639
|
+
}
|
|
3640
|
+
// Add the result line
|
|
3641
|
+
tex += (`\n\\tkzTabLine{${tos.signs[pos].join(',')}}`);
|
|
3642
|
+
// Add the grows / vars line
|
|
3643
|
+
if (tos.type === TABLE_OF_SIGNS.GROWS) {
|
|
3644
|
+
tex += (`\n\\tkzTabVar{${tos.signs[pos + 1].join(',')}}`);
|
|
3645
|
+
}
|
|
3646
|
+
else if (tos.type === TABLE_OF_SIGNS.VARIATIONS) {
|
|
3647
|
+
// TODO: Check variations table for as tex
|
|
3648
|
+
tex += (`\n\\tkzTabVar{${tos.signs[pos + 1].join(',')}}`);
|
|
3649
|
+
}
|
|
3547
3650
|
tex += `\n\\end{tikzpicture}`;
|
|
3548
|
-
tos.tex = tex;
|
|
3549
3651
|
return tex;
|
|
3550
3652
|
};
|
|
3551
|
-
this.
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3653
|
+
this.fx = fx;
|
|
3654
|
+
this.makeStudy();
|
|
3655
|
+
return this;
|
|
3656
|
+
}
|
|
3657
|
+
get zeroes() {
|
|
3658
|
+
return this._zeroes;
|
|
3659
|
+
}
|
|
3660
|
+
get domain() {
|
|
3661
|
+
return this.fx.domain();
|
|
3662
|
+
}
|
|
3663
|
+
get signs() {
|
|
3664
|
+
return this._signs;
|
|
3665
|
+
}
|
|
3666
|
+
get asymptotes() {
|
|
3667
|
+
return this._asymptotes;
|
|
3668
|
+
}
|
|
3669
|
+
get derivative() {
|
|
3670
|
+
return this._derivative;
|
|
3671
|
+
}
|
|
3672
|
+
get tex() {
|
|
3673
|
+
return this._makeTexFromTableOfSigns(this._signs);
|
|
3674
|
+
}
|
|
3675
|
+
get texGrows() {
|
|
3676
|
+
return this._makeTexFromTableOfSigns(this._derivative);
|
|
3677
|
+
}
|
|
3678
|
+
get texVariations() {
|
|
3679
|
+
return this._makeTexFromTableOfSigns(this._variations);
|
|
3680
|
+
}
|
|
3681
|
+
makeZeroes() {
|
|
3682
|
+
return [];
|
|
3683
|
+
}
|
|
3684
|
+
;
|
|
3685
|
+
makeSigns() {
|
|
3686
|
+
return {
|
|
3687
|
+
type: TABLE_OF_SIGNS.DEFAULT,
|
|
3688
|
+
fx: null,
|
|
3689
|
+
factors: [],
|
|
3690
|
+
zeroes: [],
|
|
3691
|
+
signs: [],
|
|
3692
|
+
extremes: {}
|
|
3693
|
+
};
|
|
3694
|
+
}
|
|
3695
|
+
;
|
|
3696
|
+
makeAsymptotes() {
|
|
3697
|
+
return [];
|
|
3698
|
+
}
|
|
3699
|
+
makeDerivative() {
|
|
3700
|
+
return {
|
|
3701
|
+
type: TABLE_OF_SIGNS.GROWS,
|
|
3702
|
+
fx: null,
|
|
3703
|
+
factors: [],
|
|
3704
|
+
zeroes: [],
|
|
3705
|
+
signs: [],
|
|
3706
|
+
extremes: {}
|
|
3707
|
+
};
|
|
3708
|
+
}
|
|
3709
|
+
makeVariation() {
|
|
3710
|
+
return {
|
|
3711
|
+
type: TABLE_OF_SIGNS.VARIATIONS,
|
|
3712
|
+
fx: null,
|
|
3713
|
+
factors: [],
|
|
3714
|
+
zeroes: [],
|
|
3715
|
+
signs: [],
|
|
3716
|
+
extremes: {}
|
|
3717
|
+
};
|
|
3718
|
+
}
|
|
3719
|
+
}
|
|
3720
|
+
exports.Study = Study;
|
|
3721
|
+
|
|
3722
|
+
|
|
3723
|
+
/***/ }),
|
|
3724
|
+
|
|
3725
|
+
/***/ 572:
|
|
3726
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
3727
|
+
|
|
3728
|
+
|
|
3729
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
3730
|
+
exports.RationalStudy = void 0;
|
|
3731
|
+
/**
|
|
3732
|
+
* The study class is a "function study" class that will get:
|
|
3733
|
+
* fx : get the function
|
|
3734
|
+
* domain : string
|
|
3735
|
+
* zeroes : Object (tex, IZero)
|
|
3736
|
+
* signs : table of signs + tex output using tkz-tab
|
|
3737
|
+
* av : vertical asymptotic
|
|
3738
|
+
* ah : horizontal asymptotic
|
|
3739
|
+
* ao : obliques
|
|
3740
|
+
* deltaX : position relative
|
|
3741
|
+
* dx : derivative
|
|
3742
|
+
* grows : growing table + tex output using tkz-tab
|
|
3743
|
+
* ddx : dérivée seconde
|
|
3744
|
+
* variations : variation table + tex output using tkz-tab
|
|
3745
|
+
*/
|
|
3746
|
+
const study_1 = __webpack_require__(996);
|
|
3747
|
+
const rational_1 = __webpack_require__(107);
|
|
3748
|
+
const fraction_1 = __webpack_require__(506);
|
|
3749
|
+
class RationalStudy extends study_1.Study {
|
|
3750
|
+
constructor(fx) {
|
|
3751
|
+
console.log('RATIONAL STUDY');
|
|
3752
|
+
super(fx);
|
|
3753
|
+
return this;
|
|
3754
|
+
}
|
|
3755
|
+
makeZeroes() {
|
|
3756
|
+
console.log('GETTING ZEROES');
|
|
3757
|
+
return this._getZeroes(this.fx);
|
|
3758
|
+
}
|
|
3759
|
+
;
|
|
3760
|
+
makeSigns() {
|
|
3761
|
+
return this._getSigns(this.fx, this.zeroes);
|
|
3762
|
+
}
|
|
3763
|
+
;
|
|
3764
|
+
makeAsymptotes() {
|
|
3765
|
+
const reduced = this.fx.clone().reduce();
|
|
3766
|
+
// Vertical
|
|
3767
|
+
let asymptotes = [];
|
|
3768
|
+
this.zeroes.filter(x => x.type === study_1.ZEROTYPE.DEFENCE).forEach(zero => {
|
|
3769
|
+
// Check if it's a hole or an asymptote
|
|
3770
|
+
// TODO: Check for a hole ! Means calculate the limits !
|
|
3771
|
+
let Ztype = study_1.ASYMPTOTE.VERTICAL, tex = `x=${zero.tex}`;
|
|
3772
|
+
if (zero.exact instanceof fraction_1.Fraction) {
|
|
3773
|
+
if (reduced.denominator.evaluate(zero.exact).isNotZero()) {
|
|
3774
|
+
Ztype = study_1.ASYMPTOTE.HOLE;
|
|
3775
|
+
tex = `(${zero.tex};${reduced.evaluate(zero.exact).tex})`;
|
|
3776
|
+
}
|
|
3557
3777
|
}
|
|
3558
3778
|
else {
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
// Add the zero if it's the current one
|
|
3563
|
-
oneLine.push(currentZero.includes(zeroes[i].tex) ? zeroSign : 't');
|
|
3564
|
-
// + / - sign after the current zero
|
|
3565
|
-
if (i < zeroes.length - 1) {
|
|
3566
|
-
oneLine.push(factor.evaluate((zeroes[i].value + zeroes[i + 1].value) / 2).sign() === 1 ? '+' : '-');
|
|
3567
|
-
}
|
|
3568
|
-
else if (i === zeroes.length - 1) {
|
|
3569
|
-
oneLine.push(factor.evaluate(zeroes[i].value + 1).sign() === 1 ? '+' : '-');
|
|
3779
|
+
if (reduced.denominator.evaluate(zero.value).isNotZero()) {
|
|
3780
|
+
Ztype = study_1.ASYMPTOTE.HOLE;
|
|
3781
|
+
tex = `(${zero.tex};${reduced.evaluate(zero.value).tex})`;
|
|
3570
3782
|
}
|
|
3571
3783
|
}
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
};
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3784
|
+
asymptotes.push({
|
|
3785
|
+
type: Ztype,
|
|
3786
|
+
tex: tex,
|
|
3787
|
+
zero: zero,
|
|
3788
|
+
limits: `\\lim_{x\\to${zero.tex} }\\ f(x) = \\pm\\infty`,
|
|
3789
|
+
deltaX: null
|
|
3790
|
+
});
|
|
3791
|
+
});
|
|
3792
|
+
// Sloped asymptote
|
|
3793
|
+
let NDegree = this.fx.numerator.degree(), DDegree = this.fx.denominator.degree();
|
|
3794
|
+
if (NDegree.isEqual(DDegree)) {
|
|
3795
|
+
let H = this.fx.numerator.monomByDegree().coefficient.clone().divide(this.fx.denominator.monomByDegree().coefficient).tex;
|
|
3796
|
+
let { reminder } = reduced.euclidian();
|
|
3797
|
+
asymptotes.push({
|
|
3798
|
+
type: study_1.ASYMPTOTE.HORIZONTAL,
|
|
3799
|
+
tex: `y=${H}`,
|
|
3800
|
+
zero: null,
|
|
3801
|
+
limits: `\\lim_{x\\to\\infty}\\ f(x) = ${H}`,
|
|
3802
|
+
deltaX: new rational_1.Rational(reminder, reduced.denominator)
|
|
3803
|
+
});
|
|
3591
3804
|
}
|
|
3592
|
-
else if (
|
|
3593
|
-
|
|
3805
|
+
else if (DDegree.greater(NDegree)) {
|
|
3806
|
+
asymptotes.push({
|
|
3807
|
+
type: study_1.ASYMPTOTE.HORIZONTAL,
|
|
3808
|
+
tex: `y=0`,
|
|
3809
|
+
zero: null,
|
|
3810
|
+
limits: `\\lim_{x\\to\\infty}\\ f(x) = ${0}`,
|
|
3811
|
+
deltaX: null
|
|
3812
|
+
});
|
|
3594
3813
|
}
|
|
3595
|
-
else {
|
|
3596
|
-
|
|
3814
|
+
else if (NDegree.value - 1 === DDegree.value) {
|
|
3815
|
+
// Calculate the slope
|
|
3816
|
+
let { quotient, reminder } = reduced.euclidian();
|
|
3817
|
+
asymptotes.push({
|
|
3818
|
+
type: study_1.ASYMPTOTE.SLOPE,
|
|
3819
|
+
tex: `y=${quotient.tex}`,
|
|
3820
|
+
zero: null,
|
|
3821
|
+
limits: ``,
|
|
3822
|
+
deltaX: new rational_1.Rational(reminder, reduced.denominator)
|
|
3823
|
+
});
|
|
3597
3824
|
}
|
|
3825
|
+
return asymptotes;
|
|
3598
3826
|
}
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3827
|
+
;
|
|
3828
|
+
makeDerivative() {
|
|
3829
|
+
let dx = this.fx.clone().derivative(), tos = this._getSigns(dx, this._getZeroes(dx), study_1.TABLE_OF_SIGNS.GROWS);
|
|
3830
|
+
console.log(tos.factors.length, tos.signs.length);
|
|
3831
|
+
let result = this.makeGrowsResult(this.fx, tos);
|
|
3832
|
+
tos.signs.push(result.growsLine);
|
|
3833
|
+
tos.extremes = result.extremes;
|
|
3834
|
+
console.log(tos.signs.length);
|
|
3835
|
+
return tos;
|
|
3607
3836
|
}
|
|
3608
|
-
|
|
3609
|
-
|
|
3837
|
+
;
|
|
3838
|
+
makeVariation() {
|
|
3839
|
+
// Get the zeroes, make signs.
|
|
3840
|
+
let dx = this.derivative.fx.clone().derivative(), tos = this._getSigns(dx, this._getZeroes(dx), study_1.TABLE_OF_SIGNS.VARIATIONS);
|
|
3841
|
+
let result = this.makeVariationsResult(this.fx, tos);
|
|
3842
|
+
tos.signs.push(result.varsLine);
|
|
3843
|
+
tos.extremes = result.extremes;
|
|
3844
|
+
return tos;
|
|
3610
3845
|
}
|
|
3611
|
-
|
|
3612
|
-
|
|
3846
|
+
;
|
|
3847
|
+
_getZeroes(fx) {
|
|
3848
|
+
// All zeroes.
|
|
3849
|
+
let zeroes = [];
|
|
3850
|
+
fx.numerator.getZeroes().filter(x => !isNaN(x.value)).forEach(z => {
|
|
3851
|
+
// add the item
|
|
3852
|
+
zeroes.push({
|
|
3853
|
+
tex: z.tex,
|
|
3854
|
+
value: z.value,
|
|
3855
|
+
exact: z.exact,
|
|
3856
|
+
extrema: study_1.FUNCTION_EXTREMA.NOTHING,
|
|
3857
|
+
type: study_1.ZEROTYPE.ZERO
|
|
3858
|
+
});
|
|
3859
|
+
});
|
|
3860
|
+
fx.denominator.getZeroes().filter(x => !isNaN(x.value)).forEach(z => {
|
|
3861
|
+
let idx = this.indexOfZero(zeroes, z);
|
|
3862
|
+
if (idx !== -1) {
|
|
3863
|
+
zeroes[idx].type = study_1.ZEROTYPE.DEFENCE;
|
|
3864
|
+
}
|
|
3865
|
+
else {
|
|
3866
|
+
// Add the item
|
|
3867
|
+
zeroes.push({
|
|
3868
|
+
tex: z.tex,
|
|
3869
|
+
value: z.value,
|
|
3870
|
+
exact: z.exact,
|
|
3871
|
+
extrema: study_1.FUNCTION_EXTREMA.NOTHING,
|
|
3872
|
+
type: study_1.ZEROTYPE.DEFENCE
|
|
3873
|
+
});
|
|
3874
|
+
}
|
|
3875
|
+
});
|
|
3876
|
+
// sort all zeroes
|
|
3877
|
+
zeroes.sort((a, b) => a.value - b.value);
|
|
3878
|
+
return zeroes;
|
|
3879
|
+
}
|
|
3880
|
+
_getSigns(fx, zeroes, typeOfTable) {
|
|
3881
|
+
// Factorize the rational
|
|
3882
|
+
let signs = [], factors = [];
|
|
3883
|
+
fx.numerator.factors.forEach(factor => {
|
|
3884
|
+
signs.push(this.makeOneLineForSigns(factor, zeroes, study_1.ZEROTYPE.ZERO));
|
|
3885
|
+
factors.push(factor.clone());
|
|
3886
|
+
});
|
|
3887
|
+
fx.denominator.factors.forEach(factor => {
|
|
3888
|
+
signs.push(this.makeOneLineForSigns(factor, zeroes, study_1.ZEROTYPE.DEFENCE));
|
|
3889
|
+
factors.push(factor.clone());
|
|
3890
|
+
});
|
|
3891
|
+
signs.push(this.makeSignsResult(signs));
|
|
3892
|
+
return {
|
|
3893
|
+
type: typeOfTable,
|
|
3894
|
+
fx,
|
|
3895
|
+
factors,
|
|
3896
|
+
zeroes,
|
|
3897
|
+
signs,
|
|
3898
|
+
extremes: {}
|
|
3899
|
+
};
|
|
3613
3900
|
}
|
|
3614
3901
|
}
|
|
3615
|
-
exports.
|
|
3902
|
+
exports.RationalStudy = RationalStudy;
|
|
3616
3903
|
|
|
3617
3904
|
|
|
3618
3905
|
/***/ }),
|