pimath 0.0.15 → 0.0.19

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 (97) hide show
  1. package/dev/index.html +39 -3
  2. package/dev/pi.js +933 -721
  3. package/dev/pi.js.map +1 -1
  4. package/dist/pi.js +1 -1
  5. package/dist/pi.js.map +1 -1
  6. package/esm/main.js +24 -22
  7. package/esm/main.js.map +1 -1
  8. package/esm/maths/algebra/equation.d.ts +3 -1
  9. package/esm/maths/algebra/equation.js +32 -25
  10. package/esm/maths/algebra/equation.js.map +1 -1
  11. package/esm/maths/algebra/index.d.ts +0 -20
  12. package/esm/maths/algebra/index.js +18 -33
  13. package/esm/maths/algebra/index.js.map +1 -1
  14. package/esm/maths/algebra/linearSystem.d.ts +1 -1
  15. package/esm/maths/algebra/linearSystem.js +19 -15
  16. package/esm/maths/algebra/linearSystem.js.map +1 -1
  17. package/esm/maths/algebra/logicalset.js +7 -3
  18. package/esm/maths/algebra/logicalset.js.map +1 -1
  19. package/esm/maths/algebra/monom.d.ts +15 -18
  20. package/esm/maths/algebra/monom.js +182 -84
  21. package/esm/maths/algebra/monom.js.map +1 -1
  22. package/esm/maths/algebra/polynom.d.ts +6 -27
  23. package/esm/maths/algebra/polynom.js +62 -218
  24. package/esm/maths/algebra/polynom.js.map +1 -1
  25. package/esm/maths/algebra/rational.js +15 -10
  26. package/esm/maths/algebra/rational.js.map +1 -1
  27. package/esm/maths/coefficients/fraction.d.ts +20 -10
  28. package/esm/maths/coefficients/fraction.js +83 -15
  29. package/esm/maths/coefficients/fraction.js.map +1 -1
  30. package/esm/maths/coefficients/index.js +14 -2
  31. package/esm/maths/coefficients/index.js.map +1 -1
  32. package/esm/maths/coefficients/nthroot.js +5 -1
  33. package/esm/maths/coefficients/nthroot.js.map +1 -1
  34. package/esm/maths/geometry/circle.d.ts +16 -1
  35. package/esm/maths/geometry/circle.js +95 -14
  36. package/esm/maths/geometry/circle.js.map +1 -1
  37. package/esm/maths/geometry/index.d.ts +0 -17
  38. package/esm/maths/geometry/index.js +17 -28
  39. package/esm/maths/geometry/index.js.map +1 -1
  40. package/esm/maths/geometry/line.d.ts +20 -4
  41. package/esm/maths/geometry/line.js +123 -49
  42. package/esm/maths/geometry/line.js.map +1 -1
  43. package/esm/maths/geometry/point.d.ts +1 -0
  44. package/esm/maths/geometry/point.js +22 -12
  45. package/esm/maths/geometry/point.js.map +1 -1
  46. package/esm/maths/geometry/triangle.js +31 -27
  47. package/esm/maths/geometry/triangle.js.map +1 -1
  48. package/esm/maths/geometry/vector.d.ts +0 -1
  49. package/esm/maths/geometry/vector.js +22 -21
  50. package/esm/maths/geometry/vector.js.map +1 -1
  51. package/esm/maths/numeric.js +5 -1
  52. package/esm/maths/numeric.js.map +1 -1
  53. package/esm/maths/random/index.d.ts +3 -1
  54. package/esm/maths/random/index.js +32 -14
  55. package/esm/maths/random/index.js.map +1 -1
  56. package/esm/maths/random/randomCore.js +5 -1
  57. package/esm/maths/random/randomCore.js.map +1 -1
  58. package/esm/maths/random/rndFraction.d.ts +9 -0
  59. package/esm/maths/random/rndFraction.js +30 -0
  60. package/esm/maths/random/rndFraction.js.map +1 -0
  61. package/esm/maths/random/rndHelpers.js +5 -1
  62. package/esm/maths/random/rndHelpers.js.map +1 -1
  63. package/esm/maths/random/rndMonom.d.ts +2 -2
  64. package/esm/maths/random/rndMonom.js +15 -8
  65. package/esm/maths/random/rndMonom.js.map +1 -1
  66. package/esm/maths/random/rndPolynom.js +14 -11
  67. package/esm/maths/random/rndPolynom.js.map +1 -1
  68. package/esm/maths/random/rndTypes.d.ts +5 -0
  69. package/esm/maths/random/rndTypes.js +2 -1
  70. package/esm/maths/shutingyard.js +5 -1
  71. package/esm/maths/shutingyard.js.map +1 -1
  72. package/package.json +5 -5
  73. package/src/maths/algebra/equation.ts +13 -7
  74. package/src/maths/algebra/index.ts +1 -17
  75. package/src/maths/algebra/linearSystem.ts +3 -3
  76. package/src/maths/algebra/monom.ts +764 -612
  77. package/src/maths/algebra/monom_bck.backup +746 -0
  78. package/src/maths/algebra/polynom.ts +977 -1176
  79. package/src/maths/algebra/rational.ts +6 -6
  80. package/src/maths/coefficients/fraction.ts +98 -27
  81. package/src/maths/geometry/circle.ts +133 -21
  82. package/src/maths/geometry/index.ts +0 -14
  83. package/src/maths/geometry/line.ts +162 -58
  84. package/src/maths/geometry/point.ts +9 -0
  85. package/src/maths/geometry/vector.ts +1 -5
  86. package/src/maths/random/index.ts +7 -1
  87. package/src/maths/random/rndFraction.ts +37 -0
  88. package/src/maths/random/rndMonom.ts +6 -3
  89. package/src/maths/random/rndPolynom.ts +0 -1
  90. package/src/maths/random/rndTypes.ts +5 -0
  91. package/src/maths/shutingyard.ts +2 -0
  92. package/tests/algebra/monom.test.ts +47 -8
  93. package/tests/algebra/polynom.test.ts +13 -22
  94. package/tests/coefficients/fraction.test.ts +35 -38
  95. package/tests/shutingyard.test.ts +0 -1
  96. package/tsconfig.json +2 -2
  97. package/tsconfig.testing.json +28 -0
