pimath 0.0.64 → 0.0.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/.eslintrc.js +23 -23
  2. package/dist/pi.js +236 -56
  3. package/dist/pi.js.map +1 -1
  4. package/dist/pi.min.js +1 -1
  5. package/dist/pi.min.js.map +1 -1
  6. package/docs/assets/highlight.css +78 -78
  7. package/docs/assets/main.js +52 -52
  8. package/docs/assets/style.css +1413 -1413
  9. package/docs/classes/Logicalset.Logicalset-1.html +4 -4
  10. package/docs/classes/Polynom.Rational.html +3 -3
  11. package/docs/classes/algebra_equation.Equation.html +25 -25
  12. package/docs/classes/algebra_monom.Monom.html +113 -113
  13. package/docs/classes/algebra_polynom.Polynom.html +29 -29
  14. package/docs/classes/coefficients_fraction.Fraction.html +18 -18
  15. package/docs/classes/coefficients_nthroot.NthRoot.html +2 -2
  16. package/docs/classes/geometry_circle.Circle.html +2 -2
  17. package/docs/classes/geometry_line.Line.html +2 -2
  18. package/docs/classes/geometry_triangle.Triangle.html +16 -16
  19. package/docs/classes/numeric.Numeric.html +13 -13
  20. package/docs/classes/shutingyard.Shutingyard.html +17 -17
  21. package/docs/index.html +10 -10
  22. package/docs/interfaces/algebra_equation.ISolution.html +2 -2
  23. package/docs/modules/Logicalset.html +2 -2
  24. package/docs/modules/Polynom.html +2 -2
  25. package/docs/modules/Vector.html +2 -2
  26. package/esm/maths/algebra/equation.js +2 -2
  27. package/esm/maths/algebra/equation.js.map +1 -1
  28. package/esm/maths/algebra/polynom.d.ts +4 -5
  29. package/esm/maths/algebra/polynom.js +2 -2
  30. package/esm/maths/algebra/polynom.js.map +1 -1
  31. package/esm/maths/algebra/rational.d.ts +8 -10
  32. package/esm/maths/algebra/rational.js +9 -5
  33. package/esm/maths/algebra/study/rationalStudy.d.ts +1 -2
  34. package/esm/maths/algebra/study/rationalStudy.js +32 -20
  35. package/esm/maths/algebra/study/rationalStudy.js.map +1 -1
  36. package/esm/maths/algebra/study.d.ts +16 -24
  37. package/esm/maths/algebra/study.js +65 -24
  38. package/esm/maths/algebra/study.js.map +1 -1
  39. package/esm/maths/coefficients/fraction.d.ts +8 -6
  40. package/esm/maths/coefficients/fraction.js +34 -17
  41. package/esm/maths/coefficients/fraction.js.map +1 -1
  42. package/esm/maths/expressions/expression.d.ts +21 -0
  43. package/esm/maths/expressions/expression.js +161 -0
  44. package/esm/maths/expressions/expression.js.map +1 -0
  45. package/esm/maths/expressions/expressionFactor.d.ts +29 -0
  46. package/esm/maths/expressions/expressionFactor.js +109 -0
  47. package/esm/maths/expressions/expressionFactor.js.map +1 -0
  48. package/esm/maths/expressions/expressionMember.d.ts +16 -0
  49. package/esm/maths/expressions/expressionMember.js +90 -0
  50. package/esm/maths/expressions/expressionMember.js.map +1 -0
  51. package/esm/maths/expressions/expressionOperators.d.ts +8 -0
  52. package/esm/maths/expressions/expressionOperators.js +42 -0
  53. package/esm/maths/expressions/expressionOperators.js.map +1 -0
  54. package/esm/maths/expressions/expressionParser.d.ts +12 -0
  55. package/esm/maths/expressions/expressionParser.js +219 -0
  56. package/esm/maths/expressions/expressionParser.js.map +1 -0
  57. package/esm/maths/expressions/factors/ExpFactor.d.ts +7 -0
  58. package/esm/maths/expressions/factors/ExpFactor.js +22 -0
  59. package/esm/maths/expressions/factors/ExpFactor.js.map +1 -0
  60. package/esm/maths/expressions/factors/ExpFactorConstant.d.ts +13 -0
  61. package/esm/maths/expressions/factors/ExpFactorConstant.js +49 -0
  62. package/esm/maths/expressions/factors/ExpFactorConstant.js.map +1 -0
  63. package/esm/maths/expressions/factors/ExpFactorExponential.d.ts +7 -0
  64. package/esm/maths/expressions/factors/ExpFactorExponential.js +18 -0
  65. package/esm/maths/expressions/factors/ExpFactorExponential.js.map +1 -0
  66. package/esm/maths/expressions/factors/ExpFactorNumber.d.ts +13 -0
  67. package/esm/maths/expressions/factors/ExpFactorNumber.js +36 -0
  68. package/esm/maths/expressions/factors/ExpFactorNumber.js.map +1 -0
  69. package/esm/maths/expressions/factors/ExpFactorPower.d.ts +9 -0
  70. package/esm/maths/expressions/factors/ExpFactorPower.js +22 -0
  71. package/esm/maths/expressions/factors/ExpFactorPower.js.map +1 -0
  72. package/esm/maths/expressions/factors/ExpFactorSin.d.ts +7 -0
  73. package/esm/maths/expressions/factors/ExpFactorSin.js +22 -0
  74. package/esm/maths/expressions/factors/ExpFactorSin.js.map +1 -0
  75. package/esm/maths/expressions/factors/ExpFactorTrigo.d.ts +19 -0
  76. package/esm/maths/expressions/factors/ExpFactorTrigo.js +40 -0
  77. package/esm/maths/expressions/factors/ExpFactorTrigo.js.map +1 -0
  78. package/esm/maths/expressions/factors/ExpFactorVariable.d.ts +12 -0
  79. package/esm/maths/expressions/factors/ExpFactorVariable.js +33 -0
  80. package/esm/maths/expressions/factors/ExpFactorVariable.js.map +1 -0
  81. package/esm/maths/expressions/internals.d.ts +12 -0
  82. package/esm/maths/expressions/internals.js +29 -0
  83. package/esm/maths/expressions/internals.js.map +1 -0
  84. package/esm/maths/shutingyard.d.ts +4 -1
  85. package/esm/maths/shutingyard.js +137 -21
  86. package/esm/maths/shutingyard.js.map +1 -1
  87. package/graph.svg +1033 -0
  88. package/package.json +1 -1
  89. package/src/maths/algebra/equation.ts +2 -2
  90. package/src/maths/algebra/polynom.ts +1 -0
  91. package/src/maths/algebra/study/rationalStudy.ts +26 -12
  92. package/src/maths/algebra/study.ts +48 -5
  93. package/src/maths/coefficients/fraction.ts +111 -86
  94. package/src/maths/expressions/expression.ts +191 -0
  95. package/src/maths/expressions/expressionFactor.ts +138 -0
  96. package/src/maths/expressions/expressionMember.ts +114 -0
  97. package/src/maths/expressions/expressionOperators.ts +49 -0
  98. package/src/maths/expressions/expressionParser.ts +249 -0
  99. package/src/maths/expressions/factors/ExpFactor.ts +26 -0
  100. package/src/maths/expressions/factors/ExpFactorConstant.ts +56 -0
  101. package/src/maths/expressions/factors/ExpFactorExponential.ts +19 -0
  102. package/src/maths/expressions/factors/ExpFactorNumber.ts +44 -0
  103. package/src/maths/expressions/factors/ExpFactorPower.ts +24 -0
  104. package/src/maths/expressions/factors/ExpFactorTrigo.ts +44 -0
  105. package/src/maths/expressions/factors/ExpFactorVariable.ts +40 -0
  106. package/src/maths/expressions/internals.ts +14 -0
  107. package/src/maths/shutingyard.ts +156 -26
  108. package/tests/algebra/study.test.ts +29 -4
  109. package/tests/coefficients/fraction.test.ts +17 -0
  110. package/tests/expressions/expressions.test.ts +124 -0
  111. package/tests/shutingyard.test.ts +22 -0
  112. package/.idea/shelf/Uncommitted_changes_before_Update_at_17_04_2022_12_40_[Changes]/shelved.patch +0 -21
  113. package/.idea/shelf/Uncommitted_changes_before_Update_at_17_04_2022_12_40__Changes_.xml +0 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pimath",
