binary-tree-typed 2.4.4 → 2.5.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.
- package/README.md +0 -84
- package/dist/cjs/index.cjs +965 -420
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs-legacy/index.cjs +962 -417
- package/dist/cjs-legacy/index.cjs.map +1 -1
- package/dist/esm/index.mjs +965 -421
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm-legacy/index.mjs +962 -418
- package/dist/esm-legacy/index.mjs.map +1 -1
- package/dist/types/common/error.d.ts +23 -0
- package/dist/types/common/index.d.ts +1 -0
- package/dist/types/data-structures/base/iterable-element-base.d.ts +1 -1
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +128 -51
- package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +210 -164
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +439 -78
- package/dist/types/data-structures/binary-tree/bst.d.ts +311 -28
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +217 -31
- package/dist/types/data-structures/binary-tree/segment-tree.d.ts +218 -152
- package/dist/types/data-structures/binary-tree/tree-map.d.ts +1281 -5
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1087 -201
- package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +858 -65
- package/dist/types/data-structures/binary-tree/tree-set.d.ts +1133 -5
- package/dist/types/data-structures/graph/abstract-graph.d.ts +44 -0
- package/dist/types/data-structures/graph/directed-graph.d.ts +220 -47
- package/dist/types/data-structures/graph/map-graph.d.ts +59 -1
- package/dist/types/data-structures/graph/undirected-graph.d.ts +218 -59
- package/dist/types/data-structures/hash/hash-map.d.ts +230 -77
- package/dist/types/data-structures/heap/heap.d.ts +287 -99
- package/dist/types/data-structures/heap/max-heap.d.ts +46 -0
- package/dist/types/data-structures/heap/min-heap.d.ts +59 -0
- package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +286 -44
- package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +278 -65
- package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +415 -12
- package/dist/types/data-structures/matrix/matrix.d.ts +331 -0
- package/dist/types/data-structures/priority-queue/max-priority-queue.d.ts +57 -0
- package/dist/types/data-structures/priority-queue/min-priority-queue.d.ts +60 -0
- package/dist/types/data-structures/priority-queue/priority-queue.d.ts +60 -0
- package/dist/types/data-structures/queue/deque.d.ts +313 -66
- package/dist/types/data-structures/queue/queue.d.ts +211 -42
- package/dist/types/data-structures/stack/stack.d.ts +174 -32
- package/dist/types/data-structures/trie/trie.d.ts +213 -43
- package/dist/types/types/data-structures/binary-tree/segment-tree.d.ts +1 -1
- package/dist/types/types/data-structures/linked-list/skip-linked-list.d.ts +1 -4
- package/dist/types/types/data-structures/queue/deque.d.ts +6 -0
- package/dist/umd/binary-tree-typed.js +959 -414
- package/dist/umd/binary-tree-typed.js.map +1 -1
- package/dist/umd/binary-tree-typed.min.js +3 -3
- package/dist/umd/binary-tree-typed.min.js.map +1 -1
- package/package.json +2 -2
- package/src/common/error.ts +60 -0
- package/src/common/index.ts +2 -0
- package/src/data-structures/base/iterable-element-base.ts +2 -2
- package/src/data-structures/binary-tree/avl-tree.ts +134 -51
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +303 -247
- package/src/data-structures/binary-tree/binary-tree.ts +542 -121
- package/src/data-structures/binary-tree/bst.ts +346 -37
- package/src/data-structures/binary-tree/red-black-tree.ts +309 -96
- package/src/data-structures/binary-tree/segment-tree.ts +372 -248
- package/src/data-structures/binary-tree/tree-map.ts +1292 -13
- package/src/data-structures/binary-tree/tree-multi-map.ts +1098 -215
- package/src/data-structures/binary-tree/tree-multi-set.ts +863 -69
- package/src/data-structures/binary-tree/tree-set.ts +1143 -15
- package/src/data-structures/graph/abstract-graph.ts +106 -1
- package/src/data-structures/graph/directed-graph.ts +223 -47
- package/src/data-structures/graph/map-graph.ts +59 -1
- package/src/data-structures/graph/undirected-graph.ts +299 -59
- package/src/data-structures/hash/hash-map.ts +243 -79
- package/src/data-structures/heap/heap.ts +291 -102
- package/src/data-structures/heap/max-heap.ts +48 -3
- package/src/data-structures/heap/min-heap.ts +59 -0
- package/src/data-structures/linked-list/doubly-linked-list.ts +286 -44
- package/src/data-structures/linked-list/singly-linked-list.ts +278 -65
- package/src/data-structures/linked-list/skip-linked-list.ts +689 -90
- package/src/data-structures/matrix/matrix.ts +425 -22
- package/src/data-structures/priority-queue/max-priority-queue.ts +59 -3
- package/src/data-structures/priority-queue/min-priority-queue.ts +60 -0
- package/src/data-structures/priority-queue/priority-queue.ts +60 -0
- package/src/data-structures/queue/deque.ts +343 -68
- package/src/data-structures/queue/queue.ts +211 -42
- package/src/data-structures/stack/stack.ts +174 -32
- package/src/data-structures/trie/trie.ts +215 -44
- package/src/types/data-structures/binary-tree/segment-tree.ts +1 -1
- package/src/types/data-structures/linked-list/skip-linked-list.ts +2 -1
- package/src/types/data-structures/queue/deque.ts +7 -0
- package/src/utils/utils.ts +4 -2
|
@@ -6,10 +6,94 @@
|
|
|
6
6
|
* @license MIT License
|
|
7
7
|
*/
|
|
8
8
|
import type { MatrixOptions } from '../../types';
|
|
9
|
+
import { ERR } from '../../common';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
*
|
|
12
13
|
*/
|
|
14
|
+
/**
|
|
15
|
+
* Matrix — a numeric matrix with standard linear algebra operations.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* // Basic matrix arithmetic
|
|
19
|
+
* const a = new Matrix([
|
|
20
|
+
* [1, 2],
|
|
21
|
+
* [3, 4]
|
|
22
|
+
* ]);
|
|
23
|
+
* const b = new Matrix([
|
|
24
|
+
* [5, 6],
|
|
25
|
+
* [7, 8]
|
|
26
|
+
* ]);
|
|
27
|
+
*
|
|
28
|
+
* const sum = a.add(b);
|
|
29
|
+
* console.log(sum?.data); // [
|
|
30
|
+
* // [6, 8],
|
|
31
|
+
* // [10, 12]
|
|
32
|
+
* // ];
|
|
33
|
+
*
|
|
34
|
+
* const diff = b.subtract(a);
|
|
35
|
+
* console.log(diff?.data); // [
|
|
36
|
+
* // [4, 4],
|
|
37
|
+
* // [4, 4]
|
|
38
|
+
* // ];
|
|
39
|
+
* @example
|
|
40
|
+
* // Matrix multiplication for transformations
|
|
41
|
+
* // 2x3 matrix * 3x2 matrix = 2x2 matrix
|
|
42
|
+
* const a = new Matrix([
|
|
43
|
+
* [1, 2, 3],
|
|
44
|
+
* [4, 5, 6]
|
|
45
|
+
* ]);
|
|
46
|
+
* const b = new Matrix([
|
|
47
|
+
* [7, 8],
|
|
48
|
+
* [9, 10],
|
|
49
|
+
* [11, 12]
|
|
50
|
+
* ]);
|
|
51
|
+
*
|
|
52
|
+
* const product = a.multiply(b);
|
|
53
|
+
* console.log(product?.rows); // 2;
|
|
54
|
+
* console.log(product?.cols); // 2;
|
|
55
|
+
* // Row 0: 1*7+2*9+3*11=58, 1*8+2*10+3*12=64
|
|
56
|
+
* // Row 1: 4*7+5*9+6*11=139, 4*8+5*10+6*12=154
|
|
57
|
+
* console.log(product?.data); // [
|
|
58
|
+
* // [58, 64],
|
|
59
|
+
* // [139, 154]
|
|
60
|
+
* // ];
|
|
61
|
+
* @example
|
|
62
|
+
* // Matrix transpose (square matrix)
|
|
63
|
+
* const m = new Matrix([
|
|
64
|
+
* [1, 2, 3],
|
|
65
|
+
* [4, 5, 6],
|
|
66
|
+
* [7, 8, 9]
|
|
67
|
+
* ]);
|
|
68
|
+
*
|
|
69
|
+
* const transposed = m.transpose();
|
|
70
|
+
* console.log(transposed.rows); // 3;
|
|
71
|
+
* console.log(transposed.cols); // 3;
|
|
72
|
+
* console.log(transposed.data); // [
|
|
73
|
+
* // [1, 4, 7],
|
|
74
|
+
* // [2, 5, 8],
|
|
75
|
+
* // [3, 6, 9]
|
|
76
|
+
* // ];
|
|
77
|
+
*
|
|
78
|
+
* // Transpose of transpose = original
|
|
79
|
+
* console.log(transposed.transpose().data); // m.data;
|
|
80
|
+
* @example
|
|
81
|
+
* // Get and set individual cells
|
|
82
|
+
* const m = new Matrix([
|
|
83
|
+
* [0, 0, 0],
|
|
84
|
+
* [0, 0, 0]
|
|
85
|
+
* ]);
|
|
86
|
+
*
|
|
87
|
+
* m.set(0, 1, 42);
|
|
88
|
+
* m.set(1, 2, 99);
|
|
89
|
+
*
|
|
90
|
+
* console.log(m.get(0, 1)); // 42;
|
|
91
|
+
* console.log(m.get(1, 2)); // 99;
|
|
92
|
+
* console.log(m.get(0, 0)); // 0;
|
|
93
|
+
*
|
|
94
|
+
* // Out of bounds returns undefined
|
|
95
|
+
* console.log(m.get(5, 5)); // undefined;
|
|
96
|
+
*/
|
|
13
97
|
export class Matrix {
|
|
14
98
|
/**
|
|
15
99
|
* The constructor function initializes a matrix object with the provided data and options, or with
|
|
@@ -105,6 +189,33 @@ export class Matrix {
|
|
|
105
189
|
* retrieve from the data array.
|
|
106
190
|
* @returns The `get` function returns a number if the provided row and column indices are valid.
|
|
107
191
|
* Otherwise, it returns `undefined`.
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
* @example
|
|
204
|
+
* // Get and set individual cells
|
|
205
|
+
* const m = new Matrix([
|
|
206
|
+
* [0, 0, 0],
|
|
207
|
+
* [0, 0, 0]
|
|
208
|
+
* ]);
|
|
209
|
+
*
|
|
210
|
+
* m.set(0, 1, 42);
|
|
211
|
+
* m.set(1, 2, 99);
|
|
212
|
+
*
|
|
213
|
+
* console.log(m.get(0, 1)); // 42;
|
|
214
|
+
* console.log(m.get(1, 2)); // 99;
|
|
215
|
+
* console.log(m.get(0, 0)); // 0;
|
|
216
|
+
*
|
|
217
|
+
* // Out of bounds returns undefined
|
|
218
|
+
* console.log(m.get(5, 5)); // undefined;
|
|
108
219
|
*/
|
|
109
220
|
get(row: number, col: number): number | undefined {
|
|
110
221
|
if (this.isValidIndex(row, col)) {
|
|
@@ -123,6 +234,24 @@ export class Matrix {
|
|
|
123
234
|
* @returns a boolean value. It returns true if the index (row, col) is valid and the value is
|
|
124
235
|
* successfully set in the data array. It returns false if the index is invalid and the value is not
|
|
125
236
|
* set.
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
* @example
|
|
249
|
+
* // Modify individual cells
|
|
250
|
+
* const m = Matrix.zeros(2, 2);
|
|
251
|
+
* console.log(m.set(0, 0, 5)); // true;
|
|
252
|
+
* console.log(m.set(1, 1, 10)); // true;
|
|
253
|
+
* console.log(m.get(0, 0)); // 5;
|
|
254
|
+
* console.log(m.get(1, 1)); // 10;
|
|
126
255
|
*/
|
|
127
256
|
set(row: number, col: number, value: number): boolean {
|
|
128
257
|
if (this.isValidIndex(row, col)) {
|
|
@@ -147,10 +276,43 @@ export class Matrix {
|
|
|
147
276
|
* @param {Matrix} matrix - The `matrix` parameter is an instance of the `Matrix` class.
|
|
148
277
|
* @returns The `add` method returns a new `Matrix` object that represents the result of adding the
|
|
149
278
|
* current matrix with the provided `matrix` parameter.
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
* @example
|
|
291
|
+
* // Basic matrix arithmetic
|
|
292
|
+
* const a = new Matrix([
|
|
293
|
+
* [1, 2],
|
|
294
|
+
* [3, 4]
|
|
295
|
+
* ]);
|
|
296
|
+
* const b = new Matrix([
|
|
297
|
+
* [5, 6],
|
|
298
|
+
* [7, 8]
|
|
299
|
+
* ]);
|
|
300
|
+
*
|
|
301
|
+
* const sum = a.add(b);
|
|
302
|
+
* console.log(sum?.data); // [
|
|
303
|
+
* // [6, 8],
|
|
304
|
+
* // [10, 12]
|
|
305
|
+
* // ];
|
|
306
|
+
*
|
|
307
|
+
* const diff = b.subtract(a);
|
|
308
|
+
* console.log(diff?.data); // [
|
|
309
|
+
* // [4, 4],
|
|
310
|
+
* // [4, 4]
|
|
311
|
+
* // ];
|
|
150
312
|
*/
|
|
151
313
|
add(matrix: Matrix): Matrix | undefined {
|
|
152
314
|
if (!this.isMatchForCalculate(matrix)) {
|
|
153
|
-
throw new Error('
|
|
315
|
+
throw new Error(ERR.matrixDimensionMismatch('addition'));
|
|
154
316
|
}
|
|
155
317
|
|
|
156
318
|
const resultData: number[][] = [];
|
|
@@ -160,10 +322,7 @@ export class Matrix {
|
|
|
160
322
|
const a = this.get(i, j),
|
|
161
323
|
b = matrix.get(i, j);
|
|
162
324
|
if (a !== undefined && b !== undefined) {
|
|
163
|
-
|
|
164
|
-
if (added) {
|
|
165
|
-
resultData[i][j] = added;
|
|
166
|
-
}
|
|
325
|
+
resultData[i][j] = this._addFn(a, b) ?? 0;
|
|
167
326
|
}
|
|
168
327
|
}
|
|
169
328
|
}
|
|
@@ -183,10 +342,27 @@ export class Matrix {
|
|
|
183
342
|
* @param {Matrix} matrix - The `matrix` parameter is an instance of the `Matrix` class. It
|
|
184
343
|
* represents the matrix that you want to subtract from the current matrix.
|
|
185
344
|
* @returns a new Matrix object with the result of the subtraction operation.
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
* @example
|
|
357
|
+
* // Element-wise subtraction
|
|
358
|
+
* const a = Matrix.from([[5, 6], [7, 8]]);
|
|
359
|
+
* const b = Matrix.from([[1, 2], [3, 4]]);
|
|
360
|
+
* const result = a.subtract(b);
|
|
361
|
+
* console.log(result?.toArray()); // [[4, 4], [4, 4]];
|
|
186
362
|
*/
|
|
187
363
|
subtract(matrix: Matrix): Matrix | undefined {
|
|
188
364
|
if (!this.isMatchForCalculate(matrix)) {
|
|
189
|
-
throw new Error('
|
|
365
|
+
throw new Error(ERR.matrixDimensionMismatch('subtraction'));
|
|
190
366
|
}
|
|
191
367
|
|
|
192
368
|
const resultData: number[][] = [];
|
|
@@ -196,10 +372,7 @@ export class Matrix {
|
|
|
196
372
|
const a = this.get(i, j),
|
|
197
373
|
b = matrix.get(i, j);
|
|
198
374
|
if (a !== undefined && b !== undefined) {
|
|
199
|
-
|
|
200
|
-
if (subtracted) {
|
|
201
|
-
resultData[i][j] = subtracted;
|
|
202
|
-
}
|
|
375
|
+
resultData[i][j] = this._subtractFn(a, b) ?? 0;
|
|
203
376
|
}
|
|
204
377
|
}
|
|
205
378
|
}
|
|
@@ -218,10 +391,43 @@ export class Matrix {
|
|
|
218
391
|
* as a new matrix.
|
|
219
392
|
* @param {Matrix} matrix - The `matrix` parameter is an instance of the `Matrix` class.
|
|
220
393
|
* @returns a new Matrix object.
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
* @example
|
|
406
|
+
* // Matrix multiplication for transformations
|
|
407
|
+
* // 2x3 matrix * 3x2 matrix = 2x2 matrix
|
|
408
|
+
* const a = new Matrix([
|
|
409
|
+
* [1, 2, 3],
|
|
410
|
+
* [4, 5, 6]
|
|
411
|
+
* ]);
|
|
412
|
+
* const b = new Matrix([
|
|
413
|
+
* [7, 8],
|
|
414
|
+
* [9, 10],
|
|
415
|
+
* [11, 12]
|
|
416
|
+
* ]);
|
|
417
|
+
*
|
|
418
|
+
* const product = a.multiply(b);
|
|
419
|
+
* console.log(product?.rows); // 2;
|
|
420
|
+
* console.log(product?.cols); // 2;
|
|
421
|
+
* // Row 0: 1*7+2*9+3*11=58, 1*8+2*10+3*12=64
|
|
422
|
+
* // Row 1: 4*7+5*9+6*11=139, 4*8+5*10+6*12=154
|
|
423
|
+
* console.log(product?.data); // [
|
|
424
|
+
* // [58, 64],
|
|
425
|
+
* // [139, 154]
|
|
426
|
+
* // ];
|
|
221
427
|
*/
|
|
222
428
|
multiply(matrix: Matrix): Matrix | undefined {
|
|
223
429
|
if (this.cols !== matrix.rows) {
|
|
224
|
-
throw new Error('
|
|
430
|
+
throw new Error(ERR.matrixDimensionMismatch('multiplication (A.cols must equal B.rows)'));
|
|
225
431
|
}
|
|
226
432
|
|
|
227
433
|
const resultData: number[][] = [];
|
|
@@ -256,10 +462,40 @@ export class Matrix {
|
|
|
256
462
|
* The transpose function takes a matrix and returns a new matrix that is the transpose of the
|
|
257
463
|
* original matrix.
|
|
258
464
|
* @returns The transpose() function returns a new Matrix object with the transposed data.
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
* @example
|
|
477
|
+
* // Matrix transpose (square matrix)
|
|
478
|
+
* const m = new Matrix([
|
|
479
|
+
* [1, 2, 3],
|
|
480
|
+
* [4, 5, 6],
|
|
481
|
+
* [7, 8, 9]
|
|
482
|
+
* ]);
|
|
483
|
+
*
|
|
484
|
+
* const transposed = m.transpose();
|
|
485
|
+
* console.log(transposed.rows); // 3;
|
|
486
|
+
* console.log(transposed.cols); // 3;
|
|
487
|
+
* console.log(transposed.data); // [
|
|
488
|
+
* // [1, 4, 7],
|
|
489
|
+
* // [2, 5, 8],
|
|
490
|
+
* // [3, 6, 9]
|
|
491
|
+
* // ];
|
|
492
|
+
*
|
|
493
|
+
* // Transpose of transpose = original
|
|
494
|
+
* console.log(transposed.transpose().data); // m.data;
|
|
259
495
|
*/
|
|
260
496
|
transpose(): Matrix {
|
|
261
|
-
if (this.data.some(row => row.length !== this.
|
|
262
|
-
throw new Error(
|
|
497
|
+
if (this.data.some(row => row.length !== this.cols)) {
|
|
498
|
+
throw new Error(ERR.matrixNotRectangular());
|
|
263
499
|
}
|
|
264
500
|
|
|
265
501
|
const resultData: number[][] = [];
|
|
@@ -284,11 +520,33 @@ export class Matrix {
|
|
|
284
520
|
/**
|
|
285
521
|
* The `inverse` function calculates the inverse of a square matrix using Gaussian elimination.
|
|
286
522
|
* @returns a Matrix object, which represents the inverse of the original matrix.
|
|
523
|
+
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
|
|
529
|
+
|
|
530
|
+
|
|
531
|
+
|
|
532
|
+
|
|
533
|
+
|
|
534
|
+
* @example
|
|
535
|
+
* // Compute the inverse of a 2x2 matrix
|
|
536
|
+
* const m = Matrix.from([[4, 7], [2, 6]]);
|
|
537
|
+
* const inv = m.inverse();
|
|
538
|
+
* console.log(inv); // defined;
|
|
539
|
+
* // A * A^-1 should ≈ Identity
|
|
540
|
+
* const product = m.multiply(inv!);
|
|
541
|
+
* console.log(product?.get(0, 0)); // toBeCloseTo;
|
|
542
|
+
* console.log(product?.get(0, 1)); // toBeCloseTo;
|
|
543
|
+
* console.log(product?.get(1, 0)); // toBeCloseTo;
|
|
544
|
+
* console.log(product?.get(1, 1)); // toBeCloseTo;
|
|
287
545
|
*/
|
|
288
546
|
inverse(): Matrix | undefined {
|
|
289
547
|
// Check if the matrix is square
|
|
290
548
|
if (this.rows !== this.cols) {
|
|
291
|
-
throw new Error(
|
|
549
|
+
throw new Error(ERR.matrixNotSquare());
|
|
292
550
|
}
|
|
293
551
|
|
|
294
552
|
// Create an augmented matrix [this | I]
|
|
@@ -318,7 +576,7 @@ export class Matrix {
|
|
|
318
576
|
|
|
319
577
|
if (pivotRow === this.rows) {
|
|
320
578
|
// Matrix is singular, and its inverse does not exist
|
|
321
|
-
throw new Error(
|
|
579
|
+
throw new Error(ERR.matrixSingular());
|
|
322
580
|
}
|
|
323
581
|
|
|
324
582
|
// Swap rows to make the pivot the current row
|
|
@@ -329,7 +587,7 @@ export class Matrix {
|
|
|
329
587
|
|
|
330
588
|
if (pivotElement === 0) {
|
|
331
589
|
// Handle division by zero
|
|
332
|
-
throw new Error(
|
|
590
|
+
throw new Error(ERR.matrixSingular());
|
|
333
591
|
}
|
|
334
592
|
|
|
335
593
|
augmentedMatrix._scaleRow(i, 1 / pivotElement);
|
|
@@ -364,12 +622,27 @@ export class Matrix {
|
|
|
364
622
|
* The dot function calculates the dot product of two matrices and returns a new matrix.
|
|
365
623
|
* @param {Matrix} matrix - The `matrix` parameter is an instance of the `Matrix` class.
|
|
366
624
|
* @returns a new Matrix object.
|
|
625
|
+
|
|
626
|
+
|
|
627
|
+
|
|
628
|
+
|
|
629
|
+
|
|
630
|
+
|
|
631
|
+
|
|
632
|
+
|
|
633
|
+
|
|
634
|
+
|
|
635
|
+
|
|
636
|
+
* @example
|
|
637
|
+
* // Dot product of two matrices
|
|
638
|
+
* const a = Matrix.from([[1, 2], [3, 4]]);
|
|
639
|
+
* const b = Matrix.from([[5, 6], [7, 8]]);
|
|
640
|
+
* const result = a.dot(b);
|
|
641
|
+
* console.log(result?.toArray()); // [[19, 22], [43, 50]];
|
|
367
642
|
*/
|
|
368
643
|
dot(matrix: Matrix): Matrix | undefined {
|
|
369
644
|
if (this.cols !== matrix.rows) {
|
|
370
|
-
throw new Error(
|
|
371
|
-
'Number of columns in the first matrix must be equal to the number of rows in the second matrix for dot product.'
|
|
372
|
-
);
|
|
645
|
+
throw new Error(ERR.matrixDimensionMismatch('dot product (A.cols must equal B.rows)'));
|
|
373
646
|
}
|
|
374
647
|
|
|
375
648
|
const resultData: number[][] = [];
|
|
@@ -419,15 +692,145 @@ export class Matrix {
|
|
|
419
692
|
* and properties as the current instance.
|
|
420
693
|
*/
|
|
421
694
|
clone(): Matrix {
|
|
422
|
-
return new Matrix(
|
|
423
|
-
|
|
424
|
-
|
|
695
|
+
return new Matrix(
|
|
696
|
+
this._data.map(row => [...row]),
|
|
697
|
+
{
|
|
698
|
+
rows: this.rows,
|
|
699
|
+
cols: this.cols,
|
|
700
|
+
addFn: this.addFn,
|
|
701
|
+
subtractFn: this.subtractFn,
|
|
702
|
+
multiplyFn: this.multiplyFn
|
|
703
|
+
}
|
|
704
|
+
);
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
// ─── Standard interface ─────────────────────────────────────
|
|
708
|
+
|
|
709
|
+
/**
|
|
710
|
+
* Returns [rows, cols] dimensions tuple.
|
|
711
|
+
*/
|
|
712
|
+
get size(): [number, number] {
|
|
713
|
+
return [this._rows, this._cols];
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
isEmpty(): boolean {
|
|
717
|
+
return this._rows === 0 || this._cols === 0;
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
/**
|
|
721
|
+
* Returns a deep copy of the data as a plain 2D array.
|
|
722
|
+
*/
|
|
723
|
+
toArray(): number[][] {
|
|
724
|
+
return this._data.map(row => [...row]);
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
/**
|
|
728
|
+
* Returns a flat row-major array.
|
|
729
|
+
*/
|
|
730
|
+
flatten(): number[] {
|
|
731
|
+
const result: number[] = [];
|
|
732
|
+
for (const row of this._data) {
|
|
733
|
+
for (const v of row) result.push(v);
|
|
734
|
+
}
|
|
735
|
+
return result;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
/**
|
|
739
|
+
* Iterates over rows.
|
|
740
|
+
*/
|
|
741
|
+
[Symbol.iterator](): IterableIterator<number[]> {
|
|
742
|
+
const data = this._data;
|
|
743
|
+
let i = 0;
|
|
744
|
+
return {
|
|
745
|
+
[Symbol.iterator]() {
|
|
746
|
+
return this;
|
|
747
|
+
},
|
|
748
|
+
next(): IteratorResult<number[]> {
|
|
749
|
+
if (i < data.length) {
|
|
750
|
+
return { value: [...data[i++]], done: false };
|
|
751
|
+
}
|
|
752
|
+
return { value: undefined as any, done: true };
|
|
753
|
+
}
|
|
754
|
+
};
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
/**
|
|
758
|
+
* Visits each element with its row and column index.
|
|
759
|
+
*/
|
|
760
|
+
forEach(callback: (value: number, row: number, col: number) => void): void {
|
|
761
|
+
for (let i = 0; i < this._rows; i++) {
|
|
762
|
+
for (let j = 0; j < this._cols; j++) {
|
|
763
|
+
callback(this._data[i][j], i, j);
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
/**
|
|
769
|
+
* Maps each element (number → number) and returns a new Matrix.
|
|
770
|
+
*/
|
|
771
|
+
map(callback: (value: number, row: number, col: number) => number): Matrix {
|
|
772
|
+
const resultData: number[][] = [];
|
|
773
|
+
for (let i = 0; i < this._rows; i++) {
|
|
774
|
+
resultData[i] = [];
|
|
775
|
+
for (let j = 0; j < this._cols; j++) {
|
|
776
|
+
resultData[i][j] = callback(this._data[i][j], i, j);
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
return new Matrix(resultData, {
|
|
780
|
+
rows: this._rows,
|
|
781
|
+
cols: this._cols,
|
|
425
782
|
addFn: this.addFn,
|
|
426
783
|
subtractFn: this.subtractFn,
|
|
427
784
|
multiplyFn: this.multiplyFn
|
|
428
785
|
});
|
|
429
786
|
}
|
|
430
787
|
|
|
788
|
+
print(): void {
|
|
789
|
+
for (const row of this._data) {
|
|
790
|
+
console.log(row.join('\t'));
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
// ─── Factory methods ────────────────────────────────────────
|
|
795
|
+
|
|
796
|
+
/**
|
|
797
|
+
* Creates a rows×cols zero matrix.
|
|
798
|
+
* @example
|
|
799
|
+
* ```ts
|
|
800
|
+
* const z = Matrix.zeros(2, 3); // [[0,0,0],[0,0,0]]
|
|
801
|
+
* ```
|
|
802
|
+
*/
|
|
803
|
+
static zeros(rows: number, cols: number): Matrix {
|
|
804
|
+
const data: number[][] = Array.from({ length: rows }, () => new Array(cols).fill(0));
|
|
805
|
+
return new Matrix(data);
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
/**
|
|
809
|
+
* Creates an n×n identity matrix.
|
|
810
|
+
* @example
|
|
811
|
+
* ```ts
|
|
812
|
+
* const I = Matrix.identity(3); // [[1,0,0],[0,1,0],[0,0,1]]
|
|
813
|
+
* ```
|
|
814
|
+
*/
|
|
815
|
+
static identity(n: number): Matrix {
|
|
816
|
+
const data: number[][] = Array.from({ length: n }, (_, i) =>
|
|
817
|
+
Array.from({ length: n }, (_, j) => (i === j ? 1 : 0))
|
|
818
|
+
);
|
|
819
|
+
return new Matrix(data);
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
/**
|
|
823
|
+
* Creates a Matrix from a plain 2D array (deep copy).
|
|
824
|
+
* @example
|
|
825
|
+
* ```ts
|
|
826
|
+
* const m = Matrix.from([[1, 2], [3, 4]]);
|
|
827
|
+
* m.get(0, 1); // 2
|
|
828
|
+
* ```
|
|
829
|
+
*/
|
|
830
|
+
static from(data: number[][]): Matrix {
|
|
831
|
+
return new Matrix(data.map(row => [...row]));
|
|
832
|
+
}
|
|
833
|
+
|
|
431
834
|
protected _addFn(a: number | undefined, b: number): number | undefined {
|
|
432
835
|
if (a === undefined) return b;
|
|
433
836
|
return a + b;
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { PriorityQueueOptions } from '../../types';
|
|
9
9
|
import { PriorityQueue } from './priority-queue';
|
|
10
|
+
import { ERR } from '../../common';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Max-oriented priority queue (max-heap) built on {@link PriorityQueue}.
|
|
@@ -15,6 +16,63 @@ import { PriorityQueue } from './priority-queue';
|
|
|
15
16
|
* @template E Element type stored in the queue.
|
|
16
17
|
* @template R Extra record/metadata associated with each element.
|
|
17
18
|
* @example
|
|
19
|
+
* // Job scheduling by priority
|
|
20
|
+
* const jobs = new MaxPriorityQueue<number>();
|
|
21
|
+
*
|
|
22
|
+
* jobs.add(3); // low priority
|
|
23
|
+
* jobs.add(7); // high priority
|
|
24
|
+
* jobs.add(5); // medium priority
|
|
25
|
+
* jobs.add(10); // critical
|
|
26
|
+
*
|
|
27
|
+
* // Highest priority job first
|
|
28
|
+
* console.log(jobs.poll()); // 10;
|
|
29
|
+
* console.log(jobs.poll()); // 7;
|
|
30
|
+
* console.log(jobs.poll()); // 5;
|
|
31
|
+
* console.log(jobs.poll()); // 3;
|
|
32
|
+
* @example
|
|
33
|
+
* // Auction system with highest bid tracking
|
|
34
|
+
* interface Bid {
|
|
35
|
+
* bidder: string;
|
|
36
|
+
* amount: number;
|
|
37
|
+
* }
|
|
38
|
+
*
|
|
39
|
+
* const auction = new MaxPriorityQueue<Bid>([], {
|
|
40
|
+
* comparator: (a, b) => b.amount - a.amount
|
|
41
|
+
* });
|
|
42
|
+
*
|
|
43
|
+
* auction.add({ bidder: 'Alice', amount: 100 });
|
|
44
|
+
* auction.add({ bidder: 'Bob', amount: 250 });
|
|
45
|
+
* auction.add({ bidder: 'Charlie', amount: 175 });
|
|
46
|
+
*
|
|
47
|
+
* // Current highest bid
|
|
48
|
+
* console.log(auction.peek()?.bidder); // 'Bob';
|
|
49
|
+
* console.log(auction.peek()?.amount); // 250;
|
|
50
|
+
*
|
|
51
|
+
* // Process winning bid
|
|
52
|
+
* const winner = auction.poll()!;
|
|
53
|
+
* console.log(winner.bidder); // 'Bob';
|
|
54
|
+
* console.log(auction.peek()?.bidder); // 'Charlie';
|
|
55
|
+
* @example
|
|
56
|
+
* // CPU process scheduling
|
|
57
|
+
* const cpuQueue = new MaxPriorityQueue<[number, string]>([], {
|
|
58
|
+
* comparator: (a, b) => b[0] - a[0]
|
|
59
|
+
* });
|
|
60
|
+
*
|
|
61
|
+
* cpuQueue.add([5, 'System process']);
|
|
62
|
+
* cpuQueue.add([1, 'Background task']);
|
|
63
|
+
* cpuQueue.add([8, 'User interaction']);
|
|
64
|
+
* cpuQueue.add([3, 'Network sync']);
|
|
65
|
+
*
|
|
66
|
+
* const order = [];
|
|
67
|
+
* while (cpuQueue.size > 0) {
|
|
68
|
+
* order.push(cpuQueue.poll()![1]);
|
|
69
|
+
* }
|
|
70
|
+
* console.log(order); // [
|
|
71
|
+
* // 'User interaction',
|
|
72
|
+
* // 'System process',
|
|
73
|
+
* // 'Network sync',
|
|
74
|
+
* // 'Background task'
|
|
75
|
+
* // ];
|
|
18
76
|
*/
|
|
19
77
|
export class MaxPriorityQueue<E = any, R = any> extends PriorityQueue<E, R> {
|
|
20
78
|
/**
|
|
@@ -28,9 +86,7 @@ export class MaxPriorityQueue<E = any, R = any> extends PriorityQueue<E, R> {
|
|
|
28
86
|
super(elements, {
|
|
29
87
|
comparator: (a: E, b: E): number => {
|
|
30
88
|
if (typeof a === 'object' || typeof b === 'object') {
|
|
31
|
-
throw TypeError(
|
|
32
|
-
`When comparing object types, a custom comparator must be defined in the constructor's options parameter.`
|
|
33
|
-
);
|
|
89
|
+
throw new TypeError(ERR.comparatorRequired('MaxPriorityQueue'));
|
|
34
90
|
}
|
|
35
91
|
if (a < b) return 1;
|
|
36
92
|
if (a > b) return -1;
|
|
@@ -15,6 +15,66 @@ import { PriorityQueue } from './priority-queue';
|
|
|
15
15
|
* @template E Element type stored in the queue.
|
|
16
16
|
* @template R Extra record/metadata associated with each element.
|
|
17
17
|
* @example
|
|
18
|
+
* // Shortest job first scheduling
|
|
19
|
+
* const jobs = new MinPriorityQueue<number>();
|
|
20
|
+
*
|
|
21
|
+
* jobs.add(8); // 8 seconds
|
|
22
|
+
* jobs.add(2); // 2 seconds
|
|
23
|
+
* jobs.add(5); // 5 seconds
|
|
24
|
+
* jobs.add(1); // 1 second
|
|
25
|
+
*
|
|
26
|
+
* // Shortest job first
|
|
27
|
+
* console.log(jobs.poll()); // 1;
|
|
28
|
+
* console.log(jobs.poll()); // 2;
|
|
29
|
+
* console.log(jobs.poll()); // 5;
|
|
30
|
+
* console.log(jobs.poll()); // 8;
|
|
31
|
+
* @example
|
|
32
|
+
* // Event-driven simulation with timestamps
|
|
33
|
+
* interface Event {
|
|
34
|
+
* time: number;
|
|
35
|
+
* action: string;
|
|
36
|
+
* }
|
|
37
|
+
*
|
|
38
|
+
* const timeline = new MinPriorityQueue<Event>([], {
|
|
39
|
+
* comparator: (a, b) => a.time - b.time
|
|
40
|
+
* });
|
|
41
|
+
*
|
|
42
|
+
* timeline.add({ time: 300, action: 'Timeout' });
|
|
43
|
+
* timeline.add({ time: 100, action: 'Request received' });
|
|
44
|
+
* timeline.add({ time: 200, action: 'Processing done' });
|
|
45
|
+
* timeline.add({ time: 150, action: 'Cache hit' });
|
|
46
|
+
*
|
|
47
|
+
* const order = [];
|
|
48
|
+
* while (timeline.size > 0) {
|
|
49
|
+
* order.push(timeline.poll()!.action);
|
|
50
|
+
* }
|
|
51
|
+
* console.log(order); // [
|
|
52
|
+
* // 'Request received',
|
|
53
|
+
* // 'Cache hit',
|
|
54
|
+
* // 'Processing done',
|
|
55
|
+
* // 'Timeout'
|
|
56
|
+
* // ];
|
|
57
|
+
* @example
|
|
58
|
+
* // Huffman coding frequency selection
|
|
59
|
+
* // Character frequencies for Huffman tree building
|
|
60
|
+
* const freq = new MinPriorityQueue<[number, string]>([], {
|
|
61
|
+
* comparator: (a, b) => a[0] - b[0]
|
|
62
|
+
* });
|
|
63
|
+
*
|
|
64
|
+
* freq.add([5, 'a']);
|
|
65
|
+
* freq.add([9, 'b']);
|
|
66
|
+
* freq.add([12, 'c']);
|
|
67
|
+
* freq.add([2, 'd']);
|
|
68
|
+
*
|
|
69
|
+
* // Always pick two lowest frequencies
|
|
70
|
+
* const first = freq.poll()!;
|
|
71
|
+
* const second = freq.poll()!;
|
|
72
|
+
* console.log(first[1]); // 'd'; // freq 2
|
|
73
|
+
* console.log(second[1]); // 'a'; // freq 5
|
|
74
|
+
*
|
|
75
|
+
* // Combined node goes back
|
|
76
|
+
* freq.add([first[0] + second[0], first[1] + second[1]]);
|
|
77
|
+
* console.log(freq.peek()![0]); // 7;
|
|
18
78
|
*/
|
|
19
79
|
export class MinPriorityQueue<E = any, R = any> extends PriorityQueue<E, R> {
|
|
20
80
|
/**
|