pimath 0.0.38 → 0.0.41

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 (38) hide show
  1. package/dist/pi.js +361 -112
  2. package/dist/pi.js.map +1 -1
  3. package/dist/pi.min.js +1 -1
  4. package/dist/pi.min.js.map +1 -1
  5. package/docs/assets/search.js +1 -1
  6. package/esm/index.d.ts +2 -2
  7. package/esm/index.js +2 -2
  8. package/esm/maths/algebra/equation.d.ts +6 -2
  9. package/esm/maths/algebra/equation.js +49 -9
  10. package/esm/maths/algebra/equation.js.map +1 -1
  11. package/esm/maths/algebra/polynom.d.ts +4 -1
  12. package/esm/maths/algebra/polynom.js +120 -62
  13. package/esm/maths/algebra/polynom.js.map +1 -1
  14. package/esm/maths/algebra/rational.d.ts +16 -6
  15. package/esm/maths/algebra/rational.js +140 -29
  16. package/esm/maths/algebra/rational.js.map +1 -1
  17. package/esm/maths/coefficients/fraction.d.ts +3 -1
  18. package/esm/maths/coefficients/fraction.js +37 -5
  19. package/esm/maths/coefficients/fraction.js.map +1 -1
  20. package/esm/maths/coefficients/{nthroot.d.ts → nthRoot.d.ts} +5 -5
  21. package/esm/maths/coefficients/{nthroot.js → nthRoot.js} +5 -5
  22. package/esm/maths/coefficients/{nthroot.js.map → nthRoot.js.map} +1 -1
  23. package/esm/maths/geometry/line.js +8 -0
  24. package/esm/maths/geometry/line.js.map +1 -1
  25. package/package.json +1 -1
  26. package/src/index.ts +2 -2
  27. package/src/maths/algebra/equation.ts +58 -12
  28. package/src/maths/algebra/polynom.ts +128 -68
  29. package/src/maths/algebra/rational.ts +242 -98
  30. package/src/maths/coefficients/fraction.ts +44 -6
  31. package/src/maths/coefficients/{nthroot.ts → nthRoot.ts} +5 -5
  32. package/src/maths/geometry/line.ts +6 -0
  33. package/src/maths/geometry/point.ts +2 -2
  34. package/tests/algebra/equation.test.ts +38 -0
  35. package/tests/algebra/monom.test.ts +1 -4
  36. package/tests/algebra/rationnal.test.ts +68 -0
  37. package/tests/coefficients/fraction.test.ts +43 -1
  38. package/tests/geometry/circle.test.ts +4 -2
package/dist/pi.js CHANGED
@@ -14,7 +14,7 @@ const numexp_1 = __webpack_require__(735);
14
14
  const shutingyard_1 = __webpack_require__(505);
15
15
  const random_1 = __webpack_require__(330);
16
16
  const fraction_1 = __webpack_require__(506);
17
- const nthroot_1 = __webpack_require__(923);
17
+ const nthRoot_1 = __webpack_require__(872);
18
18
  const monom_1 = __webpack_require__(937);
19
19
  const polynom_1 = __webpack_require__(38);
20
20
  const equation_1 = __webpack_require__(760);