@@ -131,17 +131,17 @@ import {Fraction} from "../coefficients/fraction";
131
131
 
132
132
  N.divide(D)
133
133
 
134
- if (N.degree(letter) > 0) {
135
- return N.coefficient.sign() * (Math.pow((value > 0 ? 1 : -1), N.degree(letter) % 2)) === 1 ? Infinity : -Infinity
134
+ if (N.degree(letter).isStrictlyPositive()) {
135
+ return N.coefficient.sign() * (Math.pow((value > 0 ? 1 : -1), N.degree(letter).value % 2)) === 1 ? Infinity : -Infinity
136
136
  }
137
- if (N.degree(letter) === 0) {
137
+ if (N.degree(letter).isZero()) {
138
138
  return N.coefficient
139
139
  }
140
- if (N.degree(letter) > 0) {
141
- return N.coefficient.sign() * (Math.pow(-1, N.degree(letter) % 2)) === 1 ? 0 : -0
140
+ if (N.degree(letter).isStrictlyPositive()) {
141
+ return N.coefficient.sign() * (Math.pow(-1, N.degree(letter).value % 2)) === 1 ? 0 : -0
142
142
  }
143
143
  } else {
144
- return this._numerator.evaluate({letter: value}).divide(this._denominator.evaluate({letter: value}))
144
+ return this._numerator.evaluate({letter: new Fraction(value)}).divide(this._denominator.evaluate({letter: new Fraction(value)}))
145
145
  }
146
146
  }
147
147
  }
@@ -1,4 +1,5 @@
1
1
  import {Numeric} from "../numeric";
2
+ import {Random} from "../random";
2
3
 
