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.
Files changed (58) hide show
  1. package/.eslintrc.js +23 -23
  2. package/.idea/misc.xml +5 -0
  3. package/.idea/php.xml +1 -1
  4. package/.idea/shelf/Uncommitted_changes_before_Update_at_17_04_2022_12_40_[Changes]/shelved.patch +21 -0
  5. package/.idea/shelf/Uncommitted_changes_before_Update_at_17_04_2022_12_40__Changes_.xml +4 -0
  6. package/dist/pi.js +638 -351
  7. package/dist/pi.js.map +1 -1
  8. package/dist/pi.min.js +1 -1
  9. package/dist/pi.min.js.map +1 -1
  10. package/docs/assets/highlight.css +78 -78
  11. package/docs/assets/main.js +52 -52
  12. package/docs/assets/style.css +1413 -1413
  13. package/docs/classes/Logicalset.Logicalset-1.html +4 -4
  14. package/docs/classes/Polynom.Rational.html +3 -3
  15. package/docs/classes/algebra_equation.Equation.html +25 -25
  16. package/docs/classes/algebra_monom.Monom.html +113 -113
  17. package/docs/classes/algebra_polynom.Polynom.html +29 -29
  18. package/docs/classes/coefficients_fraction.Fraction.html +18 -18
  19. package/docs/classes/coefficients_nthroot.NthRoot.html +2 -2
  20. package/docs/classes/geometry_circle.Circle.html +2 -2
  21. package/docs/classes/geometry_line.Line.html +2 -2
  22. package/docs/classes/geometry_triangle.Triangle.html +16 -16
  23. package/docs/classes/numeric.Numeric.html +13 -13
  24. package/docs/classes/shutingyard.Shutingyard.html +17 -17
  25. package/docs/index.html +10 -10
  26. package/docs/interfaces/algebra_equation.ISolution.html +2 -2
  27. package/docs/modules/Logicalset.html +2 -2
  28. package/docs/modules/Polynom.html +2 -2
  29. package/docs/modules/Vector.html +2 -2
  30. package/esm/maths/algebra/linearSystem.js +0 -1
  31. package/esm/maths/algebra/linearSystem.js.map +1 -1
  32. package/esm/maths/algebra/monom.d.ts +1 -0
  33. package/esm/maths/algebra/monom.js +18 -0
  34. package/esm/maths/algebra/monom.js.map +1 -1
  35. package/esm/maths/algebra/polynom.d.ts +30 -11
  36. package/esm/maths/algebra/polynom.js +144 -258
  37. package/esm/maths/algebra/polynom.js.map +1 -1
  38. package/esm/maths/algebra/rational.d.ts +12 -15
  39. package/esm/maths/algebra/rational.js +14 -103
  40. package/esm/maths/algebra/rational.js.map +1 -1
  41. package/esm/maths/algebra/study/rationalStudy.d.ts +33 -0
  42. package/esm/maths/algebra/study/rationalStudy.js +174 -0
  43. package/esm/maths/algebra/study/rationalStudy.js.map +1 -0
  44. package/esm/maths/algebra/study.d.ts +133 -0
  45. package/esm/maths/algebra/study.js +275 -0
  46. package/esm/maths/algebra/study.js.map +1 -0
  47. package/package.json +1 -1
  48. package/src/maths/algebra/linearSystem.ts +0 -1
  49. package/src/maths/algebra/monom.ts +19 -0
  50. package/src/maths/algebra/polynom.ts +185 -278
  51. package/src/maths/algebra/rational.ts +24 -132
  52. package/src/maths/algebra/study/rationalStudy.ts +208 -0
  53. package/src/maths/algebra/study.ts +384 -0
  54. package/tests/algebra/monom.test.ts +2 -5
  55. package/tests/algebra/polynom.test.ts +2 -3
  56. package/tests/algebra/rationnal.test.ts +0 -43
  57. package/tests/algebra/study.test.ts +18 -0
  58. 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
