@pawells/math-extended 1.0.1 → 1.0.2

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 (85) hide show
  1. package/package.json +1 -1
  2. package/build/angles.spec.d.ts +0 -2
  3. package/build/angles.spec.d.ts.map +0 -1
  4. package/build/angles.spec.js +0 -147
  5. package/build/angles.spec.js.map +0 -1
  6. package/build/clamp.spec.d.ts +0 -2
  7. package/build/clamp.spec.d.ts.map +0 -1
  8. package/build/clamp.spec.js +0 -19
  9. package/build/clamp.spec.js.map +0 -1
  10. package/build/documentation-validation.spec.d.ts +0 -11
  11. package/build/documentation-validation.spec.d.ts.map +0 -1
  12. package/build/documentation-validation.spec.js +0 -401
  13. package/build/documentation-validation.spec.js.map +0 -1
  14. package/build/interpolation.spec.d.ts +0 -2
  15. package/build/interpolation.spec.d.ts.map +0 -1
  16. package/build/interpolation.spec.js +0 -480
  17. package/build/interpolation.spec.js.map +0 -1
  18. package/build/matrices/arithmetic.spec.d.ts +0 -2
  19. package/build/matrices/arithmetic.spec.d.ts.map +0 -1
  20. package/build/matrices/arithmetic.spec.js +0 -915
  21. package/build/matrices/arithmetic.spec.js.map +0 -1
  22. package/build/matrices/asserts.spec.d.ts +0 -2
  23. package/build/matrices/asserts.spec.d.ts.map +0 -1
  24. package/build/matrices/asserts.spec.js +0 -565
  25. package/build/matrices/asserts.spec.js.map +0 -1
  26. package/build/matrices/core.spec.d.ts +0 -2
  27. package/build/matrices/core.spec.d.ts.map +0 -1
  28. package/build/matrices/core.spec.js +0 -634
  29. package/build/matrices/core.spec.js.map +0 -1
  30. package/build/matrices/decompositions.spec.d.ts +0 -2
  31. package/build/matrices/decompositions.spec.d.ts.map +0 -1
  32. package/build/matrices/decompositions.spec.js +0 -195
  33. package/build/matrices/decompositions.spec.js.map +0 -1
  34. package/build/matrices/linear-algebra.spec.d.ts +0 -2
  35. package/build/matrices/linear-algebra.spec.d.ts.map +0 -1
  36. package/build/matrices/linear-algebra.spec.js +0 -355
  37. package/build/matrices/linear-algebra.spec.js.map +0 -1
  38. package/build/matrices/normalization.spec.d.ts +0 -2
  39. package/build/matrices/normalization.spec.d.ts.map +0 -1
  40. package/build/matrices/normalization.spec.js +0 -335
  41. package/build/matrices/normalization.spec.js.map +0 -1
  42. package/build/matrices/transformations.spec.d.ts +0 -2
  43. package/build/matrices/transformations.spec.d.ts.map +0 -1
  44. package/build/matrices/transformations.spec.js +0 -755
  45. package/build/matrices/transformations.spec.js.map +0 -1
  46. package/build/quaternions/asserts.spec.d.ts +0 -2
  47. package/build/quaternions/asserts.spec.d.ts.map +0 -1
  48. package/build/quaternions/asserts.spec.js +0 -320
  49. package/build/quaternions/asserts.spec.js.map +0 -1
  50. package/build/quaternions/conversions.spec.d.ts +0 -2
  51. package/build/quaternions/conversions.spec.d.ts.map +0 -1
  52. package/build/quaternions/conversions.spec.js +0 -344
  53. package/build/quaternions/conversions.spec.js.map +0 -1
  54. package/build/quaternions/core.spec.d.ts +0 -2
  55. package/build/quaternions/core.spec.d.ts.map +0 -1
  56. package/build/quaternions/core.spec.js +0 -294
  57. package/build/quaternions/core.spec.js.map +0 -1
  58. package/build/quaternions/interpolation.spec.d.ts +0 -2
  59. package/build/quaternions/interpolation.spec.d.ts.map +0 -1
  60. package/build/quaternions/interpolation.spec.js +0 -64
  61. package/build/quaternions/interpolation.spec.js.map +0 -1
  62. package/build/quaternions/predefined.spec.d.ts +0 -2
  63. package/build/quaternions/predefined.spec.d.ts.map +0 -1
  64. package/build/quaternions/predefined.spec.js +0 -35
  65. package/build/quaternions/predefined.spec.js.map +0 -1
  66. package/build/random.spec.d.ts +0 -2
  67. package/build/random.spec.d.ts.map +0 -1
  68. package/build/random.spec.js +0 -267
  69. package/build/random.spec.js.map +0 -1
  70. package/build/vectors/asserts.spec.d.ts +0 -2
  71. package/build/vectors/asserts.spec.d.ts.map +0 -1
  72. package/build/vectors/asserts.spec.js +0 -260
  73. package/build/vectors/asserts.spec.js.map +0 -1
  74. package/build/vectors/core.spec.d.ts +0 -2
  75. package/build/vectors/core.spec.d.ts.map +0 -1
  76. package/build/vectors/core.spec.js +0 -343
  77. package/build/vectors/core.spec.js.map +0 -1
  78. package/build/vectors/interpolation.spec.d.ts +0 -2
  79. package/build/vectors/interpolation.spec.d.ts.map +0 -1
  80. package/build/vectors/interpolation.spec.js +0 -378
  81. package/build/vectors/interpolation.spec.js.map +0 -1
  82. package/build/vectors/predefined.spec.d.ts +0 -2
  83. package/build/vectors/predefined.spec.d.ts.map +0 -1
  84. package/build/vectors/predefined.spec.js +0 -333
  85. package/build/vectors/predefined.spec.js.map +0 -1