3
4
  export class Fraction {
4
5
  private _numerator: number;
@@ -95,8 +96,8 @@ export class Fraction {
95
96
  S = value.split('/');
96
97
 
97
98
  // Security checks
98
- if (S.length > 2) throw "Two many divide signs";
99
- if (S.map(x => x === '' || isNaN(Number(x))).includes(true)) throw "Not a number"
99
+ if (S.length > 2) throw "Two many divide signs";
100
+ if (S.map(x => x === '' || isNaN(Number(x))).includes(true)) throw "Not a number"
100
101
 
101
102
 
102
103
  if (S.length === 1) {
@@ -193,18 +194,26 @@ export class Fraction {
193
194
  return this;
194
195
  };
195
196
 
196
- add = (F: Fraction): Fraction => {
197
- let N: number = this._numerator,
198
- D: number = this._denominator;
197
+ add = (F: Fraction | number): Fraction => {
198
+ if (F instanceof Fraction) {
199
+ let N: number = this._numerator,
200
+ D: number = this._denominator;
199
201
 
200
- this._numerator = N * F.denominator + F.numerator * D;
201
- this._denominator = D * F.denominator;
202
+ this._numerator = N * F.denominator + F.numerator * D;
203
+ this._denominator = D * F.denominator;
204
+ }else{
205
+ return this.add(new Fraction(F))
206
+ }
202
207
 
203
208
  return this.reduce();
204
209
  };
205
210
 
206
- subtract = (F: Fraction): Fraction => {
207
- return this.add(F.clone().opposed());
211
+ subtract = (F: Fraction | number): Fraction => {
212
+ if (F instanceof Fraction) {
213
+ return this.add(F.clone().opposed());
214
+ } else {
215
+ return this.add(-F)
216
+ }
208
217
  };
209
218
 
210
219
  multiply = (F: Fraction | number): Fraction => {
@@ -241,10 +250,16 @@ export class Fraction {
241
250
 
242
251
  return this;
243
252
  }
244
- pow = (p: number): Fraction => {
253
+ pow = (p: number | Fraction): Fraction => {
254
+ // TODO: Fraction.pow with a value different than a safe integer ?
255
+ if (p instanceof Fraction) {
256
+ return this.pow(p.value)
257
+ }
258
+
245
259
  if (!Number.isSafeInteger(p)) {
246
260
  return this.invalid();
247
261
  }
262
+
248
263
  this.reduce();
249
264
 
250
265
  if (p < 0) {
@@ -287,6 +302,32 @@ export class Fraction {
287
302
  return this;
288
303
  };
289
304
 
305
+
306
+ static max = (...fractions: (Fraction|number)[]): Fraction => {
307
+ let M = new Fraction(fractions[0])
308
+
309
+ for (let m of fractions) {
310
+ let compare = new Fraction(m)
311
+ if (compare.greater(M)) {
312
+ M = compare.clone()
313
+ }
314
+ }
315
+
316
+ return M
317
+ }
318
+ static min = (...fractions: (Fraction|number)[]): Fraction => {
319
+ let M = new Fraction(fractions[0])
320
+
321
+ for (let m of fractions) {
322
+ let compare = new Fraction(m)
323
+ if (compare.lesser(M)) {
324
+ M = compare.clone()
325
+ }
326
+ }
327
+
328
+ return M
329
+ }
330
+
290
331
  // ------------------------------------------
291
332
  // Mathematical operations specific to fractions
292
333
  // ------------------------------------------
@@ -319,49 +360,55 @@ export class Fraction {
319
360
  * @param F (Coefficient) The coefficient to compare
320
361
  * @param sign (string| default is =): authorized values: =, <, <=, >, >= with some variations.
321
362
  */
322
- compare = (F: Fraction, sign?: string): boolean => {
363
+ compare = (F: unknown, sign?: string): boolean => {
323
364
  if (sign === undefined) {
324
365
  sign = '=';
325
366
  }
326
367
 
368
+ let compareFraction: Fraction
369
+ if (F instanceof Fraction) {
370
+ compareFraction = F.clone()
371
+ } else {
372
+ compareFraction = new Fraction(F)
373
+ }
327
374
 
328
375
  switch (sign) {
329
376
  case '>':
330
- return this.value > F.value;
377
+ return this.value > compareFraction.value;
331
378
  case ">=" || "=>" || "geq":
332
- return this.value >= F.value;
379
+ return this.value >= compareFraction.value;
333
380
  case "<":
334
- return this.value < F.value;
381
+ return this.value < compareFraction.value;
335
382
  case "<=" || "=>" || "leq":
336
- return this.value <= F.value;
383
+ return this.value <= compareFraction.value;
337
384
  case "=":
338
- // let F2: Fraction = F.clone().reduce(),
385
+ // let F2: Fraction = compareFraction.clone().reduce(),
339
386
  // F1: Fraction = this.clone().reduce();
340
387
  // return (F1.numerator === F2.numerator && F1.denominator === F2.denominator);
341
- return this.value === F.value;
388
+ return this.value === compareFraction.value;
342
389
  case "<>":
343
- return this.value !== F.value;
390
+ return this.value !== compareFraction.value;
344
391
  default:
345
392
  return false;
346
393
  }
347
394
  };
348
395
  /* Compare shortcuts */
349
- lesser = (than: Fraction): Boolean => {
396
+ lesser = (than: Fraction | number): Boolean => {
350
397
  return this.compare(than, '<');
351
398
  };
352
- leq = (than: Fraction): Boolean => {
399
+ leq = (than: Fraction | number): Boolean => {
353
400
  return this.compare(than, '<=');
354
401
  };
355
- greater = (than: Fraction): Boolean => {
402
+ greater = (than: Fraction | number): Boolean => {
356
403
  return this.compare(than, '>');
357
404
  };
358
- geq = (than: Fraction): Boolean => {
405
+ geq = (than: Fraction | number): Boolean => {
359
406
  return this.compare(than, '>=');
360
407
  };
361
- isEqual = (than: Fraction): boolean => {
408
+ isEqual = (than: Fraction | number): boolean => {
362
409
  return this.compare(than, '=');
363
410
  }
364
- isDifferent = (than: Fraction): boolean => {
411
+ isNotEqual = (than: Fraction | number): boolean => {
365
412
  return this.compare(than, '<>');
366
413
  }
367
414
  isOpposed = (p: Fraction): boolean => {
@@ -373,14 +420,26 @@ export class Fraction {
373
420
  isZero = (): boolean => {
374
421
  return this._numerator === 0;
375
422
  }
423
+ isNotZero = (): boolean => {
424
+ return this._numerator !== 0;
425
+ }
376
426
  isOne = (): boolean => {
377
427
  return this._numerator === 1 && this._denominator === 1;
378
428
  }
429
+ isNegativeOne = (): boolean => {
430
+ return this._numerator === -1 && this._denominator === 1;
431
+ }
379
432
  isPositive = (): boolean => {
380
- return this.sign()===1;
433
+ return this.sign() === 1;
381
434
  }
382
435
  isNegative = (): boolean => {
383
- return this.sign()===-1;
436
+ return this.sign() === -1;
437
+ }
438
+ isStrictlyPositive = (): boolean => {
439
+ return this.value > 0
440
+ }
441
+ isStrictlyNegative = (): Boolean => {
442
+ return this.value < 0
384
443
  }
385
444
  isNaN = (): boolean => {
386
445
  return isNaN(this._numerator);
@@ -395,7 +454,19 @@ export class Fraction {
395
454
  return Math.sqrt(this._numerator) % 1 === 0 && Math.sqrt(this._denominator) % 1 === 0
396
455
  }
397
456
  isReduced = (): boolean => {
398
- return Math.abs(Numeric.gcd(this._numerator, this._denominator))===1
457
+ return Math.abs(Numeric.gcd(this._numerator, this._denominator)) === 1
458
+ }
459
+ isNatural = (): boolean => {
460
+ return this.clone().reduce().denominator === 1
461
+ }
462
+ isRational = (): boolean => {
463
+ return !this.isNatural()
464
+ }
465
+ isEven = (): boolean => {
466
+ return this.isNatural() && this.value % 2 === 0
467
+ }
468
+ isOdd = (): boolean => {
469
+ return this.isNatural() && this.value % 2 === 1
399
470
  }
400
471
  sign = (): number => {
401
472
  return (this._numerator * this._denominator >= 0) ? 1 : -1;
@@ -1,47 +1,159 @@
1
1
  import {Point} from "./point";
2
- import {Fraction} from "../coefficients/fraction";
3
- import {Equation} from "../algebra/equation";
4
- import {Polynom} from "../algebra/polynom";
2
+ import {Fraction} from "../coefficients";
3
+ import {Equation, Monom, Polynom} from "../algebra";
4
+ import {Line} from "./line";
5
+ import {Vector} from "./vector";
5
6
 
6
7
 
7
8
  export class Circle {
8
9
  private _center: Point;
9
10
  private _radius: Fraction;
11
+ private _squareRadius: Fraction;
12
+ private _cartesian: Equation;
10
13
  private _exists: boolean;
14
+
11
15
  constructor(...values: any) {
12
16
  this._exists = false
13
17
 
14
- if(values!==undefined){this.parse(...values)}
18
+ if (values !== undefined) {
19
+ this.parse(...values)
20
+ }
15
21
  }
16
22
 
17
- private parse(...values: any) {
18
- if(values.length===2){
19
- this._center = new Point(values[0])
20
- this._radius = new Fraction(values[1])
23
+
24
+ get center(): Point {
25
+ return this._center;
26
+ }
27
+
28
+ get radius(): { tex: string, display: string } {
29
+ if (this._squareRadius.isSquare()) {
30
+ return {
31
+ tex: this._squareRadius.clone().sqrt().tex,
32
+ display: this._squareRadius.clone().sqrt().display,
33
+ }
34
+ } else {
35
+ return {
36
+ tex: `\\sqrt{${this._squareRadius.tex}}`,
37
+ display: `sqrt(${this._squareRadius.display})`
38
+ }
21
39
  }
40
+ return this._squareRadius
22
41
  }
23
42
 
24
43
  get tex(): string {
25
44
  let cx, cy
26
- if(this._center.x.isZero()){
45
+ if (this._center.x.isZero()) {
27
46
  cx = 'x^2'
28
- }else{
29
- cx = `\\left(x-${this._center.x.tex}\\right)^2`
47
+ } else {
48
+ cx = `\\left(x${this._center.x.isNegative() ? '+' : '-'}${this._center.x.clone().abs().tex}\\right)^2`
30
49
  }
31
- if(this._center.y.isZero()){
50
+ if (this._center.y.isZero()) {
32
51
  cy = 'y^2'
33
- }else{
34
- cy = `\\left(y-${this._center.y.tex}\\right)^2`
52
+ } else {
53
+ cy = `\\left(y${this._center.y.isNegative() ? '+' : '-'}${this._center.y.clone().abs().tex}\\right)^2`
54
+ }
55
+ return `${cx}+${cy}=${this._squareRadius.tex}`
56
+ }
57
+
58
+ get developed(): string {
59
+ return this._cartesian.tex
60
+ }
61
+
62
+
63
+ // TODO: reformat code for better display.
64
+ get display(): string {
65
+ return this._cartesian.display
66
+ }
67
+
68
+ get cartesian(): Equation {
69
+ return this._cartesian
70
+ }
71
+
72
+ private parse(...values: any) {
73
+ if (values.length === 1 && typeof values[0] === 'string') {
74
+ this.checkCircle(new Equation(values[0]))
75
+ } else if (values.length >= 2) {
76
+ this._center = new Point(values[0])
77
+
78
+ if (values[1] instanceof Point) {
79
+ // Go through this point
80
+ this._squareRadius = new Vector(this._center, values[1]).normSquare
81
+ } else {
82
+ if (values[2] === true) {
83
+ this._squareRadius = new Fraction(values[1])
84
+ } else {
85
+ this._radius = new Fraction(values[1])
86
+ this._squareRadius = this._radius.clone().pow(2)
87
+ }
88
+ }
89
+ this._cartesian = (new Equation(
90
+ new Polynom(`(x-(${this._center.x.display}))^2+(y-(${this._center.y.display}))^2`),
91
+ new Polynom(`${this._squareRadius.display}`)
92
+ )).moveLeft()
35
93
  }
36
- return `${cx}+${cy}=${this._radius.pow(2).tex}`
37
94
  }
38
95
 
39
- get developed():string {
40
- let equ = new Equation(
41
- new Polynom(`(x-(${this._center.x.display}))^2+(y-(${this._center.y.display}))^2`),
42
- new Polynom(`${this._radius.pow(2).display}`)
43
- )
44
96
 
45
- return equ.moveLeft().tex;
97
+ checkCircle = (P: Equation): boolean => {
98
+ if (P.degree('x').value === 2 && P.degree('y').value === 2) {
99
+ // Both must be of degree 2.
100
+ let x2 = P.left.monomByDegree(2, 'x'),
101
+ y2 = P.left.monomByDegree(2, 'y'),
102
+ x1: Monom, y1: Monom, c: Monom
103
+
104
+ // Both square monoms must have the same coefficient.
105
+ if (x2.coefficient.isEqual(y2.coefficient)) {
106
+ P.divide(x2.coefficient)
107
+
108
+ x1 = P.left.monomByDegree(1, 'x')
109
+ y1 = P.left.monomByDegree(1, 'y')
110
+
111
+ c = P.left.monomByDegree(0)
112
+
113
+ this._center = new Point(
114
+ x1.coefficient.clone().divide(2).opposed(),
115
+ y1.coefficient.clone().divide(2).opposed()
116
+ )
117
+
118
+ this._squareRadius = c.coefficient.clone().opposed()
119
+ .add(this._center.x.clone().pow(2))
120
+ .add(this._center.y.clone().pow(2))
121
+
122
+ }
123
+ }
124
+
125
+ return false
126
+ }
127
+
128
+ /**
129
+ * Get the relative position between circle and line. It corresponds to the number of intersection.
130
+ * @param {Line} L
131
+ * @returns {number}
132
+ */
133
+ relativePosition = (L: Line): number => {
134
+ let distance = L.distanceTo(this.center),
135
+ radius = Math.sqrt(this._squareRadius.value)
136
+
137
+ if (distance.value - radius > 0.0000000001) {
138
+ return 0 // external
139
+ } else if (Math.abs(distance.value - radius) < 0.0000000001) {
140
+ return 1 // tangent
141
+ } else {
142
+ return 2 // external
143
+ }
144
+ }
145
+
146
+ lineIntersection = (L: Line): Point[] => {
147
+ let P1: Point, P2: Point
148
+
149
+ const equ = this._cartesian.clone(),
150
+ yLine = L.equation.clone().isolate('y')
151
+
152
+ if (yLine instanceof Equation) {
153
+ equ.replaceBy('y', yLine.right)
154
+ equ.solve()
155
+ }
156
+
157
+ return []
46
158
  }
47
159
  }
@@ -3,17 +3,3 @@ export * from "./triangle"
3
3
  export * from "./point"
4
4
  export * from "./circle"
5
5
  export * from "./line"
6
-
7
- import {Circle as _Circle} from "./circle";
8
- import {Line as _Line} from "./line";
9
- import {Point as _Point} from "./point";
10
- import {Triangle as _Triangle} from "./triangle";
11
- import {Vector as _Vector} from "./vector";
12
-
13
- export namespace Geometry {
14
- export class Circle extends _Circle{}
15
- export class Line extends _Line{}
16
- export class Point extends _Point{}
17
- export class Triangle extends _Triangle{}
18
- export class Vector extends _Vector{}
19
- }