@@ -33,7 +33,7 @@ exports.l = {
33
33
  Numeric: numeric_1.Numeric,
34
34
  NumExp: numexp_1.NumExp,
35
35
  Fraction: fraction_1.Fraction,
36
- Root: nthroot_1.Nthroot,
36
+ Root: nthRoot_1.NthRoot,
37
37
  Monom: monom_1.Monom,
38
38
  Polynom: polynom_1.Polynom,
39
39
  Equation: equation_1.Equation,
@@ -61,11 +61,16 @@ window.Pi = exports.l;
61
61
 
62
62
 
63
63
  Object.defineProperty(exports, "__esModule", ({ value: true }));
64
- exports.Equation = void 0;
64
+ exports.Equation = exports.PARTICULAR_SOLUTION = void 0;
65
65
  const polynom_1 = __webpack_require__(38);
66
66
  const numeric_1 = __webpack_require__(956);
67
67
  const fraction_1 = __webpack_require__(506);
68
- const nthroot_1 = __webpack_require__(923);
68
+ const nthRoot_1 = __webpack_require__(872);
69
+ var PARTICULAR_SOLUTION;
70
+ (function (PARTICULAR_SOLUTION) {
71
+ PARTICULAR_SOLUTION["real"] = "\\mathbb{R}";
72
+ PARTICULAR_SOLUTION["varnothing"] = "\\varnothing";
73
+ })(PARTICULAR_SOLUTION = exports.PARTICULAR_SOLUTION || (exports.PARTICULAR_SOLUTION = {}));
69
74
  class Equation {
70
75
  /**
71
76
  * Create an Equation using two polynoms.
@@ -74,8 +79,8 @@ class Equation {
74
79
  */
75
80
  constructor(...equations) {
76
81
  // Undetermined texSolutions.
77
- this._varnothing = '\\varnothing';
78
- this._real = '\\mathbb{R}';
82
+ this._varnothing = PARTICULAR_SOLUTION.varnothing;
83
+ this._real = PARTICULAR_SOLUTION.real;
79
84
  // ------------------------------------------
80
85
  // Creation / parsing functions
81
86
  // -----------------------------------------------
@@ -270,6 +275,8 @@ class Equation {
270
275
  default:
271
276
  this._solveDegree3plus();
272
277
  }
278
+ // cleanup the solutions.
279
+ this._solutions = Equation.makeSolutionsUnique(this._solutions);
273
280
  return this;
274
281
  };
275
282
  this.test = (values) => {
@@ -400,7 +407,7 @@ class Equation {
400
407
  }
401
408
  else {
402
409
  this._solutions = [{
403
- tex: v.display,
410
+ tex: v.tex,
404
411
  value: v.value,
405
412
  exact: v
406
413
  }];
@@ -460,7 +467,7 @@ class Equation {
460
467
  ];
461
468
  }
462
469
  else {
463
- nthDelta = new nthroot_1.Nthroot(delta).reduce();
470
+ nthDelta = new nthRoot_1.NthRoot(delta).reduce();
464
471
  if (nthDelta.hasRadical()) {
465
472
  // -b +- coeff\sqrt{radical}
466
473
  // -------------------------
@@ -634,9 +641,27 @@ class Equation {
634
641
  }
635
642
  return this._solutions;
636
643
  };
637
- this._solveDegree3plus = () => {
638
- // TODO: try to resolve equations with a degree superior than 2.
639
- this._solutions = [{ tex: 'solve x - not yet handled', value: NaN, exact: false }]; // ESLint remove system :(
644
+ this._solveDegree3plus = (letter) => {
645
+ // Push everything to the left
646
+ // factorize
647
+ // solve each factors.
648
+ let equ = this.clone().moveLeft();
649
+ equ.left.factorize();
650
+ this._solutions = [];
651
+ equ.left.factors.forEach(factor => {
652
+ if (factor.degree(letter).leq(2)) {
653
+ let factorAsEquation = new Equation(factor, 0);
654
+ factorAsEquation.solve();
655
+ factorAsEquation.solutions.forEach(solution => {
656
+ this._solutions.push(solution);
657
+ });
658
+ }
659
+ else {
660
+ console.log(factor.tex, ': cannot actually get the solution of this equation');
661
+ }
662
+ });
663
+ // TODO: check equation resolution for more than degree 2
664
+ // this._solutions = [{tex: 'solve x - not yet handled', value: NaN, exact: false}]; // ESLint remove system :(
640
665
  return this._solutions;
641
666
  };
642
667
  // Default equation
@@ -751,6 +776,21 @@ class Equation {
751
776
  set randomizeDefaults(value) {
752
777
  this._randomizeDefaults = value;
753
778
  }
779
+ static makeSolutionsUnique(solutions, sorted) {
780
+ let solutionAsTex = [], uniqueSolutions = solutions.filter(sol => {
781
+ if (!solutionAsTex.includes(sol.tex)) {
782
+ solutionAsTex.push(sol.tex);
783
+ return true;
784
+ }
785
+ else {
786
+ return false;
787
+ }
788
+ });
789
+ if (sorted === true) {
790
+ uniqueSolutions.sort((a, b) => a.value - b.value);
791
+ }
792
+ return uniqueSolutions;
793
+ }
754
794
  }
755
795
  exports.Equation = Equation;
756
796
 
@@ -2043,6 +2083,7 @@ const monom_1 = __webpack_require__(937);
2043
2083
  const shutingyard_1 = __webpack_require__(505);
2044
2084
  const numeric_1 = __webpack_require__(956);
2045
2085
  const fraction_1 = __webpack_require__(506);
2086
+ const equation_1 = __webpack_require__(760);
2046
2087
  /**
2047
2088
  * Polynom class can handle polynoms, reorder, resolve, ...
2048
2089
  * ```
@@ -2545,6 +2586,7 @@ class Polynom {
2545
2586
  P = P.euclidian(tempPolynom).quotient;
2546
2587
  }
2547
2588
  let securityLoop = P.degree().clone().multiply(2).value;
2589
+ let result;
2548
2590
  // securityLoop = 0
2549
2591
  while (securityLoop >= 0) {
2550
2592
  securityLoop--;
@@ -2560,7 +2602,7 @@ class Polynom {
2560
2602
  for (let m1d of m1) {
2561
2603
  for (let m2d of m2) {
2562
2604
  // if(m1d.degree()===m2d.degree()){continue}
2563
- let dividerPolynom = new Polynom(), result;
2605
+ let dividerPolynom = new Polynom();
2564
2606
  dividerPolynom.monoms = [m1d.clone(), m2d.clone()];
2565
2607
  result = P.euclidian(dividerPolynom);
2566
2608
  if (result.reminder.isZero()) {
@@ -2578,72 +2620,103 @@ class Polynom {
2578
2620
  }
2579
2621
  }
2580
2622
  }
2623
+ if (!P.isOne()) {
2624
+ factors.push(P.clone());
2625
+ }
2581
2626
  this.factors = factors;
2582
2627
  return factors;
2583
2628
  };
2584
2629
  // TODO: get zeroes for more than first degree and for more than natural degrees
2585
2630
  this.getZeroes = () => {
2586
- const Z = [];
2587
- switch (this.degree().value) {
2588
- case 0:
2589
- if (this._monoms[0].coefficient.value === 0) {
2590
- return [true];
2591
- }
2592
- else {
2593
- return [false];
2594
- }
2595
- case 1:
2596
- // There is only one monoms,
2597
- if (this._monoms.length === 1) {
2598
- return [new fraction_1.Fraction().zero()];
2599
- }
2600
- else {
2601
- const P = this.clone().reduce().reorder();
2602
- return [P.monoms[1].coefficient.opposed().divide(P.monoms[0].coefficient)];
2603
- }
2604
- // TODO: Determine the zeros of an equation of second degree.
2605
- //case 2:
2606
- default:
2607
- // Make sure the polynom is factorized.
2608
- if (this._factors.length === 0) {
2609
- this.factorize();
2610
- }
2611
- let zeroes = [], zeroesAsTex = [];
2612
- for (let P of this._factors) {
2613
- if (P.degree().greater(2)) {
2614
- // TODO: Handle other polynom.
2615
- }
2616
- else if (P.degree().value === 2) {
2617
- let A = P.monomByDegree(2).coefficient, B = P.monomByDegree(1).coefficient, C = P.monomByDegree(0).coefficient, D = B.clone().pow(2).subtract(A.clone().multiply(C).multiply(4));
2618
- if (D.value > 0) {
2619
- /*console.log('Two zeroes for ', P.tex); */
2620
- let x1 = (-(B.value) + Math.sqrt(D.value)) / (2 * A.value), x2 = (-(B.value) - Math.sqrt(D.value)) / (2 * A.value);
2621
- zeroes.push(new fraction_1.Fraction(x1.toFixed(3)).reduce());
2622
- zeroes.push(new fraction_1.Fraction(x2.toFixed(3)).reduce());
2623
- }
2624
- else if (D.value === 0) {
2625
- /*console.log('One zero for ', P.tex); */
2626
- }
2627
- else {
2628
- console.log('No zero for ', P.tex);
2629
- }
2630
- }
2631
- else {
2632
- for (let z of P.getZeroes()) {
2633
- // Check if the zero is already in the list.
2634
- if (z === false || z === true) {
2635
- continue;
2636
- }
2637
- if (zeroesAsTex.indexOf(z.frac) === -1) {
2638
- zeroes.push(z);
2639
- zeroesAsTex.push(z.frac);
2640
- }
2641
- }
2642
- }
2643
- }
2644
- return zeroes;
2645
- }
2646
- return Z;
2631
+ let equ = new equation_1.Equation(this.clone(), 0);
2632
+ equ.solve();
2633
+ return equ.solutions;
2634
+ //
2635
+ // const Z: Fraction[] = [];
2636
+ //
2637
+ // // ISolution: {tex: string, value: number, exact: boolean|Fraction|...}
2638
+ //
2639
+ // switch (this.degree().value) {
2640
+ // case 0:
2641
+ // if (this._monoms[0].coefficient.value === 0) {
2642
+ // return [{
2643
+ // tex: '\\mathbb{R}',
2644
+ // value: NaN,
2645
+ // exact: false
2646
+ // }];
2647
+ // } else {
2648
+ // return [{
2649
+ // tex: '\\varnothing',
2650
+ // value: NaN,
2651
+ // exact: false
2652
+ // }];
2653
+ // }
2654
+ // case 1:
2655
+ // // There is only one monoms,
2656
+ // if (this._monoms.length === 1) {
2657
+ // return [{
2658
+ // tex: '0',
2659
+ // value: 0,
2660
+ // exact: new Fraction().zero()
2661
+ // }];
2662
+ // } else {
2663
+ // const P = this.clone().reduce().reorder();
2664
+ // const coeff = P.monoms[1].coefficient.opposed().divide(P.monoms[0].coefficient)
2665
+ // return [{
2666
+ // tex: coeff.tex,
2667
+ // value: coeff.value,
2668
+ // exact: coeff
2669
+ // }];
2670
+ // }
2671
+ // // TODO: Determine the zeros of an equation of second degree.
2672
+ // //case 2:
2673
+ // default:
2674
+ // // Make sure the polynom is factorized.
2675
+ // if (this._factors.length === 0) {
2676
+ // this.factorize()
2677
+ // }
2678
+ //
2679
+ // let zeroes:Fraction[] = [], zeroesAsTex = [];
2680
+ // for (let P of this._factors) {
2681
+ // if (P.degree().greater(2)) {
2682
+ // // TODO: get zeroes of polynom with a degree greater than 2.
2683
+ //
2684
+ // } else if (P.degree().value === 2) {
2685
+ // let A = P.monomByDegree(2).coefficient,
2686
+ // B = P.monomByDegree(1).coefficient,
2687
+ // C = P.monomByDegree(0).coefficient,
2688
+ // D = B.clone().pow(2).subtract(A.clone().multiply(C).multiply(4));
2689
+ //
2690
+ // if (D.value > 0) {
2691
+ // /*console.log('Two zeroes for ', P.tex); */
2692
+ // let x1 = (-(B.value) + Math.sqrt(D.value)) / (2 * A.value),
2693
+ // x2 = (-(B.value) - Math.sqrt(D.value)) / (2 * A.value);
2694
+ //
2695
+ // zeroes.push(new Fraction(x1.toFixed(3)).reduce());
2696
+ // zeroes.push(new Fraction(x2.toFixed(3)).reduce());
2697
+ // } else if (D.value === 0) {
2698
+ // /*console.log('One zero for ', P.tex); */
2699
+ // } else {
2700
+ // console.log('No zero for ', P.tex);
2701
+ // }
2702
+ // } else {
2703
+ // for (let z of P.getZeroes()) {
2704
+ // // Check if the zero is already in the list.
2705
+ // // if (z === false || z === true) {
2706
+ // // continue;
2707
+ // // }
2708
+ // if (zeroesAsTex.indexOf(z.frac) === -1) {
2709
+ // zeroes.push(z);
2710
+ // zeroesAsTex.push(z.frac);
2711
+ // }
2712
+ // }
2713
+ // }
2714
+ // }
2715
+ //
2716
+ //
2717
+ // return zeroes;
2718
+ // }
2719
+ // return Z;
2647
2720
  };
