@pawells/math-extended 2.0.0 → 3.0.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 (118) hide show
  1. package/README.md +15 -21
  2. package/build/clamp.d.ts +5 -5
  3. package/build/clamp.js +5 -5
  4. package/build/core.d.ts +23 -0
  5. package/build/core.d.ts.map +1 -0
  6. package/build/core.js +25 -0
  7. package/build/core.js.map +1 -0
  8. package/build/index.d.ts +1 -4
  9. package/build/index.d.ts.map +1 -1
  10. package/build/index.js +1 -6
  11. package/build/index.js.map +1 -1
  12. package/build/interpolation.d.ts +158 -171
  13. package/build/interpolation.d.ts.map +1 -1
  14. package/build/interpolation.js +162 -181
  15. package/build/interpolation.js.map +1 -1
  16. package/build/matrices/arithmetic.d.ts +132 -132
  17. package/build/matrices/arithmetic.d.ts.map +1 -1
  18. package/build/matrices/arithmetic.js +194 -226
  19. package/build/matrices/arithmetic.js.map +1 -1
  20. package/build/matrices/asserts.d.ts +30 -408
  21. package/build/matrices/asserts.d.ts.map +1 -1
  22. package/build/matrices/asserts.js +98 -542
  23. package/build/matrices/asserts.js.map +1 -1
  24. package/build/matrices/core.d.ts +117 -46
  25. package/build/matrices/core.d.ts.map +1 -1
  26. package/build/matrices/core.js +127 -103
  27. package/build/matrices/core.js.map +1 -1
  28. package/build/matrices/decompositions.d.ts +95 -96
  29. package/build/matrices/decompositions.d.ts.map +1 -1
  30. package/build/matrices/decompositions.js +119 -160
  31. package/build/matrices/decompositions.js.map +1 -1
  32. package/build/matrices/index.d.ts +0 -1
  33. package/build/matrices/index.d.ts.map +1 -1
  34. package/build/matrices/index.js +0 -3
  35. package/build/matrices/index.js.map +1 -1
  36. package/build/matrices/linear-algebra.d.ts +45 -8
  37. package/build/matrices/linear-algebra.d.ts.map +1 -1
  38. package/build/matrices/linear-algebra.js +76 -32
  39. package/build/matrices/linear-algebra.js.map +1 -1
  40. package/build/matrices/normalization.d.ts +29 -8
  41. package/build/matrices/normalization.d.ts.map +1 -1
  42. package/build/matrices/normalization.js +32 -23
  43. package/build/matrices/normalization.js.map +1 -1
  44. package/build/matrices/transformations.d.ts +116 -148
  45. package/build/matrices/transformations.d.ts.map +1 -1
  46. package/build/matrices/transformations.js +69 -91
  47. package/build/matrices/transformations.js.map +1 -1
  48. package/build/matrices/types.d.ts +32 -60
  49. package/build/matrices/types.d.ts.map +1 -1
  50. package/build/matrices/types.js +63 -1
  51. package/build/matrices/types.js.map +1 -1
  52. package/build/quaternions/asserts.d.ts +29 -38
  53. package/build/quaternions/asserts.d.ts.map +1 -1
  54. package/build/quaternions/asserts.js +61 -77
  55. package/build/quaternions/asserts.js.map +1 -1
  56. package/build/quaternions/conversions.d.ts +26 -26
  57. package/build/quaternions/conversions.d.ts.map +1 -1
  58. package/build/quaternions/conversions.js +24 -24
  59. package/build/quaternions/core.d.ts +70 -69
  60. package/build/quaternions/core.d.ts.map +1 -1
  61. package/build/quaternions/core.js +71 -71
  62. package/build/quaternions/core.js.map +1 -1
  63. package/build/quaternions/index.d.ts +0 -1
  64. package/build/quaternions/index.d.ts.map +1 -1
  65. package/build/quaternions/index.js +0 -2
  66. package/build/quaternions/index.js.map +1 -1
  67. package/build/quaternions/interpolation.d.ts +16 -16
  68. package/build/quaternions/interpolation.d.ts.map +1 -1
  69. package/build/quaternions/interpolation.js +21 -21
  70. package/build/quaternions/interpolation.js.map +1 -1
  71. package/build/quaternions/predefined.d.ts +10 -10
  72. package/build/quaternions/predefined.d.ts.map +1 -1
  73. package/build/quaternions/predefined.js +9 -9
  74. package/build/quaternions/types.d.ts +23 -12
  75. package/build/quaternions/types.d.ts.map +1 -1
  76. package/build/quaternions/types.js +51 -1
  77. package/build/quaternions/types.js.map +1 -1
  78. package/build/random.d.ts +66 -20
  79. package/build/random.d.ts.map +1 -1
  80. package/build/random.js +73 -20
  81. package/build/random.js.map +1 -1
  82. package/build/vectors/asserts.d.ts +50 -220
  83. package/build/vectors/asserts.d.ts.map +1 -1
  84. package/build/vectors/asserts.js +141 -327
  85. package/build/vectors/asserts.js.map +1 -1
  86. package/build/vectors/core.d.ts +182 -229
  87. package/build/vectors/core.d.ts.map +1 -1
  88. package/build/vectors/core.js +234 -288
  89. package/build/vectors/core.js.map +1 -1
  90. package/build/vectors/index.d.ts +0 -1
  91. package/build/vectors/index.d.ts.map +1 -1
  92. package/build/vectors/index.js +0 -2
  93. package/build/vectors/index.js.map +1 -1
  94. package/build/vectors/interpolation.d.ts +40 -40
  95. package/build/vectors/interpolation.d.ts.map +1 -1
  96. package/build/vectors/interpolation.js +75 -86
  97. package/build/vectors/interpolation.js.map +1 -1
  98. package/build/vectors/predefined.d.ts +31 -7
  99. package/build/vectors/predefined.d.ts.map +1 -1
  100. package/build/vectors/predefined.js +30 -6
  101. package/build/vectors/predefined.js.map +1 -1
  102. package/build/vectors/types.d.ts +26 -4
  103. package/build/vectors/types.d.ts.map +1 -1
  104. package/build/vectors/types.js +50 -1
  105. package/build/vectors/types.js.map +1 -1
  106. package/package.json +3 -2
  107. package/build/matrices/_exports.d.ts +0 -13
  108. package/build/matrices/_exports.d.ts.map +0 -1
  109. package/build/matrices/_exports.js +0 -13
  110. package/build/matrices/_exports.js.map +0 -1
  111. package/build/quaternions/_exports.d.ts +0 -11
  112. package/build/quaternions/_exports.d.ts.map +0 -1
  113. package/build/quaternions/_exports.js +0 -11
  114. package/build/quaternions/_exports.js.map +0 -1
  115. package/build/vectors/_exports.d.ts +0 -10
  116. package/build/vectors/_exports.d.ts.map +0 -1
  117. package/build/vectors/_exports.js +0 -10
  118. package/build/vectors/_exports.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  import { AssertNumber } from '@pawells/typescript-common';
