pimath 0.0.28 → 0.0.32

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 (96) hide show
  1. package/dev/pi.js +864 -487
  2. package/dev/pi.js.map +1 -1
  3. package/dist/pi.js +1 -1
  4. package/dist/pi.js.map +1 -1
  5. package/docs/assets/search.js +1 -1
  6. package/docs/classes/algebra.Equation.html +9 -9
  7. package/docs/classes/algebra.LinearSystem.html +1 -1
  8. package/docs/classes/algebra.Logicalset.html +2 -2
  9. package/docs/classes/algebra.Monom.html +42 -40
  10. package/docs/classes/algebra.Polynom.html +10 -10
  11. package/docs/classes/algebra.PolynomExpFactor.html +1 -0
  12. package/docs/classes/algebra.PolynomExpProduct.html +1 -0
  13. package/docs/classes/algebra.Rational.html +2 -2
  14. package/docs/classes/coefficients.Fraction.html +4 -4
  15. package/docs/classes/coefficients.Nthroot.html +1 -1
  16. package/docs/classes/geometry.Circle.html +2 -2
  17. package/docs/classes/geometry.Line.html +2 -2
  18. package/docs/classes/geometry.Point.html +1 -1
  19. package/docs/classes/geometry.Triangle.html +6 -6
  20. package/docs/classes/geometry.Vector.html +1 -1
  21. package/docs/classes/numeric.Numeric.html +5 -5
  22. package/docs/classes/shutingyard.Shutingyard.html +7 -8
  23. package/docs/enums/shutingyard.ShutingyardMode.html +1 -0
  24. package/docs/enums/shutingyard.ShutingyardType.html +1 -0
  25. package/docs/index.html +1 -1
  26. package/docs/interfaces/geometry.remarquableLines.html +1 -1
  27. package/docs/modules/algebra.html +1 -1
  28. package/docs/modules/coefficients.html +1 -1
  29. package/docs/modules/geometry.html +1 -1
  30. package/docs/modules/numeric.html +1 -1
  31. package/docs/modules/random.Random.html +1 -1
  32. package/docs/modules/random.html +1 -1
  33. package/docs/modules/shutingyard.html +1 -1
  34. package/docs/modules.html +1 -1
  35. package/esm/main.js +3 -1
  36. package/esm/main.js.map +1 -1
  37. package/esm/maths/algebra/equation.js +1 -1
  38. package/esm/maths/algebra/equation.js.map +1 -1
  39. package/esm/maths/algebra/index.d.ts +1 -0
  40. package/esm/maths/algebra/index.js +1 -0
  41. package/esm/maths/algebra/index.js.map +1 -1
  42. package/esm/maths/algebra/monom.d.ts +4 -1
  43. package/esm/maths/algebra/monom.js +52 -37
  44. package/esm/maths/algebra/monom.js.map +1 -1
  45. package/esm/maths/algebra/polynom.d.ts +19 -15
  46. package/esm/maths/algebra/polynom.js +242 -174
  47. package/esm/maths/algebra/polynom.js.map +1 -1
  48. package/esm/maths/coefficients/fraction.d.ts +3 -0
  49. package/esm/maths/coefficients/fraction.js +21 -8
  50. package/esm/maths/coefficients/fraction.js.map +1 -1
  51. package/esm/maths/{numexp.d.ts → expressions/numexp.d.ts} +3 -0
  52. package/esm/maths/{numexp.js → expressions/numexp.js} +46 -15
  53. package/esm/maths/expressions/numexp.js.map +1 -0
  54. package/esm/maths/expressions/polynomexp.bkp.d.ts +33 -0
  55. package/esm/maths/expressions/polynomexp.bkp.js +186 -0
  56. package/esm/maths/expressions/polynomexp.bkp.js.map +1 -0
  57. package/esm/maths/expressions/polynomexp.d.ts +52 -0
  58. package/esm/maths/expressions/polynomexp.js +233 -0
  59. package/esm/maths/expressions/polynomexp.js.map +1 -0
  60. package/esm/maths/geometry/line.d.ts +4 -2
  61. package/esm/maths/geometry/line.js +6 -2
  62. package/esm/maths/geometry/line.js.map +1 -1
  63. package/esm/maths/geometry/vector.js +7 -2
  64. package/esm/maths/geometry/vector.js.map +1 -1
  65. package/esm/maths/shutingyard.d.ts +7 -7
  66. package/esm/maths/shutingyard.js +5 -7
  67. package/esm/maths/shutingyard.js.map +1 -1
  68. package/package.json +1 -1
  69. package/{dev → public}/demo.css +0 -0
  70. package/{dev → public}/index.html +48 -14
  71. package/{dev → public}/playground.html +1 -1
  72. package/src/main.ts +13 -2
  73. package/src/maths/algebra/equation.ts +1 -1
  74. package/src/maths/algebra/index.ts +2 -1
  75. package/src/maths/algebra/monom.ts +71 -49
  76. package/src/maths/algebra/polynom.ts +432 -309
  77. package/src/maths/coefficients/fraction.ts +28 -11
  78. package/src/maths/{numexp.ts → expressions/numexp.ts} +42 -20
  79. package/src/maths/expressions/polynomexp.bkp.ts +223 -0
  80. package/src/maths/expressions/polynomexp.ts +309 -0
  81. package/src/maths/geometry/line.ts +7 -2
  82. package/src/maths/geometry/vector.ts +10 -2
  83. package/src/maths/shutingyard.ts +15 -64
  84. package/tests/algebra/monom.test.ts +12 -8
  85. package/tests/algebra/polynom.test.ts +28 -2
  86. package/tests/numexp.test.ts +34 -0
  87. package/tests/polynomexp.test.ts +15 -0
  88. package/tests/shutingyard.test.ts +4 -4
  89. package/tsconfig.json +0 -1
  90. package/esm/docs.d.ts +0 -6
  91. package/esm/docs.js +0 -7
  92. package/esm/docs.js.map +0 -1
  93. package/esm/maths/numexp.js.map +0 -1
  94. package/esm/maths/random/random.d.ts +0 -13
  95. package/esm/maths/random/random.js +0 -27
  96. package/esm/maths/random/random.js.map +0 -1