- let factors = [];
2708
- // Extract the common monom
2709
- let P = this.clone().reorder(), M = P.commonMonom(), tempPolynom;
2710
- // It has a common monom.
2711
- if (!M.isOne()) {
2712
- tempPolynom = new Polynom(M);
2713
- factors = [tempPolynom.clone()];
2714
- P = P.euclidian(tempPolynom).quotient;
2715
- }
2716
- let securityLoop = P.degree().clone().multiply(2).value;
2717
- let result;
2718
- // securityLoop = 0
2719
- while (securityLoop >= 0) {
2720
- securityLoop--;
2721
- if (P.monoms.length < 2) {
2722
- if (!P.isOne()) {
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
- else if (P.degree(letter).isOne()) {
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
- P.one();
2731
- break;
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
- // Get the first and last monom and build all their dividers.
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
- if (!P.isOne()) {
2751
- factors.push(P.clone());
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
- let equ = new equation_1.Equation(this.clone(), 0);
2759
- equ.solve();
2760
- return equ.solutions;
2761
- //
2762
- // const Z: Fraction[] = [];
2763
- //
2764
- // // ISolution: {tex: string, value: number, exact: boolean|Fraction|...}
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
- m2.forEach(m2d => {
2966
- if (m1d.degree(letter).isNotEqual(m2d.degree(letter))) {
2967
- allDividers.push(new Polynom(m1d, m2d));
2968
- allDividers.push(new Polynom(m1d, m2d.clone().opposed()));
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._factors;
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 = this._numerator.clone();
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.makeTableOfSigns = () => {
3484
- // Factorize the numerator and the denominator
3485
- this._numerator.factorize();
3486
- this._denominator.factorize();
3487
- let zeroes = equation_1.Equation.makeSolutionsUnique([...this._numerator.getZeroes(), ...this._denominator.getZeroes()], true).filter(x => !isNaN(x.value)), NFactors = this._numerator.factors, DFactors = this._denominator.factors;
3488
- let tableOfSigns = [], result = [];
3489
- NFactors.forEach(factor => {
3490
- tableOfSigns.push(this._makeOneLineOfTableOfSigns(factor, zeroes, 'z'));
3491
- });
3492
- DFactors.forEach(factor => {
3493
- tableOfSigns.push(this._makeOneLineOfTableOfSigns(factor, zeroes, 'd'));
3494
- });
3495
- // Empty line
3496
- tableOfSigns.push([]);
3497
- // Add the final row as cumulative
3498
- let resultLine = tableOfSigns[0].map((x, index) => {
3499
- if (index === 0) {
3500
- return '';
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 (index === tableOfSigns[0].length - 1) {
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
- for (let current of tableOfSigns) {
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
- // Add the variation line.
3530
- // TODO: add the variation line.
3531
- tableOfSigns.push(resultLine);
3532
- let tos = {
3533
- factors: [...NFactors, ...DFactors],
3534
- zeroes: zeroes,
3535
- signs: tableOfSigns,
3536
- tex: ''
3537
- };
3538
- this._makeTexFromTableOfSigns(tos);
3539
- return tos;
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,\\(${tos.factors.map(x => x.tex).join('\\)/1,\\(')}\\)/1,/.1,\\(f(x)\\)/1.2}{{\\scriptsize \\hspace{1cm} \\(-\\infty\\)},\\(${tos.zeroes.map(x => x.tex).join('\\),\\(')}\\),{\\scriptsize \\hspace{-1cm} \\(+\\infty\\)}}`;
3544
- tos.signs.forEach(list => {
3545
- tex += (`\n\\tkzTabLine{${list.join(',')}}`);
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._makeOneLineOfTableOfSigns = (factor, zeroes, zeroSign) => {
3552
- let oneLine = [], currentZero = factor.getZeroes().map(x => x.tex);
3553
- // First +/- sign, before the first zero
3554
- oneLine.push('');
3555
- if (factor.degree().isZero()) {
3556
- oneLine.push(factor.monoms[0].coefficient.sign() === 1 ? '+' : '-');
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
- oneLine.push(factor.evaluate(zeroes[0].value - 1).sign() === 1 ? '+' : '-');
3560
- }
3561
- for (let i = 0; i < zeroes.length; i++) {
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
- oneLine.push('');
3573
- return oneLine;
3574
- };
3575
- this.evaluate = (values) => {
3576
- const r = new fraction_1.Fraction().zero();
3577
- let N = this._numerator.evaluate(values), D = this._numerator.evaluate(values);
3578
- return N.divide(D);
3579
- };
3580
- if (numerator instanceof polynom_1.Polynom) {
3581
- this._numerator = numerator.clone();
3582
- }
3583
- else if (typeof numerator === 'string') {
3584
- this._numerator = new polynom_1.Polynom(numerator);
3585
- }
3586
- else {
3587
- this._numerator = new polynom_1.Polynom();
3588
- }
3589
- if (denominator instanceof polynom_1.Polynom) {
3590
- this._denominator = denominator.clone();
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 (typeof denominator === 'string') {
3593
- this._denominator = new polynom_1.Polynom(denominator);
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
- this._denominator = new polynom_1.Polynom();
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
- get numerator() {
3600
- return this._numerator;
3601
- }
3602
- get denominator() {
3603
- return this._denominator;
3604
- }
3605
- get tex() {
3606
- return `\\frac{ ${this._numerator.tex} }{ ${this._denominator.tex} }`;
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
- get texFactors() {
3609
- return `\\frac{ ${this._numerator.texFactors} }{ ${this._denominator.texFactors} }`;
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
- get plotFunction() {
3612
- return `(${this._numerator.plotFunction})/(${this._denominator.plotFunction})`;
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.Rational = Rational;
3902
+ exports.RationalStudy = RationalStudy;
3616
3903
 
3617
3904
 
3618
3905
  /***/ }),