2
- import { AssertMatrices, AssertMatrix, AssertMatrix1, AssertMatrix2, AssertMatrix3, AssertMatrix4, AssertMatrixRow, AssertMatrixValue } from './asserts.js';
3
- import { MatrixCreate, MatrixIsSquare, MatrixSize } from './core.js';
2
+ import { AssertMatricesCompatible, AssertMatrix, AssertMatrix1, AssertMatrix2, AssertMatrix3, AssertMatrix4, AssertMatrixSquare, MatrixError } from './asserts.js';
3
+ import { MatrixCreate, MatrixSize } from './core.js';
4
4
  import { ValidateVector, AssertVector } from '../vectors/asserts.js';
5
5
  /**
6
6
  * Performs element-wise addition of two matrices.
@@ -28,42 +28,40 @@ import { ValidateVector, AssertVector } from '../vectors/asserts.js';
28
28
  * @throws {Error} If matrices have different dimensions or contain invalid values
29
29
  *
30
30
  * @example
31
- * ```typescript
32
- * ```typescript
33
- * // Adding 2×2 matrices
34
- * MatrixAdd([[1, 2], [3, 4]], [[5, 6], [7, 8]]) // Returns [[6, 8], [10, 12]]
35
- * // Adding 1×3 row vectors
36
- * MatrixAdd([[1, 2, 3]], [[4, 5, 6]]) // Returns [[5, 7, 9]]
37
- * // Type-safe matrix addition with specific matrix types
38
- * const matrixA: TMatrix2 = [[1, 2], [3, 4]];
39
- * const matrixB: TMatrix2 = [[5, 6], [7, 8]];
40
- * const result: TMatrix2 = MatrixAdd(matrixA, matrixB);
41
- * ```
42
- * ```
31
+ * ```typescript
32
+ * ```typescript
33
+ * // Adding 2×2 matrices
34
+ * MatrixAdd([[1, 2], [3, 4]], [[5, 6], [7, 8]]) // Returns [[6, 8], [10, 12]]
35
+ * // Adding 1×3 row vectors
36
+ * MatrixAdd([[1, 2, 3]], [[4, 5, 6]]) // Returns [[5, 7, 9]]
37
+ * // Type-safe matrix addition with specific matrix types
38
+ * const matrixA: TMatrix2 = [[1, 2], [3, 4]];
39
+ * const matrixB: TMatrix2 = [[5, 6], [7, 8]];
40
+ * const result: TMatrix2 = MatrixAdd(matrixA, matrixB);
41
+ * ```
42
+ * ```
43
43
  */