@@ -0,0 +1,309 @@
1
+ import {Polynom, PolynomParsingType} from "../algebra";
2
+ import {Fraction, FractionParsingType} from "../coefficients";
3
+
4
+ type PolynomExpMathFunctionType = { name: string; fn: Function, tex: string }
5
+
6
+ export class PolynomExpFactor {
7
+ constructor(polynom: PolynomParsingType, degree?: FractionParsingType, mathFunction?: PolynomExpMathFunctionType) {
8
+ this._polynom = new Polynom(polynom)
9
+ this._degree = new Fraction(degree === undefined ? 1 : degree)
10
+ this._fn = mathFunction
11
+ this._powerAsInteger = true
12
+ this._forceParenthesis = true
13
+ }
14
+
15
+ private _forceParenthesis: boolean
16
+
17
+ get forceParenthesis(): boolean {
18
+ return this._forceParenthesis;
19
+ }
20
+
21
+ set forceParenthesis(value: boolean) {
22
+ this._forceParenthesis = value;
23
+ }
24
+
25
+ private _fn: PolynomExpMathFunctionType
26
+
27
+ get fn(): PolynomExpMathFunctionType {
28
+ return this._fn;
29
+ }
30
+
31
+ set fn(value: PolynomExpMathFunctionType) {
32
+ this._fn = value;
33
+ }
34
+
35
+ private _powerAsInteger: boolean
36
+
37
+ get powerAsInteger(): boolean {
38
+ return this._powerAsInteger;
39
+ }
40
+
41
+ set powerAsInteger(value: boolean) {
42
+ this._powerAsInteger = value;
43
+ }
44
+
45
+ private _polynom: Polynom
46
+
47
+ get polynom(): Polynom {
48
+ return this._polynom;
49
+ }
50
+
51
+ set polynom(value: Polynom) {
52
+ this._polynom = value;
53
+ }
54
+
55
+ private _degree: Fraction
56
+
57
+ get degree(): Fraction {
58
+ return this._degree;
59
+ }
60
+
61
+ set degree(value: Fraction) {
62
+ this._degree = value;
63
+ }
64
+
65
+ get tex(): string {
66
+ let tex
67
+
68
+ if (this._degree.isOne() && (this._fn !== undefined || !this._forceParenthesis)) {
69
+ // If degree is one, no need to add the parenthesis.
70
+ tex = this._polynom.tex
71
+ } else {
72
+ // the degree is not one, add the parenthesis.
73
+ if (this._powerAsInteger && !this._degree.isRelative()) {
74
+ // the degree is a fraction and we want natural powers => use sqrt.
75
+ tex = `\\sqrt${this._degree.denominator !== 2 ? `[ ${this._degree.denominator} ]` : ''}{ ${this._polynom.tex} }^{ ${this._degree.numerator} }`
76
+ } else if (this.isCoefficient && this.firstCoefficient.isNatural()) {
77
+ // the value is a natural number (eg 3, 7, ...)
78
+ tex = this._polynom.tex + this._texDegree
79
+ } else {
80
+ // In any other case, add the parenthesis by default
81
+ tex = `\\left( ${this._polynom.tex} \\right)${this._texDegree}`
82
+ }
83
+ }
84
+
85
+ if (this._fn !== undefined && this._fn.tex !== undefined) {
86
+ tex = `${this._fn.tex}\\left( ${tex} \\right)`
87
+ }
88
+ return tex
89
+ }
90
+
91
+ get isCoefficient(): boolean {
92
+ // TODO: Maybe reduce the coefficient if it isn't of degree one.
93
+ return this._polynom.degree().isZero();
94
+
95
+ }
96
+
97
+ get firstCoefficient(): Fraction {
98
+ return this._polynom.monomByDegree().coefficient
99
+ }
100
+
101
+ private get _texDegree(): string {
102
+ if (this._degree.isOne()) {
103
+ return ''
104
+ } else {
105
+ return `^{ ${this._degree.tfrac} }`
106
+ }
107
+ }
108
+
109
+ setForceParenthesis(value?: boolean): PolynomExpFactor {
110
+ this._forceParenthesis = value === undefined || value
111
+ return this
112
+ }
113
+
114
+ derivative(letter?: string): PolynomExpProduct {
115
+ if (this._degree.isOne()) {
116
+ return new PolynomExpProduct(
117
+ new PolynomExpFactor(this._polynom.clone().derivative(letter))
118
+ )
119
+ } else {
120
+ return new PolynomExpProduct(
121
+ new PolynomExpFactor(this._degree.clone()),
122
+ new PolynomExpFactor(this._polynom.clone().derivative(letter)),
123
+ new PolynomExpFactor(this._polynom.clone(), this._degree.clone().subtract(1))
124
+ )
125
+ }
126
+ }
127
+ }
128
+
129
+ export class PolynomExpProduct {
130
+ constructor(...values: PolynomExpFactor[]) {
131
+ this._factors = values || []
132
+ this._positive = true
133
+ this._asPositiveDegree = true
134
+ }
135
+
136
+ private _fn: PolynomExpMathFunctionType
137
+
138
+ get fn(): PolynomExpMathFunctionType {
139
+ return this._fn;
140
+ }
141
+
142
+ set fn(value: PolynomExpMathFunctionType) {
143
+ this._fn = value;
144
+ }
145
+
146
+ private _factors: PolynomExpFactor[]
147
+
148
+ get factors(): PolynomExpFactor[] {
149
+ return this._factors;
150
+ }
151
+
152
+ set factors(value: PolynomExpFactor[]) {
153
+ this._factors = value;
154
+ }
155
+
156
+ private _positive: boolean
157
+
158
+ get positive(): boolean {
159
+ return this._positive;
160
+ }
161
+
162
+ set positive(value: boolean) {
163
+ this._positive = value;
164
+ }
165
+
166
+ private _asPositiveDegree: boolean
167
+
168
+ get asPositiveDegree(): boolean {
169
+ return this._asPositiveDegree;
170
+ }
171
+
172
+ set asPositiveDegree(value: boolean) {
173
+ this._asPositiveDegree = value;
174
+ }
175
+
176
+ get tex(): string {
177
+ let parenthesis = this._factors.length>1
178
+ // Default value
179
+ let tex = this._factors.map(factor => factor.setForceParenthesis(parenthesis).tex).join(' \\cdot ')
180
+
181
+ // Change the value in some cases...
182
+ if (this._asPositiveDegree) {
183
+ const numerators = this._factors.filter(x => x.degree.isPositive()),
184
+ denominators = this._factors.filter(x => x.degree.isNegative())
185
+
186
+ let numeratorsAsTex, denominatorsAsTex
187
+
188
+ if (denominators.length > 0) {
189
+ if (numerators.length === 0) {
190
+ numeratorsAsTex = [1]
191
+ } else if (numerators.length === 1) {
192
+ numeratorsAsTex = [numerators[0].setForceParenthesis(false).tex]
193
+ } else {
194
+ parenthesis = numerators.length>1
195
+ numeratorsAsTex = numerators.map(factor => factor.setForceParenthesis(parenthesis).tex)
196
+ }
197
+
198
+ // Change all denominators degrees to positive.
199
+ denominators.map(x => x.degree.opposed())
200
+ if (denominators.length === 1) {
201
+ denominatorsAsTex = [denominators[0].setForceParenthesis(false).tex]
202
+ } else {
203
+ parenthesis = denominators.length>1
204
+ denominatorsAsTex = denominators.map(factor => factor.setForceParenthesis(parenthesis).tex)
205
+ }
206
+ // restore all degrees to negative again.
207
+ denominators.map(x => x.degree.opposed())
208
+
209
+ tex = `\\dfrac{ ${numeratorsAsTex.join(' \\cdot ')} }{ ${denominatorsAsTex.join(' \\cdot ')} }`
210
+ }
211
+ }
212
+
213
+ // Apply the modification
214
+ if (this._fn !== undefined && this._fn.name !== undefined && this._fn.name !== '') {
215
+ tex = `${this._fn.tex}\\left( ${tex} \\right)`
216
+ }
217
+ return tex
218
+ }
219
+
220
+ reduce(): PolynomExpProduct {
221
+ let coefficients = this._factors.filter(factor => factor.isCoefficient),
222
+ polynoms = this._factors.filter(factor => !factor.isCoefficient)
223
+
224
+ let result = new Fraction().one()
225
+
226
+ if (coefficients.length > 1) {
227
+ for (const factor of coefficients) {
228
+ if (factor.degree.isPositive()) {
229
+ result.multiply(factor.polynom.monoms[0].coefficient.pow(factor.degree))
230
+ } else {
231
+ result.divide(factor.polynom.monoms[0].coefficient.pow(factor.degree.clone().abs()))
232
+ }
233
+ }
234
+ } else if (coefficients.length === 1) {
235
+ result = coefficients[0].polynom.monoms[0].coefficient
236
+ }
237
+
238
+ if (result.isOne()) {
239
+ this._factors = [...polynoms]
240
+ } else if (!result.isRelative()) {
241
+ this._factors = [
242
+ new PolynomExpFactor(result.numerator),
243
+ new PolynomExpFactor(result.denominator, -1),
244
+ ...polynoms
245
+ ]
246
+ } else {
247
+ this._factors = [
248
+ new PolynomExpFactor(result),
249
+ ...polynoms
250
+ ]
251
+ }
252
+ return this
253
+ }
254
+
255
+ integrate(letter?: string): PolynomExpProduct {
256
+ // Handle this kind of case:
257
+ // A * f' * F^n
258
+ // A * f' / F^n, n != 1
259
+ // A * f_1 * f_2 * f_3, where (f_1 * f_2)' = f_3
260
+ if (this._factors.length === 2) {
261
+ // Check polynoms degree: one must of one degree less than the other.
262
+ let d1 = this._factors[0].polynom.degree(letter).value,
263
+ d2 = this._factors[1].polynom.degree(letter).value
264
+
265
+ if (d1 === d2 + 1) {
266
+ return this._integrateWithInternalDerivative(this._factors[0], this._factors[1], letter)
267
+ } else if (d1 + 1 === d2) {
268
+ return this._integrateWithInternalDerivative(this._factors[1], this._factors[0], letter)
269
+ }
270
+ }
271
+ return
272
+ }
273
+
274
+ public applyMathFunction(mathFn: PolynomExpMathFunctionType): PolynomExpProduct {
275
+ this._fn = mathFn
276
+ return this
277
+ }
278
+
279
+ private _integrateWithInternalDerivative(P: PolynomExpFactor, Pinternal: PolynomExpFactor, letter?: string): PolynomExpProduct {
280
+ // Get the internal derivative
281
+ let internalDerivative: Polynom = P.polynom.clone().derivative(letter)
282
+
283
+ // Get the factor.
284
+ let {quotient, reminder} = Pinternal.polynom.clone().euclidian(internalDerivative)
285
+
286
+ if (reminder.isZero() && quotient.degree(letter).isZero()) {
287
+ // All the conditions are done. Actual situation is
288
+ // (4x-10)(x^2-5x+7)^9
289
+ // P1 = (x^2-5x+7), P2 = (2x-5)
290
+ // => 1/10 * quotient * (x^2-5x+7)^10
291
+
292
+ if (P.degree.isEqual(-1)) {
293
+ return (new PolynomExpProduct(
294
+ new PolynomExpFactor(quotient, 1),
295
+ new PolynomExpFactor(P.polynom.clone(), 1, {
296
+ name: 'ln', tex: '\\ln', fn: (x: number) => Math.log(x)
297
+ })
298
+ ))
299
+ } else {
300
+ return new PolynomExpProduct(
301
+ new PolynomExpFactor(P.degree.clone().add(1).invert(), 1),
302
+ new PolynomExpFactor(quotient, 1),
303
+ new PolynomExpFactor(P.polynom.clone(), P.degree.clone().add(1))
304
+ )
305
+ }
306
+ }
307
+ return
308
+ }
309
+ }
@@ -10,8 +10,9 @@ import {Numeric} from "../numeric";
10
10
 
