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,474 @@
1
+ import type {IExpressionMultiply, InputAlgebra, InputValue, IPiMathObject} from "../pimath.interface"
2
+ import {Polynom} from "./polynom"
3
+ import type {Vector} from "../geometry"
4
+ import {operation_pow} from "./operations"
5
+
6
+ export type IMatrixValues = InputAlgebra<Polynom>[][]
7
+
8
+ export class Matrix implements IPiMathObject<Matrix>,
9
+ IExpressionMultiply<Matrix> {
10
+ #digits: number | null = null
11
+ #matrix_parenthesis = true
12
+ #values: Polynom[][] = []
13
+
14
+ constructor(rowCount?: number, colCount?: number) {
15
+ if (rowCount) {
16
+ colCount = colCount ?? rowCount
17
+ this.fromDimensions(rowCount, colCount)
18
+ }
19
+
20
+ return this
21
+ }
22
+
23
+ public parse(values: IMatrixValues): this {
24
+ return this.fromValues(values)
25
+
26
+ return this
27
+ }
28
+
29
+ public clone(): Matrix {
30
+ // Copy the matrix.
31
+ const duplicates: IMatrixValues = []
32
+
33
+ this.#values.forEach(row => {
34
+ const dup_row: Polynom[] = []
35
+ row.forEach(value => {
36
+ dup_row.push(value.clone())
37
+ })
38
+
39
+ duplicates.push(dup_row)
40
+ })
41
+
42
+ return new Matrix().fromValues(duplicates)
43
+ }
44
+
45
+ get tex(): string {
46
+ if (this.#values.length === 0) {
47
+ return ""
48
+ }
49
+
50
+ const wrapper = this.#matrix_parenthesis ? 'pmatrix' : 'bmatrix'
51
+
52
+
53
+ const output = [
54
+ `\\begin{${wrapper}}`,
55
+ ...this.rows
56
+ .map(row => '\t' + row
57
+ .map(p => this.#digits !== null && p.value ? +p.value.toFixed(this.#digits):p.tex)
58
+ .join(' & ') + '\\\\'
59
+ ),
60
+ `\\end{${wrapper}}`
61
+ ].join('\n')
62
+
63
+ this.#digits = null
64
+
65
+ return output
66
+ }
67
+
68
+ get display(): string {
69
+ if (this.#values.length === 0) {
70
+ return ""
71
+ }
72
+
73
+ const wrapper = this.#matrix_parenthesis ? ['(', ')'] : ['[', ']']
74
+
75
+ const output = wrapper[0] +
76
+ this.map(aij => this.#digits !== null && aij.value ? +aij.value.toFixed(this.#digits): aij.display)
77
+ .map(row => `(${row.join(',')})`)
78
+ .join(',') +
79
+ wrapper[1]
80
+
81
+ this.#digits = null
82
+
83
+ return output
84
+ }
85
+
86
+ public add(value: Matrix): this {
87
+ if (!this.canBeAdded(value)) {
88
+ throw new Error("Cannot add a matrix with different dimensions.")
89
+ }
90
+ this.forEach((aij, i, j) => {
91
+ aij.add(value.values[i][j])
92
+ })
93
+
94
+ return this
95
+ }
96
+
97
+ public aij(i: number, j: number) {
98
+ if (i < 0 || i > this.dimension.rows || j < 0 || j > this.dimension.cols) {
99
+ return null
100
+ }
101
+
102
+ return this.#values[i][j]
103
+ }
104
+
105
+ get bmatrix(): this {
106
+ this.#matrix_parenthesis = false
107
+ return this
108
+ }
109
+
110
+ public canBeAdded(matrix: Matrix): boolean {
111
+ const {rows, cols} = this.dimension
112
+ const {rows: rows2, cols: cols2} = matrix.dimension
113
+
114
+ return rows === rows2 && cols === cols2
115
+ }
116
+
117
+ public canBeInverted(): boolean {
118
+ if (!this.isSquare()) {
119
+ return false
120
+ }
121
+
122
+ const determinant = this.determinant()
123
+ if (determinant.isZero()) {
124
+ return false
125
+ }
126
+
127
+ return true
128
+ }
129
+
130
+ public canBeMultiplied(matrix: Matrix): boolean {
131
+ return this.dimension.cols === matrix.dimension.rows
132
+ }
133
+
134
+ public characteristic_polynom(letter?: string): Polynom {
135
+ letter ??= 'k'
136
+
137
+ return this.clone().subtract(
138
+ new Matrix(this.dimension.rows).one().multiply(new Polynom(letter))
139
+ ).determinant()
140
+ }
141
+
142
+ public cofactor(row: number, column: number): Polynom {
143
+ // Remove a line.
144
+ const coMatrix = this.clone()
145
+
146
+ coMatrix.values.splice(row, 1)
147
+
148
+ // Remove a column
149
+ coMatrix.values.forEach(row => {
150
+ row.splice(column, 1)
151
+ })
152
+
153
+ return coMatrix.determinant().multiply((-1) ** (row + column))
154
+ }
155
+
156
+ get cols(): Polynom[][] {
157
+ // Return the rows of the transposed matrix !
158
+ const arr = Array.from({length: this.dimension.cols}, () => {
159
+ return Array.from({length: this.dimension.rows}, () => new Polynom())
160
+ })
161
+
162
+ this.forEach((aij, i, j) => {
163
+ arr[j][i] = aij
164
+ })
165
+
166
+ return arr
167
+ }
168
+
169
+ public determinant(): Polynom {
170
+ if (!this.isSquare()) {
171
+ throw new Error('Matrix is not square')
172
+ }
173
+
174
+ // Use the first line.
175
+ // For each value, create the cofactor matrix -> get the determinant
176
+ const det = new Polynom()
177
+
178
+ // It's a 1x1 matrix
179
+ if (this.#values.length === 1) {
180
+ return this.#values[0][0].clone()
181
+ }
182
+
183
+ // It's a matrix greater than 1x1
184
+ this.values[0].forEach((aij, column) => {
185
+ const C = this.cofactor(0, column)
186
+ det.add(aij.clone().multiply(C))
187
+ })
188
+
189
+ return det
190
+ }
191
+
192
+ get dimension(): { rows: number, cols: number } {
193
+ return {
194
+ rows: this.#values.length,
195
+ cols: this.#values[0].length,
196
+ }
197
+ }
198
+
199
+ public flat(): Polynom[] {
200
+ return this.#values.flat()
201
+ }
202
+
203
+ public forEach(callback: (aij: Polynom, row: number, column: number) => void): void {
204
+ this.#values.forEach((row, i) => {
205
+ row.forEach((aij, j) => {
206
+ callback(aij, i, j)
207
+ })
208
+ })
209
+ }
210
+
211
+ public fromDimensions(rows: number, cols: number): this {
212
+ this.#values = Array.from({length: rows}, () => {
213
+ return Array.from({length: cols}, () => new Polynom())
214
+ }) as unknown as Polynom[][]
215
+
216
+ return this
217
+ }
218
+
219
+ public fromString(value: string): this {
220
+ // value = ((a,b),(c,d),(e,f))
221
+ if (value.startsWith('((') && value.endsWith("))")) {
222
+ return this.fromString(value.substring(1, value.length - 1))
223
+ }
224
+
225
+ // value = (a,b),(c,d),(e,f)
226
+ const arr = value.split('),(')
227
+
228
+ this.#values = arr
229
+ .map((row, index) => {
230
+ // (a,b or c,d or e,f)
231
+ if (index === 0) {
232
+ return row.substring(1).split(',')
233
+ } else if (index === arr.length - 1) {
234
+ return row.substring(0, row.length - 1).split(',')
235
+ }
236
+
237
+ return row.split(',')
238
+ })
239
+ .map(rowItems =>
240
+ rowItems.map(item => new Polynom(item))
241
+ )
242
+
243
+ return this
244
+ }
245
+
246
+ public fromValues(values: IMatrixValues): this {
247
+ this.#values = []
248
+
249
+ // Check dimensions of each rows.
250
+ const L = values[0].length
251
+ if (values.some(row => row.length !== L)) {
252
+ throw new Error("Each line must be the same length")
253
+ }
254
+
255
+ values.forEach(row => {
256
+ const dup_row: Polynom[] = []
257
+ row.forEach(value => {
258
+ dup_row.push(new Polynom(value))
259
+ })
260
+
261
+ this.#values.push(dup_row)
262
+ })
263
+
264
+ return this
265
+ }
266
+
267
+ public fromVectors(...vectors: Vector[]): this {
268
+
269
+ this.#values = []
270
+
271
+ // Each vectors must be the same dimension
272
+ const L = vectors[0].dimension
273
+ if (vectors.some(v => v.dimension !== L)) {
274
+ throw new Error("Each vectors must be the same dimension")
275
+ }
276
+
277
+ this.fromDimensions(vectors[0].dimension, vectors.length)
278
+
279
+ vectors.forEach((vector, column) => {
280
+ vector.array.forEach((value, row) => {
281
+ this.#values[row][column] = new Polynom(value)
282
+ })
283
+ })
284
+
285
+ return this
286
+ }
287
+
288
+ public inverse(): this {
289
+ if (!this.canBeInverted()) {
290
+ throw new Error('The matrix cannot be inverted.')
291
+ }
292
+
293
+ const cofactors_matrix = new Matrix().fromDimensions(this.dimension.rows, this.dimension.cols)
294
+ cofactors_matrix.forEach((_, row, column) => {
295
+ cofactors_matrix.setValue(row, column, this.cofactor(row, column))
296
+ })
297
+
298
+ cofactors_matrix.transpose()
299
+
300
+ // Copy the value to "this"
301
+ const determinant = this.determinant()
302
+ cofactors_matrix.forEach((aij, i, j) => this.setValue(i, j, aij.divide(determinant).reduce()))
303
+
304
+ return this
305
+ }
306
+
307
+ public isEqual(value: Matrix): boolean {
308
+ // Two matrix are equals if they are the same dimension and all aij are equals.
309
+ if (!this.canBeAdded(value)) {
310
+ return false
311
+ }
312
+
313
+ let aij_are_equals = true
314
+ this.forEach((aij, row, column) => {
315
+ aij_are_equals &&= aij.isEqual(value.values[row][column])
316
+ })
317
+
318
+ return aij_are_equals
319
+ }
320
+
321
+ public isOne(): boolean {
322
+ for (let row = 0; row < this.#values.length; row++) {
323
+ for (let col = 0; col < this.#values[row].length; col++) {
324
+ if (col === row && !this.#values[row][col].isOne()) {
325
+ return false
326
+ }
327
+ if (col !== row && !this.#values[row][col].isZero()) {
328
+ return false
329
+ }
330
+ }
331
+ }
332
+
333
+ return true
334
+ }
335
+
336
+ public isSquare(): boolean {
337
+ return this.dimension.cols === this.dimension.rows
338
+ }
339
+
340
+ public isZero(): boolean {
341
+ return this.flat().every(v => v.isZero())
342
+ }
343
+
344
+ public map<T>(callback: (aij: Polynom, row: number, column: number) => T): T[][] {
345
+ const {rows, cols} = this.dimension
346
+
347
+ const arr = Array.from({length: rows}, () => {
348
+ return Array.from({length: cols}, () => undefined as T)
349
+ })
350
+
351
+ this.#values.forEach((row, i) => {
352
+ row.forEach((aij, j) => {
353
+ arr[i][j] = callback(aij, i, j)
354
+ })
355
+ })
356
+
357
+ return arr
358
+ }
359
+
360
+ public multiply(value: InputValue<Polynom> | Matrix): this {
361
+ if (value instanceof Matrix) {
362
+ if (!this.canBeMultiplied(value)) {
363
+ throw new Error(`Cannot multiply a matrix with incompatibles dimensions`)
364
+ }
365
+
366
+ // Multiply two matrix
367
+ const result = new Matrix(this.dimension.rows, value.dimension.cols)
368
+ result.forEach((_, i, j) => {
369
+ // Multiply this.rows[i] by this.cols[j]
370
+ const row = this.rows[i]
371
+ const col = value.cols[j]
372
+
373
+ const v = new Polynom()
374
+
375
+ row.forEach((left, k) => {
376
+ v.add(left.clone().multiply(col[k]))
377
+ })
378
+
379
+ result.setValue(i, j, v)
380
+ })
381
+
382
+ this.#values = result.values
383
+ return this
384
+ }
385
+
386
+ // Scalar multiplication
387
+ this.forEach((aij, i, j) => {
388
+ this.setValue(i, j, aij.multiply(value))
389
+ })
390
+ return this
391
+ }
392
+
393
+ public one(): this {
394
+ this.forEach((aij, row, column) => {
395
+ if (row === column) {
396
+ aij.one()
397
+ } else {
398
+ aij.zero()
399
+ }
400
+ })
401
+ return this
402
+ }
403
+
404
+ public opposite(): this {
405
+ this.forEach((aij) => {
406
+ aij.opposite()
407
+ })
408
+ return this
409
+ }
410
+
411
+ get pmatrix(): this {
412
+ this.#matrix_parenthesis = true
413
+ return this
414
+ }
415
+
416
+ public pow(value: number): this {
417
+ return operation_pow(this as Matrix, value) as this
418
+ }
419
+
420
+ public reduce(): Matrix {
421
+ throw new Error('Not yet implemented')
422
+ }
423
+
424
+ get rows(): Polynom[][] {
425
+ return this.#values
426
+ }
427
+
428
+ public setValue(row: number, column: number, value: InputAlgebra<Polynom>): this {
429
+ const {rows, cols} = this.dimension
430
+ if ((row < 0 || row >= rows) ||
431
+ column < 0 || column >= cols) {
432
+ throw new Error(`${row}x${column} is out of range (${rows}x${cols})`)
433
+ }
434
+
435
+ this.#values[row][column] = new Polynom(value)
436
+ return this
437
+ }
438
+
439
+ public subtract(value: Matrix): this {
440
+ if (!this.canBeAdded(value)) {
441
+ throw new Error("Cannot subtract a matrix with different dimensions.")
442
+ }
443
+
444
+ this.forEach((aij, i, j) => {
445
+ aij.subtract(value.values[i][j])
446
+ })
447
+
448
+ return this
449
+ }
450
+
451
+ toFixed(value: number): this {
452
+ this.#digits = value
453
+ return this
454
+ }
455
+
456
+ public transpose(): this {
457
+ const temp = this.clone()
458
+
459
+ temp.forEach((aij, i, j) => {
460
+ this.setValue(j, i, aij.clone())
461
+ })
462
+
463
+ return this
464
+ }
465
+
466
+ get values(): Polynom[][] {
467
+ return this.#values
468
+ }
469
+
470
+ public zero(): this {
471
+ this.forEach(aij => aij.zero())
472
+ return this
473
+ }
474
+ }