@@ -1,915 +0,0 @@
1
- import { MatrixAdd, MatrixSubtract, MatrixMultiply, MatrixSubmatrix, MatrixPad, MatrixCombine, } from './arithmetic.js';
2
- import { AssertMatrixRow } from './asserts.js';
3
- import { MatrixCreate } from './core.js';
4
- describe('Matrix Arithmetic', () => {
5
- describe('MatrixAdd', () => {
6
- it('should add two 1x1 matrices', () => {
7
- const a = [[5]];
8
- const b = [[3]];
9
- const result = MatrixAdd(a, b);
10
- expect(result).toEqual([[8]]);
11
- });
12
- it('should add two 2x2 matrices', () => {
13
- const a = [[1, 2], [3, 4]];
14
- const b = [[5, 6], [7, 8]];
15
- const result = MatrixAdd(a, b);
16
- expect(result).toEqual([[6, 8], [10, 12]]);
17
- });
18
- it('should add two 3x3 matrices', () => {
19
- const a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
20
- const b = [[9, 8, 7], [6, 5, 4], [3, 2, 1]];
21
- const result = MatrixAdd(a, b);
22
- expect(result).toEqual([[10, 10, 10], [10, 10, 10], [10, 10, 10]]);
23
- });
24
- it('should add matrices with negative numbers', () => {
25
- const a = [[1, -2], [-3, 4]];
26
- const b = [[-1, 2], [3, -4]];
27
- const result = MatrixAdd(a, b);
28
- expect(result).toEqual([[0, 0], [0, 0]]);
29
- });
30
- it('should add matrices with zeros', () => {
31
- const a = [[1, 2], [3, 4]];
32
- const b = [[0, 0], [0, 0]];
33
- const result = MatrixAdd(a, b);
34
- expect(result).toEqual([[1, 2], [3, 4]]);
35
- });
36
- it('should add matrices with decimal numbers', () => {
37
- const a = [[1.5, 2.5], [3.5, 4.5]];
38
- const b = [[0.5, 0.5], [0.5, 0.5]];
39
- const result = MatrixAdd(a, b);
40
- expect(result).toEqual([[2, 3], [4, 5]]);
41
- });
42
- it('should throw error for matrices with different dimensions', () => {
43
- const a = [[1, 2], [3, 4]];
44
- const b = [[1, 2, 3], [4, 5, 6]];
45
- expect(() => MatrixAdd(a, b)).toThrow();
46
- });
47
- });
48
- describe('MatrixSubtract', () => {
49
- it('should subtract two 1x1 matrices', () => {
50
- const a = [[8]];
51
- const b = [[3]];
52
- const result = MatrixSubtract(a, b);
53
- expect(result).toEqual([[5]]);
54
- });
55
- it('should subtract two 2x2 matrices', () => {
56
- const a = [[5, 6], [7, 8]];
57
- const b = [[1, 2], [3, 4]];
58
- const result = MatrixSubtract(a, b);
59
- expect(result).toEqual([[4, 4], [4, 4]]);
60
- });
61
- it('should subtract two 3x3 matrices', () => {
62
- const a = [[10, 10, 10], [10, 10, 10], [10, 10, 10]];
63
- const b = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
64
- const result = MatrixSubtract(a, b);
65
- expect(result).toEqual([[9, 8, 7], [6, 5, 4], [3, 2, 1]]);
66
- });
67
- it('should handle negative results', () => {
68
- const a = [[1, 2], [3, 4]];
69
- const b = [[5, 6], [7, 8]];
70
- const result = MatrixSubtract(a, b);
71
- expect(result).toEqual([[-4, -4], [-4, -4]]);
72
- });
73
- it('should subtract zero matrix', () => {
74
- const a = [[1, 2], [3, 4]];
75
- const b = [[0, 0], [0, 0]];
76
- const result = MatrixSubtract(a, b);
77
- expect(result).toEqual([[1, 2], [3, 4]]);
78
- });
79
- it('should handle decimal numbers', () => {
80
- const a = [[3.5, 4.5], [5.5, 6.5]];
81
- const b = [[1.5, 2.5], [3.5, 4.5]];
82
- const result = MatrixSubtract(a, b);
83
- expect(result).toEqual([[2, 2], [2, 2]]);
84
- });
85
- it('should throw error for matrices with different dimensions', () => {
86
- const a = [[1, 2], [3, 4]];
87
- const b = [[1], [2], [3]];
88
- expect(() => MatrixSubtract(a, b)).toThrow();
89
- });
90
- });
91
- describe('MatrixMultiply', () => {
92
- describe('overload: scalar multiplication (matrix, scalar) -> matrix', () => {
93
- it('should multiply 1x1 matrix by scalar', () => {
94
- const matrix = [[5]];
95
- const result = MatrixMultiply(matrix, 3);
96
- expect(result).toEqual([[15]]);
97
- });
98
- it('should multiply 2x2 matrix by scalar', () => {
99
- const matrix = [[1, 2], [3, 4]];
100
- const result = MatrixMultiply(matrix, 2);
101
- expect(result).toEqual([[2, 4], [6, 8]]);
102
- });
103
- it('should multiply 3x3 matrix by scalar', () => {
104
- const matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
105
- const result = MatrixMultiply(matrix, 2);
106
- expect(result).toEqual([[2, 4, 6], [8, 10, 12], [14, 16, 18]]);
107
- });
108
- it('should multiply 4x4 matrix by scalar', () => {
109
- const matrix = [
110
- [1, 2, 3, 4],
111
- [5, 6, 7, 8],
112
- [9, 10, 11, 12],
113
- [13, 14, 15, 16],
114
- ];
115
- const result = MatrixMultiply(matrix, 0.5);
116
- expect(result).toEqual([
117
- [0.5, 1, 1.5, 2],
118
- [2.5, 3, 3.5, 4],
119
- [4.5, 5, 5.5, 6],
120
- [6.5, 7, 7.5, 8],
121
- ]);
122
- });
123
- it('should multiply matrix by zero', () => {
124
- const matrix = [[1, 2], [3, 4]];
125
- const result = MatrixMultiply(matrix, 0);
126
- expect(result).toEqual([[0, 0], [0, 0]]);
127
- });
128
- it('should multiply matrix by negative scalar', () => {
129
- const matrix = [[1, 2], [3, 4]];
130
- const result = MatrixMultiply(matrix, -1);
131
- expect(result).toEqual([[-1, -2], [-3, -4]]);
132
- });
133
- it('should multiply matrix by decimal scalar', () => {
134
- const matrix = [[2, 4], [6, 8]];
135
- const result = MatrixMultiply(matrix, 0.5);
136
- expect(result).toEqual([[1, 2], [3, 4]]);
137
- });
138
- it('should multiply rectangular matrix by scalar', () => {
139
- const matrix = [[1, 2, 3], [4, 5, 6]];
140
- const result = MatrixMultiply(matrix, 3);
141
- expect(result).toEqual([[3, 6, 9], [12, 15, 18]]);
142
- });
143
- it('should preserve matrix type with scalar multiplication', () => {
144
- const matrix = [[1, 2], [3, 4]];
145
- const scalar = 5;
146
- const result = MatrixMultiply(matrix, scalar);
147
- expect(typeof result).toBe('object');
148
- expect(Array.isArray(result)).toBe(true);
149
- expect(Array.isArray(result[0])).toBe(true);
150
- });
151
- });
152
- describe('overload: vector multiplication (matrix, vector) -> vector', () => {
153
- it('should multiply 2x2 matrix by 2D vector', () => {
154
- const matrix = [[1, 2], [3, 4]];
155
- const vector = [5, 6];
156
- const result = MatrixMultiply(matrix, vector);
157
- expect(result).toEqual([17, 39]);
158
- });
159
- it('should multiply 3x3 matrix by 3D vector', () => {
160
- const matrix = [[1, 0, 0], [0, 1, 0], [0, 0, 1]];
161
- const vector = [5, 6, 7];
162
- const result = MatrixMultiply(matrix, vector);
163
- expect(result).toEqual([5, 6, 7]);
164
- });
165
- it('should multiply 4x4 matrix by 4D vector', () => {
166
- const matrix = [
167
- [1, 0, 0, 0],
168
- [0, 2, 0, 0],
169
- [0, 0, 3, 0],
170
- [0, 0, 0, 4],
171
- ];
172
- const vector = [1, 2, 3, 4];
173
- const result = MatrixMultiply(matrix, vector);
174
- expect(result).toEqual([1, 4, 9, 16]);
175
- });
176
- it('should multiply rectangular matrix by vector', () => {
177
- const matrix = [[1, 2, 3], [4, 5, 6]];
178
- const vector = [1, 2, 3];
179
- const result = MatrixMultiply(matrix, vector);
180
- expect(result).toEqual([14, 32]);
181
- });
182
- it('should handle zero vector', () => {
183
- const matrix = [[1, 2], [3, 4]];
184
- const vector = [0, 0];
185
- const result = MatrixMultiply(matrix, vector);
186
- expect(result).toEqual([0, 0]);
187
- });
188
- it('should handle vector with negative values', () => {
189
- const matrix = [[1, 2], [3, 4]];
190
- const vector = [-1, 2];
191
- const result = MatrixMultiply(matrix, vector);
192
- expect(result).toEqual([3, 5]);
193
- });
194
- it('should handle vector with decimal values', () => {
195
- const matrix = [[2, 0], [0, 2]];
196
- const vector = [1.5, 2.5];
197
- const result = MatrixMultiply(matrix, vector);
198
- expect(result).toEqual([3, 5]);
199
- });
200
- it('should perform identity transformation', () => {
201
- const identity = [[1, 0, 0], [0, 1, 0], [0, 0, 1]];
202
- const vector = [7, 8, 9];
203
- const result = MatrixMultiply(identity, vector);
204
- expect(result).toEqual([7, 8, 9]);
205
- });
206
- it('should perform linear transformation', () => {
207
- // Rotation by 90 degrees counterclockwise in 2D
208
- const rotationMatrix = [[0, -1], [1, 0]];
209
- const vector = [1, 0];
210
- const result = MatrixMultiply(rotationMatrix, vector);
211
- expect(result).toEqual([0, 1]);
212
- });
213
- it('should return vector result type', () => {
214
- const matrix = [[1, 2], [3, 4]];
215
- const vector = [1, 1];
216
- const result = MatrixMultiply(matrix, vector);
217
- expect(Array.isArray(result)).toBe(true);
218
- expect(result.length).toBe(2);
219
- expect(typeof result[0]).toBe('number');
220
- expect(typeof result[1]).toBe('number');
221
- });
222
- it('should throw error for incompatible dimensions', () => {
223
- const matrix = [[1, 2], [3, 4]];
224
- const vector = [1, 2, 3]; // Wrong size
225
- expect(() => MatrixMultiply(matrix, vector)).toThrow(/Matrix-vector multiplication requires matrix columns/);
226
- });
227
- it('should throw error for empty vector', () => {
228
- const matrix = [[1, 2], [3, 4]];
229
- const vector = [];
230
- expect(() => MatrixMultiply(matrix, vector)).toThrow(/Matrix-vector multiplication requires matrix columns/);
231
- });
232
- it('should handle matrix-vector multiplication examples from documentation', () => {
233
- // Example from the documentation
234
- const matrix = [[1, 2, 3], [4, 5, 6]];
235
- const vector = [7, 8, 9];
236
- const result = MatrixMultiply(matrix, vector);
237
- expect(result).toEqual([50, 122]);
238
- });
239
- it('should handle single row matrix multiplication', () => {
240
- const matrix = [[1, 2, 3]];
241
- const vector = [4, 5, 6];
242
- const result = MatrixMultiply(matrix, vector);
243
- expect(result).toEqual([32]);
244
- });
245
- it('should handle single column matrix multiplication', () => {
246
- const matrix = [[1], [2], [3]];
247
- const vector = [5];
248
- const result = MatrixMultiply(matrix, vector);
249
- expect(result).toEqual([5, 10, 15]);
250
- });
251
- it('should handle very large vectors', () => {
252
- const matrix = [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]];
253
- const vector = [1, 1, 1, 1, 1];
254
- const result = MatrixMultiply(matrix, vector);
255
- expect(result).toEqual([15, 40]);
256
- });
257
- it('should preserve precision with decimal arithmetic', () => {
258
- const matrix = [[0.1, 0.2], [0.3, 0.4]];
259
- const vector = [0.5, 0.6];
260
- const result = MatrixMultiply(matrix, vector);
261
- expect(result[0]).toBeCloseTo(0.17, 10);
262
- expect(result[1]).toBeCloseTo(0.39, 10);
263
- });
264
- it('should handle scaling transformations', () => {
265
- const scalingMatrix = [[2, 0], [0, 3]];
266
- const vector = [4, 5];
267
- const result = MatrixMultiply(scalingMatrix, vector);
268
- expect(result).toEqual([8, 15]);
269
- });
270
- it('should handle reflection transformations', () => {
271
- // Reflection across x-axis
272
- const reflectionMatrix = [[1, 0], [0, -1]];
273
- const vector = [3, 4];
274
- const result = MatrixMultiply(reflectionMatrix, vector);
275
- expect(result).toEqual([3, -4]);
276
- });
277
- it('should handle shear transformations', () => {
278
- // Horizontal shear
279
- const shearMatrix = [[1, 2], [0, 1]];
280
- const vector = [1, 3];
281
- const result = MatrixMultiply(shearMatrix, vector);
282
- expect(result).toEqual([7, 3]);
283
- });
284
- });
285
- describe('overload: matrix multiplication (matrix, matrix) -> matrix', () => {
286
- it('should multiply two 1x1 matrices', () => {
287
- const a = [[5]];
288
- const b = [[3]];
289
- const result = MatrixMultiply(a, b);
290
- expect(result).toEqual([[15]]);
291
- });
292
- it('should multiply two 2x2 matrices', () => {
293
- const a = [[1, 2], [3, 4]];
294
- const b = [[5, 6], [7, 8]];
295
- const result = MatrixMultiply(a, b);
296
- expect(result).toEqual([[19, 22], [43, 50]]);
297
- });
298
- it('should multiply two 3x3 matrices', () => {
299
- const a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
300
- const b = [[9, 8, 7], [6, 5, 4], [3, 2, 1]];
301
- const result = MatrixMultiply(a, b);
302
- expect(result).toEqual([[30, 24, 18], [84, 69, 54], [138, 114, 90]]);
303
- });
304
- it('should multiply two 4x4 matrices', () => {
305
- const a = [
306
- [1, 2, 3, 4],
307
- [5, 6, 7, 8],
308
- [9, 10, 11, 12],
309
- [13, 14, 15, 16],
310
- ];
311
- const b = [
312
- [16, 15, 14, 13],
313
- [12, 11, 10, 9],
314
- [8, 7, 6, 5],
315
- [4, 3, 2, 1],
316
- ];
317
- const result = MatrixMultiply(a, b);
318
- expect(result).toEqual([
319
- [80, 70, 60, 50],
320
- [240, 214, 188, 162],
321
- [400, 358, 316, 274],
322
- [560, 502, 444, 386],
323
- ]);
324
- });
325
- it('should multiply rectangular matrices (2x3 × 3x2)', () => {
326
- const a = [[1, 2, 3], [4, 5, 6]];
327
- const b = [[7, 8], [9, 10], [11, 12]];
328
- const result = MatrixMultiply(a, b);
329
- expect(result).toEqual([[58, 64], [139, 154]]);
330
- });
331
- it('should multiply rectangular matrices (3x2 × 2x4)', () => {
332
- const a = [[1, 2], [3, 4], [5, 6]];
333
- const b = [[7, 8, 9, 10], [11, 12, 13, 14]];
334
- const result = MatrixMultiply(a, b);
335
- expect(result).toEqual([
336
- [29, 32, 35, 38],
337
- [65, 72, 79, 86],
338
- [101, 112, 123, 134],
339
- ]);
340
- });
341
- it('should multiply by identity matrix', () => {
342
- const a = [[1, 2], [3, 4]];
343
- const identity = [[1, 0], [0, 1]];
344
- const result = MatrixMultiply(a, identity);
345
- expect(result).toEqual([[1, 2], [3, 4]]);
346
- });
347
- it('should multiply identity by matrix', () => {
348
- const identity = [[1, 0, 0], [0, 1, 0], [0, 0, 1]];
349
- const a = [[2, 3, 4], [5, 6, 7], [8, 9, 10]];
350
- const result = MatrixMultiply(identity, a);
351
- expect(result).toEqual([[2, 3, 4], [5, 6, 7], [8, 9, 10]]);
352
- });
353
- it('should handle matrices with zeros', () => {
354
- const a = [[1, 2], [3, 4]];
355
- const b = [[0, 0], [0, 0]];
356
- const result = MatrixMultiply(a, b);
357
- expect(result).toEqual([[0, 0], [0, 0]]);
358
- });
359
- it('should handle matrices with negative values', () => {
360
- const a = [[1, -2], [-3, 4]];
361
- const b = [[-1, 2], [3, -4]];
362
- const result = MatrixMultiply(a, b);
363
- expect(result).toEqual([[-7, 10], [15, -22]]);
364
- });
365
- it('should handle matrices with decimal values', () => {
366
- const a = [[1.5, 2.5], [3.5, 4.5]];
367
- const b = [[0.5, 1.5], [2.5, 3.5]];
368
- const result = MatrixMultiply(a, b);
369
- expect(result).toEqual([[7, 11], [13, 21]]);
370
- });
371
- it('should verify non-commutativity (A×B ≠ B×A)', () => {
372
- const a = [[1, 2], [3, 4]];
373
- const b = [[5, 6], [7, 8]];
374
- const ab = MatrixMultiply(a, b);
375
- const ba = MatrixMultiply(b, a);
376
- expect(ab).toEqual([[19, 22], [43, 50]]);
377
- expect(ba).toEqual([[23, 34], [31, 46]]);
378
- expect(ab).not.toEqual(ba);
379
- });
380
- it('should verify associativity ((A×B)×C = A×(B×C))', () => {
381
- const a = [[1, 2]];
382
- const b = [[3], [4]];
383
- const c = [[5, 6]];
384
- const abC = MatrixMultiply(MatrixMultiply(a, b), c);
385
- const aBc = MatrixMultiply(a, MatrixMultiply(b, c));
386
- expect(abC).toEqual(aBc);
387
- });
388
- it('should return proper matrix type', () => {
389
- const a = [[1, 2], [3, 4]];
390
- const b = [[5, 6], [7, 8]];
391
- const result = MatrixMultiply(a, b);
392
- expect(Array.isArray(result)).toBe(true);
393
- expect(Array.isArray(result[0])).toBe(true);
394
- expect(result.length).toBe(2);
395
- const [firstRow] = result;
396
- if (firstRow) {
397
- expect(firstRow.length).toBe(2);
398
- }
399
- });
400
- it('should throw error for incompatible dimensions', () => {
401
- const a = [[1, 2], [3, 4]]; // 2x2
402
- const b = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]; // 3x3
403
- expect(() => MatrixMultiply(a, b)).toThrow();
404
- });
405
- it('should throw error for dimension mismatch in rectangular matrices', () => {
406
- const a = [[1, 2, 3], [4, 5, 6]]; // 2x3
407
- const b = [[1, 2], [3, 4]]; // 2x2 (need 3x2)
408
- expect(() => MatrixMultiply(a, b)).toThrow();
409
- });
410
- });
411
- describe('overload type safety and dispatch', () => {
412
- it('should correctly dispatch to scalar multiplication', () => {
413
- const matrix = [[1, 2], [3, 4]];
414
- const scalar = 5;
415
- // Type should be inferred as IMatrix
416
- const result = MatrixMultiply(matrix, scalar);
417
- expect(result).toEqual([[5, 10], [15, 20]]);
418
- expect(Array.isArray(result)).toBe(true);
419
- expect(Array.isArray(result[0])).toBe(true);
420
- });
421
- it('should correctly dispatch to vector multiplication', () => {
422
- const matrix = [[1, 2], [3, 4]];
423
- const vector = [2, 3];
424
- // Type should be inferred as TVector (1D array)
425
- const result = MatrixMultiply(matrix, vector);
426
- expect(result).toEqual([8, 18]);
427
- expect(Array.isArray(result)).toBe(true);
428
- expect(typeof result[0]).toBe('number');
429
- });
430
- it('should correctly dispatch to matrix multiplication', () => {
431
- const matrixA = [[1, 2], [3, 4]];
432
- const matrixB = [[2, 0], [1, 2]];
433
- // Type should be inferred as IMatrix
434
- const result = MatrixMultiply(matrixA, matrixB);
435
- expect(result).toEqual([[4, 4], [10, 8]]);
436
- expect(Array.isArray(result)).toBe(true);
437
- expect(Array.isArray(result[0])).toBe(true);
438
- expect(result[0].length).toBe(2); // Square matrix
439
- });
440
- it('should handle mixed operand types correctly', () => {
441
- const matrix = [[2, 1], [1, 2]];
442
- // Scalar multiplication
443
- const scalarResult = MatrixMultiply(matrix, 3);
444
- expect(scalarResult).toEqual([[6, 3], [3, 6]]);
445
- // Vector multiplication
446
- const vectorResult = MatrixMultiply(matrix, [1, 2]);
447
- expect(vectorResult).toEqual([4, 5]);
448
- // Matrix multiplication
449
- const matrixResult = MatrixMultiply(matrix, [[1, 0], [0, 1]]);
450
- expect(matrixResult).toEqual([[2, 1], [1, 2]]);
451
- });
452
- it('should preserve specific matrix types in results', () => {
453
- const matrix1 = [[5]];
454
- const matrix2 = [[1, 2], [3, 4]];
455
- const matrix3 = [[1, 0, 0], [0, 1, 0], [0, 0, 1]];
456
- // All should return IMatrix type (base type)
457
- const result1 = MatrixMultiply(matrix1, 2);
458
- const result2 = MatrixMultiply(matrix2, 0.5);
459
- const result3 = MatrixMultiply(matrix3, 3);
460
- expect(result1).toEqual([[10]]);
461
- expect(result2).toEqual([[0.5, 1], [1.5, 2]]);
462
- expect(result3).toEqual([[3, 0, 0], [0, 3, 0], [0, 0, 3]]);
463
- });
464
- it('should handle edge cases for each overload', () => {
465
- const matrix = [[1, 0], [0, 1]];
466
- // Scalar: multiply by 0
467
- const zeroScalar = MatrixMultiply(matrix, 0);
468
- expect(zeroScalar).toEqual([[0, 0], [0, 0]]);
469
- // Vector: zero vector
470
- const zeroVector = MatrixMultiply(matrix, [0, 0]);
471
- expect(zeroVector).toEqual([0, 0]);
472
- // Matrix: zero matrix
473
- const zeroMatrix = MatrixMultiply(matrix, [[0, 0], [0, 0]]);
474
- expect(zeroMatrix).toEqual([[0, 0], [0, 0]]);
475
- });
476
- it('should validate input types correctly', () => {
477
- const matrix = [[1, 2], [3, 4]];
478
- // Test type detection with edge values
479
- expect(MatrixMultiply(matrix, 1)).toEqual([[1, 2], [3, 4]]);
480
- expect(MatrixMultiply(matrix, -1)).toEqual([[-1, -2], [-3, -4]]);
481
- expect(MatrixMultiply(matrix, 0.5)).toEqual([[0.5, 1], [1.5, 2]]);
482
- });
483
- it('should handle type coercion edge cases', () => {
484
- const matrix = [[2, 3]];
485
- // Ensure vector is detected correctly vs matrix
486
- const vectorResult = MatrixMultiply(matrix, [4, 5]);
487
- expect(vectorResult).toEqual([23]);
488
- // Ensure 2D matrix is detected correctly
489
- const matrixResult = MatrixMultiply(matrix, [[4], [5]]);
490
- expect(matrixResult).toEqual([[23]]);
491
- });
492
- it('should maintain precision in type-specific operations', () => {
493
- const matrix2 = [[1.1, 2.2], [3.3, 4.4]];
494
- const vector2 = [0.5, 0.25];
495
- const result = MatrixMultiply(matrix2, vector2);
496
- expect(result[0]).toBeCloseTo((1.1 * 0.5) + (2.2 * 0.25), 10);
497
- expect(result[1]).toBeCloseTo((3.3 * 0.5) + (4.4 * 0.25), 10);
498
- });
499
- });
500
- describe.skip('large matrix multiplication (Strassen)', () => {
501
- it('should handle large square matrices using Strassen algorithm', () => {
502
- // Create 32x32 matrices to trigger Strassen algorithm
503
- const size = 32;
504
- const a = MatrixCreate(size, size);
505
- const b = MatrixCreate(size, size);
506
- // Fill with simple pattern for testing
507
- for (let i = 0; i < size; i++) {
508
- const arow = a[i];
509
- AssertMatrixRow(arow, { rowIndex: i });
510
- const brow = b[i];
511
- AssertMatrixRow(brow, { rowIndex: i });
512
- for (let j = 0; j < size; j++) {
513
- arow[j] = i + j;
514
- brow[j] = i - j;
515
- }
516
- }
517
- // This should use Strassen algorithm internally
518
- const result = MatrixMultiply(a, b);
519
- const [resultRow] = result;
520
- AssertMatrixRow(resultRow, { rowIndex: 0 });
521
- expect(result).toBeDefined();
522
- expect(result.length).toBe(size);
523
- expect(resultRow.length).toBe(size);
524
- });
525
- it('should use standard algorithm for matrices smaller than 32x32', () => {
526
- // Create 31x31 matrices - should use standard algorithm, not Strassen
527
- const size = 31;
528
- const a = MatrixCreate(size, size);
529
- const b = MatrixCreate(size, size);
530
- // Fill with simple pattern for testing
531
- for (let i = 0; i < size; i++) {
532
- const arow = a[i];
533
- AssertMatrixRow(arow, { rowIndex: i });
534
- const brow = b[i];
535
- AssertMatrixRow(brow, { rowIndex: i });
536
- for (let j = 0; j < size; j++) {
537
- arow[j] = i + j;
538
- brow[j] = i - j;
539
- }
540
- }
541
- // This should use standard algorithm internally
542
- const result = MatrixMultiply(a, b);
543
- const [resultRow] = result;
544
- AssertMatrixRow(resultRow, { rowIndex: 0 });
545
- expect(result).toBeDefined();
546
- expect(result.length).toBe(size);
547
- expect(resultRow.length).toBe(size);
548
- });
549
- it('should handle boundary case at 32x32 threshold', () => {
550
- // Test exactly at the Strassen threshold
551
- const size = 32;
552
- const identity = MatrixCreate(size, size);
553
- const testMatrix = MatrixCreate(size, size);
554
- // Create identity matrix
555
- for (let i = 0; i < size; i++) {
556
- const identityRow = identity[i];
557
- AssertMatrixRow(identityRow, { rowIndex: i });
558
- const testRow = testMatrix[i];
559
- AssertMatrixRow(testRow, { rowIndex: i });
560
- for (let j = 0; j < size; j++) {
561
- identityRow[j] = i === j ? 1 : 0;
562
- testRow[j] = (i * size) + j; // Sequential values for testing
563
- }
564
- }
565
- // Identity multiplication should preserve the matrix
566
- const result = MatrixMultiply(identity, testMatrix);
567
- expect(result).toEqual(testMatrix);
568
- });
569
- it('should handle very large matrices (64x64) with Strassen', () => {
570
- const size = 64;
571
- const a = MatrixCreate(64);
572
- const b = MatrixCreate(64);
573
- // Fill with identity pattern for predictable results
574
- for (let i = 0; i < size; i++) {
575
- const arow = a[i];
576
- AssertMatrixRow(arow, { rowIndex: i });
577
- const brow = b[i];
578
- AssertMatrixRow(brow, { rowIndex: i });
579
- for (let j = 0; j < size; j++) {
580
- arow[j] = i === j ? 1 : 0; // Identity matrix
581
- brow[j] = j; // Simple pattern
582
- }
583
- }
584
- const result = MatrixMultiply(a, b);
585
- const [firstRow, secondRow] = result;
586
- AssertMatrixRow(firstRow, { rowIndex: 0 });
587
- AssertMatrixRow(secondRow, { rowIndex: 1 });
588
- // Verify identity multiplication worked
589
- expect(firstRow[0]).toBe(0);
590
- expect(secondRow[1]).toBe(1);
591
- expect(result[size - 1]?.[size - 1]).toBe(size - 1);
592
- });
593
- });
594
- describe('edge cases and error handling', () => {
595
- it('should throw descriptive errors for dimension mismatches', () => {
596
- const matrix2x3 = [[1, 2, 3], [4, 5, 6]];
597
- const matrix2x2 = [[1, 2], [3, 4]];
598
- const vector3 = [1, 2, 3];
599
- // Matrix-matrix dimension mismatch
600
- expect(() => MatrixMultiply(matrix2x3, matrix2x2))
601
- .toThrow(/Matrix row must be an array|incompatible.+multiplication/i);
602
- // Matrix-vector dimension mismatch
603
- expect(() => MatrixMultiply(matrix2x2, vector3))
604
- .toThrow(/Matrix-vector multiplication requires matrix columns/);
605
- // Empty vector
606
- expect(() => MatrixMultiply(matrix2x2, []))
607
- .toThrow(/Matrix-vector multiplication requires matrix columns/);
608
- });
609
- it('should handle matrices with extreme values', () => {
610
- const matrix = [[Number.MAX_SAFE_INTEGER, 0], [0, Number.MIN_SAFE_INTEGER]];
611
- const scalar = 0.5;
612
- const result = MatrixMultiply(matrix, scalar);
613
- expect(result[0]).toBeDefined();
614
- expect(result[1]).toBeDefined();
615
- expect(result[0]?.[0]).toBe(Number.MAX_SAFE_INTEGER * 0.5);
616
- expect(result[1]?.[1]).toBe(Number.MIN_SAFE_INTEGER * 0.5);
617
- });
618
- it('should handle very small decimal numbers', () => {
619
- const matrix = [[1e-10, 2e-10], [3e-10, 4e-10]];
620
- const scalar = 1e10;
621
- const result = MatrixMultiply(matrix, scalar);
622
- expect(result[0]?.[0]).toBeCloseTo(1, 10);
623
- expect(result[0]?.[1]).toBeCloseTo(2, 10);
624
- expect(result[1]?.[0]).toBeCloseTo(3, 10);
625
- expect(result[1]?.[1]).toBeCloseTo(4, 10);
626
- });
627
- it('should preserve exact zero values', () => {
628
- const matrix = [[0, 1], [1, 0]];
629
- const vector = [5, 0];
630
- const result = MatrixMultiply(matrix, vector);
631
- expect(result[0]).toBe(0);
632
- expect(result[1]).toBe(5);
633
- });
634
- it('should handle NaN and Infinity gracefully', () => {
635
- const matrix = [[1, 2], [3, 4]];
636
- // NaN scalar should throw validation error
637
- expect(() => MatrixMultiply(matrix, NaN))
638
- .toThrow(/Scalar multiplier must be a valid number/);
639
- // Infinity scalar should throw validation error
640
- expect(() => MatrixMultiply(matrix, Infinity))
641
- .toThrow(/Scalar multiplier must be a valid number/);
642
- });
643
- it('should handle matrices with mixed positive/negative values', () => {
644
- const matrix = [[-1, 2, -3], [4, -5, 6]];
645
- const vector = [-1, -1, -1];
646
- const result = MatrixMultiply(matrix, vector);
647
- expect(result[0]).toBe((-1 * -1) + (2 * -1) + (-3 * -1)); // 1 - 2 + 3 = 2
648
- expect(result[1]).toBe((4 * -1) + (-5 * -1) + (6 * -1)); // -4 + 5 - 6 = -5
649
- });
650
- it('should handle single-element matrices and vectors', () => {
651
- const matrix1x1 = [[5]];
652
- const vector1 = [3];
653
- const result = MatrixMultiply(matrix1x1, vector1);
654
- expect(result).toEqual([15]);
655
- });
656
- it('should handle wide and tall rectangular matrices', () => {
657
- // Wide matrix (1x5)
658
- const wideMatrix = [[1, 2, 3, 4, 5]];
659
- const vector5 = [1, 1, 1, 1, 1];
660
- const wideResult = MatrixMultiply(wideMatrix, vector5);
661
- expect(wideResult).toEqual([15]);
662
- // Tall matrix (5x1)
663
- const tallMatrix = [[1], [2], [3], [4], [5]];
664
- const vector1 = [2];
665
- const tallResult = MatrixMultiply(tallMatrix, vector1);
666
- expect(tallResult).toEqual([2, 4, 6, 8, 10]);
667
- });
668
- });
669
- describe.skip('performance and optimization tests', () => {
670
- it('should handle optimized small matrix sizes efficiently', () => {
671
- // Test all optimized sizes: 1x1, 2x2, 3x3, 4x4
672
- const matrix1 = [[2]];
673
- const matrix2 = [[1, 2], [3, 4]];
674
- const matrix3 = [[1, 0, 0], [0, 1, 0], [0, 0, 1]];
675
- const matrix4 = [
676
- [1, 0, 0, 0],
677
- [0, 1, 0, 0],
678
- [0, 0, 1, 0],
679
- [0, 0, 0, 1],
680
- ];
681
- // Test matrix-matrix multiplication for optimized sizes
682
- const result1 = MatrixMultiply(matrix1, matrix1);
683
- const result2 = MatrixMultiply(matrix2, matrix2);
684
- const result3 = MatrixMultiply(matrix3, matrix3);
685
- const result4 = MatrixMultiply(matrix4, matrix4);
686
- expect(result1).toEqual([[4]]);
687
- expect(result2).toEqual([[7, 10], [15, 22]]);
688
- expect(result3).toEqual(matrix3); // Identity matrix
689
- expect(result4).toEqual(matrix4); // Identity matrix
690
- });
691
- it('should maintain consistency between algorithms', () => {
692
- // Create a small matrix that would use standard algorithm
693
- const size = 8;
694
- const matrix = MatrixCreate(size, size);
695
- // Fill with known pattern
696
- for (let i = 0; i < size; i++) {
697
- const row = matrix[i];
698
- AssertMatrixRow(row, { rowIndex: i });
699
- for (let j = 0; j < size; j++) {
700
- row[j] = (i + 1) * (j + 1);
701
- }
702
- }
703
- // Multiply by identity - should preserve matrix
704
- const identity = MatrixCreate(size, size);
705
- for (let i = 0; i < size; i++) {
706
- const row = identity[i];
707
- AssertMatrixRow(row, { rowIndex: i });
708
- for (let j = 0; j < size; j++) {
709
- row[j] = i === j ? 1 : 0;
710
- }
711
- }
712
- const result = MatrixMultiply(matrix, identity);
713
- expect(result).toEqual(matrix);
714
- });
715
- it('should handle repeated operations consistently', () => {
716
- const matrix = [[1, 2], [3, 4]];
717
- const vector = [1, 1];
718
- // Perform same operation multiple times
719
- const results = Array.from({ length: 5 }, () => MatrixMultiply(matrix, vector));
720
- // All results should be identical
721
- results.forEach((result) => {
722
- expect(result).toEqual([3, 7]);
723
- });
724
- });
725
- it('should handle chained multiplications correctly', () => {
726
- const a = [[1, 2]];
727
- const b = [[3], [4]];
728
- const c = [[5, 6]];
729
- // Test associativity: (A*B)*C = A*(B*C)
730
- const leftAssoc = MatrixMultiply(MatrixMultiply(a, b), c);
731
- const rightAssoc = MatrixMultiply(a, MatrixMultiply(b, c));
732
- expect(leftAssoc).toEqual(rightAssoc);
733
- });
734
- });
735
- });
736
- describe('MatrixSubmatrix', () => {
737
- it('should extract 2x2 submatrix from top-left', () => {
738
- const matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]];
739
- const result = MatrixSubmatrix(matrix, 0, 0, 2, 2);
740
- expect(result).toEqual([[1, 2], [5, 6]]);
741
- });
742
- it('should extract 2x2 submatrix from center', () => {
743
- const matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]];
744
- const result = MatrixSubmatrix(matrix, 1, 1, 2, 2);
745
- expect(result).toEqual([[6, 7], [10, 11]]);
746
- });
747
- it('should extract single element', () => {
748
- const matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
749
- const result = MatrixSubmatrix(matrix, 1, 1, 1, 1);
750
- expect(result).toEqual([[5]]);
751
- });
752
- it('should extract full row', () => {
753
- const matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
754
- const result = MatrixSubmatrix(matrix, 0, 1, 3, 1);
755
- expect(result).toEqual([[4, 5, 6]]);
756
- });
757
- it('should extract full column', () => {
758
- const matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
759
- const result = MatrixSubmatrix(matrix, 1, 0, 1, 3);
760
- expect(result).toEqual([[2], [5], [8]]);
761
- });
762
- it('should handle edge case at matrix boundaries', () => {
763
- const matrix = [[1, 2], [3, 4]];
764
- const result = MatrixSubmatrix(matrix, 1, 1, 1, 1);
765
- expect(result).toEqual([[4]]);
766
- });
767
- });
768
- describe('MatrixPad', () => {
769
- it('should pad 2x2 matrix to 4x4', () => {
770
- const matrix = [[1, 2], [3, 4]];
771
- const result = MatrixPad(matrix, 4, 4);
772
- expect(result).toEqual([
773
- [1, 2, 0, 0],
774
- [3, 4, 0, 0],
775
- [0, 0, 0, 0],
776
- [0, 0, 0, 0],
777
- ]);
778
- });
779
- it('should pad matrix asymmetrically', () => {
780
- const matrix = [[1, 2], [3, 4]];
781
- const result = MatrixPad(matrix, 3, 4);
782
- expect(result).toEqual([
783
- [1, 2, 0, 0],
784
- [3, 4, 0, 0],
785
- [0, 0, 0, 0],
786
- ]);
787
- });
788
- it('should pad single element matrix', () => {
789
- const matrix = [[5]];
790
- const result = MatrixPad(matrix, 3, 3);
791
- expect(result).toEqual([
792
- [5, 0, 0],
793
- [0, 0, 0],
794
- [0, 0, 0],
795
- ]);
796
- });
797
- it('should handle padding with same dimensions', () => {
798
- const matrix = [[1, 2], [3, 4]];
799
- const result = MatrixPad(matrix, 2, 2);
800
- expect(result).toEqual([[1, 2], [3, 4]]);
801
- });
802
- it('should pad only rows', () => {
803
- const matrix = [[1, 2, 3], [4, 5, 6]];
804
- const result = MatrixPad(matrix, 4, 3);
805
- expect(result).toEqual([
806
- [1, 2, 3],
807
- [4, 5, 6],
808
- [0, 0, 0],
809
- [0, 0, 0],
810
- ]);
811
- });
812
- it('should pad only columns', () => {
813
- const matrix = [[1, 2], [3, 4], [5, 6]];
814
- const result = MatrixPad(matrix, 3, 4);
815
- expect(result).toEqual([
816
- [1, 2, 0, 0],
817
- [3, 4, 0, 0],
818
- [5, 6, 0, 0],
819
- ]);
820
- });
821
- });
822
- describe('MatrixCombine', () => {
823
- it('should combine four 2x2 matrices into 4x4', () => {
824
- const c11 = [[1, 2], [3, 4]];
825
- const c12 = [[5, 6], [7, 8]];
826
- const c21 = [[9, 10], [11, 12]];
827
- const c22 = [[13, 14], [15, 16]];
828
- const result = MatrixCombine(c11, c12, c21, c22);
829
- expect(result).toEqual([
830
- [1, 2, 5, 6],
831
- [3, 4, 7, 8],
832
- [9, 10, 13, 14],
833
- [11, 12, 15, 16],
834
- ]);
835
- });
836
- it('should combine four 1x1 matrices into 2x2', () => {
837
- const c11 = [[1]];
838
- const c12 = [[2]];
839
- const c21 = [[3]];
840
- const c22 = [[4]];
841
- const result = MatrixCombine(c11, c12, c21, c22);
842
- expect(result).toEqual([
843
- [1, 2],
844
- [3, 4],
845
- ]);
846
- });
847
- it('should handle matrices with negative numbers', () => {
848
- const c11 = [[1, -2], [-3, 4]];
849
- const c12 = [[-5, 6], [7, -8]];
850
- const c21 = [[9, -10], [-11, 12]];
851
- const c22 = [[-13, 14], [15, -16]];
852
- const result = MatrixCombine(c11, c12, c21, c22);
853
- expect(result).toEqual([
854
- [1, -2, -5, 6],
855
- [-3, 4, 7, -8],
856
- [9, -10, -13, 14],
857
- [-11, 12, 15, -16],
858
- ]);
859
- });
860
- it('should handle matrices with zeros', () => {
861
- const c11 = [[0, 0], [0, 0]];
862
- const c12 = [[1, 2], [3, 4]];
863
- const c21 = [[5, 6], [7, 8]];
864
- const c22 = [[0, 0], [0, 0]];
865
- const result = MatrixCombine(c11, c12, c21, c22);
866
- expect(result).toEqual([
867
- [0, 0, 1, 2],
868
- [0, 0, 3, 4],
869
- [5, 6, 0, 0],
870
- [7, 8, 0, 0],
871
- ]);
872
- });
873
- });
874
- describe('integration tests', () => {
875
- it('should perform complex operations sequence', () => {
876
- // Create two 2x2 matrices
877
- const a = [[1, 2], [3, 4]];
878
- const b = [[5, 6], [7, 8]];
879
- // Add them
880
- const sum = MatrixAdd(a, b);
881
- expect(sum).toEqual([[6, 8], [10, 12]]);
882
- // Multiply result by scalar
883
- const scaled = MatrixMultiply(sum, 0.5);
884
- expect(scaled).toEqual([[3, 4], [5, 6]]);
885
- // Subtract original matrix from result
886
- const diff = MatrixSubtract(scaled, a);
887
- expect(diff).toEqual([[2, 2], [2, 2]]);
888
- });
889
- it('should work with submatrix operations in Strassen context', () => {
890
- const matrix = [
891
- [1, 2, 3, 4],
892
- [5, 6, 7, 8],
893
- [9, 10, 11, 12],
894
- [13, 14, 15, 16],
895
- ];
896
- // Extract quadrants
897
- const c11 = MatrixSubmatrix(matrix, 0, 0, 2, 2);
898
- const c12 = MatrixSubmatrix(matrix, 2, 0, 2, 2);
899
- const c21 = MatrixSubmatrix(matrix, 0, 2, 2, 2);
900
- const c22 = MatrixSubmatrix(matrix, 2, 2, 2, 2);
901
- // Recombine
902
- const reconstructed = MatrixCombine(c11, c12, c21, c22);
903
- expect(reconstructed).toEqual(matrix);
904
- });
905
- it('should handle padding and submatrix extraction round trip', () => {
906
- const original = [[1, 2], [3, 4]];
907
- // Pad to larger size
908
- const padded = MatrixPad(original, 4, 4);
909
- // Extract original size back
910
- const extracted = MatrixSubmatrix(padded, 0, 0, 2, 2);
911
- expect(extracted).toEqual(original);
912
- });
913
- });
914
- });
915
- //# sourceMappingURL=arithmetic.spec.js.map