11
11
  enum LinePropriety {
12
12
  None,
13
- Parallel,
14
- Perpendicular
13
+ Parallel='parallel',
14
+ Perpendicular = 'perpendicular',
15
+ Tangent = 'tangent'
15
16
  }
16
17
 
17
18
  export class Line {
@@ -312,6 +313,9 @@ export class Line {
312
313
  isSameAs = (line: Line): Boolean => {
313
314
  return this.slope.isEqual(line.slope) && this.height.isEqual(line.height);
314
315
  }
316
+ isVertical = (): Boolean => {
317
+ return this.slope.isInfinity()
318
+ }
315
319
  simplify = (): Line => {
316
320
  let lcm = Numeric.lcm(this._a.denominator, this._b.denominator, this._c.denominator),
317
321
  gcd = Numeric.gcd(this._a.numerator, this._b.numerator, this._c.numerator);
@@ -429,6 +433,7 @@ export class Line {
429
433
  }
430
434
 
431
435
  getValueAtX = (value: Fraction|number): Fraction => {
436
+
432
437
  const equ = this.equation.clone().isolate('y'),
433
438
  F = new Fraction(value)
434
439
 
@@ -81,12 +81,20 @@ export class Vector {
81
81
  }
82
82
 
83
83
  // Fractions or a number are give
84
- if (values[0].isFraction || !isNaN(values[0])) {
84
+ if (values[0] instanceof Fraction || !isNaN(values[0])) {
85
85
  this._x = new Fraction(values[0])
86
86
  }
87
- if (values[1].isFraction || !isNaN(values[1])) {
87
+ if (values[1] instanceof Fraction || !isNaN(values[1])) {
88
88
  this._y = new Fraction(values[1])
89
89
  }
90
+
91
+ if(
92
+ (typeof values[0] === 'object' && !isNaN(values[0].x) && !isNaN(values[0].x)) &&
93
+ (typeof values[1] === 'object' && !isNaN(values[1].x) && !isNaN(values[1].x))
94
+ ){
95
+ this._x = new Fraction(+values[1].x-values[0].x)
96
+ this._y = new Fraction(+values[1].y-values[0].y)
97
+ }
90
98
  }
91
99
 
92
100
  return this;
@@ -1,7 +1,7 @@
1
1
  import {loadHighlighter} from "typedoc/dist/lib/utils/highlighter";
2
2
  import exp = require("constants");
3
3
 
4
- type tokenType = {
4
+ export type tokenType = {
5
5
  [key: string]: {
6
6
  precedence: number,
7
7
  associative: string,
@@ -13,6 +13,7 @@ export const tokenConstant:{[Key:string]:number} = {
13
13
  pi: Math.PI,
14
14
  e: Math.exp(1)
15
15
  }
16
+
16
17
  export enum ShutingyardType {
17
18
  VARIABLE='variable',
18
19
  COEFFICIENT='coefficient',
@@ -21,14 +22,17 @@ export enum ShutingyardType {
21
22
  FUNCTION = 'function',
22
23
  MONOM = 'monom'
23
24
  }
25
+
24
26
  export enum ShutingyardMode {
25
27
  POLYNOM= 'polynom',
26
28
  SET = 'set',
27
29
  NUMERIC = 'numeric'
28
30
  }
29
31
 
32
+ export type Token = { token: string, tokenType: string }
33
+
30
34
  export class Shutingyard {
31
- private _rpn: { token: string, tokenType: string }[] = [];
35
+ private _rpn: Token[] = [];
32
36
  readonly _mode: ShutingyardMode;
33
37
  private _tokenConfig: tokenType;
34
38
  private _tokenConstant: {[Key:string]: number}
@@ -77,7 +81,9 @@ export class Shutingyard {
77
81
  'sin': {precedence: 4, associative: 'right', type: ShutingyardType.FUNCTION},
78
82
  'cos': {precedence: 4, associative: 'right', type: ShutingyardType.FUNCTION},
79
83
  'tan': {precedence: 4, associative: 'right', type: ShutingyardType.FUNCTION},
84
+ 'sqrt': {precedence: 4, associative: 'right', type: ShutingyardType.FUNCTION},
80
85
  }
86
+ this._uniformize = false
81
87
  } else {
82
88
  this._tokenConfig = {
83
89
  '^': {precedence: 4, associative: 'right', type: ShutingyardType.OPERATION},
@@ -85,10 +91,10 @@ export class Shutingyard {
85
91
  '/': {precedence: 3, associative: 'left', type: ShutingyardType.OPERATION},
86
92
  '+': {precedence: 2, associative: 'left', type: ShutingyardType.OPERATION},
87
93
  '-': {precedence: 2, associative: 'left', type: ShutingyardType.OPERATION},
88
- '%': {precedence: 3, associative: 'right', type: ShutingyardType.OPERATION},
89
- 'sin': {precedence: 4, associative: 'right', type: ShutingyardType.FUNCTION},
90
- 'cos': {precedence: 4, associative: 'right', type: ShutingyardType.FUNCTION},
91
- 'tan': {precedence: 4, associative: 'right', type: ShutingyardType.FUNCTION},
94
+ // '%': {precedence: 3, associative: 'right', type: ShutingyardType.OPERATION},
95
+ // 'sin': {precedence: 4, associative: 'right', type: ShutingyardType.FUNCTION},
96
+ // 'cos': {precedence: 4, associative: 'right', type: ShutingyardType.FUNCTION},
97
+ // 'tan': {precedence: 4, associative: 'right', type: ShutingyardType.FUNCTION},
92
98
  }
93
99
  this._uniformize = true
94
100
  }
@@ -102,7 +108,7 @@ export class Shutingyard {
102
108
  * @param expr (string) Expression to analyse
103
109
  * @param start (number) CUrrent position in the expr string.
104
110
  */
105
- NextToken2(expr: string, start: number): [string, number, string] {
111
+ NextToken(expr: string, start: number): [string, number, string] {
106
112
  let token: string, tokenType: string;
107
113
  token = '';
108
114
  tokenType = '';
@@ -146,7 +152,7 @@ export class Shutingyard {
146
152
  if(token===''){
147
153
  // No function found ! Might be a coefficient !
148
154
  if( expr[start].match(/[0-9]/) ) {
149
- if(this._mode === ShutingyardMode.POLYNOM) {
155
+ if(this._mode === ShutingyardMode.POLYNOM && false) {
150
156
  token = expr.substring(start).match(/^([0-9.,/]+)/)[0]
151
157
  }else{
152
158
  token = expr.substring(start).match(/^([0-9.,]+)/)[0]
@@ -167,61 +173,6 @@ export class Shutingyard {
167
173
  return [token, start + token.length, tokenType];
168
174
  }
169
175
 
170
- // NextToken(expr: string, start: number): [string, number, string] {
171
- // let tokenMatch: string[], token: string, tokenType: string;
172
- //
173
- // this.NextToken2(expr, start)
174
- // // Detect a fraction monoms or return empty array
175
- // tokenMatch = (expr.substring(start).match(/^[0-9/a-zA-Z^]+/g)) || [];
176
- //
177
- // if (expr.substring(start, start + 3).match(/^(sin|cos|tan)/g)) {
178
- // token = expr.substring(start, start+3)
179
- // tokenType = 'function'
180
- // } else if (tokenMatch.length > 0) {
181
- // token = tokenMatch[0];
182
- // tokenType = 'monom';
183
- // }
184
- // // It's an operation !
185
- // else if (expr[start].match(/[+\-*/^]/g)) {
186
- // token = expr[start];
187
- // tokenType = 'operation';
188
- // } else if (expr[start].match(/[&|!]/g)) {
189
- // token = expr[start];
190
- // tokenType = 'operation';
191
- // }
192
- // // It's an opening parenthese
193
- // else if (expr[start] === '(') {
194
- // token = '(';
195
- // tokenType = '(';
196
- // }
197
- // // It's a closing parenthese
198
- // else if (expr[start] === ')') {
199
- // token = ')';
200
- // tokenType = ')';
201
- // }
202
- // // It's an argument separator for a function
203
- // else if (expr[start] === ',') {
204
- // token = ',';
205
- // tokenType = 'function-argument';
206
- // }
207
- // // It's a monom.
208
- // else {
209
- // // TODO: Actually, negative exposant aren't supported.
210
- // // token = (expr.substring(start).match(/^[\da-z\^]+/g)[0])||'';
211
- // token = tokenMatch[0];
212
- // tokenType = 'monom';
213
- //
214
- // if (token === '') {
215
- // token = expr[start];
216
- // tokenType = 'monom';
217
- // console.log('SHUTING YARD - NEXT TOKEN: error at ', start);
218
- // }
219
- // }
220
- //
221
- // // console.log(token, start + token.length, tokenType);
222
- // return [token, start + token.length, tokenType];
223
- // }
224
-
225
176
  /**
226
177
  * Sanitize an expression by adding missing common operation (multiplication between parentheseses)
227
178
  * @param expr
@@ -290,7 +241,7 @@ export class Shutingyard {
290
241
  }
291
242
 
292
243
  // Get the next token and the corresponding new (ending) position
293
- [token, tokenPos, tokenType] = this.NextToken2(expr, tokenPos);
244
+ [token, tokenPos, tokenType] = this.NextToken(expr, tokenPos);
294
245
 
295
246
  switch (tokenType) {
296
247
  case 'monom':
@@ -3,8 +3,10 @@ import {Monom} from "../../src/maths/algebra";
3
3
  import {Random} from "../../src/maths/random";
4
4
  import {describe} from "mocha";
5
5
  import {Fraction} from "../../src/maths/coefficients";
6
+ import {Shutingyard} from "../../src/maths/shutingyard";
7
+ import {log} from "util";
6
8
 
7
- describe('Monom tests', () => {
9
+ describe('Monom with integer power', () => {
8
10
  it('parsing', () => {
9
11
  const M0a = new Monom('3');
10
12
  expect(M0a.tex).to.be.equal('3')
@@ -25,10 +27,10 @@ describe('Monom tests', () => {
25
27
  expect(M3.tex).to.be.equal('-3x^{-2}')
26
28
 
27
29
  const M4 = new Monom('3x^(2/3)')
28
- expect(M4.tex).to.be.equal('3x^{2/3}')
30
+ expect(M4.tex).to.be.equal('3x^{\\tfrac{ 2 }{ 3 }}')
29
31
 
30
32
  const M5 = new Monom('-3x^(-2/3)y^(-5)8x^3')
31
- expect(M5.tex).to.be.equal('-24x^{7/3}y^{-5}')
33
+ expect(M5.tex).to.be.equal('-24x^{\\tfrac{ 7 }{ 3 }}y^{-5}')
32
34
  })
33
35
 
34
36
  it('basic operations', () => {
@@ -66,15 +68,17 @@ describe('Monom tests', () => {
66
68
  });
67
69
  })
68
70
 
69
- describe('Monom as numerical expression WIP', () => {
71
+ describe('Monom with fraction power', () => {
70
72
  it('should create a numerical expression', () => {
71
- let M = new Monom()
73
+ const inputStr: string = '-1/5x^(2/3)'
74
+ const M = new Monom(inputStr),
75
+ N = new Monom('7x^(4/5)')
72
76
 
73
- M.coefficient = new Fraction(3, 7)
74
- M.setLetter('3', new Fraction(0.5).reduce())
77
+ M.multiply(N.clone())
75
78
 
76
79
  console.log(M.tex)
80
+
77
81
  // TODO: Problem while displaying numerical expression
78
- console.log(M.display)
82
+ expect(M.tex).to.be.equal('-\\dfrac{ 7 }{ 5 }x^{\\tfrac{ 22 }{ 15 }}')
79
83
  })
80
84
  })
@@ -3,6 +3,7 @@ import {Fraction} from "../../src/maths/coefficients";
3
3
  import {Monom, Polynom} from "../../src/maths/algebra";
4
4
  import {Random} from "../../src/maths/random";
5
5
  import {describe} from "mocha";
6
+ import {Shutingyard} from "../../src/maths/shutingyard";
6
7
 
7
8
  describe('Polynom tests', () => {
8
9
  it('Parse polynom', () => {
@@ -11,6 +12,13 @@ describe('Polynom tests', () => {
11
12
  expect(options.tex).to.be.equal('2x^{4}+10x^{3}+6x^{2}-18x');
12
13
  });
13
14
 
15
+ it('Parse polynom with coefficient as fraction', ()=>{
16
+ const P = new Polynom('-3/5x-2')
17
+
18
+ console.log(P.tex)
19
+ expect(P.tex).to.be.equal('-\\dfrac{ 3 }{ 5 }x-2')
20
+ })
21
+
14
22
  it('Tex display', () => {
15
23
  const options = new Polynom('x^2-2x+1');
16
24
  expect(options.tex).to.be.equal('x^{2}-2x+1');
@@ -36,7 +44,7 @@ describe('Polynom tests', () => {
36
44
  expect(F.integrate(0, 2).value).to.be.equal(-4)
37
45
  expect(G.integrate(-3, 3).display).to.be.equal('174/5')
38
46
  })
39
- it('Random Polynom of degree 5', function () {
47
+ it('Random Polynom of degree 5', () => {
40
48
  let P = Random.polynom({
41
49
  degree: 6,
42
50
  numberOfMonoms: 3,
@@ -50,7 +58,7 @@ describe('Polynom tests', () => {
50
58
  expect(P.degree().value).to.be.equal(6)
51
59
  });
52
60
 
53
- it('should calculate correctly the quotient and reminder', function () {
61
+ it('should calculate correctly the quotient and reminder', () => {
54
62
  let P = new Polynom('(x-3)(x^2+5x-4)+12'),
55
63
  D = new Polynom('x-3')
56
64
 
@@ -60,3 +68,21 @@ describe('Polynom tests', () => {
60
68
  expect(euclidian.reminder.tex).to.be.equal('12')
61
69
  });
62
70
  })
71
+
72
+ describe('Polynom parsing with rational power', ()=>{
73
+ it('should parse with rational powers', ()=> {
74
+ const P = new Polynom('3x^(2/3)-5x+5/3');
75
+
76
+ expect(P.tex).to.be.equal('3x^{\\tfrac{ 2 }{ 3 }}-5x+\\dfrac{ 5 }{ 3 }')
77
+ })
78
+ })
79
+
80
+
81
+ // TODO: working with roots !
82
+ // describe('WIP : working with roots', ()=>{
83
+ // it('should parse with roots coefficient', ()=>{
84
+ // let P = new Polynom('sqrt(x)-5')
85
+ //
86
+ // expect(P.degree().value).to.be.equal(0.5)
87
+ // })
88
+ // })
@@ -0,0 +1,34 @@
1
+ import {expect} from 'chai';
2
+ import {NumExp} from "../src/maths/expressions/numexp";
3
+ import exp = require("constants");
4
+
5
+ describe('Numerical expression', () => { // the tests container
6
+ it('RPN for numerical expression', () => {
7
+ const RPN = new NumExp('3*x+5').rpn
8
+ expect(RPN.map(x => x.token)).to.have.all.members(['3', 'x', '*', '5', '+'])
9
+
10
+ const RPN2 = new NumExp('-3*x^2-5').rpn
11
+ expect(RPN2.map(x=>x.token)).to.have.all.members(['3', 'x', '2', '^', '*', '-', '5', '-'])
12
+ })
13
+
14
+ it('Evaluate for numerical expression', () => {
15
+ const expr = new NumExp('3*x+5')
16
+ expect(expr.evaluate({x: 5})).to.be.equal(20)
17
+
18
+ const expr2 = new NumExp('-3*x^2-5')
19
+ expect(expr2.evaluate({x: -2})).to.be.equal(-17)
20
+ })
21
+
22
+ it('Evaluation simple mathematical functions', () => {
23
+ const expr = new NumExp('sqrt(x)')
24
+ expect(expr.evaluate({x: 9})).to.be.equal(3)
25
+ })
26
+
27
+ it('should detect invalid rpn parsing', function () {
28
+ const exprValid = new NumExp('3*sin(x)'),
29
+ exprInvalid = new NumExp('3*sin')
30
+
31
+ expect(exprValid.isValid).to.be.true
32
+ expect(exprInvalid.isValid).to.be.false
33
+ });
34
+ });
@@ -0,0 +1,15 @@
1
+ import {describe} from "mocha";
2
+ import {PolynomExpFactor, PolynomExpProduct} from "../src/maths/expressions/polynomexp";
3
+
4
+ describe('PolynomExpression concepts', () => {
5
+ it('should display tex', function () {
6
+ const F1 = new PolynomExpFactor('2x-5', 2.5),
7
+ F2 = new PolynomExpFactor('2-x', 0.5),
8
+ PP = new PolynomExpProduct(F1, F2)
9
+
10
+ const D = F1.derivative()
11
+
12
+ console.log(D.tex)
13
+ console.log(D.reduce().tex)
14
+ });
15
+ })