pimath 0.1.39 → 0.2.0

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/dist/pimath.js +3127 -2865
  2. package/dist/pimath.js.map +1 -1
  3. package/package.json +16 -12
  4. package/src/algebra/equation.ts +558 -0
  5. package/src/algebra/equationSolver.ts +488 -0
  6. package/src/algebra/factor.ts +338 -0
  7. package/src/algebra/index.ts +11 -0
  8. package/src/algebra/linearSystem.ts +439 -0
  9. package/src/algebra/logicalset.ts +255 -0
  10. package/src/algebra/matrix.ts +474 -0
  11. package/src/algebra/monom.ts +977 -0
  12. package/src/algebra/operations.ts +23 -0
  13. package/src/algebra/polyFactor.ts +668 -0
  14. package/src/algebra/polynom.ts +1247 -0
  15. package/src/analyze/index.ts +4 -0
  16. package/src/analyze/solution.ts +178 -0
  17. package/src/analyze/tableOfSigns.ts +30 -0
  18. package/src/coefficients/fraction.ts +718 -0
  19. package/src/coefficients/index.ts +4 -0
  20. package/src/coefficients/root.ts +346 -0
  21. package/src/geometry/TupleN.ts +128 -0
  22. package/src/geometry/circle.ts +456 -0
  23. package/src/geometry/geomMath.ts +71 -0
  24. package/src/geometry/index.ts +11 -0
  25. package/src/geometry/line.ts +653 -0
  26. package/src/geometry/line3.ts +211 -0
  27. package/src/geometry/plane3.ts +179 -0
  28. package/src/geometry/point.ts +104 -0
  29. package/src/geometry/sphere3.ts +214 -0
  30. package/src/geometry/triangle.ts +482 -0
  31. package/src/geometry/vector.ts +225 -0
  32. package/src/helpers.ts +35 -0
  33. package/src/index.ts +61 -0
  34. package/src/numeric.ts +196 -0
  35. package/src/pimath.interface.ts +162 -0
  36. package/src/randomization/algebra/rndEquation.ts +41 -0
  37. package/src/randomization/algebra/rndMonom.ts +39 -0
  38. package/src/randomization/algebra/rndPolynom.ts +100 -0
  39. package/src/randomization/coefficient/rndFraction.ts +38 -0
  40. package/src/randomization/geometry/rndCircle.ts +27 -0
  41. package/src/randomization/geometry/rndLine.ts +35 -0
  42. package/src/randomization/geometry/rndLine3.ts +27 -0
  43. package/src/randomization/geometry/rndVector.ts +63 -0
  44. package/src/randomization/random.ts +89 -0
  45. package/src/randomization/rndHelpers.ts +102 -0
  46. package/src/randomization/rndTypes.ts +67 -0
  47. package/types/algebra/equation.d.ts +18 -17
  48. package/types/algebra/equation.d.ts.map +1 -1
  49. package/types/algebra/equationSolver.d.ts +7 -3
  50. package/types/algebra/equationSolver.d.ts.map +1 -1
  51. package/types/algebra/factor.d.ts +1 -1
  52. package/types/algebra/factor.d.ts.map +1 -1
  53. package/types/algebra/linearSystem.d.ts +23 -6
  54. package/types/algebra/linearSystem.d.ts.map +1 -1
  55. package/types/algebra/logicalset.d.ts +1 -1
  56. package/types/algebra/logicalset.d.ts.map +1 -1
  57. package/types/algebra/monom.d.ts +1 -6
  58. package/types/algebra/monom.d.ts.map +1 -1
  59. package/types/algebra/operations.d.ts.map +1 -1
  60. package/types/algebra/polyFactor.d.ts +9 -4
  61. package/types/algebra/polyFactor.d.ts.map +1 -1
  62. package/types/algebra/polynom.d.ts +10 -7
  63. package/types/algebra/polynom.d.ts.map +1 -1
  64. package/types/analyze/index.d.ts +2 -0
  65. package/types/analyze/index.d.ts.map +1 -0
  66. package/types/analyze/solution.d.ts +27 -0
  67. package/types/analyze/solution.d.ts.map +1 -0
  68. package/types/analyze/tableOfSigns.d.ts +9 -0
  69. package/types/analyze/tableOfSigns.d.ts.map +1 -0
  70. package/types/coefficients/fraction.d.ts +14 -12
  71. package/types/coefficients/fraction.d.ts.map +1 -1
  72. package/types/coefficients/index.d.ts +1 -1
  73. package/types/coefficients/index.d.ts.map +1 -1
  74. package/types/coefficients/root.d.ts +41 -0
  75. package/types/coefficients/root.d.ts.map +1 -0
  76. package/types/geometry/TupleAbstract.d.ts +22 -0
  77. package/types/geometry/TupleAbstract.d.ts.map +1 -0
  78. package/types/geometry/TupleN.d.ts +24 -0
  79. package/types/geometry/TupleN.d.ts.map +1 -0
  80. package/types/geometry/circle.d.ts +26 -17
  81. package/types/geometry/circle.d.ts.map +1 -1
  82. package/types/geometry/geomMath.d.ts +2 -1
  83. package/types/geometry/geomMath.d.ts.map +1 -1
  84. package/types/geometry/index.d.ts.map +1 -1
  85. package/types/geometry/line.d.ts +21 -30
  86. package/types/geometry/line.d.ts.map +1 -1
  87. package/types/geometry/line3.d.ts +19 -19
  88. package/types/geometry/line3.d.ts.map +1 -1
  89. package/types/geometry/matrix.d.ts +11 -11
  90. package/types/geometry/plane3.d.ts +9 -9
  91. package/types/geometry/plane3.d.ts.map +1 -1
  92. package/types/geometry/point.d.ts +12 -7
  93. package/types/geometry/point.d.ts.map +1 -1
  94. package/types/geometry/triangle.d.ts +68 -23
  95. package/types/geometry/triangle.d.ts.map +1 -1
  96. package/types/geometry/vector.d.ts +24 -44
  97. package/types/geometry/vector.d.ts.map +1 -1
  98. package/types/helpers.d.ts +1 -0
  99. package/types/helpers.d.ts.map +1 -1
  100. package/types/index.d.ts +6 -4
  101. package/types/index.d.ts.map +1 -1
  102. package/types/numeric.d.ts +2 -0
  103. package/types/numeric.d.ts.map +1 -1
  104. package/types/pimath.interface.d.ts +38 -44
  105. package/types/pimath.interface.d.ts.map +1 -1
  106. package/types/randomization/algebra/rndPolynom.d.ts.map +1 -1
  107. package/types/randomization/coefficient/rndFraction.d.ts +1 -1
  108. package/types/randomization/coefficient/rndFraction.d.ts.map +1 -1
  109. package/types/randomization/geometry/rndLine.d.ts.map +1 -1
  110. package/types/randomization/random.d.ts +3 -2
  111. package/types/randomization/random.d.ts.map +1 -1
  112. package/types/randomization/rndTypes.d.ts +15 -10
  113. package/types/randomization/rndTypes.d.ts.map +1 -1
