pimath 0.1.39 → 0.1.40

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 (65) hide show
  1. package/dist/pimath.js +188 -159
  2. package/dist/pimath.js.map +1 -1
  3. package/package.json +4 -2
  4. package/src/algebra/equation.ts +556 -0
  5. package/src/algebra/equationSolver.ts +539 -0
  6. package/src/algebra/factor.ts +339 -0
  7. package/src/algebra/index.ts +11 -0
  8. package/src/algebra/linearSystem.ts +388 -0
  9. package/src/algebra/logicalset.ts +256 -0
  10. package/src/algebra/matrix.ts +474 -0
  11. package/src/algebra/monom.ts +1015 -0
  12. package/src/algebra/operations.ts +24 -0
  13. package/src/algebra/polyFactor.ts +668 -0
  14. package/src/algebra/polynom.ts +1394 -0
  15. package/src/analyze/solution.ts +115 -0
  16. package/src/analyze/tableOfSigns.ts +30 -0
  17. package/src/coefficients/fraction.ts +678 -0
  18. package/src/coefficients/index.ts +4 -0
  19. package/src/coefficients/nthRoot.ts +149 -0
  20. package/src/coefficients/root.ts +299 -0
  21. package/src/geometry/circle.ts +386 -0
  22. package/src/geometry/geomMath.ts +70 -0
  23. package/src/geometry/index.ts +10 -0
  24. package/src/geometry/line.ts +677 -0
  25. package/src/geometry/line3.ts +206 -0
  26. package/src/geometry/plane3.ts +170 -0
  27. package/src/geometry/point.ts +66 -0
  28. package/src/geometry/sphere3.ts +214 -0
  29. package/src/geometry/triangle.ts +354 -0
  30. package/src/geometry/vector.ts +341 -0
  31. package/src/helpers.ts +35 -0
  32. package/src/index.ts +60 -0
  33. package/src/numeric.ts +199 -0
  34. package/src/pimath.interface.ts +160 -0
  35. package/src/randomization/algebra/rndEquation.ts +41 -0
  36. package/src/randomization/algebra/rndMonom.ts +39 -0
  37. package/src/randomization/algebra/rndPolynom.ts +86 -0
  38. package/src/randomization/coefficient/rndFraction.ts +38 -0
  39. package/src/randomization/geometry/rndCircle.ts +27 -0
  40. package/src/randomization/geometry/rndLine.ts +37 -0
  41. package/src/randomization/geometry/rndLine3.ts +27 -0
  42. package/src/randomization/geometry/rndVector.ts +63 -0
  43. package/src/randomization/random.ts +91 -0
  44. package/src/randomization/rndHelpers.ts +102 -0
  45. package/src/randomization/rndTypes.ts +63 -0
  46. package/types/algebra/equationSolver.d.ts +3 -0
  47. package/types/algebra/equationSolver.d.ts.map +1 -1
  48. package/types/algebra/polyFactor.d.ts +5 -0
  49. package/types/algebra/polyFactor.d.ts.map +1 -1
  50. package/types/analyze/solution.d.ts +21 -0
  51. package/types/analyze/solution.d.ts.map +1 -0
  52. package/types/analyze/tableOfSigns.d.ts +9 -0
  53. package/types/analyze/tableOfSigns.d.ts.map +1 -0
  54. package/types/coefficients/root.d.ts +38 -0
  55. package/types/coefficients/root.d.ts.map +1 -0
  56. package/types/geometry/point.d.ts +1 -1
  57. package/types/geometry/point.d.ts.map +1 -1
  58. package/types/helpers.d.ts +1 -0
  59. package/types/helpers.d.ts.map +1 -1
  60. package/types/index.d.ts +1 -0
  61. package/types/index.d.ts.map +1 -1
  62. package/types/numeric.d.ts +2 -0
  63. package/types/numeric.d.ts.map +1 -1
  64. package/types/pimath.interface.d.ts +26 -26
  65. package/types/pimath.interface.d.ts.map +1 -1