3
- "version": "0.0.64",
3
+ "version": "0.0.67",
4
4
  "description": "A math library for teacher :)",
5
5
  "scripts": {
6
6
  "test": "mocha -r ts-node/register 'tests/**/*.test.ts'",
@@ -576,9 +576,9 @@ export class Equation {
576
576
  } else {
577
577
  // Must handle the case if the m1 monom is negative.
578
578
  if ((this.isGreater() && m1.sign() === 1) || (!this.isGreater() && m1.sign() === -1)) {
579
- s = `\\left${this.isAlsoEqual() ? '\\[' : '\\]'}${v};+\\infty\\right\\[`;
579
+ s = `\\left${this.isAlsoEqual() ? '\\[' : '\\]'}${v.tex};+\\infty\\right\\[`;
580
580
  } else {
581
- s = `\\left\\]-\\infty;${v} \\right\\${this.isAlsoEqual() ? '\\]' : '\\['}`;
581
+ s = `\\left\\]-\\infty;${v.tex} \\right\\${this.isAlsoEqual() ? '\\]' : '\\['}`;
582
582
  }
583
583
  }
584
584
  this._solutions = [{
@@ -259,6 +259,7 @@ export class Polynom {
259
259
  this._factors = []
260
260
  this.mark_as_dirty()
261
261
 
262
+ // TODO: allow to enter a liste of Fraction (a, b, c, ...) to make a polynom ax^n + bx^(n-1) + cx^(n-2) + ...
262
263
  if (typeof inputStr === 'string') {
263
264
  return this._parseString(inputStr, ...values)
264
265
  } else if (
@@ -36,7 +36,6 @@ export class RationalStudy extends Study {
36
36
  }
37
37
 
38
38
  makeZeroes(): IZero[] {
39
- console.log('GETTING ZEROES')
40
39
  return this._getZeroes(this.fx)
41
40
  };
42
41
 
@@ -68,11 +67,13 @@ export class RationalStudy extends Study {
68
67
  }
69
68
 
70
69
  asymptotes.push({
70
+ fx: null,
71
71
  type: Ztype,
72
72
  tex: tex,
73
73
  zero: zero,
74
74
  limits: `\\lim_{x\\to${zero.tex} }\\ f(x) = \\pm\\infty`,
75
- deltaX: null
75
+ deltaX: null,
76
+ tableOfSign: null
76
77
  })
77
78
  })
78
79
 
@@ -80,35 +81,45 @@ export class RationalStudy extends Study {
80
81
  let NDegree = this.fx.numerator.degree(),
81
82
  DDegree = this.fx.denominator.degree()
82
83
  if (NDegree.isEqual(DDegree)) {
83
- let H = this.fx.numerator.monomByDegree().coefficient.clone().divide(this.fx.denominator.monomByDegree().coefficient).tex
84
+ let H = this.fx.numerator.monomByDegree().coefficient.clone().divide(this.fx.denominator.monomByDegree().coefficient),
85
+ Htex = H.tex
86
+
87
+ let {reminder} = reduced.euclidian(),
88
+ deltaX = new Rational(reminder, reduced.denominator)
84
89
 
85
- let {reminder} = reduced.euclidian()
86
90
 
87
91
  asymptotes.push({
92
+ fx: new Polynom(H),
88
93
  type: ASYMPTOTE.HORIZONTAL,
89
- tex: `y=${H}`,
94
+ tex: `y=${Htex}`,
90
95
  zero: null,
91
- limits: `\\lim_{x\\to\\infty}\\ f(x) = ${H}`,
92
- deltaX: new Rational(reminder, reduced.denominator)
96
+ limits: `\\lim_{x\\to\\infty}\\ f(x) = ${Htex}`,
97
+ deltaX,
98
+ tableOfSign: this._getSigns(deltaX)
93
99
  })
94
100
  } else if (DDegree.greater(NDegree)) {
95
101
  asymptotes.push({
102
+ fx: new Polynom('0'),
96
103
  type: ASYMPTOTE.HORIZONTAL,
97
104
  tex: `y=0`,
98
105
  zero: null,
99
106
  limits: `\\lim_{x\\to\\infty}\\ f(x) = ${0}`,
100
- deltaX: null
107
+ deltaX: null,
108
+ tableOfSign: null
101
109
  })
102
110
  } else if (NDegree.value - 1 === DDegree.value) {
103
111
  // Calculate the slope
104
- let {quotient, reminder} = reduced.euclidian()
112
+ let {quotient, reminder} = reduced.euclidian(),
113
+ deltaX = new Rational(reminder, reduced.denominator)
105
114
 
106
115
  asymptotes.push({
116
+ fx: quotient.clone(),
107
117
  type: ASYMPTOTE.SLOPE,
108
118
  tex: `y=${quotient.tex}`,
109
119
  zero: null,
110
120
  limits: ``,
111
- deltaX: new Rational(reminder, reduced.denominator)
121
+ deltaX: new Rational(reminder, reduced.denominator),
122
+ tableOfSign: this._getSigns(deltaX)
112
123
  })
113
124
  }
114
125
 
@@ -119,7 +130,6 @@ export class RationalStudy extends Study {
119
130
  let dx = this.fx.clone().derivative(),
120
131
  tos = this._getSigns(dx, this._getZeroes(dx), TABLE_OF_SIGNS.GROWS)
121
132
 
122
- console.log(tos.factors.length, tos.signs.length)
123
133
  let result = this.makeGrowsResult(tos)
124
134
  tos.signs.push(result.growsLine)
125
135
  tos.extremes = result.extremes
@@ -175,11 +185,15 @@ export class RationalStudy extends Study {
175
185
  return zeroes
176
186
  }
177
187
 
178
- private _getSigns(fx: Rational, zeroes: IZero[], typeOfTable?: TABLE_OF_SIGNS): ITableOfSigns {
188
+ private _getSigns(fx: Rational, zeroes?: IZero[], typeOfTable?: TABLE_OF_SIGNS): ITableOfSigns {
179
189
  // Factorize the rational
180
190
  let signs: (string[])[] = [],
181
191
  factors: Polynom[] = []
182
192
 
193
+ if (zeroes === undefined) {
194
+ zeroes = this._getZeroes(fx)
195
+ }
196
+
183
197
  fx.numerator.factors.forEach(factor => {
184
198
  signs.push(this.makeOneLineForSigns(factor, zeroes, ZEROTYPE.ZERO))
185
199
  factors.push(factor.clone())
@@ -8,6 +8,7 @@ import {ISolution} from "./equation";
8
8
  import {Polynom} from "./polynom";
9
9
  import {Fraction} from "../coefficients/fraction";
10
10
  import {Point} from "../geometry/point";
11
+ import {NumExp} from "../expressions/numexp";
11
12
 
12
13
  export type StudyableFunction = Rational
13
14
 
@@ -31,11 +32,13 @@ export enum ASYMPTOTE {
31
32
  }
32
33
 
33
34
  export interface IAsymptote {
35
+ fx: Polynom,
34
36
  deltaX: StudyableFunction
35
37
  limits: string,
36
38
  tex: string,
37
39
  type: ASYMPTOTE,
38
40
  zero: IZero,
41
+ tableOfSign: ITableOfSigns
39
42
  }
40
43
 
41
44
  export enum FUNCTION_EXTREMA {
@@ -69,9 +72,9 @@ export interface ITableOfSigns {
69
72
  }
70
73
 
71
74
  export enum TABLE_OF_SIGNS {
72
- DEFAULT,
73
- GROWS,
74
- VARIATIONS
75
+ SIGNS = "signs",
76
+ GROWS = "grows",
77
+ VARIATIONS = "variatins"
75
78
  }
76
79
 
77
80
  /**
@@ -251,6 +254,9 @@ export class Study {
251
254
  xTex: string, yTex: string,
252
255
  pointType: FUNCTION_EXTREMA
253
256
 
257
+ // TODO: NumExp should parse something that isn't yet plotFunction
258
+ let exp = new NumExp(this.fx.plotFunction)
259
+
254
260
  if (zero instanceof Fraction) {
255
261
  let value: Fraction = zero,
256
262
  evalY = this.fx.evaluate(value)
@@ -261,7 +267,7 @@ export class Study {
261
267
  yTex = evalY.tex
262
268
  } else {
263
269
  x = zeroes[i].value
264
- y = this.fx.evaluate(zeroes[i].value).value
270
+ y = exp.evaluate({x})
265
271
 
266
272
  xTex = x.toFixed(2)
267
273
  yTex = y.toFixed(2)
@@ -317,7 +323,7 @@ export class Study {
317
323
 
318
324
  makeSigns(): ITableOfSigns {
319
325
  return {
320
- type: TABLE_OF_SIGNS.DEFAULT,
326
+ type: TABLE_OF_SIGNS.SIGNS,
321
327
  fx: null,
322
328
  factors: [],
323
329
  zeroes: [],
@@ -390,4 +396,41 @@ export class Study {
390
396
 
391
397
  return tex
392
398
  }
399
+
400
+ drawCode = (): string => {
401
+ // Function as string
402
+ let code = `f(x)=${this.fx.plotFunction}`
403
+
404
+ // Asymptotes
405
+ let i: number = 1
406
+ this.asymptotes.forEach(asymptote => {
407
+ if (asymptote.type === ASYMPTOTE.VERTICAL) {
408
+ code += `\nav_${i}=line x=${asymptote.zero.value}->red,dash`
409
+ i++
410
+ } else if (asymptote.type === ASYMPTOTE.HORIZONTAL) {
411
+ code += `\nah=line y=${asymptote.fx.monoms[0].coefficient.value}->orange,dash`
412
+ } else if (asymptote.type === ASYMPTOTE.SLOPE) {
413
+ code += `\nao=line y=${asymptote.fx.plotFunction}->red,dash`
414
+ }
415
+ i++
416
+ })
417
+
418
+ // Extremes
419
+ for (let zero in this.derivative.extremes) {
420
+ let extreme = this.derivative.extremes[zero]
421
+
422
+ code += `\nM_${i}(${extreme.value.x},${extreme.value.y})*`
423
+ i++
424
+ }
425
+
426
+ // Zeroes
427
+ this.zeroes.forEach(zero => {
428
+ if (zero.type === ZEROTYPE.ZERO) {
429
+ code += `\nZ_${i}(${zero.value},0)*`
430
+ i++
431
+ }
432
+ })
433
+
434
+ return code
435
+ }
393
436
  }
@@ -1,14 +1,15 @@
1
1
  import {Numeric} from "../numeric";
2
2
 
3
- export type FractionParsingType = number|string|Fraction
3
+ export type FractionParsingType = number | string | Fraction
4
+
4
5
  /**
5
6
  * The fraction class make possible to handle
6
7
  * TODO: Write the documentation correctly.
7
8
  * \\(\frac{a}{b}\\) or \\[\frac{a}{b}\\] values.
8
9
  */
9
10
  export class Fraction {
10
- private _numerator: number;
11
11
  private _denominator: number;
12
+ private _numerator: number;
12
13
 
13
14
  constructor(value?: unknown, denominatorOrPeriodic?: number) {
14
15
  this._numerator = 1;
@@ -47,24 +48,32 @@ export class Fraction {
47
48
 
48
49
  // Display getter
49
50
  get tex(): string {
50
- if(this.isInfinity()){
51
- return `${this.sign()===1?'+':'-'}\\infty`
51
+ if (this.isInfinity()) {
52
+ return `${this.sign() === 1 ? '+' : '-'}\\infty`
52
53
  }
53
54
 
54
- if (this._denominator === 1) {
55
- return `${this._numerator}`;
56
- } else if (this._numerator < 0) {
57
- return `-\\frac{ ${-this._numerator} }{ ${this._denominator} }`;
55
+ if (this.isExact()) {
56
+ if (this._denominator === 1) {
57
+ return `${this._numerator}`;
58
+ } else if (this._numerator < 0) {
59
+ return `-\\frac{ ${-this._numerator} }{ ${this._denominator} }`;
60
+ } else {
61
+ return `\\frac{ ${this._numerator} }{ ${this._denominator} }`;
62
+ }
58
63
  } else {
59
- return `\\frac{ ${this._numerator} }{ ${this._denominator} }`;
64
+ return this.value.toFixed(3)
60
65
  }
61
66
  }
62
67
 
63
68
  get display(): string {
64
- if (this._denominator === 1) {
65
- return `${this._numerator}`;
69
+ if (this.isExact()) {
70
+ if (this._denominator === 1) {
71
+ return `${this._numerator}`;
72
+ } else {
73
+ return `${this._numerator}/${this._denominator}`;
74
+ }
66
75
  } else {
67
- return `${this._numerator}/${this._denominator}`;
76
+ return this.value.toFixed(3)
68
77
  }
69
78
  }
70
79
 
@@ -76,12 +85,89 @@ export class Fraction {
76
85
  get dfrac(): string {
77
86
  return this.tex.replace('\\frac', '\\dfrac');
78
87
  }
88
+
79
89
  get tfrac(): string {
80
90
  return this.tex.replace('\\frac', '\\tfrac')
81
91
  }
82
92
 
93
+ static max = (...fractions: (Fraction | number)[]): Fraction => {
94
+ let M = new Fraction(fractions[0])
95
+
96
+ for (let m of fractions) {
97
+ let compare = new Fraction(m)
98
+ if (compare.greater(M)) {
99
+ M = compare.clone()
100
+ }
101
+ }
102
+
103
+ return M
104
+ }
105
+
106
+ static min = (...fractions: (Fraction | number)[]): Fraction => {
107
+ let M = new Fraction(fractions[0])
108
+
109
+ for (let m of fractions) {
110
+ let compare = new Fraction(m)
111
+ if (compare.lesser(M)) {
112
+ M = compare.clone()
113
+ }
114
+ }
115
+
116
+ return M
117
+ }
118
+
83
119
  // ------------------------------------------
84
120
  // Creation / parsing functions
121
+
122
+ static average = (...fractions: (Fraction | number)[]): Fraction => {
123
+ let M = new Fraction().zero()
124
+
125
+ for (let f of fractions) {
126
+ M.add(f)
127
+ }
128
+
129
+ M.divide(fractions.length)
130
+
131
+ return M
132
+ }
133
+
134
+ static unique = (fractions: Fraction[], sorted?: boolean): Fraction[] => {
135
+ // TODO: make sure it's wokring -> test !
136
+ let unique: { [Key: string]: boolean } = {},
137
+ distinct: Fraction[] = []
138
+ fractions.forEach(x => {
139
+ if (!unique[x.clone().reduce().tex]) {
140
+ distinct.push(x.clone())
141
+ unique[x.tex] = true
142
+ }
143
+ })
144
+
145
+ if (sorted) {
146
+ return Fraction.sort(distinct)
147
+ } else {
148
+ return distinct
149
+ }
150
+ }
151
+
152
+ static sort = (fractions: Fraction[], reverse?: boolean): Fraction[] => {
153
+ // Todo make sure it's the correct order, not reverse -> make a test
154
+ let sorted = fractions.sort((a, b) => a.value - b.value)
155
+
156
+ if (reverse) {
157
+ sorted.reverse()
158
+ }
159
+
160
+ return sorted
161
+ }
162
+
163
+ isApproximative = (): boolean => {
164
+ return this._numerator.toString().length >= 15 && this._denominator.toString().length >= 15
165
+ }
166
+
167
+ isExact = (): boolean => {
168
+ return !this.isApproximative()
169
+ }
170
+
85
171
  // ------------------------------------------
86
172
  /**
87
173
  * Parse the value to get the numerator and denominator
@@ -100,16 +186,15 @@ export class Fraction {
100
186
 
101
187
  switch (typeof value) {
102
188
  case "string":
103
- // Split the sting value in two parts: Numerator/Denominator
189
+ // Split the string value in two parts: Numerator/Denominator
104
190
  S = value.split('/');
105
191
 
106
192
  // Security checks
107
- if (S.length > 2) throw "Two many divide signs";
108
- if (S.map(x => x === '' || isNaN(Number(x))).includes(true)) throw "Not a number"
109
-
193
+ if (S.length > 2) throw value + " has too many divide signs";
194
+ if (S.map(x => x === '' || isNaN(Number(x))).includes(true)) throw value + " is not a valid number"
110
195
 
111
196
  if (S.length === 1) {
112
- // No divide sign
197
+ // No divide sign - it's a number
113
198
  return this.parse(+S[0]);
114
199
  } else if (S.length === 2) {
115
200
  // One divide signe
@@ -123,6 +208,7 @@ export class Fraction {
123
208
  }
124
209
  } else {
125
210
  // More than one divide sign ?
211
+ // This is impossible
126
212
  this._numerator = NaN;
127
213
  this._denominator = 1;
128
214
  }
@@ -164,6 +250,9 @@ export class Fraction {
164
250
  return this;
165
251
  };
166
252
 
253
+ // ------------------------------------------
254
+ // Mathematical operations
255
+
167
256
  clone = (): Fraction => {
168
257
  let F = new Fraction();
169
258
  F.numerator = +this._numerator;
@@ -195,8 +284,6 @@ export class Fraction {
195
284
  return this;
196
285
  };
197
286
 
198
- // ------------------------------------------
199
- // Mathematical operations
200
287
  // ------------------------------------------
201
288
  opposed = (): Fraction => {
202
289
  this._numerator = -this._numerator;
@@ -259,6 +346,7 @@ export class Fraction {
259
346
 
260
347
  return this;
261
348
  }
349
+
262
350
  pow = (p: number | Fraction): Fraction => {
263
351
  // TODO: Fraction.pow with a value different than a safe integer !
264
352
  if (p instanceof Fraction) {
@@ -275,13 +363,13 @@ export class Fraction {
275
363
  let controlNumerator = Math.floor(Math.pow(this._numerator, Math.abs(p))),
276
364
  controlDenominator = Math.floor(Math.pow(this._denominator, Math.abs(p)))
277
365
 
278
- if(controlNumerator ** Math.abs(p) === this._numerator
366
+ if (controlNumerator ** Math.abs(p) === this._numerator
279
367
  &&
280
- controlDenominator ** Math.abs(p) === this._denominator){
368
+ controlDenominator ** Math.abs(p) === this._denominator) {
281
369
 
282
370
  this._numerator = this._numerator ** Math.abs(p);
283
371
  this._denominator = this._denominator ** Math.abs(p);
284
- }else{
372
+ } else {
285
373
  this._numerator = this._numerator ** Math.abs(p);
286
374
  this._denominator = this._denominator ** Math.abs(p);
287
375
  }
@@ -320,72 +408,9 @@ export class Fraction {
320
408
  return this;
321
409
  };
322
410
 
323
-
324
- static max = (...fractions: (Fraction | number)[]): Fraction => {
325
- let M = new Fraction(fractions[0])
326
-
327
- for (let m of fractions) {
328
- let compare = new Fraction(m)
329
- if (compare.greater(M)) {
330
- M = compare.clone()
331
- }
332
- }
333
-
334
- return M
335
- }
336
- static min = (...fractions: (Fraction | number)[]): Fraction => {
337
- let M = new Fraction(fractions[0])
338
-
339
- for (let m of fractions) {
340
- let compare = new Fraction(m)
341
- if (compare.lesser(M)) {
342
- M = compare.clone()
343
- }
344
- }
345
-
346
- return M
347
- }
348
-
349
- static average = (...fractions: (Fraction|number)[]): Fraction => {
350
- let M = new Fraction().zero()
351
-
352
- for(let f of fractions){
353
- M.add(f)
354
- }
355
-
356
- M.divide(fractions.length)
357
-
358
- return M
359
- }
360
-
361
- static unique = (fractions: Fraction[], sorted?: boolean): Fraction[] => {
362
- // TODO: make sure it's wokring -> test !
363
- let unique:{[Key:string]:boolean} = {},
364
- distinct: Fraction[] = []
365
- fractions.forEach(x => {
366
- if(!unique[x.clone().reduce().tex]){
367
- distinct.push(x.clone())
368
- unique[x.tex]=true
369
- }
370
- })
371
-
372
- if(sorted) {
373
- return Fraction.sort(distinct)
374
- }else{
375
- return distinct
376
- }
377
- }
378
- static sort = (fractions: Fraction[], reverse?:boolean): Fraction[] => {
379
- // Todo make sure it's the correct order, not reverse -> make a test
380
- let sorted = fractions.sort((a, b)=>a.value-b.value)
381
-
382
- if(reverse){sorted.reverse()}
383
-
384
- return sorted
385
- }
386
-
387
411
  // ------------------------------------------
388
412
  // Mathematical operations specific to fractions
413
+
389
414
  // ------------------------------------------
390
415
  reduce = (): Fraction => {
391
416
  let g = Numeric.gcd(this._numerator, this._denominator);