@emasoft/svg-matrix 1.0.28 → 1.0.30

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 (46) hide show
  1. package/README.md +325 -0
  2. package/bin/svg-matrix.js +985 -378
  3. package/bin/svglinter.cjs +4172 -433
  4. package/bin/svgm.js +723 -180
  5. package/package.json +16 -4
  6. package/src/animation-references.js +71 -52
  7. package/src/arc-length.js +160 -96
  8. package/src/bezier-analysis.js +257 -117
  9. package/src/bezier-intersections.js +411 -148
  10. package/src/browser-verify.js +240 -100
  11. package/src/clip-path-resolver.js +350 -142
  12. package/src/convert-path-data.js +279 -134
  13. package/src/css-specificity.js +78 -70
  14. package/src/flatten-pipeline.js +751 -263
  15. package/src/geometry-to-path.js +511 -182
  16. package/src/index.js +191 -46
  17. package/src/inkscape-support.js +18 -7
  18. package/src/marker-resolver.js +278 -164
  19. package/src/mask-resolver.js +209 -98
  20. package/src/matrix.js +147 -67
  21. package/src/mesh-gradient.js +187 -96
  22. package/src/off-canvas-detection.js +201 -104
  23. package/src/path-analysis.js +187 -107
  24. package/src/path-data-plugins.js +628 -167
  25. package/src/path-simplification.js +0 -1
  26. package/src/pattern-resolver.js +125 -88
  27. package/src/polygon-clip.js +111 -66
  28. package/src/svg-boolean-ops.js +194 -118
  29. package/src/svg-collections.js +22 -18
  30. package/src/svg-flatten.js +282 -164
  31. package/src/svg-parser.js +427 -200
  32. package/src/svg-rendering-context.js +147 -104
  33. package/src/svg-toolbox.js +16381 -3370
  34. package/src/svg2-polyfills.js +93 -224
  35. package/src/transform-decomposition.js +46 -41
  36. package/src/transform-optimization.js +89 -68
  37. package/src/transforms2d.js +49 -16
  38. package/src/transforms3d.js +58 -22
  39. package/src/use-symbol-resolver.js +150 -110
  40. package/src/vector.js +67 -15
  41. package/src/vendor/README.md +110 -0
  42. package/src/vendor/inkscape-hatch-polyfill.js +401 -0
  43. package/src/vendor/inkscape-hatch-polyfill.min.js +8 -0
  44. package/src/vendor/inkscape-mesh-polyfill.js +843 -0
  45. package/src/vendor/inkscape-mesh-polyfill.min.js +8 -0
  46. package/src/verification.js +288 -124
package/src/matrix.js CHANGED
@@ -1,5 +1,5 @@
1
- import Decimal from 'decimal.js';
2
- import { Vector } from './vector.js';
1
+ import Decimal from "decimal.js";
2
+ import { Vector } from "./vector.js";
3
3
 
4
4
  /**
5
5
  * Helper to convert any numeric input to Decimal.
@@ -7,7 +7,7 @@ import { Vector } from './vector.js';
7
7
  * @param {number|string|Decimal} x - The value to convert
8
8
  * @returns {Decimal} The Decimal representation
9
9
  */
10
- const D = x => (x instanceof Decimal ? x : new Decimal(x));
10
+ const D = (x) => (x instanceof Decimal ? x : new Decimal(x));
11
11
 
12
12
  /**
13
13
  * Matrix - Decimal-backed matrix class for arbitrary-precision matrix operations.
@@ -16,6 +16,11 @@ const D = x => (x instanceof Decimal ? x : new Decimal(x));
16
16
  * Supports basic operations (add, sub, mul, transpose), linear algebra
17
17
  * (LU, QR, determinant, inverse, solve), and matrix exponential.
18
18
  *
19
+ * @class
20
+ * @property {Array<Array<Decimal>>} data - 2D array of Decimal matrix elements
21
+ * @property {number} rows - Number of rows in the matrix
22
+ * @property {number} cols - Number of columns in the matrix
23
+ *
19
24
  * @example
20
25
  * const M = Matrix.from([[1, 2], [3, 4]]);
21
26
  * const I = Matrix.identity(2);
@@ -29,12 +34,14 @@ export class Matrix {
29
34
  * @throws {Error} If data is not a non-empty 2D array with consistent row lengths
30
35
  */
