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,346 @@
1
+ import {Fraction} from "./fraction"
2
+ import type {IExpression, InputValue, IPiMathObject} from "../pimath.interface"
3
+ import {stripParenthesis} from "../helpers"
4
+ import {Numeric} from "../numeric"
5
+
6
+ export class Root implements IPiMathObject<Root>, IExpression<Root> {
7
+ #factor: Fraction
8
+ #index: number
9
+ #radical: Fraction
10
+ #withSign = false
11
+
12
+ constructor(value?: InputValue<Root | Fraction>) {
13
+ this.#index = 2
14
+ this.#factor = new Fraction().zero()
15
+ this.#radical = new Fraction().zero()
16
+
17
+ if (value) {
18
+ this.parse(value)
19
+ }
20
+
21
+
22
+ return this
23
+ }
24
+
25
+ parse(value: InputValue<Root | Fraction>): this {
26
+ // should be able to parse "display" roots.
27
+ // sqrt12 or sqrt(12) or sqrt(12/5) => [2, 12 or 12/5, 1]
28
+ // root(n)10 or root(n)(10) or root(n)(10/3) => [n, 10 or 10/3, 1]
29
+ // 7sqrt12 or 7sqrt(12) or 7sqrt(12/5) => [2, 12 or 12/5, 7]
30
+ // 7root(n)10 or 7root(n)(10) or 7root(n)(10/3) => [n, 10 or 10/3, 7]
31
+
32
+ if (value instanceof Root) {
33
+ this.index = value.index
34
+ this.radical = value.radical.clone()
35
+ this.factor = value.factor.clone()
36
+
37
+ return this
38
+ }
39
+
40
+ if (value instanceof Fraction) {
41
+ this.index = 2
42
+ this.factor = value.clone()
43
+ this.radical.one()
44
+
45
+ return this
46
+ }
47
+
48
+ if (typeof value === "string") {
49
+ if (value.includes('sqrt')) {
50
+ return this.#parse_sqrt(value)
51
+ }
52
+
53
+ if (value.includes('root')) {
54
+ return this.#parse_root(value)
55
+ }
56
+ }
57
+
58
+ this.index = 2
59
+ this.factor = new Fraction(value)
60
+ this.radical.one()
61
+
62
+ return this
63
+ }
64
+
65
+ clone(): Root {
66
+ return new Root().from(this.index, this.radical, this.factor)
67
+ }
68
+
69
+ get tex(): string {
70
+ // b \sqrt{}
71
+ // b
72
+ // \sqrt{}
73
+ // -\sqrt{}
74
+
75
+ // Force the plus sign.
76
+ const plus = this.#withSign && this.factor.isPositive() ? '+' : ''
77
+
78
+ // There is no radical - output the factor
79
+ if (this.#radical.isZero()) return `${plus}${this.#factor.tex}`
80
+
81
+ // The radical has an index of 1 - no radical.
82
+ if (this.index === 1) return `${plus}${this.factor.clone().multiply(this.radical).tex}`
83
+
84
+ // Make the root part
85
+ const rad = this.index === 2
86
+ ? `\\sqrt{ ${this.#radical.tex} }`
87
+ : `\\sqrt[ ${this.index} ]{ ${this.#radical.tex} }`
88
+
89
+ if (this.#factor.isUnit()) {
90
+ return this.#withSign
91
+ ? `${this.#factor.isOne() ? plus : '-'} ${rad}`
92
+ : `${this.#factor.isOne() ? '' : '-'}${rad}`
93
+ }
94
+
95
+ return `${plus}${this.#factor.tex} ${rad}`
96
+ }
97
+
98
+ get display(): string {
99
+ const plus = this.#withSign && this.factor.isPositive() ? '+' : ''
100
+
101
+ // There is no radical - output the factor
102
+ if (this.#radical.isZero()) return `${plus}${this.#factor.display}`
103
+
104
+ // The radical has an index of 1 - no radical.
105
+ if (this.index === 1) return `${plus}${this.factor.clone().multiply(this.radical).display}`
106
+
107
+ // Make the root part
108
+ const rad = this.index === 2
109
+ ? `sqrt(${this.#radical.tex})`
110
+ : `root(${this.index})(${this.#radical.display})`
111
+
112
+ if (this.#factor.isUnit()) return `${this.#factor.isOne() ? plus : '-'}${rad}`
113
+
114
+ return `${plus}${this.#factor.display}${rad}`
115
+ }
116
+
117
+ add(value: InputValue<Root>): this {
118
+ // start by reducing
119
+ this.reduce()
120
+ const rt = new Root(value).reduce()
121
+
122
+ if (
123
+ this.index !== rt.index ||
124
+ !this.radical.isEqual(rt.radical)
125
+ ) {
126
+ throw new Error("Add can only be done with two same index and radical")
127
+ }
128
+
129
+ this.factor.add(rt.factor)
130
+
131
+ return this
132
+ }
133
+
134
+ divide(value: InputValue<Root>): this {
135
+ return this.multiply(new Root(value).inverse())
136
+ }
137
+
138
+ get factor(): Fraction {
139
+ return this.#factor
140
+ }
141
+
142
+ set factor(value: Fraction) {
143
+ this.#factor = value
144
+ }
145
+
146
+ from(index: number, radical: InputValue<Fraction>, factor?: InputValue<Fraction>): this {
147
+ // set the index
148
+ this.index = index
149
+
150
+ // set the racial
151
+ this.radical = new Fraction(radical)
152
+
153
+ // set the factor if any
154
+ this.factor = factor ? new Fraction(factor) : new Fraction().one()
155
+
156
+ return this
157
+ }
158
+
159
+ /**
160
+ * convert to root(index)(radical), without factor
161
+ */
162
+ group(): this {
163
+ this.radical.multiply(this.factor.pow(this.index))
164
+ this.factor.one()
165
+
166
+ return this
167
+ }
168
+
169
+ get index(): number {
170
+ return this.#index
171
+ }
172
+
173
+ set index(value: number) {
174
+ if (!Number.isSafeInteger(value) || value <= 0) {
175
+ throw new Error("Index must be a strictly positive integer.")
176
+ }
177
+ this.#index = value
178
+ }
179
+
180
+ get indexAsPow(): Fraction {
181
+ return new Fraction(this.index).inverse()
182
+ }
183
+
184
+ inverse(): this {
185
+ this.factor.inverse()
186
+ this.radical.inverse()
187
+ return this
188
+ }
189
+
190
+ isEqual(root: Root): boolean {
191
+ return this.value === root.value
192
+ }
193
+
194
+ isOne(): boolean {
195
+ return this.factor.isOne() && this.radical.isOne()
196
+ }
197
+
198
+ isRational(): boolean {
199
+ const reduced = this.clone().reduce()
200
+
201
+ if(reduced.radical.isOne()) return reduced.factor.exact
202
+
203
+ if(reduced.index===1) return reduced.factor.exact && reduced.radical.exact
204
+
205
+ return false
206
+ }
207
+
208
+ isZero(): boolean {
209
+ return this.factor.isZero() || this.radical.isZero()
210
+ }
211
+
212
+ multiply(value: InputValue<Root>): this {
213
+ const rt = new Root(value)
214
+
215
+ this.factor.multiply(rt.factor)
216
+
217
+ if (this.index === rt.index) {
218
+ this.radical.multiply(rt.radical)
219
+ return this
220
+ }
221
+
222
+ if (this.radical.isEqual(rt.radical)) {
223
+ const F = this.indexAsPow.add(rt.indexAsPow).reduce()
224
+ this.index = F.denominator
225
+ this.radical = this.radical.pow(F.numerator)
226
+ return this
227
+ }
228
+
229
+ throw new Error('Multiply can only be done if radical or index as equals.')
230
+ }
231
+
232
+ one(): this {
233
+ this.radical.one()
234
+ this.factor.one()
235
+
236
+ return this
237
+ }
238
+
239
+ opposite(): this {
240
+ this.factor.opposite()
241
+ return this
242
+ }
243
+
244
+ pow(value: number): this {
245
+ this.factor.pow(value)
246
+
247
+ const g = Numeric.gcd(this.index, value)
248
+ this.index = this.index / g
249
+ this.radical.pow(value / g)
250
+
251
+ return this
252
+ }
253
+
254
+ get radical(): Fraction {
255
+ return this.#radical
256
+ }
257
+
258
+ set radical(value: Fraction) {
259
+ this.#radical = value
260
+ }
261
+
262
+ reduce(): this {
263
+ // 1. extract roots
264
+ // 2. avoid roots at denominator.
265
+
266
+ // Remove the roots at denominator
267
+ if (this.radical.isRational()) {
268
+ const den = this.radical.denominator
269
+ this.radical.denominator = 1
270
+ this.radical.numerator *= den
271
+
272
+ this.factor.divide(den)
273
+ }
274
+
275
+ // Extract the greatest root from.
276
+ const greatest = Numeric.greatestPower(this.radical.value, this.index)
277
+
278
+ this.factor.multiply(Math.pow(greatest, 1 / this.index))
279
+ this.radical.divide(greatest)
280
+
281
+ return this
282
+ }
283
+
284
+ root(value: number): this {
285
+ this.group()
286
+ this.index = this.index * value
287
+ return this
288
+ }
289
+
290
+ sqrt(): this {
291
+ return this.root(2)
292
+ }
293
+
294
+ subtract(value: InputValue<Root>): this {
295
+ const rt = new Root(value)
296
+
297
+ return this.add(rt.opposite())
298
+ }
299
+
300
+ public get value(): number {
301
+ return Numeric.numberCorrection(this.factor.value * Math.pow(this.radical.value, 1 / this.index))
302
+ }
303
+
304
+ get withSign(): this {
305
+ this.#withSign = true
306
+ return this
307
+ }
308
+
309
+ get withoutSign(): this {
310
+ this.#withSign = false
311
+ return this
312
+ }
313
+
314
+ zero(): this {
315
+ this.radical.zero()
316
+ this.factor.zero()
317
+ return this
318
+ }
319
+
320
+ #parse_root(value: string): this {
321
+ // value = a root(n)b or a root(n)(b)
322
+ const [factor, index_radical] = value.split('root')
323
+ const [index, radical] = index_radical.split(')')
324
+
325
+ this.index = +stripParenthesis(index)
326
+
327
+ this.radical = new Fraction(stripParenthesis(radical))
328
+
329
+ this.factor = factor === '' ? new Fraction().one() : new Fraction(factor)
330
+
331
+ return this
332
+ }
333
+
334
+ #parse_sqrt(value: string): this {
335
+ // value = asqrtb
336
+ const [factor, radical] = value.split('sqrt')
337
+
338
+ this.index = 2
339
+
340
+ this.radical = new Fraction(stripParenthesis(radical))
341
+
342
+ this.factor = factor === '' ? new Fraction().one() : new Fraction(factor)
343
+
344
+ return this
345
+ }
346
+ }
@@ -0,0 +1,128 @@
1
+ /**
2
+ * POint module contains everything necessary to handle 2d Points
3
+ * It's a "wrapper" of the Vector class.
4
+ * @module Point
5
+ */
6
+
7
+ import {Fraction} from "../coefficients"
8
+ import type {InputValue} from "../pimath.interface"
9
+
10
+ export abstract class TupleN {
11
+ #array: Fraction[] = []
12
+ #onChange?: () => void
13
+
14
+ constructor(...values: InputValue<Fraction>[]) {
15
+ this.#array = values.map(x => new Fraction(x))
16
+ };
17
+
18
+ public abstract clone(): void
19
+
20
+ public copy(): Fraction[] {
21
+ return this.#array.map(x => x.clone())
22
+ }
23
+
24
+ abstract get tex(): string
25
+
26
+ abstract get display(): string
27
+
28
+ get array(): Fraction[] {
29
+ return this.#array
30
+ }
31
+
32
+ set array(value: Fraction[]) {
33
+ this.#array = value
34
+ }
35
+
36
+ get dimension(): number {
37
+ return this.array.length
38
+ }
39
+
40
+ public fromString(value: string): this {
41
+ // Remove the first letter if it's a parenthesis.
42
+ if (value.startsWith('(')) {
43
+ value = value.substring(1)
44
+ }
45
+
46
+ // Remove the last letter if it's a parenthesis.
47
+ if (value.endsWith(')')) {
48
+ value = value.substring(0, value.length - 1)
49
+ }
50
+
51
+ // Split comma, semi colon or single space.
52
+ const components = value.split(/[,;\s]/g)
53
+ .filter((v) => v.trim() !== '')
54
+
55
+ // there must be at least two Pages.
56
+ if (components.length < 2) {
57
+ return this
58
+ }
59
+
60
+ // Validate the fraction values.
61
+ this.#array = components.map(x => new Fraction(x))
62
+ return this
63
+ }
64
+
65
+ get onChange(): undefined | (() => void) {
66
+ return this.#onChange
67
+ }
68
+
69
+ set onChange(value: undefined | (() => void)) {
70
+ this.#onChange = value
71
+ }
72
+
73
+ setDimension(value = 2): this {
74
+ if (value < 2) {
75
+ throw new Error('Dimension must be at least 2')
76
+ }
77
+
78
+ if (value < this.dimension) {
79
+ this.#array = this.#array.slice(0, value)
80
+ } else if (value > this.dimension) {
81
+ for (let i = this.dimension; i < value; i++) {
82
+ this.#array.push(new Fraction(0))
83
+ }
84
+ }
85
+
86
+ return this
87
+ }
88
+
89
+ get x(): Fraction {
90
+ return this.#array[0]
91
+ }
92
+
93
+ set x(value: Fraction | number | string) {
94
+ this.#array[0] = new Fraction(value)
95
+ this.#onChange?.()
96
+ }
97
+
98
+ get y(): Fraction {
99
+ return this.#array[1]
100
+ }
101
+
102
+ set y(value: Fraction | number | string) {
103
+ this.#array[1] = new Fraction(value)
104
+ this.#onChange?.()
105
+ }
106
+
107
+ get z(): Fraction {
108
+ if (this.dimension < 3) {
109
+ throw new Error('Vector is not 3D')
110
+ }
111
+ return this.#array[2]
112
+ }
113
+
114
+ set z(value: Fraction | number | string) {
115
+ if (this.dimension < 3) {
116
+ throw new Error('Vector is not 3D')
117
+ }
118
+ this.#array[2] = new Fraction(value)
119
+ this.#onChange?.()
120
+ }
121
+
122
+ zero = (): this => {
123
+ this.#array.forEach(x => x.zero())
124
+ this.#onChange?.()
125
+ return this
126
+ }
127
+
128
+ }