@@ -0,0 +1,149 @@
1
+ // TODO: Remove NthRoot class
2
+ /**
3
+ * NthRoot is something like "a+b\sqrt{3}
4
+ */
5
+ export class NthRoot {
6
+ #radical: number
7
+ #nth: number
8
+ #coefficient: number
9
+ #isValid: boolean
10
+
11
+ constructor(...values: number[]) {
12
+ this.#radical = 1
13
+ this.#coefficient = 1
14
+ this.#nth = 2
15
+ this.#isValid = true
16
+
17
+ if (values.length > 0) {
18
+ this.parse(values[0], values[1], values[2])
19
+ }
20
+ }
21
+
22
+ // ------------------------------------------
23
+ // Getter and setter
24
+ // ------------------------------------------
25
+ get radical(): number {
26
+ return this.#radical
27
+ }
28
+
29
+ set radical(value: number) {
30
+ this.#radical = value
31
+ }
32
+
33
+ get nth(): number {
34
+ return this.#nth
35
+ }
36
+
37
+ set nth(value: number) {
38
+ if (Number.isSafeInteger(value) && value >= 2) {
39
+ this.#nth = value
40
+ } else {
41
+ // Error setting the nth root.
42
+ console.log('Error setting the nth root')
43
+ this.#nth = 2
44
+ }
45
+ }
46
+
47
+ get coefficient(): number {
48
+ return this.#coefficient
49
+ }
50
+
51
+ set coefficient(value: number) {
52
+ this.#coefficient = value
53
+ }
54
+
55
+ get tex(): string {
56
+ let C: string
57
+
58
+ if (this.#coefficient === 1) {
59
+ C = ''
60
+ } else if (this.#coefficient === -1) {
61
+ C = '-'
62
+ } else {
63
+ C = this.#coefficient.toString()
64
+ }
65
+
66
+ if (this.#radical === 1) {
67
+ return `${this.#coefficient}`
68
+ } else {
69
+ if (this.#nth === 2) {
70
+ return `${C}\\sqrt{${this.#radical}}`
71
+ } else {
72
+ return `${C}\\sqrt[${this.#nth}]{${this.#radical}}`
73
+ }
74
+ }
75
+ }
76
+
77
+ get display(): string {
78
+ let C: string
79
+
80
+ if (this.#coefficient === 1) {
81
+ C = ''
82
+ } else if (this.#coefficient === -1) {
83
+ C = '-'
84
+ } else {
85
+ C = this.#coefficient.toString()
86
+ }
87
+
88
+ if (this.#radical === 1) {
89
+ return `${this.#coefficient}`
90
+ } else {
91
+ if (this.#nth === 2) {
92
+ return `${C}sqrt{${this.#radical}}`
93
+ } else {
94
+ return `${C}root(${this.#nth}){${this.#radical}}`
95
+ }
96
+ }
97
+ }
98
+
99
+ get value(): number {
100
+ return this.#coefficient * Math.pow(this.#radical, 1 / this.#nth)
101
+ }
102
+
103
+ // ------------------------------------------
104
+ // Creation / parsing functions
105
+ // ------------------------------------------
106
+ parse = (radical: number, nthroot?: number, coefficient?: number): this => {
107
+ this.#coefficient = coefficient ?? 1
108
+ this.#nth = nthroot ?? 2
109
+ this.#radical = radical
110
+
111
+ if (this.#nth % 2 === 0 && this.#radical < 0) {
112
+ this.#isValid = false
113
+ }
114
+ return this
115
+ }
116
+
117
+ // ------------------------------------------
118
+ // Mathematical operations
119
+ // ------------------------------------------
120
+ reduce = (): this => {
121
+ // Max value to test.
122
+ let V = Math.floor(Math.pow(this.#radical, 1 / this.#nth))
123
+ while (V > 1) {
124
+ if (this.#radical % Math.pow(V, this.#nth) === 0) {
125
+ // It's dividable by V^n
126
+ this.#coefficient *= V
127
+ this.#radical = this.#radical / Math.pow(V, this.#nth)
128
+
129
+ // Redifine the new testing value (this is optimization)
130
+ V = Math.floor(Math.pow(this.#radical, 1 / this.#nth))
131
+ continue
132
+ }
133
+ V--
134
+ }
135
+ return this
136
+ }
137
+
138
+ multiply = (N: NthRoot): this => {
139
+ this.#radical *= N.radical
140
+ return this.reduce()
141
+ }
142
+
143
+ // ------------------------------------------
144
+ // Help functions
145
+ // ------------------------------------------
146
+ hasRadical = (): boolean => {
147
+ return !(this.#radical === 1 || this.#radical === 0 || !this.#isValid)
148
+ }
149
+ }
@@ -0,0 +1,299 @@
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
+
11
+ constructor(value?: InputValue<Root | Fraction>) {
12
+ this.#index = 2
13
+ this.#factor = new Fraction().one()
14
+ this.#radical = new Fraction().zero()
15
+
16
+ if (value) {
17
+ this.parse(value)
18
+ }
19
+
20
+
21
+ return this
22
+ }
23
+
24
+ parse(value: InputValue<Root | Fraction>): this {
25
+ // should be able to parse "display" roots.
26
+ // sqrt12 or sqrt(12) or sqrt(12/5) => [2, 12 or 12/5, 1]
27
+ // root(n)10 or root(n)(10) or root(n)(10/3) => [n, 10 or 10/3, 1]
28
+ // 7sqrt12 or 7sqrt(12) or 7sqrt(12/5) => [2, 12 or 12/5, 7]
29
+ // 7root(n)10 or 7root(n)(10) or 7root(n)(10/3) => [n, 10 or 10/3, 7]
30
+
31
+ if (value instanceof Root) {
32
+ this.index = value.index
33
+ this.radical = value.radical.clone()
34
+ this.factor = value.factor.clone()
35
+
36
+ return this
37
+ }
38
+ if (value instanceof Fraction) {
39
+ this.index = 2
40
+ this.factor = value.clone()
41
+ this.radical.one()
42
+
43
+ return this
44
+ }
45
+
46
+ if (typeof value === "string") {
47
+ if (value.includes('sqrt')) {
48
+ return this.#parse_sqrt(value)
49
+ }
50
+
51
+ if (value.includes('root')) {
52
+ return this.#parse_root(value)
53
+ }
54
+ }
55
+
56
+ this.index = 2
57
+ this.factor = new Fraction(value)
58
+ this.radical.one()
59
+
60
+ return this
61
+ }
62
+
63
+ clone(): Root {
64
+ return new Root().from(this.index, this.radical, this.factor)
65
+ }
66
+
67
+ get tex(): string {
68
+ const output =
69
+ this.factor.isOne()
70
+ ? ''
71
+ : this.factor.isNegative()
72
+ ? '-'
73
+ : this.factor.tex
74
+
75
+ if (this.index === 1) {
76
+
77
+ return output
78
+ }
79
+
80
+ if (this.index === 2) {
81
+
82
+ return output
83
+ }
84
+
85
+ return output
86
+ }
87
+
88
+ get display(): string {
89
+ return this.factor.display
90
+ }
91
+
92
+ add(value: InputValue<Root>): this {
93
+ const rt = new Root(value)
94
+
95
+ if (
96
+ this.index !== rt.index &&
97
+ !this.radical.isEqual(rt.radical)
98
+ ) {
99
+ throw new Error("Add can only be done with two same index and radical")
100
+ }
101
+
102
+ this.factor.add(rt.factor)
103
+
104
+ return this
105
+ }
106
+
107
+ divide(value: InputValue<Root>): this {
108
+ return this.multiply(new Root(value).inverse())
109
+ }
110
+
111
+ get factor(): Fraction {
112
+ return this.#factor
113
+ }
114
+
115
+ set factor(value: Fraction) {
116
+ this.#factor = value
117
+ }
118
+
119
+ from(index: number, radical: InputValue<Fraction>, factor?: InputValue<Fraction>): this {
120
+ // set the index
121
+ this.index = index
122
+
123
+ // set the racial
124
+ this.radical = new Fraction(radical)
125
+
126
+ // set the factor if any
127
+ this.factor = factor ? new Fraction(factor) : new Fraction().one()
128
+
129
+ return this
130
+ }
131
+
132
+ /**
133
+ * convert to root(index)(radical), without factor
134
+ */
135
+ group(): this {
136
+
137
+ this.radical.multiply(this.factor.pow(this.index))
138
+ this.factor.one()
139
+
140
+ return this
141
+ }
142
+
143
+ get index(): number {
144
+ return this.#index
145
+ }
146
+
147
+ set index(value: number) {
148
+ if (!Number.isSafeInteger(value) || value <= 0) {
149
+ throw new Error("Index must be a strictly positive integer.")
150
+ }
151
+ this.#index = value
152
+ }
153
+
154
+ get indexAsPow(): Fraction {
155
+ return new Fraction(this.index).inverse()
156
+ }
157
+
158
+ inverse(): this {
159
+ this.factor.inverse()
160
+ this.radical.inverse()
161
+ return this
162
+ }
163
+
164
+ isEqual(root: Root): boolean {
165
+ return this.value === root.value
166
+ }
167
+
168
+ isOne(): boolean {
169
+ return this.factor.isOne() && this.radical.isOne()
170
+ }
171
+
172
+ isZero(): boolean {
173
+ return this.factor.isZero() || this.radical.isZero()
174
+ }
175
+
176
+ multiply(value: InputValue<Root>): this {
177
+ const rt = new Root(value)
178
+
179
+ this.factor.multiply(rt.factor)
180
+
181
+ if (this.index === rt.index) {
182
+ this.radical.multiply(rt.radical)
183
+ return this
184
+ }
185
+
186
+ if (this.radical.isEqual(rt.radical)) {
187
+ const F = this.indexAsPow.add(rt.indexAsPow).reduce()
188
+ this.index = F.denominator
189
+ this.radical = this.radical.pow(F.numerator)
190
+ return this
191
+ }
192
+
193
+ throw new Error('Multiply can only be done if radical or index as equals.')
194
+ }
195
+
196
+ one(): this {
197
+ this.radical.one()
198
+ this.factor.one()
199
+
200
+ return this
201
+ }
202
+
203
+ opposite(): this {
204
+ this.factor.opposite()
205
+ return this
206
+ }
207
+
208
+ pow(value: number): this {
209
+ this.factor.pow(value)
210
+
211
+ const g = Numeric.gcd(this.index, value)
212
+ this.index = this.index / g
213
+ this.radical.pow(value / g)
214
+
215
+ return this
216
+ }
217
+
218
+ get radical(): Fraction {
219
+ return this.#radical
220
+ }
221
+
222
+ set radical(value: Fraction) {
223
+ this.#radical = value
224
+ }
225
+
226
+ reduce(): this {
227
+ // 1. extract roots
228
+ // 2. avoid roots at denominator.
229
+
230
+ // Remove the roots at denominator
231
+ if (this.radical.isRational()) {
232
+ const den = this.radical.denominator
233
+ this.radical.denominator = 1
234
+ this.radical.numerator *= den
235
+
236
+ this.factor.divide(den)
237
+ }
238
+
239
+ // Extract the greatest root from.
240
+ const greatest = Numeric.greatestPower(this.radical.value, this.index)
241
+ this.factor = this.factor.multiply(Math.pow(greatest, 1 / this.index))
242
+ this.radical = this.radical.divide(greatest)
243
+
244
+ return this
245
+ }
246
+
247
+ root(value: number): this {
248
+ this.group()
249
+ this.index = this.index * value
250
+ return this
251
+ }
252
+
253
+ sqrt(): this {
254
+ return this.root(2)
255
+ }
256
+
257
+ subtract(value: InputValue<Root>): this {
258
+ const rt = new Root(value)
259
+
260
+ return this.add(rt.opposite())
261
+ }
262
+
263
+ public get value(): number {
264
+ return Numeric.numberCorrection(this.factor.value * Math.pow(this.radical.value, 1 / this.index))
265
+ }
266
+
267
+ zero(): this {
268
+ this.radical.zero()
269
+ this.factor.zero()
270
+ return this
271
+ }
272
+
273
+ #parse_root(value: string): this {
274
+ // value = a root(n)b or a root(n)(b)
275
+ const [factor, index_radical] = value.split('root')
276
+ const [index, radical] = index_radical.split(')')
277
+
278
+ this.index = +stripParenthesis(index)
279
+
280
+ this.radical = new Fraction(stripParenthesis(radical))
281
+
282
+ this.factor = factor === '' ? new Fraction().one() : new Fraction(factor)
283
+
284
+ return this
285
+ }
286
+
287
+ #parse_sqrt(value: string): this {
288
+ // value = asqrtb
289
+ const [factor, radical] = value.split('sqrt')
290
+
291
+ this.index = 2
292
+
293
+ this.radical = new Fraction(stripParenthesis(radical))
294
+
295
+ this.factor = factor === '' ? new Fraction().one() : new Fraction(factor)
296
+
297
+ return this
298
+ }
299
+ }