31
36
  constructor(data) {
32
- if (!Array.isArray(data) || data.length === 0) throw new Error('Matrix requires non-empty 2D array');
37
+ if (!Array.isArray(data) || data.length === 0)
38
+ throw new Error("Matrix requires non-empty 2D array");
33
39
  const cols = data[0].length;
34
40
  for (const row of data) {
35
- if (!Array.isArray(row) || row.length !== cols) throw new Error('All rows must have same length');
41
+ if (!Array.isArray(row) || row.length !== cols)
42
+ throw new Error("All rows must have same length");
36
43
  }
37
- this.data = data.map(r => r.map(v => D(v)));
44
+ this.data = data.map((r) => r.map((v) => D(v)));
38
45
  this.rows = data.length;
39
46
  this.cols = cols;
40
47
  }
@@ -55,7 +62,9 @@ export class Matrix {
55
62
  * @returns {Matrix} New r×c zero matrix
56
63
  */
57
64
  static zeros(r, c) {
58
- const out = Array.from({ length: r }, () => Array.from({ length: c }, () => new Decimal(0)));
65
+ const out = Array.from({ length: r }, () =>
66
+ Array.from({ length: c }, () => new Decimal(0)),
67
+ );
59
68
  return new Matrix(out);
60
69
  }
61
70
 
@@ -65,7 +74,11 @@ export class Matrix {
65
74
  * @returns {Matrix} New n×n identity matrix
66
75
  */
67
76
  static identity(n) {
68
- const out = Array.from({ length: n }, (_, i) => Array.from({ length: n }, (_, j) => (i === j ? new Decimal(1) : new Decimal(0))));
77
+ const out = Array.from({ length: n }, (_, i) =>
78
+ Array.from({ length: n }, (_, j) =>
79
+ (i === j ? new Decimal(1) : new Decimal(0)),
80
+ ),
81
+ );
69
82
  return new Matrix(out);
70
83
  }
71
84
 
@@ -74,7 +87,7 @@ export class Matrix {
74
87
  * @returns {Matrix} New Matrix with copied values
75
88
  */
76
89
  clone() {
77
- return new Matrix(this.data.map(r => r.map(v => new Decimal(v))));
90
+ return new Matrix(this.data.map((r) => r.map((v) => new Decimal(v))));
78
91
  }
79
92
 
80
93
  /**
@@ -83,7 +96,7 @@ export class Matrix {
83
96
  * @returns {string[][]} 2D array of string values
84
97
  */
85
98
  toArrayOfStrings() {
86
- return this.data.map(r => r.map(v => v.toString()));
99
+ return this.data.map((r) => r.map((v) => v.toString()));
87
100
  }
88
101
 
89
102
  /**
@@ -92,7 +105,7 @@ export class Matrix {
92
105
  * @returns {number[][]} 2D array of number values
93
106
  */
94
107
  toNumberArray() {
95
- return this.data.map(r => r.map(v => v.toNumber()));
108
+ return this.data.map((r) => r.map((v) => v.toNumber()));
96
109
  }
97
110
 
98
111
  /**
@@ -113,12 +126,14 @@ export class Matrix {
113
126
  let v;
114
127
  if (vec instanceof Vector) v = vec;
115
128
  else if (Array.isArray(vec)) v = Vector.from(vec);
116
- else throw new Error('applyToVector expects Vector or array');
117
- if (this.cols !== v.length) throw new Error('shape mismatch: matrix cols must equal vector length');
129
+ else throw new Error("applyToVector expects Vector or array");
130
+ if (this.cols !== v.length)
131
+ throw new Error("shape mismatch: matrix cols must equal vector length");
118
132
  const out = [];
119
133
  for (let i = 0; i < this.rows; i++) {
120
134
  let sum = new Decimal(0);
121
- for (let j = 0; j < this.cols; j++) sum = sum.plus(this.data[i][j].mul(v.data[j]));
135
+ for (let j = 0; j < this.cols; j++)
136
+ sum = sum.plus(this.data[i][j].mul(v.data[j]));
122
137
  out.push(sum);
123
138
  }
124
139
  return new Vector(out);
@@ -132,11 +147,14 @@ export class Matrix {
132
147
  */
133
148
  add(other) {
134
149
  if (other instanceof Matrix) {
135
- if (this.rows !== other.rows || this.cols !== other.cols) throw new Error('shape mismatch: matrices must have same dimensions');
136
- return new Matrix(this.data.map((r, i) => r.map((v, j) => v.plus(other.data[i][j]))));
150
+ if (this.rows !== other.rows || this.cols !== other.cols)
151
+ throw new Error("shape mismatch: matrices must have same dimensions");
152
+ return new Matrix(
153
+ this.data.map((r, i) => r.map((v, j) => v.plus(other.data[i][j]))),
154
+ );
137
155
  } else {
138
156
  const s = D(other);
139
- return new Matrix(this.data.map(r => r.map(v => v.plus(s))));
157
+ return new Matrix(this.data.map((r) => r.map((v) => v.plus(s))));
140
158
  }
141
159
  }
142
160
 
@@ -148,11 +166,14 @@ export class Matrix {
148
166
  */
149
167
  sub(other) {
150
168
  if (other instanceof Matrix) {
151
- if (this.rows !== other.rows || this.cols !== other.cols) throw new Error('shape mismatch: matrices must have same dimensions');
152
- return new Matrix(this.data.map((r, i) => r.map((v, j) => v.minus(other.data[i][j]))));
169
+ if (this.rows !== other.rows || this.cols !== other.cols)
170
+ throw new Error("shape mismatch: matrices must have same dimensions");
171
+ return new Matrix(
172
+ this.data.map((r, i) => r.map((v, j) => v.minus(other.data[i][j]))),
173
+ );
153
174
  } else {
154
175
  const s = D(other);
155
- return new Matrix(this.data.map(r => r.map(v => v.minus(s))));
176
+ return new Matrix(this.data.map((r) => r.map((v) => v.minus(s))));
156
177
  }
157
178
  }
158
179
 
@@ -164,19 +185,25 @@ export class Matrix {
164
185
  */
165
186
  mul(other) {
166
187
  if (other instanceof Matrix) {
167
- if (this.cols !== other.rows) throw new Error('shape mismatch: A.cols must equal B.rows for matrix multiplication');
168
- const out = Array.from({ length: this.rows }, () => Array.from({ length: other.cols }, () => new Decimal(0)));
188
+ if (this.cols !== other.rows)
189
+ throw new Error(
190
+ "shape mismatch: A.cols must equal B.rows for matrix multiplication",
191
+ );
192
+ const out = Array.from({ length: this.rows }, () =>
193
+ Array.from({ length: other.cols }, () => new Decimal(0)),
194
+ );
169
195
  for (let i = 0; i < this.rows; i++) {
170
196
  for (let k = 0; k < this.cols; k++) {
171
197
  const aik = this.data[i][k];
172
198
  if (aik.isZero()) continue;
173
- for (let j = 0; j < other.cols; j++) out[i][j] = out[i][j].plus(aik.mul(other.data[k][j]));
199
+ for (let j = 0; j < other.cols; j++)
200
+ out[i][j] = out[i][j].plus(aik.mul(other.data[k][j]));
174
201
  }
175
202
  }
176
203
  return new Matrix(out);
177
204
  } else {
178
205
  const s = D(other);
179
- return new Matrix(this.data.map(r => r.map(v => v.mul(s))));
206
+ return new Matrix(this.data.map((r) => r.map((v) => v.mul(s))));
180
207
  }
181
208
  }
182
209
 
@@ -188,8 +215,8 @@ export class Matrix {
188
215
  */
189
216
  div(scalar) {
190
217
  const s = D(scalar);
191
- if (s.isZero()) throw new Error('Cannot divide by zero');
192
- return new Matrix(this.data.map(r => r.map(v => v.div(s))));
218
+ if (s.isZero()) throw new Error("Cannot divide by zero");
219
+ return new Matrix(this.data.map((r) => r.map((v) => v.div(s))));
193
220
  }
194
221
 
195
222
  /**
@@ -197,7 +224,7 @@ export class Matrix {
197
224
  * @returns {Matrix} New Matrix with negated elements
198
225
  */
199
226
  negate() {
200
- return new Matrix(this.data.map(r => r.map(v => v.negated())));
227
+ return new Matrix(this.data.map((r) => r.map((v) => v.negated())));
201
228
  }
202
229
 
203
230
  /**
@@ -205,7 +232,9 @@ export class Matrix {
205
232
  * @returns {Matrix} New transposed Matrix
206
233
  */
207
234
  transpose() {
208
- const out = Array.from({ length: this.cols }, (_, i) => Array.from({ length: this.rows }, (_, j) => new Decimal(this.data[j][i])));
235
+ const out = Array.from({ length: this.cols }, (_, i) =>
236
+ Array.from({ length: this.rows }, (_, j) => new Decimal(this.data[j][i])),
237
+ );
209
238
  return new Matrix(out);
210
239
  }
211
240
 
@@ -216,7 +245,8 @@ export class Matrix {
216
245
  * @throws {Error} If matrix is not square
217
246
  */
218
247
  trace() {
219
- if (!this.isSquare()) throw new Error('Trace only defined for square matrices');
248
+ if (!this.isSquare())
249
+ throw new Error("Trace only defined for square matrices");
220
250
  let sum = new Decimal(0);
221
251
  for (let i = 0; i < this.rows; i++) {
222
252
  sum = sum.plus(this.data[i][i]);
@@ -251,11 +281,14 @@ export class Matrix {
251
281
  * @throws {Error} If matrix is not square or is singular
252
282
  */
253
283
  lu() {
254
- if (!this.isSquare()) throw new Error('LU decomposition requires square matrix');
284
+ if (!this.isSquare())
285
+ throw new Error("LU decomposition requires square matrix");
255
286
  const n = this.rows;
256
- const A = this.data.map(r => r.map(v => new Decimal(v)));
287
+ const A = this.data.map((r) => r.map((v) => new Decimal(v)));
257
288
  const Pvec = Array.from({ length: n }, (_, i) => i);
258
- const L = Array.from({ length: n }, () => Array.from({ length: n }, () => new Decimal(0)));
289
+ const L = Array.from({ length: n }, () =>
290
+ Array.from({ length: n }, () => new Decimal(0)),
291
+ );
259
292
  for (let i = 0; i < n; i++) L[i][i] = new Decimal(1);
260
293
 
261
294
  for (let k = 0; k < n; k++) {
@@ -264,26 +297,39 @@ export class Matrix {
264
297
  let maxAbs = A[k][k].abs();
265
298
  for (let i = k + 1; i < n; i++) {
266
299
  const aabs = A[i][k].abs();
267
- if (aabs.greaterThan(maxAbs)) { maxAbs = aabs; pivot = i; }
300
+ if (aabs.greaterThan(maxAbs)) {
301
+ maxAbs = aabs;
302
+ pivot = i;
303
+ }
268
304
  }
269
- if (A[pivot][k].isZero()) throw new Error('Singular matrix: LU decomposition failed');
305
+ if (A[pivot][k].isZero())
306
+ throw new Error("Singular matrix: LU decomposition failed");
270
307
  // Swap rows
271
308
  if (pivot !== k) {
272
- const tmp = A[k]; A[k] = A[pivot]; A[pivot] = tmp;
273
- const tmpIdx = Pvec[k]; Pvec[k] = Pvec[pivot]; Pvec[pivot] = tmpIdx;
309
+ const tmp = A[k];
310
+ A[k] = A[pivot];
311
+ A[pivot] = tmp;
312
+ const tmpIdx = Pvec[k];
313
+ Pvec[k] = Pvec[pivot];
314
+ Pvec[pivot] = tmpIdx;
274
315
  for (let j = 0; j < k; j++) {
275
- const t = L[k][j]; L[k][j] = L[pivot][j]; L[pivot][j] = t;
316
+ const t = L[k][j];
317
+ L[k][j] = L[pivot][j];
318
+ L[pivot][j] = t;
276
319
  }
277
320
  }
278
321
  // Elimination
279
322
  for (let i = k + 1; i < n; i++) {
280
323
  const factor = A[i][k].div(A[k][k]);
281
324
  L[i][k] = factor;
282
- for (let j = k; j < n; j++) A[i][j] = A[i][j].minus(factor.mul(A[k][j]));
325
+ for (let j = k; j < n; j++)
326
+ A[i][j] = A[i][j].minus(factor.mul(A[k][j]));
283
327
  }
284
328
  }
285
329
 
286
- const U = Array.from({ length: n }, (_, i) => Array.from({ length: n }, (_, j) => (j < i ? new Decimal(0) : A[i][j])));
330
+ const U = Array.from({ length: n }, (_, i) =>
331
+ Array.from({ length: n }, (_, j) => (j < i ? new Decimal(0) : A[i][j])),
332
+ );
287
333
  const P = Matrix.zeros(n, n);
288
334
  for (let i = 0; i < n; i++) P.data[i][Pvec[i]] = new Decimal(1);
289
335
  return { L: new Matrix(L), U: new Matrix(U), P: P };
@@ -296,9 +342,10 @@ export class Matrix {
296
342
  * @throws {Error} If matrix is not square
297
343
  */
298
344
  determinant() {
299
- if (!this.isSquare()) throw new Error('Determinant only defined for square matrices');
345
+ if (!this.isSquare())
346
+ throw new Error("Determinant only defined for square matrices");
300
347
  const n = this.rows;
301
- const { L, U, P } = this.lu();
348
+ const { L: _L, U, P } = this.lu();
302
349
  let det = new Decimal(1);
303
350
  for (let i = 0; i < n; i++) det = det.mul(U.data[i][i]);
304
351
  // Compute permutation sign
@@ -323,13 +370,18 @@ export class Matrix {
323
370
  * @throws {Error} If matrix is not square or is singular
324
371
  */
325
372
  inverse() {
326
- if (!this.isSquare()) throw new Error('Inverse only defined for square matrices');
373
+ if (!this.isSquare())
374
+ throw new Error("Inverse only defined for square matrices");
327
375
  const n = this.rows;
328
376
  // Create augmented matrix [A | I]
329
377
  const aug = Array.from({ length: n }, (_, i) =>
330
378
  Array.from({ length: 2 * n }, (_, j) =>
331
- (j < n ? new Decimal(this.data[i][j]) : (j - n === i ? new Decimal(1) : new Decimal(0)))
332
- )
379
+ (j < n
380
+ ? new Decimal(this.data[i][j])
381
+ : j - n === i
382
+ ? new Decimal(1)
383
+ : new Decimal(0)),
384
+ ),
333
385
  );
334
386
  // Gauss-Jordan elimination
335
387
  for (let col = 0; col < n; col++) {
@@ -338,12 +390,18 @@ export class Matrix {
338
390
  let maxAbs = aug[col][col].abs();
339
391
  for (let r = col + 1; r < n; r++) {
340
392
  const aabs = aug[r][col].abs();
341
- if (aabs.greaterThan(maxAbs)) { maxAbs = aabs; pivot = r; }
393
+ if (aabs.greaterThan(maxAbs)) {
394
+ maxAbs = aabs;
395
+ pivot = r;
396
+ }
342
397
  }
343
- if (aug[pivot][col].isZero()) throw new Error('Singular matrix: inverse does not exist');
398
+ if (aug[pivot][col].isZero())
399
+ throw new Error("Singular matrix: inverse does not exist");
344
400
  // Swap rows
345
401
  if (pivot !== col) {
346
- const tmp = aug[col]; aug[col] = aug[pivot]; aug[pivot] = tmp;
402
+ const tmp = aug[col];
403
+ aug[col] = aug[pivot];
404
+ aug[pivot] = tmp;
347
405
  }
348
406
  // Scale pivot row
349
407
  const pivval = aug[col][col];
@@ -353,11 +411,12 @@ export class Matrix {
353
411
  if (r === col) continue;
354
412
  const factor = aug[r][col];
355
413
  if (factor.isZero()) continue;
356
- for (let j = 0; j < 2 * n; j++) aug[r][j] = aug[r][j].minus(factor.mul(aug[col][j]));
414
+ for (let j = 0; j < 2 * n; j++)
415
+ aug[r][j] = aug[r][j].minus(factor.mul(aug[col][j]));
357
416
  }
358
417
  }
359
418
  // Extract inverse from augmented matrix
360
- const inv = aug.map(row => row.slice(n));
419
+ const inv = aug.map((row) => row.slice(n));
361
420
  return new Matrix(inv);
362
421
  }
363
422
 
@@ -372,13 +431,18 @@ export class Matrix {
372
431
  let B;
373
432
  if (b instanceof Vector) B = b;
374
433
  else if (Array.isArray(b)) B = Vector.from(b);
375
- else throw new Error('b must be Vector or array');
376
- if (!this.isSquare()) throw new Error('solve() only implemented for square matrices');
434
+ else throw new Error("b must be Vector or array");
435
+ if (!this.isSquare())
436
+ throw new Error("solve() only implemented for square matrices");
377
437
  const n = this.rows;
378
- if (B.length !== n) throw new Error('dimension mismatch: b length must equal matrix rows');
438
+ if (B.length !== n)
439
+ throw new Error("dimension mismatch: b length must equal matrix rows");
379
440
  // Create augmented matrix [A | b]
380
441
  const aug = Array.from({ length: n }, (_, i) =>
381
- Array.from({ length: n + 1 }, (_, j) => new Decimal(j < n ? this.data[i][j] : B.data[i]))
442
+ Array.from(
443
+ { length: n + 1 },
444
+ (_, j) => new Decimal(j < n ? this.data[i][j] : B.data[i]),
445
+ ),
382
446
  );
383
447
  // Forward elimination
384
448
  for (let col = 0; col < n; col++) {
@@ -386,14 +450,23 @@ export class Matrix {
386
450
  let maxAbs = aug[col][col].abs();
387
451
  for (let r = col + 1; r < n; r++) {
388
452
  const aabs = aug[r][col].abs();
389
- if (aabs.greaterThan(maxAbs)) { maxAbs = aabs; pivot = r; }
453
+ if (aabs.greaterThan(maxAbs)) {
454
+ maxAbs = aabs;
455
+ pivot = r;
456
+ }
457
+ }
458
+ if (aug[pivot][col].isZero())
459
+ throw new Error("Singular matrix: no unique solution");
460
+ if (pivot !== col) {
461
+ const tmp = aug[col];
462
+ aug[col] = aug[pivot];
463
+ aug[pivot] = tmp;
390
464
  }
391
- if (aug[pivot][col].isZero()) throw new Error('Singular matrix: no unique solution');
392
- if (pivot !== col) { const tmp = aug[col]; aug[col] = aug[pivot]; aug[pivot] = tmp; }
393
465
  for (let r = col + 1; r < n; r++) {
394
466
  const factor = aug[r][col].div(aug[col][col]);
395
467
  if (factor.isZero()) continue;
396
- for (let j = col; j < n + 1; j++) aug[r][j] = aug[r][j].minus(factor.mul(aug[col][j]));
468
+ for (let j = col; j < n + 1; j++)
469
+ aug[r][j] = aug[r][j].minus(factor.mul(aug[col][j]));
397
470
  }
398
471
  }
399
472
  // Back substitution
@@ -412,8 +485,9 @@ export class Matrix {
412
485
  * @returns {{Q: Matrix, R: Matrix}} QR decomposition components
413
486
  */
414
487
  qr() {
415
- const m = this.rows, n = this.cols;
416
- let A = this.data.map(r => r.map(v => new Decimal(v)));
488
+ const m = this.rows,
489
+ n = this.cols;
490
+ const A = this.data.map((r) => r.map((v) => new Decimal(v)));
417
491
  const Q = Matrix.identity(m).data;
418
492
 
419
493
  for (let k = 0; k < Math.min(m, n); k++) {
@@ -442,21 +516,25 @@ export class Matrix {
442
516
  // Apply Householder reflection to A
443
517
  for (let j = k; j < n; j++) {
444
518
  let dot = new Decimal(0);
445
- for (let i = 0; i < v.length; i++) dot = dot.plus(v[i].mul(A[k + i][j]));
446
- for (let i = 0; i < v.length; i++) A[k + i][j] = A[k + i][j].minus(new Decimal(2).mul(v[i]).mul(dot));
519
+ for (let i = 0; i < v.length; i++)
520
+ dot = dot.plus(v[i].mul(A[k + i][j]));
521
+ for (let i = 0; i < v.length; i++)
522
+ A[k + i][j] = A[k + i][j].minus(new Decimal(2).mul(v[i]).mul(dot));
447
523
  }
448
524
 
449
525
  // Apply Householder reflection to Q
450
526
  for (let j = 0; j < m; j++) {
451
527
  let dot = new Decimal(0);
452
- for (let i = 0; i < v.length; i++) dot = dot.plus(v[i].mul(Q[k + i][j]));
453
- for (let i = 0; i < v.length; i++) Q[k + i][j] = Q[k + i][j].minus(new Decimal(2).mul(v[i]).mul(dot));
528
+ for (let i = 0; i < v.length; i++)
529
+ dot = dot.plus(v[i].mul(Q[k + i][j]));
530
+ for (let i = 0; i < v.length; i++)
531
+ Q[k + i][j] = Q[k + i][j].minus(new Decimal(2).mul(v[i]).mul(dot));
454
532
  }
455
533
  }
456
534
 
457
535
  // Extract R (upper triangular part of A)
458
536
  const R = Array.from({ length: m }, (_, i) =>
459
- Array.from({ length: n }, (_, j) => (i <= j ? A[i][j] : new Decimal(0)))
537
+ Array.from({ length: n }, (_, j) => (i <= j ? A[i][j] : new Decimal(0))),
460
538
  );
461
539
  return { Q: new Matrix(Q).transpose(), R: new Matrix(R) };
462
540
  }
@@ -472,7 +550,8 @@ export class Matrix {
472
550
  */
473
551
  exp(options = {}) {
474
552
  const n = this.rows;
475
- if (!this.isSquare()) throw new Error('Matrix exponential requires square matrix');
553
+ if (!this.isSquare())
554
+ throw new Error("Matrix exponential requires square matrix");
476
555
  const ident = Matrix.identity(n);
477
556
 
478
557
  // Compute infinity norm
@@ -480,7 +559,8 @@ export class Matrix {
480
559
  let max = new Decimal(0);
481
560
  for (let i = 0; i < M.rows; i++) {
482
561
  let rowSum = new Decimal(0);
483
- for (let j = 0; j < M.cols; j++) rowSum = rowSum.plus(M.data[i][j].abs());
562
+ for (let j = 0; j < M.cols; j++)
563
+ rowSum = rowSum.plus(M.data[i][j].abs());
484
564
  if (rowSum.greaterThan(max)) max = rowSum;
485
565
  }
486
566
  return max;
@@ -498,7 +578,7 @@ export class Matrix {
498
578
 
499
579
  // Taylor series
500
580
  const maxIter = options.maxIter || 120;
501
- const tol = new Decimal(options.tolerance || '1e-40');
581
+ const tol = new Decimal(options.tolerance || "1e-40");
502
582
  let term = ident.clone();
503
583
  let result = ident.clone();
504
584
  for (let k = 1; k < maxIter; k++) {