44
44
  export function MatrixAdd(a, b) {
45
45
  // Validate matrices have compatible dimensions for addition
46
- AssertMatrices(a, b);
47
- // Initialize result matrix with same dimensions as inputs
46
+ AssertMatrix(a);
47
+ AssertMatrix(b);
48
+ AssertMatricesCompatible(a, b);
49
+ // Ensure matrices have the same dimensions
48
50
  const [arows, acols] = MatrixSize(a);
51
+ // Initialize result matrix with same dimensions as inputs
49
52
  const result = MatrixCreate(arows, acols);
50
53
  // Perform element-wise addition: C[i,j] = A[i,j] + B[i,j]
51
54
  for (let row = 0; row < arows; row++) {
52
55
  // Get row references for both input matrices
53
56
  const aRow = a[row];
54
- AssertMatrixRow(aRow);
55
57
  const bRow = b[row];
56
- AssertMatrixRow(bRow);
57
58
  // Get reference to result row for efficient access
58
59
  const resultRow = result[row];
59
- AssertMatrixRow(resultRow);
60
60
  // Add corresponding elements column by column
61
61
  for (let col = 0; col < acols; col++) {
62
62
  // Validate and extract values from both matrices
63
63
  const aVal = aRow[col];
64
- AssertMatrixValue(aVal, { rowIndex: row, columnIndex: col });
65
64
  const bVal = bRow[col];
66
- AssertMatrixValue(bVal, { rowIndex: row, columnIndex: col });
67
65
  // Store sum in result matrix
68
66
  resultRow[col] = aVal + bVal;
69
67
  }
@@ -96,21 +94,23 @@ export function MatrixAdd(a, b) {
96
94
  * @throws {Error} If matrices have different dimensions or contain invalid values
97
95
  *
98
96
  * @example
99
- * ```typescript
100
- * ```typescript
101
- * // Subtracting 2×2 matrices
102
- * MatrixSubtract([[10, 8], [6, 4]], [[3, 2], [1, 1]]) // Returns [[7, 6], [5, 3]]
103
- * // Order matters: A - B ≠ B - A
104
- * MatrixSubtract([[1, 2]], [[3, 4]]) // Returns [[-2, -2]]
105
- * MatrixSubtract([[3, 4]], [[1, 2]]) // Returns [[2, 2]]
106
- * // Self-subtraction produces zero matrix
107
- * MatrixSubtract([[5, 6]], [[5, 6]]) // Returns [[0, 0]]
108
- * ```
109
- * ```
97
+ * ```typescript
98
+ * ```typescript
99
+ * // Subtracting 2×2 matrices
100
+ * MatrixSubtract([[10, 8], [6, 4]], [[3, 2], [1, 1]]) // Returns [[7, 6], [5, 3]]
101
+ * // Order matters: A - B ≠ B - A
102
+ * MatrixSubtract([[1, 2]], [[3, 4]]) // Returns [[-2, -2]]
103
+ * MatrixSubtract([[3, 4]], [[1, 2]]) // Returns [[2, 2]]
104
+ * // Self-subtraction produces zero matrix
105
+ * MatrixSubtract([[5, 6]], [[5, 6]]) // Returns [[0, 0]]
106
+ * ```
107
+ * ```
110
108
  */
111
109
  export function MatrixSubtract(a, b) {
112
110
  // Validate matrices have compatible dimensions for subtraction
113
- AssertMatrices(a, b);
111
+ AssertMatrix(a);
112
+ AssertMatrix(b);
113
+ AssertMatricesCompatible(a, b);
114
114
  // Initialize result matrix with same dimensions as inputs
115
115
  const [arows, acols] = MatrixSize(a);
116
116
  const result = MatrixCreate(arows, acols);
@@ -118,18 +118,13 @@ export function MatrixSubtract(a, b) {
118
118
  for (let row = 0; row < arows; row++) {
119
119
  // Get row references for both input matrices
120
120
  const aRow = a[row];
121
- AssertMatrixRow(aRow);
122
121
  const bRow = b[row];
123
- AssertMatrixRow(bRow);
124
122
  // Get reference to result row for efficient access
125
123
  const resultRow = result[row];
126
- AssertMatrixRow(resultRow);
127
124
  // Subtract corresponding elements column by column
128
125
  for (let col = 0; col < acols; col++) {
129
126
  const aVal = aRow[col];
130
- AssertMatrixValue(aVal, { rowIndex: row, columnIndex: col });
131
127
  const bVal = bRow[col];
132
- AssertMatrixValue(bVal, { rowIndex: row, columnIndex: col });
133
128
  // Store difference in result matrix
134
129
  resultRow[col] = aVal - bVal;
135
130
  }
@@ -153,13 +148,10 @@ function matrixMultiplyScalar(matrix, scalar) {
153
148
  // Apply scalar multiplication to each matrix element
154
149
  for (let row = 0; row < rows; row++) {
155
150
  const matrixRow = matrix[row];
156
- AssertMatrixRow(matrixRow);
157
151
  const resultRow = result[row];
158
- AssertMatrixRow(resultRow);
159
152
  // Multiply each element in the row by the scalar
160
153
  for (let col = 0; col < cols; col++) {
161
154
  const val = matrixRow[col];
162
- AssertMatrixValue(val, { rowIndex: row, columnIndex: col });
163
155
  resultRow[col] = val * scalar;
164
156
  }
165
157
  }
@@ -172,25 +164,21 @@ function matrixMultiplyVector(matrix, vector) {
172
164
  // Get matrix dimensions
173
165
  const [matrixRows, matrixCols] = MatrixSize(matrix);
174
166
  // Verify dimensional compatibility: matrix columns must equal vector length
175
- if (matrixCols !== vector.length) {
167
+ if (matrixCols !== vector.length)
176
168
  throw new Error(`Matrix-vector multiplication requires matrix columns (${matrixCols}) to equal vector length (${vector.length})`);
177
- }
178
169
  // Initialize result vector with same length as matrix rows
179
170
  const result = new Array(matrixRows);
180
171
  // Compute each element of the result vector
181
172
  for (let row = 0; row < matrixRows; row++) {
182
173
  // Get matrix row reference
183
174
  const matrixRow = matrix[row];
184
- AssertMatrixRow(matrixRow);
185
175
  // Compute dot product of matrix row with vector
186
176
  let dotProduct = 0;
187
177
  for (let col = 0; col < matrixCols; col++) {
188
178
  // Validate matrix element
189
179
  const matrixElement = matrixRow[col];
190
- AssertMatrixValue(matrixElement, { rowIndex: row, columnIndex: col });
191
180
  // Validate vector element
192
181
  const vectorElement = vector[col];
193
- AssertNumber(vectorElement);
194
182
  // Add to dot product
195
183
  dotProduct += matrixElement * vectorElement;
196
184
  }
@@ -201,13 +189,15 @@ function matrixMultiplyVector(matrix, vector) {
201
189
  }
202
190
  function matrixMultiplyMatrix(a, b) {
203
191
  // Validate matrices are compatible for multiplication (a.columns === b.rows)
204
- AssertMatrices(a, b, { transposition: true });
192
+ AssertMatrix(a);
193
+ AssertMatrix(b);
205
194
  const [arows, acols] = MatrixSize(a);
206
- const aSquare = MatrixIsSquare(a);
207
195
  const [brows, bcols] = MatrixSize(b);
208
- const bSquare = MatrixIsSquare(b);
196
+ if (acols !== brows) {
197
+ throw new MatrixError(`Cannot multiply matrices: [${arows}×${acols}] × [${brows}×${bcols}] - columns of first matrix must equal rows of second matrix`);
198
+ }
209
199
  // Use optimized algorithms for specific square matrix sizes
210
- if (aSquare && bSquare && arows === brows && acols === bcols) {
200
+ if (arows === acols && brows === bcols && arows === brows && acols === bcols) {
211
201
  const aSizeSquare = arows;
212
202
  if (aSizeSquare === 1) {
213
203
  AssertMatrix1(a);
@@ -240,19 +230,14 @@ function matrixMultiplyMatrix(a, b) {
240
230
  // Iterate through each position in the result matrix
241
231
  for (let row = 0; row < arows; row++) {
242
232
  const aRow = a[row];
243
- AssertMatrixRow(aRow);
244
233
  const resultRow = result[row];
245
- AssertMatrixRow(resultRow);
246
234
  for (let col = 0; col < bcols; col++) {
247
235
  let sum = 0;
248
236
  // Compute dot product of matrix A row with matrix B column
249
237
  for (let k = 0; k < acols; k++) {
250
238
  const aVal = aRow[k];
251
- AssertMatrixValue(aVal, { rowIndex: row, columnIndex: k });
252
239
  const bRow = b[k];
253
- AssertMatrixRow(bRow);
254
240
  const bVal = bRow[col];
255
- AssertMatrixValue(bVal, { rowIndex: k, columnIndex: col });
256
241
  // Skip multiplication if either operand is zero (performance optimization)
257
242
  if (aVal === 0 || bVal === 0)
258
243
  continue;
@@ -285,8 +270,8 @@ function matrixMultiplyMatrix(a, b) {
285
270
  * @returns {TMatrix1} The product as a 1×1 matrix [[a×b]]
286
271
  *
287
272
  * @example
288
- * ```typescript
289
- * ```typescript
273
+ * ```typescript
274
+ * ```typescript
290
275
  * // Simple scalar values in matrix form
291
276
  * matrixMultiplyMatrix1([[5]], [[3]]) // Returns [[15]]
292
277
  * // Decimal multiplication
@@ -295,8 +280,8 @@ function matrixMultiplyMatrix(a, b) {
295
280
  * matrixMultiplyMatrix1([[-3]], [[7]]) // Returns [[-21]]
296
281
  * // Zero multiplication
297
282
  * matrixMultiplyMatrix1([[0]], [[999]]) // Returns [[0]]
298
- * ```
299
- * ```
283
+ * ```
284
+ * ```
300
285
  */
301
286
  function matrixMultiplyMatrix1(a, b) {
302
287
  return [[a[0][0] * b[0][0]]];
@@ -328,22 +313,22 @@ function matrixMultiplyMatrix1(a, b) {
328
313
  * @param b - Second 2×2 matrix
329
314
  * @returns {TMatrix2} The product as a 2×2 matrix
330
315
  * @example
331
- * ```typescript
332
- * ```typescript
333
- * // Standard 2x2 multiplication
334
- * matrixMultiplyMatrix2([[1, 2], [3, 4]], [[5, 6], [7, 8]])
335
- * // Returns [[19, 22], [43, 50]]
336
- * // Calculation:
337
- * // [1*5+2*7, 1*6+2*8] = [19, 22]
338
- * // [3*5+4*7, 3*6+4*8] = [43, 50]
339
- * // 2D rotation by 90 degrees (rotation matrix)
340
- * matrixMultiplyMatrix2([[0, -1], [1, 0]], [[1, 0], [0, 1]])
341
- * // Returns [[0, -1], [1, 0]]
342
- * // Scaling transformation
343
- * matrixMultiplyMatrix2([[2, 0], [0, 3]], [[1, 2], [3, 4]])
344
- * // Returns [[2, 4], [9, 12]]
345
- * ```
346
- * ```
316
+ * ```typescript
317
+ * ```typescript
318
+ * // Standard 2x2 multiplication
319
+ * matrixMultiplyMatrix2([[1, 2], [3, 4]], [[5, 6], [7, 8]])
320
+ * // Returns [[19, 22], [43, 50]]
321
+ * // Calculation:
322
+ * // [1*5+2*7, 1*6+2*8] = [19, 22]
323
+ * // [3*5+4*7, 3*6+4*8] = [43, 50]
324
+ * // 2D rotation by 90 degrees (rotation matrix)
325
+ * matrixMultiplyMatrix2([[0, -1], [1, 0]], [[1, 0], [0, 1]])
326
+ * // Returns [[0, -1], [1, 0]]
327
+ * // Scaling transformation
328
+ * matrixMultiplyMatrix2([[2, 0], [0, 3]], [[1, 2], [3, 4]])
329
+ * // Returns [[2, 4], [9, 12]]
330
+ * ```
331
+ * ```
347
332
  */
348
333
  function matrixMultiplyMatrix2(a, b) {
349
334
  return [
@@ -387,20 +372,20 @@ function matrixMultiplyMatrix2(a, b) {
387
372
  * @param b - Second 3×3 matrix
388
373
  * @returns {TMatrix3} The product as a 3×3 matrix
389
374
  * @example
390
- * ```typescript
391
- * ```typescript
392
- * // 3D rotation matrix multiplication (combining rotations)
393
- * const rotX = [[1, 0, 0], [0, 0.707, -0.707], [0, 0.707, 0.707]]; // X rotation
394
- * const rotY = [[0.707, 0, 0.707], [0, 1, 0], [-0.707, 0, 0.707]]; // Y rotation
395
- * matrixMultiplyMatrix3(rotX, rotY) // Combined X-Y rotation
396
- * // Identity matrix test
397
- * matrixMultiplyMatrix3([[1, 2, 3], [4, 5, 6], [7, 8, 9]], [[1, 0, 0], [0, 1, 0], [0, 0, 1]])
398
- * // Returns [[1, 2, 3], [4, 5, 6], [7, 8, 9]] (unchanged)
399
- * // Scaling transformation
400
- * matrixMultiplyMatrix3([[2, 0, 0], [0, 3, 0], [0, 0, 4]], [[1, 1, 1], [1, 1, 1], [1, 1, 1]])
401
- * // Returns [[2, 2, 2], [3, 3, 3], [4, 4, 4]]
402
- * ```
403
- * ```
375
+ * ```typescript
376
+ * ```typescript
377
+ * // 3D rotation matrix multiplication (combining rotations)
378
+ * const rotX = [[1, 0, 0], [0, 0.707, -0.707], [0, 0.707, 0.707]]; // X rotation
379
+ * const rotY = [[0.707, 0, 0.707], [0, 1, 0], [-0.707, 0, 0.707]]; // Y rotation
380
+ * matrixMultiplyMatrix3(rotX, rotY) // Combined X-Y rotation
381
+ * // Identity matrix test
382
+ * matrixMultiplyMatrix3([[1, 2, 3], [4, 5, 6], [7, 8, 9]], [[1, 0, 0], [0, 1, 0], [0, 0, 1]])
383
+ * // Returns [[1, 2, 3], [4, 5, 6], [7, 8, 9]] (unchanged)
384
+ * // Scaling transformation
385
+ * matrixMultiplyMatrix3([[2, 0, 0], [0, 3, 0], [0, 0, 4]], [[1, 1, 1], [1, 1, 1], [1, 1, 1]])
386
+ * // Returns [[2, 2, 2], [3, 3, 3], [4, 4, 4]]
387
+ * ```
388
+ * ```
404
389
  */
405
390
  function matrixMultiplyMatrix3(a, b) {
406
391
  return [
@@ -459,22 +444,22 @@ function matrixMultiplyMatrix3(a, b) {
459
444
  * @param b - Second 4×4 matrix (typically another transformation matrix)
460
445
  * @returns {TMatrix4} The product as a 4×4 matrix (combined transformation)
461
446
  * @example
462
- * ```typescript
463
- * ```typescript
464
- * // Combine translation and rotation matrices (common in 3D graphics)
465
- * const translation = [[1,0,0,5], [0,1,0,3], [0,0,1,0], [0,0,0,1]]; // Translate by (5,3,0)
466
- * const rotation = [[0,-1,0,0], [1,0,0,0], [0,0,1,0], [0,0,0,1]]; // 90° Z rotation
467
- * matrixMultiplyMatrix4(translation, rotation); // Combined transform
468
- * // Identity matrix test (should return unchanged matrix)
469
- * const testMatrix = [[1,2,3,4], [5,6,7,8], [9,10,11,12], [13,14,15,16]];
470
- * const identity = [[1,0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1]];
471
- * matrixMultiplyMatrix4(testMatrix, identity) // Returns testMatrix unchanged
472
- * // Perspective projection matrix combination
473
- * const projection = [[2,0,0,0], [0,2,0,0], [0,0,-1,-1], [0,0,-2,0]];
474
- * const view = [[1,0,0,0], [0,1,0,0], [0,0,1,-10], [0,0,0,1]];
475
- * matrixMultiplyMatrix4(projection, view); // Combined projection-view matrix
476
- * ```
477
- * ```
447
+ * ```typescript
448
+ * ```typescript
449
+ * // Combine translation and rotation matrices (common in 3D graphics)
450
+ * const translation = [[1,0,0,5], [0,1,0,3], [0,0,1,0], [0,0,0,1]]; // Translate by (5,3,0)
451
+ * const rotation = [[0,-1,0,0], [1,0,0,0], [0,0,1,0], [0,0,0,1]]; // 90° Z rotation
452
+ * matrixMultiplyMatrix4(translation, rotation); // Combined transform
453
+ * // Identity matrix test (should return unchanged matrix)
454
+ * const testMatrix = [[1,2,3,4], [5,6,7,8], [9,10,11,12], [13,14,15,16]];
455
+ * const identity = [[1,0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1]];
456
+ * matrixMultiplyMatrix4(testMatrix, identity) // Returns testMatrix unchanged
457
+ * // Perspective projection matrix combination
458
+ * const projection = [[2,0,0,0], [0,2,0,0], [0,0,-1,-1], [0,0,-2,0]];
459
+ * const view = [[1,0,0,0], [0,1,0,0], [0,0,1,-10], [0,0,0,1]];
460
+ * matrixMultiplyMatrix4(projection, view); // Combined projection-view matrix
461
+ * ```
462
+ * ```
478
463
  */
479
464
  function matrixMultiplyMatrix4(a, b) {
480
465
  return [
@@ -558,34 +543,35 @@ function matrixMultiplyMatrix4(a, b) {
558
543
  * @throws {Error} If matrices are not square or have incompatible dimensions
559
544
  *
560
545
  * @example
561
- * ```typescript
562
- * ```typescript
563
- * // Large matrix multiplication (automatically used for 32×32 and larger)
564
- * const size = 256;
565
- * const largeA = MatrixCreate(size, size); // Create 256×256 matrix
566
- * const largeB = MatrixCreate(size, size); // Create 256×256 matrix
567
- * // ... fill matrices with data ...
568
- * const result = matrixMultiplyStrassen(largeA, largeB); // Uses Strassen algorithm
569
- * // Performance comparison for large matrices:
570
- * // Standard O(n³): ~16.8M operations for 256×256
571
- * // Strassen O(n^2.807): ~11.2M operations for 256×256 (33% reduction)
572
- * // Odd-sized matrices are automatically handled with padding
573
- * const oddMatrix = MatrixCreate(127, 127); // Will be padded to 128×128 internally
574
- * const result2 = matrixMultiplyStrassen(oddMatrix, oddMatrix);
575
- * // Base case automatically falls back to standard algorithm
576
- * const small = MatrixCreate(16, 16); // Uses standard algorithm (< 32×32)
577
- * const result3 = matrixMultiplyStrassen(small, small);
578
- * ```
579
- * ```
546
+ * ```typescript
547
+ * ```typescript
548
+ * // Large matrix multiplication (automatically used for 32×32 and larger)
549
+ * const size = 256;
550
+ * const largeA = MatrixCreate(size, size); // Create 256×256 matrix
551
+ * const largeB = MatrixCreate(size, size); // Create 256×256 matrix
552
+ * // ... fill matrices with data ...
553
+ * const result = matrixMultiplyStrassen(largeA, largeB); // Uses Strassen algorithm
554
+ * // Performance comparison for large matrices:
555
+ * // Standard O(n³): ~16.8M operations for 256×256
556
+ * // Strassen O(n^2.807): ~11.2M operations for 256×256 (33% reduction)
557
+ * // Odd-sized matrices are automatically handled with padding
558
+ * const oddMatrix = MatrixCreate(127, 127); // Will be padded to 128×128 internally
559
+ * const result2 = matrixMultiplyStrassen(oddMatrix, oddMatrix);
560
+ * // Base case automatically falls back to standard algorithm
561
+ * const small = MatrixCreate(16, 16); // Uses standard algorithm (< 32×32)
562
+ * const result3 = matrixMultiplyStrassen(small, small);
563
+ * ```
564
+ * ```
580
565
  */
581
566
  function matrixMultiplyStrassen(a, b) {
582
- AssertMatrix(a, { square: true });
583
- AssertMatrix(b, { square: true });
567
+ AssertMatrix(a);
568
+ AssertMatrixSquare(a);
569
+ AssertMatrix(b);
570
+ AssertMatrixSquare(b);
584
571
  const [arows, _acols] = MatrixSize(a);
585
572
  const [brows, _bcols] = MatrixSize(b);
586
- if (arows !== brows) {
573
+ if (arows !== brows)
587
574
  throw new Error(`Matrix dimensions incompatible for multiplication: ${arows}×${arows} and ${brows}×${brows}`);
588
- }
589
575
  const n = arows;
590
576
  // Base case: use standard multiplication for small matrices to avoid overhead
591
577
  if (n < 32) {
@@ -671,29 +657,29 @@ function matrixMultiplyStrassen(a, b) {
671
657
  * @returns {TMatrix} The extracted submatrix with dimensions height×width
672
658
  * @throws {Error} If extraction bounds exceed matrix dimensions or contain invalid values
673
659
  * @example
674
- * ```typescript
675
- * ```typescript
676
- * const matrix = [
677
- * [1, 2, 3, 4],
678
- * [5, 6, 7, 8],
679
- * [9, 10, 11, 12]
680
- * ]; // 3×4 matrix
681
- * // Extract 2×2 submatrix from top-left corner
682
- * MatrixSubmatrix(matrix, 0, 0, 2, 2) // Returns [[1, 2], [5, 6]]
683
- * // Extract 2×2 submatrix from center-right region
684
- * MatrixSubmatrix(matrix, 2, 1, 2, 2) // Returns [[7, 8], [11, 12]]
685
- * // Extract single column (column vector)
686
- * MatrixSubmatrix(matrix, 1, 0, 1, 3) // Returns [[2], [6], [10]]
687
- * // Extract single row (row vector)
688
- * MatrixSubmatrix(matrix, 0, 1, 4, 1) // Returns [[5, 6, 7, 8]]
689
- * // Block matrix partitioning for algorithms
690
- * const large = MatrixCreate(8, 8); // 8×8 matrix
691
- * const topLeft = MatrixSubmatrix(large, 0, 0, 4, 4); // Top-left 4×4 block
692
- * const topRight = MatrixSubmatrix(large, 4, 0, 4, 4); // Top-right 4×4 block
693
- * const bottomLeft = MatrixSubmatrix(large, 0, 4, 4, 4); // Bottom-left 4×4 block
694
- * const bottomRight = MatrixSubmatrix(large, 4, 4, 4, 4); // Bottom-right 4×4 block
695
- * ```
696
- * ```
660
+ * ```typescript
661
+ * ```typescript
662
+ * const matrix = [
663
+ * [1, 2, 3, 4],
664
+ * [5, 6, 7, 8],
665
+ * [9, 10, 11, 12]
666
+ * ]; // 3×4 matrix
667
+ * // Extract 2×2 submatrix from top-left corner
668
+ * MatrixSubmatrix(matrix, 0, 0, 2, 2) // Returns [[1, 2], [5, 6]]
669
+ * // Extract 2×2 submatrix from center-right region
670
+ * MatrixSubmatrix(matrix, 2, 1, 2, 2) // Returns [[7, 8], [11, 12]]
671
+ * // Extract single column (column vector)
672
+ * MatrixSubmatrix(matrix, 1, 0, 1, 3) // Returns [[2], [6], [10]]
673
+ * // Extract single row (row vector)
674
+ * MatrixSubmatrix(matrix, 0, 1, 4, 1) // Returns [[5, 6, 7, 8]]
675
+ * // Block matrix partitioning for algorithms
676
+ * const large = MatrixCreate(8, 8); // 8×8 matrix
677
+ * const topLeft = MatrixSubmatrix(large, 0, 0, 4, 4); // Top-left 4×4 block
678
+ * const topRight = MatrixSubmatrix(large, 4, 0, 4, 4); // Top-right 4×4 block
679
+ * const bottomLeft = MatrixSubmatrix(large, 0, 4, 4, 4); // Bottom-left 4×4 block
680
+ * const bottomRight = MatrixSubmatrix(large, 4, 4, 4, 4); // Bottom-right 4×4 block
681
+ * ```
682
+ * ```
697
683
  */
698
684
  export function MatrixSubmatrix(matrix, startCol, startRow, width, height) {
699
685
  AssertMatrix(matrix);
@@ -701,12 +687,9 @@ export function MatrixSubmatrix(matrix, startCol, startRow, width, height) {
701
687
  // Copy elements from specified source region to result matrix
702
688
  for (let row = 0; row < height; row++) {
703
689
  const sourceRow = matrix[startRow + row];
704
- AssertMatrixRow(sourceRow);
705
690
  const resultRow = result[row];
706
- AssertMatrixRow(resultRow);
707
691
  for (let col = 0; col < width; col++) {
708
692
  const val = sourceRow[startCol + col];
709
- AssertMatrixValue(val, { rowIndex: startRow + row, columnIndex: startCol + col });
710
693
  resultRow[col] = val;
711
694
  }
712
695
  }
@@ -753,33 +736,33 @@ export function MatrixSubmatrix(matrix, startCol, startRow, width, height) {
753
736
  * @returns {TMatrix} The padded matrix with dimensions newRows×newCols
754
737
  * @throws {Error} If new dimensions are smaller than current dimensions
755
738
  * @example
756
- * ```typescript
757
- * ```typescript
758
- * const matrix = [[1, 2], [3, 4]]; // 2×2 matrix
759
- * // Pad to 4×4 matrix (symmetric padding)
760
- * MatrixPad(matrix, 4, 4)
761
- * // Returns:
762
- * // [[1, 2, 0, 0],
763
- * // [3, 4, 0, 0],
764
- * // [0, 0, 0, 0],
765
- * // [0, 0, 0, 0]]
766
- * // Pad to 3×4 matrix (asymmetric padding)
767
- * MatrixPad(matrix, 3, 4)
768
- * // Returns:
769
- * // [[1, 2, 0, 0],
770
- * // [3, 4, 0, 0],
771
- * // [0, 0, 0, 0]]
772
- * // Prepare for power-of-2 algorithm (e.g., FFT-based convolution)
773
- * const data = [[1, 2, 3], [4, 5, 6]]; // 2×3 matrix
774
- * const powerOf2 = MatrixPad(data, 4, 4); // Pad to 4×4 for FFT
775
- * // Batch size alignment in machine learning
776
- * const features = MatrixCreate(7, 10); // 7 samples, 10 features
777
- * const aligned = MatrixPad(features, 8, 10); // Align to batch size 8
778
- * // Image border padding for convolution
779
- * const image = MatrixCreate(28, 28); // 28×28 image
780
- * const padded = MatrixPad(image, 32, 32); // Add border for valid convolution
781
- * ```
782
- * ```
739
+ * ```typescript
740
+ * ```typescript
741
+ * const matrix = [[1, 2], [3, 4]]; // 2×2 matrix
742
+ * // Pad to 4×4 matrix (symmetric padding)
743
+ * MatrixPad(matrix, 4, 4)
744
+ * // Returns:
745
+ * // [[1, 2, 0, 0],
746
+ * // [3, 4, 0, 0],
747
+ * // [0, 0, 0, 0],
748
+ * // [0, 0, 0, 0]]
749
+ * // Pad to 3×4 matrix (asymmetric padding)
750
+ * MatrixPad(matrix, 3, 4)
751
+ * // Returns:
752
+ * // [[1, 2, 0, 0],
753
+ * // [3, 4, 0, 0],
754
+ * // [0, 0, 0, 0]]
755
+ * // Prepare for power-of-2 algorithm (e.g., FFT-based convolution)
756
+ * const data = [[1, 2, 3], [4, 5, 6]]; // 2×3 matrix
757
+ * const powerOf2 = MatrixPad(data, 4, 4); // Pad to 4×4 for FFT
758
+ * // Batch size alignment in machine learning
759
+ * const features = MatrixCreate(7, 10); // 7 samples, 10 features
760
+ * const aligned = MatrixPad(features, 8, 10); // Align to batch size 8
761
+ * // Image border padding for convolution
762
+ * const image = MatrixCreate(28, 28); // 28×28 image
763
+ * const padded = MatrixPad(image, 32, 32); // Add border for valid convolution
764
+ * ```
765
+ * ```
783
766
  */
784
767
  export function MatrixPad(matrix, newRows, newCols) {
785
768
  AssertMatrix(matrix);
@@ -788,12 +771,9 @@ export function MatrixPad(matrix, newRows, newCols) {
788
771
  // Copy existing values to top-left corner, zero-fill remaining positions
789
772
  for (let row = 0; row < Math.min(currentRows, newRows); row++) {
790
773
  const sourceRow = matrix[row];
791
- AssertMatrixRow(sourceRow);
792
774
  const resultRow = result[row];
793
- AssertMatrixRow(resultRow);
794
775
  for (let col = 0; col < Math.min(currentCols, newCols); col++) {
795
776
  const val = sourceRow[col];
796
- AssertMatrixValue(val, { rowIndex: row, columnIndex: col });
797
777
  resultRow[col] = val;
798
778
  }
799
779
  }
@@ -851,36 +831,36 @@ export function MatrixPad(matrix, newRows, newCols) {
851
831
  * @throws {Error} If quadrants have mismatched dimensions or invalid values
852
832
  *
853
833
  * @example
854
- * ```typescript
855
- * ```typescript
856
- * // Basic 2×2 quadrant combination
857
- * const topLeft = [[1, 2], [3, 4]];
858
- * const topRight = [[5, 6], [7, 8]];
859
- * const bottomLeft = [[9, 10], [11, 12]];
860
- * const bottomRight = [[13, 14], [15, 16]];
861
- * MatrixCombine(topLeft, topRight, bottomLeft, bottomRight)
862
- * // Returns:
863
- * // [[1, 2, 5, 6],
864
- * // [3, 4, 7, 8],
865
- * // [9, 10, 13, 14],
866
- * // [11,12, 15, 16]]
867
- * // Strassen algorithm result reconstruction
868
- * const m1 = computeStrassenProduct1(); // Computed Strassen intermediate results
869
- * const m2 = computeStrassenProduct2();
870
- * const m3 = computeStrassenProduct3();
871
- * const m4 = computeStrassenProduct4();
872
- * const finalResult = MatrixCombine(m1, m2, m3, m4); // Assemble final result
873
- * // Image processing: combining processed quadrants
874
- * const processedTopLeft = processImageQuadrant(imageTopLeft);
875
- * const processedTopRight = processImageQuadrant(imageTopRight);
876
- * const processedBottomLeft = processImageQuadrant(imageBottomLeft);
877
- * const processedBottomRight = processImageQuadrant(imageBottomRight);
878
- * const reconstructedImage = MatrixCombine(
879
- * processedTopLeft, processedTopRight,
880
- * processedBottomLeft, processedBottomRight
881
- * );
882
- * ```
883
- * ```
834
+ * ```typescript
835
+ * ```typescript
836
+ * // Basic 2×2 quadrant combination
837
+ * const topLeft = [[1, 2], [3, 4]];
838
+ * const topRight = [[5, 6], [7, 8]];
839
+ * const bottomLeft = [[9, 10], [11, 12]];
840
+ * const bottomRight = [[13, 14], [15, 16]];
841
+ * MatrixCombine(topLeft, topRight, bottomLeft, bottomRight)
842
+ * // Returns:
843
+ * // [[1, 2, 5, 6],
844
+ * // [3, 4, 7, 8],
845
+ * // [9, 10, 13, 14],
846
+ * // [11,12, 15, 16]]
847
+ * // Strassen algorithm result reconstruction
848
+ * const m1 = computeStrassenProduct1(); // Computed Strassen intermediate results
849
+ * const m2 = computeStrassenProduct2();
850
+ * const m3 = computeStrassenProduct3();
851
+ * const m4 = computeStrassenProduct4();
852
+ * const finalResult = MatrixCombine(m1, m2, m3, m4); // Assemble final result
853
+ * // Image processing: combining processed quadrants
854
+ * const processedTopLeft = processImageQuadrant(imageTopLeft);
855
+ * const processedTopRight = processImageQuadrant(imageTopRight);
856
+ * const processedBottomLeft = processImageQuadrant(imageBottomLeft);
857
+ * const processedBottomRight = processImageQuadrant(imageBottomRight);
858
+ * const reconstructedImage = MatrixCombine(
859
+ * processedTopLeft, processedTopRight,
860
+ * processedBottomLeft, processedBottomRight
861
+ * );
862
+ * ```
863
+ * ```
884
864
  */
885
865
  export function MatrixCombine(c11, c12, c21, c22) {
886
866
  AssertMatrix(c11);
@@ -894,48 +874,36 @@ export function MatrixCombine(c11, c12, c21, c22) {
894
874
  // Copy c11 to top-left quadrant [0:n, 0:n]
895
875
  for (let row = 0; row < halfSize; row++) {
896
876
  const sourceRow = c11[row];
897
- AssertMatrixRow(sourceRow);
898
877
  const resultRow = result[row];
899
- AssertMatrixRow(resultRow);
900
878
  for (let col = 0; col < halfSize; col++) {
901
879
  const val = sourceRow[col];
902
- AssertMatrixValue(val, { rowIndex: row, columnIndex: col });
903
880
  resultRow[col] = val;
904
881
  }
905
882
  }
906
883
  // Copy c12 to top-right quadrant [0:n, n:2n]
907
884
  for (let row = 0; row < halfSize; row++) {
908
885
  const sourceRow = c12[row];
909
- AssertMatrixRow(sourceRow);
910
886
  const resultRow = result[row];
911
- AssertMatrixRow(resultRow);
912
887
  for (let col = 0; col < halfSize; col++) {
913
888
  const val = sourceRow[col];
914
- AssertMatrixValue(val, { rowIndex: row, columnIndex: col });
915
889
  resultRow[col + halfSize] = val;
916
890
  }
917
891
  }
918
892
  // Copy c21 to bottom-left quadrant [n:2n, 0:n]
919
893
  for (let row = 0; row < halfSize; row++) {
920
894
  const sourceRow = c21[row];
921
- AssertMatrixRow(sourceRow);
922
895
  const resultRow = result[row + halfSize];
923
- AssertMatrixRow(resultRow);
924
896
  for (let col = 0; col < halfSize; col++) {
925
897
  const val = sourceRow[col];
926
- AssertMatrixValue(val, { rowIndex: row, columnIndex: col });
927
898
  resultRow[col] = val;
928
899
  }
929
900
  }
930
901
  // Copy c22 to bottom-right quadrant [n:2n, n:2n]
931
902
  for (let row = 0; row < halfSize; row++) {
932
903
  const sourceRow = c22[row];
933
- AssertMatrixRow(sourceRow);
934
904
  const resultRow = result[row + halfSize];
935
- AssertMatrixRow(resultRow);
936
905
  for (let col = 0; col < halfSize; col++) {
937
906
  const val = sourceRow[col];
938
- AssertMatrixValue(val, { rowIndex: row, columnIndex: col });
939
907
  resultRow[col + halfSize] = val;
940
908
  }
941
909
  }