@@ -0,0 +1,718 @@
1
+ import type {compareSign, IExpression, InputValue, IPiMathObject} from "../pimath.interface"
2
+ import {Numeric} from "../numeric"
3
+
4
+ export enum FRAC_TYPE {
5
+ frac = 'frac',
6
+ dfrac = 'dfrac',
7
+ tfrac = 'tfrac'
8
+ }
9
+
10
+ /**
11
+ * The fraction class make possible to handle
12
+ * \\(\frac{a}{b}\\) or \\[\frac{a}{b}\\] values.
13
+ */
14
+
15
+ export class Fraction implements IPiMathObject<Fraction>, IExpression<Fraction> {
16
+ #denominator = 1
17
+ #digits = 3
18
+ #exact = true
19
+ #numerator = 1
20
+ #type: FRAC_TYPE = FRAC_TYPE.frac
21
+ #withSign = false
22
+
23
+ constructor()
24
+ constructor(value: InputValue<Fraction>)
25
+ constructor(numerator: number, denominator: number)
26
+ constructor(value?: InputValue<Fraction>, denominator?: number) {
27
+
28
+ if (value !== undefined) {
29
+ this.parse(value, denominator)
30
+ }
31
+
32
+ return this
33
+ }
34
+
35
+ // ------------------------------------------
36
+ /**
37
+ * Parse the value to get the numerator and denominator
38
+ * @param value : number or string to parse to get the fraction
39
+ */
40
+ public parse = (value: InputValue<Fraction>, denominator?: number): this => {
41
+
42
+ // A null value means a zero fraction.
43
+ if (value === "") {
44
+ this.#numerator = 0
45
+ this.#denominator = 1
46
+ return this
47
+ }
48
+
49
+ if (typeof value === "string") {
50
+ return this.fromString(value)
51
+ }
52
+
53
+ if (typeof value === "number" && denominator===undefined) {
54
+ return this.fromNumber(value)
55
+ }
56
+
57
+ if (typeof value === "number" && typeof denominator==="number") {
58
+ return this.fromNumbers(value, denominator)
59
+ }
60
+
61
+ if (value instanceof Fraction) {
62
+ return this.copy(value)
63
+ }
64
+
65
+ return this
66
+ }
67
+
68
+ public clone = (): Fraction => {
69
+ const F = new Fraction()
70
+ F.numerator = this.#numerator
71
+ F.denominator = this.#denominator
72
+ F.exact = this.exact
73
+ return F
74
+ }
75
+
76
+ public copy(value: Fraction): this {
77
+ this.#numerator = value.numerator
78
+ this.#denominator = value.denominator
79
+ this.#exact = value.exact
80
+
81
+ return this
82
+ }
83
+
84
+ public get tex(): string {
85
+ if (this.isInfinity()) {
86
+ return `${this.sign() === 1 ? '+' : '-'}\\infty`
87
+ }
88
+
89
+ const plus = this.#withSign && this.isPositive() ? '+' : ''
90
+
91
+ if (this.exact) {
92
+ if (this.#denominator === 1) {
93
+ return `${plus}${this.#numerator}`
94
+ } else if (this.#numerator < 0) {
95
+ return `-\\${this.#type}{ ${-this.#numerator} }{ ${this.#denominator} }`
96
+ } else {
97
+ return `${plus}\\${this.#type}{ ${this.#numerator} }{ ${this.#denominator} }`
98
+ }
99
+ } else {
100
+ return plus + this.value.toFixed(this.#digits)
101
+ }
102
+ }
103
+
104
+ public get display(): string {
105
+ if (this.isInfinity()) {
106
+ return `${this.sign() === 1 ? '+' : '-'}oo`
107
+ }
108
+
109
+ const plus = this.#withSign && this.isPositive() ? '+' : ''
110
+
111
+ if (this.exact) {
112
+ if (this.#denominator === 1) {
113
+ return `${plus}${this.#numerator}`
114
+ } else {
115
+ return `${plus}${this.#numerator}/${this.#denominator}`
116
+ }
117
+ } else {
118
+ return plus + this.value.toFixed(this.#digits)
119
+ }
120
+ }
121
+
122
+ public static average = (...fractions: (InputValue<Fraction>)[]): Fraction => {
123
+ const M = new Fraction().zero()
124
+
125
+ for (const f of fractions) {
126
+ M.add(f)
127
+ }
128
+
129
+ M.divide(fractions.length)
130
+
131
+ return M
132
+ }
133
+
134
+ public static isFraction(value: InputValue<Fraction>) {
135
+ if (value instanceof Fraction ||
136
+ (typeof value === "number" && !isNaN(value))
137
+ ) {
138
+ return true
139
+ }
140
+
141
+ if (typeof value === "string") {
142
+ const [num, den] = value.split('/')
143
+
144
+ return !isNaN(+num) && !isNaN(+den)
145
+ }
146
+
147
+ return false
148
+
149
+ }
150
+
151
+ public static max = (...fractions: InputValue<Fraction>[]): Fraction => {
152
+ let M = new Fraction(fractions[0])
153
+
154
+ for (const m of fractions) {
155
+ const compare = new Fraction(m)
156
+ if (compare.isGreater(M)) {
157
+ M = compare.clone()
158
+ }
159
+ }
160
+
161
+ return M
162
+ }
163
+
164
+ public static min = (...fractions: (InputValue<Fraction>)[]): Fraction => {
165
+ let M = new Fraction(fractions[0])
166
+
167
+ for (const m of fractions) {
168
+ const compare = new Fraction(m)
169
+ if (compare.isLesser(M)) {
170
+ M = compare.clone()
171
+ }
172
+ }
173
+
174
+ return M
175
+ }
176
+
177
+ public static sort = (fractions: (InputValue<Fraction>)[], reverse?: boolean): Fraction[] => {
178
+ const fractionsObject: Fraction[] = fractions.map(f => f instanceof Fraction ? f : new Fraction(f))
179
+
180
+ const sorted = fractionsObject.sort((a, b) => a.value - b.value)
181
+
182
+ if (reverse) {
183
+ sorted.reverse()
184
+ }
185
+
186
+ return sorted
187
+ }
188
+
189
+ public static toSameDenominateur(...fractions: InputValue<Fraction>[]): Fraction[] {
190
+ const F = fractions.map(x => new Fraction(x))
191
+ const lcm = Numeric.lcm(...F.map(x => x.denominator))
192
+
193
+ F.forEach(x => x.amplify(lcm / x.denominator))
194
+
195
+ return F
196
+ }
197
+
198
+ public static unique = (fractions: (InputValue<Fraction>)[]): Fraction[] => {
199
+ const unique: Record<string, boolean> = {},
200
+ distinct: Fraction[] = []
201
+
202
+ fractions.forEach(x => {
203
+ if (!(x instanceof Fraction)) {
204
+ x = new Fraction(x)
205
+ }
206
+
207
+ if (!unique[x.clone().reduce().tex]) {
208
+ distinct.push(x.clone())
209
+ unique[x.tex] = true
210
+ }
211
+ })
212
+
213
+ return distinct
214
+ }
215
+
216
+ public static xMultiply = (...values: (InputValue<Fraction>)[]): Fraction => {
217
+ const R = new Fraction()
218
+
219
+ values.forEach(f=> R.multiply(f, false))
220
+
221
+ return R
222
+ }
223
+
224
+ public abs = (): this => {
225
+ this.#numerator = Math.abs(this.#numerator)
226
+ this.#denominator = Math.abs(this.#denominator)
227
+ return this
228
+ }
229
+
230
+ public add = (F: InputValue<Fraction>): Fraction => {
231
+ if (F instanceof Fraction) {
232
+ const N: number = this.#numerator,
233
+ D: number = this.#denominator
234
+
235
+ this.#numerator = N * F.denominator + F.numerator * D
236
+ this.#denominator = D * F.denominator
237
+ this.exact = this.exact && F.exact
238
+ } else {
239
+ return this.add(new Fraction(F))
240
+ }
241
+
242
+ return this.reduce()
243
+ }
244
+
245
+ public amplify = (k: number): this => {
246
+ if (Number.isSafeInteger(k)) {
247
+ this.#numerator *= k
248
+ this.#denominator *= k
249
+ }
250
+ return this
251
+ }
252
+
253
+ public areEquals = (...F: Fraction[]): boolean => {
254
+ return F.every(f => f.isEqual(F[0]))
255
+ }
256
+
257
+ /**
258
+ * Compare the current coefficient with another coefficient
259
+ * @param F (Coefficient) The coefficient to _compare
260
+ * @param sign (string| default is =): authorized values: =, <, <=, >, >= with some variations.
261
+ */
262
+ public compare = (F: InputValue<Fraction>, sign?: compareSign): boolean => {
263
+ sign ??= '='
264
+
265
+ let compareFraction: Fraction
266
+ if (F instanceof Fraction) {
267
+ compareFraction = F.clone()
268
+ } else {
269
+ compareFraction = new Fraction(F)
270
+ }
271
+
272
+ switch (sign) {
273
+ case '>':
274
+ return this.value > compareFraction.value
275
+ case ">=":
276
+ case "=>":
277
+ case "geq":
278
+ return this.value >= compareFraction.value
279
+ case "<":
280
+ return this.value < compareFraction.value
281
+ case "<=":
282
+ case "=<":
283
+ case "leq":
284
+ return this.value <= compareFraction.value
285
+ case "=":
286
+ return this.value === compareFraction.value
287
+ case "<>":
288
+ return this.value !== compareFraction.value
289
+ default:
290
+ return false
291
+ }
292
+ }
293
+
294
+ public get denominator(): number {
295
+ return this.#denominator
296
+ }
297
+
298
+ public set denominator(value: number) {
299
+ this.#denominator = value
300
+ }
301
+
302
+ public get dfrac(): this {
303
+ this.#type = FRAC_TYPE.dfrac
304
+ return this
305
+ }
306
+
307
+ digits(value: number): this {
308
+ this.#digits = value
309
+ return this
310
+ }
311
+
312
+ public divide = (F: Fraction | number): Fraction => {
313
+ const Q = new Fraction(F)
314
+
315
+ if (Q.numerator === 0) {
316
+ return new Fraction().infinite()
317
+ }
318
+
319
+ const N: number = this.#numerator,
320
+ D: number = this.#denominator
321
+
322
+ this.#numerator = N * Q.denominator
323
+ this.#denominator = D * Q.numerator
324
+
325
+ this.exact = this.exact && Q.exact
326
+ return this.reduce()
327
+ }
328
+
329
+ get exact(): boolean {
330
+ return this.#exact
331
+ }
332
+
333
+ set exact(value: boolean) {
334
+ this.#exact = value
335
+ }
336
+
337
+ public get frac(): this {
338
+ this.#type = FRAC_TYPE.frac
339
+ return this
340
+ }
341
+
342
+ public fromNumber(value: number): this {
343
+ if (Number.isSafeInteger(value)) {
344
+ // The given value is an integer
345
+ this.#numerator = value
346
+ this.#denominator = 1
347
+ this.#exact = true
348
+ return this
349
+ }
350
+
351
+ // The given value is a float number
352
+ // Get the number of decimals after the float sign
353
+ const [, decimal] = (value.toString()).split('.')
354
+ const p: number = decimal ? decimal.length : 0
355
+ const power = Math.pow(10, p)
356
+
357
+ this.#numerator = value * power
358
+ this.#denominator = power
359
+
360
+ this.#numerator = Numeric.numberCorrection(this.#numerator)
361
+ this.#denominator = Numeric.numberCorrection(this.#denominator)
362
+
363
+ this.reduce()
364
+
365
+ // assume it's not exact if the decimal part is more than 10 decimals
366
+ this.#exact = p < 10
367
+
368
+ return this
369
+ }
370
+
371
+ public fromNumbers(numerator: number, denominator: number): this {
372
+ if (Number.isSafeInteger(numerator) && Number.isSafeInteger(denominator)) {
373
+ // The given value is an integer
374
+ this.#numerator = numerator
375
+ this.#denominator = denominator
376
+ this.#exact = true
377
+ return this
378
+ }
379
+
380
+ return this.fromNumber(numerator / denominator)
381
+ }
382
+ public fromPeriodic(value: string | number, length: number): this {
383
+ const [, decimal] = (value.toString()).split(/[.,]/)
384
+ const p: number = decimal ? decimal.length : 0
385
+ const power = Math.pow(10, p)
386
+
387
+ this.#numerator = (+value) * power - Math.floor((+value) * Math.pow(10, p - length))
388
+ this.#denominator = power - Math.pow(10, p - length)
389
+ this.#exact = true
390
+
391
+ return this
392
+ }
393
+
394
+ public fromString(value: string): this {
395
+ // Split the string value in two parts: Numerator/Denominator
396
+ const S = value.split('/').map(Number)
397
+
398
+ this.#exact = true
399
+
400
+ // Only one divide sign allowed
401
+ if (S.length > 2) {
402
+ this.#numerator = NaN
403
+ return this
404
+ }
405
+
406
+ // Each parts must be a number
407
+ if (S.some(x => isNaN(x))) {
408
+ this.#numerator = NaN
409
+ return this
410
+ }
411
+
412
+ if (S.length === 1) {
413
+ // No divide sign - it's a number
414
+ return this.fromNumber(+value)
415
+ }
416
+
417
+ // One divide signe
418
+ // We check if the denominator is zero
419
+ if (S[1] === 0) {
420
+ this.#numerator = NaN
421
+ this.#denominator = 1
422
+ return this
423
+ }
424
+
425
+ this.#numerator = S[0]
426
+ this.#denominator = S[1]
427
+
428
+ return this
429
+ }
430
+
431
+ public infinite = (): this => {
432
+ this.#numerator = Infinity
433
+ this.#denominator = 1
434
+ this.exact = true
435
+ return this
436
+ }
437
+
438
+ public invalid = (): this => {
439
+ this.#numerator = NaN
440
+ this.#denominator = 1
441
+ this.exact = true
442
+ return this
443
+ }
444
+
445
+ public inverse = (): this => {
446
+ const sign = this.sign()
447
+ const n = Math.abs(this.#numerator)
448
+ this.#numerator = Math.abs(this.#denominator) * sign
449
+ this.#denominator = n
450
+
451
+ return this
452
+ }
453
+
454
+ public isEqual = (than: Fraction | number): boolean => {
455
+ return this.compare(than, '=')
456
+ }
457
+
458
+ public isEven = (): boolean => {
459
+ return this.isRelative() && this.value % 2 === 0
460
+ }
461
+
462
+ public isFinite = (): boolean => {
463
+ return !this.isInfinity() && !this.isNaN()
464
+ }
465
+
466
+ public isGeq = (than: Fraction | number): boolean => {
467
+ return this.compare(than, '>=')
468
+ }
469
+
470
+ public isGreater = (than: Fraction | number): boolean => {
471
+ return this.compare(than, '>')
472
+ }
473
+
474
+ public isInfinity = (): boolean => {
475
+ return Math.abs(this.#numerator) === Infinity
476
+ }
477
+
478
+ public isLeq = (than: Fraction | number): boolean => {
479
+ return this.compare(than, '<=')
480
+ }
481
+
482
+ public isLesser = (than: Fraction | number): boolean => {
483
+ return this.compare(than, '<')
484
+ }
485
+
486
+ public isNaN = (): boolean => {
487
+ return isNaN(this.#numerator)
488
+ }
489
+
490
+ public isNatural = (): boolean => {
491
+ return this.isRelative() && this.isPositive()
492
+ }
493
+
494
+ public isNegative = (): boolean => {
495
+ return this.sign() === -1
496
+ }
497
+
498
+ public isNotEqual = (than: Fraction | number): boolean => {
499
+ return this.compare(than, '<>')
500
+ }
501
+
502
+ public isNotZero = (): boolean => {
503
+ return this.#numerator !== 0
504
+ }
505
+
506
+ public isOdd = (): boolean => {
507
+ return this.isRelative() && this.value % 2 === 1
508
+ }
509
+
510
+ public isOne = (): boolean => {
511
+ return this.#numerator === 1 && this.#denominator === 1
512
+ }
513
+
514
+ public isPositive = (): boolean => {
515
+ return this.sign() === 1
516
+ }
517
+
518
+ public isRational = (): boolean => {
519
+ return this.exact && !this.isRelative()
520
+ }
521
+
522
+ public isReduced = (): boolean => {
523
+ return Math.abs(Numeric.gcd(this.#numerator, this.#denominator)) === 1
524
+ }
525
+
526
+ public isRelative = (): boolean => {
527
+ return this.exact && this.clone().reduce().denominator === 1
528
+ }
529
+
530
+ public isSquare = (): boolean => {
531
+ return Math.sqrt(this.#numerator) % 1 === 0 && Math.sqrt(this.#denominator) % 1 === 0
532
+ }
533
+
534
+ public isStrictlyNegative = (): boolean => {
535
+ return this.value < 0
536
+ }
537
+
538
+ public isStrictlyPositive = (): boolean => {
539
+ return this.value > 0
540
+ }
541
+
542
+ public isUnit(): boolean {
543
+ return Math.abs(this.#numerator) === 1 && this.#denominator === 1
544
+ }
545
+
546
+ // Mathematical operations specific to fractions
547
+ public isZero = (): boolean => {
548
+ return this.#numerator === 0
549
+ }
550
+
551
+ public multiply = (F: InputValue<Fraction>, reduce = true): this => {
552
+ // Parse the value.
553
+ // If it's a fraction, return a clone of it
554
+ // If it's an integer, return the fraction F/1
555
+ const Q = new Fraction(F)
556
+
557
+ this.#numerator = this.#numerator * Q.numerator
558
+ this.#denominator = this.#denominator * Q.denominator
559
+
560
+ this.exact = this.exact && Q.exact
561
+
562
+ return reduce ? this.reduce() : this
563
+ }
564
+
565
+ // ------------------------------------------
566
+ public get numerator(): number {
567
+ return this.#numerator
568
+ }
569
+
570
+ public set numerator(value: number) {
571
+ this.#numerator = value
572
+ }
573
+
574
+ public one = (): this => {
575
+ return this.fromNumber(1)
576
+ }
577
+
578
+ public opposite = (): this => {
579
+ this.#numerator = -this.#numerator
580
+ return this
581
+ }
582
+
583
+ public pow = (p: number | Fraction): Fraction => {
584
+ if (p instanceof Fraction) {
585
+ return this.pow(p.value)
586
+ }
587
+
588
+ this.reduce()
589
+ if (p < 0) {
590
+ this.inverse()
591
+ }
592
+
593
+ // Check if numerator and denominator are roots of...
594
+ // otherwise, convert to numeric.
595
+ const controlNumerator = Math.floor(Math.pow(this.#numerator, Math.abs(p))),
596
+ controlDenominator = Math.floor(Math.pow(this.#denominator, Math.abs(p)))
597
+
598
+ if (controlNumerator ** Math.abs(p) === this.#numerator
599
+ &&
600
+ controlDenominator ** Math.abs(p) === this.#denominator) {
601
+ this.#numerator = this.#numerator ** Math.abs(p)
602
+ this.#denominator = this.#denominator ** Math.abs(p)
603
+ } else {
604
+ this.#numerator = this.#numerator ** Math.abs(p)
605
+ this.#denominator = this.#denominator ** Math.abs(p)
606
+ }
607
+
608
+ return this
609
+ }
610
+
611
+ public reduce = (): this => {
612
+ const g = Numeric.gcd(this.#numerator, this.#denominator)
613
+ this.#numerator = this.#numerator / g
614
+ this.#denominator = this.#denominator / g
615
+
616
+ if (this.#denominator < 0) {
617
+ this.#denominator = -this.#denominator
618
+ this.#numerator = -this.#numerator
619
+ }
620
+ return this
621
+ }
622
+
623
+ public root = (p: number): this => {
624
+
625
+ // Check if they are perfect roots..
626
+ if (p === 0) {
627
+ return this
628
+ }
629
+
630
+ // If negative, inverse the fraction
631
+ if (p < 0) {
632
+ this.inverse()
633
+ }
634
+
635
+ // if p is not a safe integer, throw error
636
+ if (!Number.isSafeInteger(p)) {
637
+ throw new Error("The root must be an integer.")
638
+ }
639
+
640
+ // if the fraction is negative and the root is even, throw error
641
+ if (this.isNegative() && p % 2 === 0) {
642
+ throw new Error("The root of a negative number must be odd.")
643
+ }
644
+
645
+ // get the sign of the fraction and make it positive
646
+ const sign = this.sign()
647
+ this.abs()
648
+
649
+ // Reduce the fraction
650
+ this.reduce()
651
+
652
+ // Check if numerator and denominator are roots of...
653
+ // otherwise, convert to numeric.
654
+ const controlNumerator = Math.floor(Math.pow(this.#numerator, Math.abs(1 / p))),
655
+ controlDenominator = Math.floor(Math.pow(this.#denominator, Math.abs(1 / p)))
656
+
657
+ this.#numerator = Math.pow(this.#numerator, Math.abs(1 / p))
658
+ this.#denominator = Math.pow(this.#denominator, Math.abs(1 / p))
659
+
660
+ if (controlNumerator !== this.#numerator
661
+ ||
662
+ controlDenominator !== this.#denominator) {
663
+ // The fraction is not a perfect root - make it approximative
664
+ this.#numerator = this.#numerator / this.#denominator
665
+ this.#denominator = 1
666
+ this.exact = false
667
+ }
668
+
669
+ // Restore the sign
670
+ this.multiply(sign)
671
+
672
+ return this
673
+ }
674
+
675
+ public sign = (): 1 | -1 => {
676
+ return (this.#numerator * this.#denominator >= 0) ? 1 : -1
677
+ }
678
+
679
+ public sqrt = (): this => {
680
+ return this.root(2)
681
+ }
682
+
683
+ public subtract = (F: Fraction | number): Fraction => {
684
+ if (F instanceof Fraction) {
685
+ return this.add(F.clone().opposite())
686
+ } else {
687
+ return this.add(-F)
688
+ }
689
+ }
690
+
691
+ public get texWithSign(): string {
692
+ return this.isPositive() ? `+${this.tex}` : this.tex
693
+ }
694
+
695
+ public get tfrac(): this {
696
+ this.#type = FRAC_TYPE.tfrac
697
+ return this
698
+ }
699
+
700
+ public get value(): number {
701
+ const result = this.#numerator / this.#denominator
702
+ return result === 0 ? 0 : result
703
+ }
704
+
705
+ get withSign(): this {
706
+ this.#withSign = true
707
+ return this
708
+ }
709
+
710
+ get withoutSign(): this {
711
+ this.#withSign = false
712
+ return this
713
+ }
714
+
715
+ public zero = (): this => {
716
+ return this.fromNumber(0)
717
+ }
718
+ }
@@ -0,0 +1,4 @@
1
+ // Export every files from the coefficients folder
2
+
3
+ export * from './fraction'
4
+ export * from './root'