2648
2721
  // TODO: analyse the next functions to determine if they are useful or not...
2649
2722
  this.monomByDegree = (degree, letter) => {
@@ -2736,6 +2809,28 @@ class Polynom {
2736
2809
  }
2737
2810
  return M;
2738
2811
  };
2812
+ this.limitToInfinity = (letter) => {
2813
+ const M = this.monomByDegree(undefined, letter), sign = M.coefficient.sign(), degree = M.degree(letter);
2814
+ if (degree.isStrictlyPositive()) {
2815
+ return sign === 1 ? (new fraction_1.Fraction()).infinite() : (new fraction_1.Fraction()).infinite().opposed();
2816
+ }
2817
+ else if (degree.isZero()) {
2818
+ return M.coefficient;
2819
+ }
2820
+ // Any other cases
2821
+ return (new fraction_1.Fraction()).zero();
2822
+ };
2823
+ this.limitToNegativeInfinity = (letter) => {
2824
+ const M = this.monomByDegree(undefined, letter), sign = M.coefficient.sign(), degree = M.degree(letter);
2825
+ if (degree.isStrictlyPositive()) {
2826
+ return sign === -1 ? (new fraction_1.Fraction()).infinite() : (new fraction_1.Fraction()).infinite().opposed();
2827
+ }
2828
+ else if (degree.isZero()) {
2829
+ return M.coefficient;
2830
+ }
2831
+ // Any other cases
2832
+ return (new fraction_1.Fraction()).zero();
2833
+ };
2739
2834
  this.genDisplay = (output, forceSign, wrapParentheses) => {
2740
2835
  let P = '';
2741
2836
  for (const k of this._monoms) {
@@ -2993,6 +3088,9 @@ class Polynom {
2993
3088
  }
2994
3089
  get texFactors() {
2995
3090
  this.factorize();
3091
+ if (this.factors.length === 0) {
3092
+ return this.tex;
3093
+ }
2996
3094
  let tex = '';
2997
3095
  for (let f of this.factors) {
2998
3096
  if (f.monoms.length > 1) {
@@ -3188,6 +3286,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
3188
3286
  exports.Rational = void 0;
3189
3287
  const polynom_1 = __webpack_require__(38);
3190
3288
  const fraction_1 = __webpack_require__(506);
3289
+ const equation_1 = __webpack_require__(760);
3191
3290
  /**
3192
3291
  * Rational class can handle rational polynoms
3193
3292
  */
@@ -3205,18 +3304,15 @@ class Rational {
3205
3304
  };
3206
3305
  this.domain = () => {
3207
3306
  let zeroes = this._denominator.getZeroes();
3208
- if (zeroes.length === 0 || zeroes[0] === false) {
3209
- return '\\mathbb{R}';
3307
+ if (zeroes.length === 0 || zeroes[0].tex === equation_1.PARTICULAR_SOLUTION.real) {
3308
+ return equation_1.PARTICULAR_SOLUTION.real;
3210
3309
  }
3211
- else if (zeroes[0] === true) {
3212
- return '\\varnothing';
3310
+ else if (zeroes[0].tex === equation_1.PARTICULAR_SOLUTION.varnothing) {
3311
+ return equation_1.PARTICULAR_SOLUTION.varnothing;
3213
3312
  }
3214
3313
  else {
3215
3314
  return '\\mathbb{R}\\setminus\\left{' +
3216
- zeroes.map(x => {
3217
- return (typeof x === 'boolean') ? '' : x.frac;
3218
- })
3219
- .join(';') + '\\right}';
3315
+ zeroes.map(x => x.tex).join(';') + '\\right}';
3220
3316
  }
3221
3317
  };
3222
3318
  this.amplify = (P) => {
@@ -3224,6 +3320,12 @@ class Rational {
3224
3320
  this._denominator.multiply(P);
3225
3321
  return this;
3226
3322
  };
3323
+ this.derivative = (letter) => {
3324
+ let N = this._numerator.clone(), D = this._denominator.clone(), dN = N.clone().derivative(letter), dD = D.clone().derivative(letter);
3325
+ this._numerator = dN.clone().multiply(D).subtract(N.clone().multiply(dD));
3326
+ this._denominator = D.clone().pow(2);
3327
+ return this;
3328
+ };
3227
3329
  this.simplify = (P) => {
3228
3330
  let NumeratorEuclidien = this._numerator.euclidian(P);
3229
3331
  if (!NumeratorEuclidien.reminder.isZero()) {
@@ -3238,9 +3340,7 @@ class Rational {
3238
3340
  return this;
3239
3341
  };
3240
3342
  this.reduce = () => {
3241
- console.log(this._numerator.tex);
3242
3343
  this._numerator.factorize();
3243
- console.log(this._numerator.factors.map(x => x.tex));
3244
3344
  for (let f of this._numerator.factors) {
3245
3345
  this.simplify(f);
3246
3346
  }
@@ -3265,41 +3365,150 @@ class Rational {
3265
3365
  this.subtract = (R) => {
3266
3366
  return this.add(R.clone().opposed());
3267
3367
  };
3268
- this.limits = (value, letter) => {
3368
+ this.limits = (value, offset, letter) => {
3269
3369
  if (value === Infinity || value === -Infinity) {
3270
- let N = this._numerator.monomByDegree(this._numerator.degree(letter), letter), D = this._denominator.monomByDegree(this._denominator.degree(letter), letter);
3271
- N.divide(D);
3272
- if (N.degree(letter).isStrictlyPositive()) {
3273
- return N.coefficient.sign() * (Math.pow((value > 0 ? 1 : -1), N.degree(letter).value % 2)) === 1 ? Infinity : -Infinity;
3274
- }
3275
- if (N.degree(letter).isZero()) {
3276
- return N.coefficient;
3370
+ let { quotient, reminder } = this._numerator.clone().euclidian(this._denominator);
3371
+ // quotient is positive => it will be infinite.
3372
+ if (quotient.degree(letter).isStrictlyPositive()) {
3373
+ return value === Infinity ? quotient.limitToInfinity(letter) : quotient.limitToNegativeInfinity(letter);
3374
+ // return quotient.monomByDegree(undefined, letter).coefficient.sign()===1?(new Fraction()).infinite():(new Fraction()).infinite().opposed()
3277
3375
  }
3278
- if (N.degree(letter).isStrictlyPositive()) {
3279
- return N.coefficient.sign() * (Math.pow(-1, N.degree(letter).value % 2)) === 1 ? 0 : -0;
3376
+ else {
3377
+ return quotient.monomByDegree(undefined, letter).coefficient;
3280
3378
  }
3281
3379
  }
3282
3380
  else {
3283
- return this._numerator.evaluate({ letter: new fraction_1.Fraction(value) }).divide(this._denominator.evaluate({ letter: new fraction_1.Fraction(value) }));
3381
+ let evalValues = {}, evalValuesOffset = {}, theLimit, theSign, FR = this.clone().reduce();
3382
+ evalValues[letter === undefined ? 'x' : letter] = new fraction_1.Fraction(value);
3383
+ if (offset !== 'above' && offset !== 'below') {
3384
+ theLimit = FR._numerator.evaluate(evalValues)
3385
+ .divide(FR._denominator.evaluate(evalValues));
3386
+ return theLimit.isInfinity() ? theLimit.abs() : theLimit;
3387
+ }
3388
+ else {
3389
+ if (offset === 'above') {
3390
+ evalValuesOffset[letter === undefined ? 'x' : letter] = (new fraction_1.Fraction(value)).add(0.000001);
3391
+ }
3392
+ else if (offset === 'below') {
3393
+ evalValuesOffset[letter === undefined ? 'x' : letter] = (new fraction_1.Fraction(value)).subtract(0.000001);
3394
+ }
3395
+ theLimit = FR._numerator.evaluate(evalValues)
3396
+ .divide(FR._denominator.evaluate(evalValues));
3397
+ theSign = FR._numerator.evaluate(evalValuesOffset)
3398
+ .divide(FR._denominator.evaluate(evalValuesOffset)).sign();
3399
+ if (theLimit.isInfinity()) {
3400
+ return theSign === 1 ? theLimit.abs() : theLimit.abs().opposed();
3401
+ }
3402
+ else {
3403
+ return theLimit;
3404
+ }
3405
+ }
3284
3406
  }
3285
3407
  };
3408
+ this.makeTableOfSigns = () => {
3409
+ // Factorize the numerator and the denominator
3410
+ this._numerator.factorize();
3411
+ this._denominator.factorize();
3412
+ let zeroes = equation_1.Equation.makeSolutionsUnique([...this._numerator.getZeroes(), ...this._denominator.getZeroes()], true), NFactors = this._numerator.factors, DFactors = this._denominator.factors;
3413
+ let tableOfSigns = [], result = [];
3414
+ NFactors.forEach(factor => {
3415
+ tableOfSigns.push(this._makeOneLineOfTableOfSigns(factor, zeroes, 'z'));
3416
+ });
3417
+ DFactors.forEach(factor => {
3418
+ tableOfSigns.push(this._makeOneLineOfTableOfSigns(factor, zeroes, 'd'));
3419
+ });
3420
+ // Empty line
3421
+ tableOfSigns.push([]);
3422
+ // Add the final row as cumulative
3423
+ let resultLine = tableOfSigns[0].map((x, index) => {
3424
+ if (index === 0) {
3425
+ return '';
3426
+ }
3427
+ if (index === tableOfSigns[0].length - 1) {
3428
+ return '';
3429
+ }
3430
+ if (index % 2 === 0) {
3431
+ return 't';
3432
+ }
3433
+ return '+';
3434
+ });
3435
+ for (let current of tableOfSigns) {
3436
+ for (let i = 0; i < current.length; i++) {
3437
+ if (i % 2 === 0) {
3438
+ // t, z or d
3439
+ if (resultLine[i] === 'd') {
3440
+ continue;
3441
+ }
3442
+ if (current[i] !== 't') {
3443
+ resultLine[i] = current[i];
3444
+ }
3445
+ }
3446
+ else {
3447
+ // + or -
3448
+ if (current[i] === '-') {
3449
+ resultLine[i] = resultLine[i] === '+' ? '-' : '+';
3450
+ }
3451
+ }
3452
+ }
3453
+ }
3454
+ // Add the variation line.
3455
+ // TODO: add the variation line.
3456
+ tableOfSigns.push(resultLine);
3457
+ let tos = {
3458
+ factors: [...NFactors, ...DFactors],
3459
+ zeroes: zeroes,
3460
+ signs: tableOfSigns,
3461
+ tex: ''
3462
+ };
3463
+ this._makeTexFromTableOfSigns(tos);
3464
+ return tos;
3465
+ };
3466
+ this._makeTexFromTableOfSigns = (tos) => {
3467
+ let tex = `\\begin{tikzpicture}
3468
+ \\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\\)}}`;
3469
+ tos.signs.forEach(list => {
3470
+ tex += (`\n\\tkzTabLine{${list.join(',')}}`);
3471
+ });
3472
+ tex += `\n\\end{tikzpicture}`;
3473
+ tos.tex = tex;
3474
+ return tex;
3475
+ };
3476
+ this._makeOneLineOfTableOfSigns = (factor, zeroes, zeroSign) => {
3477
+ let oneLine = [],
3478
+ // TODO : check if there is no zero ?
3479
+ currentZero = factor.getZeroes().map(x => x.tex);
3480
+ // First +/- sign, before the first zero
3481
+ oneLine.push('');
3482
+ oneLine.push(factor.evaluate(zeroes[0].value - 1).sign() === 1 ? '+' : '-');
3483
+ for (let i = 0; i < zeroes.length; i++) {
3484
+ // Add the zero if it's the current one
3485
+ oneLine.push(currentZero.includes(zeroes[i].tex) ? zeroSign : 't');
3486
+ // + / - sign after the current zero
3487
+ if (i < zeroes.length - 1) {
3488
+ oneLine.push(factor.evaluate((zeroes[i].value + zeroes[i + 1].value) / 2).sign() === 1 ? '+' : '-');
3489
+ }
3490
+ else if (i === zeroes.length - 1) {
3491
+ oneLine.push(factor.evaluate(zeroes[i].value + 1).sign() === 1 ? '+' : '-');
3492
+ }
3493
+ }
3494
+ oneLine.push('');
3495
+ return oneLine;
3496
+ };
3286
3497
  this._numerator = numerator ? numerator.clone() : new polynom_1.Polynom();
3287
3498
  this._denominator = denominator ? denominator.clone() : new polynom_1.Polynom();
3288
3499
  }
3289
- get tex() {
3290
- return `\\dfrac{ ${this._numerator.tex} }{ ${this._denominator.tex} }`;
3291
- }
3292
- get texFactors() {
3293
- this._numerator.factorize();
3294
- this._denominator.factorize();
3295
- return `\\dfrac{ ${this._numerator.texFactors} }{ ${this._denominator.texFactors} }`;
3296
- }
3297
3500
  get numerator() {
3298
3501
  return this._numerator;
3299
3502
  }
3300
3503
  get denominator() {
3301
3504
  return this._denominator;
3302
3505
  }
3506
+ get tex() {
3507
+ return `\\dfrac{ ${this._numerator.tex} }{ ${this._denominator.tex} }`;
3508
+ }
3509
+ get texFactors() {
3510
+ return `\\dfrac{ ${this._numerator.texFactors} }{ ${this._denominator.texFactors} }`;
3511
+ }
3303
3512
  }
3304
3513
  exports.Rational = Rational;
3305
3514
 
@@ -3639,10 +3848,10 @@ class Fraction {
3639
3848
  return isNaN(this._numerator);
3640
3849
  };
3641
3850
  this.isInfinity = () => {
3642
- return this._numerator === Infinity;
3851
+ return Math.abs(this._numerator) === Infinity;
3643
3852
  };
3644
3853
  this.isFinite = () => {
3645
- return !this.isInfinity();
3854
+ return !this.isInfinity() && !this.isNaN();
3646
3855
  };
3647
3856
  this.isSquare = () => {
3648
3857
  return Math.sqrt(this._numerator) % 1 === 0 && Math.sqrt(this._denominator) % 1 === 0;
@@ -3687,9 +3896,6 @@ class Fraction {
3687
3896
  }
3688
3897
  return this;
3689
3898
  }
3690
- get isFraction() {
3691
- return true;
3692
- }
3693
3899
  // ------------------------------------------
3694
3900
  // Getter and setter
3695
3901
  // ------------------------------------------
@@ -3710,6 +3916,9 @@ class Fraction {
3710
3916
  }
3711
3917
  // Display getter
3712
3918
  get tex() {
3919
+ if (this.isInfinity()) {
3920
+ return `${this.sign() === 1 ? '+' : '-'}\\infty`;
3921
+ }
3713
3922
  if (this._denominator === 1) {
3714
3923
  return `${this._numerator}`;
3715
3924
  }
@@ -3760,20 +3969,52 @@ Fraction.min = (...fractions) => {
3760
3969
  }
3761
3970
  return M;
3762
3971
  };
3972
+ Fraction.average = (...fractions) => {
3973
+ let M = new Fraction().zero();
3974
+ for (let f of fractions) {
3975
+ M.add(f);
3976
+ }
3977
+ M.divide(fractions.length);
3978
+ return M;
3979
+ };
3980
+ Fraction.unique = (fractions, sorted) => {
3981
+ // TODO: make sure it's wokring -> test !
3982
+ let unique = {}, distinct = [];
3983
+ fractions.forEach(x => {
3984
+ if (!unique[x.clone().reduce().tex]) {
3985
+ distinct.push(x.clone());
3986
+ unique[x.tex] = true;
3987
+ }
3988
+ });
3989
+ if (sorted) {
3990
+ return Fraction.sort(distinct);
3991
+ }
3992
+ else {
3993
+ return distinct;
3994
+ }
3995
+ };
3996
+ Fraction.sort = (fractions, reverse) => {
3997
+ // Todo make sure it's the correct order, not reverse -> make a test
3998
+ let sorted = fractions.sort((a, b) => a.value - b.value);
3999
+ if (reverse) {
4000
+ sorted.reverse();
4001
+ }
4002
+ return sorted;
4003
+ };
3763
4004
 
3764
4005
 
3765
4006
  /***/ }),
3766
4007
 
3767
- /***/ 923:
4008
+ /***/ 872:
3768
4009
  /***/ ((__unused_webpack_module, exports) => {
3769
4010
 
3770
4011
 
3771
4012
  Object.defineProperty(exports, "__esModule", ({ value: true }));
3772
- exports.Nthroot = void 0;
4013
+ exports.NthRoot = void 0;
3773
4014
  /**
3774
- * Nthroot is something like "a+b\sqrt{3}
4015
+ * NthRoot is something like "a+b\sqrt{3}
3775
4016
  */
3776
- class Nthroot {
4017
+ class NthRoot {
3777
4018
  constructor(...values) {
3778
4019
  // ------------------------------------------
3779
4020
  // Creation / parsing functions
@@ -3879,7 +4120,7 @@ class Nthroot {
3879
4120
  return this._coefficient * Math.pow(this._radical, 1 / this._nth);
3880
4121
  }
3881
4122
  }
3882
- exports.Nthroot = Nthroot;
4123
+ exports.NthRoot = NthRoot;
3883
4124
 
3884
4125
 
3885
4126
  /***/ }),
@@ -4696,6 +4937,14 @@ class Line {
4696
4937
  return this.parseByPointAndVector(values[0], values[1]);
4697
4938
  }
4698
4939
  }
4940
+ else if (values[0] instanceof point_1.Point && values[1] instanceof Line) {
4941
+ if (values[2] === LinePropriety.Parallel || values[2] === null) {
4942
+ return this.parseByPointAndLine(values[0], values[1], LinePropriety.Parallel);
4943
+ }
4944
+ else {
4945
+ return this.parseByPointAndLine(values[0], values[1], LinePropriety.Perpendicular);
4946
+ }
4947
+ }
4699
4948
  }
4700
4949
  // TODO: Add the ability to create line from a normal vector
4701
4950
  console.log('Someting wrong happend while creating the line');