numz 0.7.0 → 0.9.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/package.json +3 -3
- package/src/discret/bitwise/algorithms/index.js +34 -0
- package/src/discret/bitwise/conversions/index.d.ts +101 -0
- package/src/discret/bitwise/conversions/index.js +61 -0
- package/src/discret/bitwise/index.js +3 -34
- package/src/discret/bitwise/operations/index.d.ts +53 -0
- package/src/discret/bitwise/operations/index.js +54 -0
- package/src/discret/index.js +2 -2
- package/src/index.js +4 -0
- package/src/matrix/AbstractMatrix.js +0 -0
- package/src/matrix/helpers/constructor.js +31 -0
- package/src/matrix/helpers/det.js +36 -0
- package/src/matrix/helpers/index.js +5 -0
- package/src/matrix/helpers/inverse.js +52 -0
- package/src/matrix/helpers/maintain.js +13 -0
- package/src/matrix/helpers/stack.js +24 -0
- package/src/matrix/index.js +557 -0
- package/src/random/index.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "numz",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "scientific computing with zikojs",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -26,9 +26,9 @@
|
|
|
26
26
|
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
27
27
|
"@rollup/plugin-terser": "^1.0.0",
|
|
28
28
|
"cross-env": "^10.1.0",
|
|
29
|
-
"rollup": "^4.63.
|
|
29
|
+
"rollup": "^4.63.1"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"ziko": "^
|
|
32
|
+
"ziko": "^2.0.0-alpha.0"
|
|
33
33
|
}
|
|
34
34
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
export const bitmasks = (n) => {
|
|
4
|
+
const res = [];
|
|
5
|
+
for (let i = 0; i < 1 << n; i++) {
|
|
6
|
+
const mask = [];
|
|
7
|
+
for (let j = 0; j < n; j++) mask.push((i >> j) & 1);
|
|
8
|
+
res.push(mask);
|
|
9
|
+
}
|
|
10
|
+
return res;
|
|
11
|
+
};
|
|
12
|
+
export const subsets_by_mask = (arr) => {
|
|
13
|
+
const n = arr.length,
|
|
14
|
+
res = [];
|
|
15
|
+
for (let i = 0; i < 1 << n; i++) {
|
|
16
|
+
const subset = [];
|
|
17
|
+
for (let j = 0; j < n; j++) if ((i >> j) & 1) subset.push(arr[j]);
|
|
18
|
+
res.push(subset);
|
|
19
|
+
}
|
|
20
|
+
return res;
|
|
21
|
+
};
|
|
22
|
+
export const gray_code = (n) => {
|
|
23
|
+
if (n === 0) return [0];
|
|
24
|
+
const prev = gray_code(n - 1);
|
|
25
|
+
return [...prev, ...prev.map((x) => x | (1 << (n - 1)))];
|
|
26
|
+
};
|
|
27
|
+
export const hamming_weight = (x) => {
|
|
28
|
+
let count = 0;
|
|
29
|
+
while (x) {
|
|
30
|
+
x &= x - 1;
|
|
31
|
+
count++;
|
|
32
|
+
}
|
|
33
|
+
return count;
|
|
34
|
+
};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a value from one numerical base to another.
|
|
3
|
+
*
|
|
4
|
+
* Supported bases are between 2 and 36.
|
|
5
|
+
*
|
|
6
|
+
* @param value Value to convert.
|
|
7
|
+
* @param fromBase Source base.
|
|
8
|
+
* @param toBase Target base.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* base2base("1010", 2, 10) // "10"
|
|
12
|
+
*/
|
|
13
|
+
export declare function base2base(
|
|
14
|
+
value: string | number,
|
|
15
|
+
fromBase: number,
|
|
16
|
+
toBase: number
|
|
17
|
+
): string;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Converts binary values to octal.
|
|
21
|
+
*/
|
|
22
|
+
export declare function bin2oct(
|
|
23
|
+
...x: (string | number)[]
|
|
24
|
+
): string[];
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Converts binary values to decimal.
|
|
28
|
+
*/
|
|
29
|
+
export declare function bin2dec(
|
|
30
|
+
...x: (string | number)[]
|
|
31
|
+
): string[];
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Converts binary values to hexadecimal.
|
|
35
|
+
*/
|
|
36
|
+
export declare function bin2hex(
|
|
37
|
+
...x: (string | number)[]
|
|
38
|
+
): string[];
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Converts octal values to binary.
|
|
42
|
+
*/
|
|
43
|
+
export declare function oct2bin(
|
|
44
|
+
...x: (string | number)[]
|
|
45
|
+
): string[];
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Converts octal values to decimal.
|
|
49
|
+
*/
|
|
50
|
+
export declare function oct2dec(
|
|
51
|
+
...x: (string | number)[]
|
|
52
|
+
): string[];
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Converts octal values to hexadecimal.
|
|
56
|
+
*/
|
|
57
|
+
export declare function oct2hex(
|
|
58
|
+
...x: (string | number)[]
|
|
59
|
+
): string[];
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Converts decimal values to binary.
|
|
63
|
+
*/
|
|
64
|
+
export declare function dec2bin(
|
|
65
|
+
...x: (string | number)[]
|
|
66
|
+
): string[];
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Converts decimal values to octal.
|
|
70
|
+
*/
|
|
71
|
+
export declare function dec2oct(
|
|
72
|
+
...x: (string | number)[]
|
|
73
|
+
): string[];
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Converts decimal values to hexadecimal.
|
|
77
|
+
*/
|
|
78
|
+
export declare function dec2hex(
|
|
79
|
+
...x: (string | number)[]
|
|
80
|
+
): string[];
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Converts hexadecimal values to binary.
|
|
84
|
+
*/
|
|
85
|
+
export declare function hex2bin(
|
|
86
|
+
...x: (string | number)[]
|
|
87
|
+
): string[];
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Converts hexadecimal values to octal.
|
|
91
|
+
*/
|
|
92
|
+
export declare function hex2oct(
|
|
93
|
+
...x: (string | number)[]
|
|
94
|
+
): string[];
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Converts hexadecimal values to decimal.
|
|
98
|
+
*/
|
|
99
|
+
export declare function hex2dec(
|
|
100
|
+
...x: (string | number)[]
|
|
101
|
+
): string[];
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
export const base2base = (value, fromBase, toBase) => {
|
|
2
|
+
if (fromBase < 2 || fromBase > 36 || toBase < 2 || toBase > 36)
|
|
3
|
+
throw new TypeError('Base must be between 2 and 36');
|
|
4
|
+
|
|
5
|
+
const dec = parseInt(value, fromBase);
|
|
6
|
+
if (Number.isNaN(dec)) throw new TypeError('Invalid value for the given base');
|
|
7
|
+
|
|
8
|
+
return dec.toString(toBase);
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const bin2oct = (...x) => mapfun(
|
|
12
|
+
n => base2base(n, 2, 8),
|
|
13
|
+
...x
|
|
14
|
+
)
|
|
15
|
+
export const bin2dec = (...x) => mapfun(
|
|
16
|
+
n => base2base(n, 2, 10),
|
|
17
|
+
...x
|
|
18
|
+
)
|
|
19
|
+
export const bin2hex = (...x) => mapfun(
|
|
20
|
+
n => base2base(n, 2, 16),
|
|
21
|
+
...x
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
export const oct2bin = (...x) => mapfun(
|
|
25
|
+
n => base2base(n, 8, 2),
|
|
26
|
+
...x
|
|
27
|
+
)
|
|
28
|
+
export const oct2dec = (...x) => mapfun(
|
|
29
|
+
n => base2base(n, 8, 10),
|
|
30
|
+
...x
|
|
31
|
+
)
|
|
32
|
+
export const oct2hex = (...x) => mapfun(
|
|
33
|
+
n => base2base(n, 8, 16),
|
|
34
|
+
...x
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
export const dec2bin = (...x) => mapfun(
|
|
38
|
+
n => base2base(n, 10, 2),
|
|
39
|
+
...x
|
|
40
|
+
)
|
|
41
|
+
export const dec2oct = (...x) => mapfun(
|
|
42
|
+
n => base2base(n, 10, 8),
|
|
43
|
+
...x
|
|
44
|
+
)
|
|
45
|
+
export const dec2hex = (...x) => mapfun(
|
|
46
|
+
n => base2base(n, 10, 16),
|
|
47
|
+
...x
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
export const hex2bin = (...x) => mapfun(
|
|
51
|
+
n => base2base(n, 16, 2),
|
|
52
|
+
...x
|
|
53
|
+
)
|
|
54
|
+
export const hex2oct = (...x) => mapfun(
|
|
55
|
+
n => base2base(n, 16, 8),
|
|
56
|
+
...x
|
|
57
|
+
)
|
|
58
|
+
export const hex2dec = (...x) => mapfun(
|
|
59
|
+
n => base2base(n, 16, 10),
|
|
60
|
+
...x
|
|
61
|
+
)
|
|
@@ -1,34 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export
|
|
4
|
-
const res = [];
|
|
5
|
-
for (let i = 0; i < 1 << n; i++) {
|
|
6
|
-
const mask = [];
|
|
7
|
-
for (let j = 0; j < n; j++) mask.push((i >> j) & 1);
|
|
8
|
-
res.push(mask);
|
|
9
|
-
}
|
|
10
|
-
return res;
|
|
11
|
-
};
|
|
12
|
-
export const subsets_by_mask = (arr) => {
|
|
13
|
-
const n = arr.length,
|
|
14
|
-
res = [];
|
|
15
|
-
for (let i = 0; i < 1 << n; i++) {
|
|
16
|
-
const subset = [];
|
|
17
|
-
for (let j = 0; j < n; j++) if ((i >> j) & 1) subset.push(arr[j]);
|
|
18
|
-
res.push(subset);
|
|
19
|
-
}
|
|
20
|
-
return res;
|
|
21
|
-
};
|
|
22
|
-
export const gray_code = (n) => {
|
|
23
|
-
if (n === 0) return [0];
|
|
24
|
-
const prev = gray_code(n - 1);
|
|
25
|
-
return [...prev, ...prev.map((x) => x | (1 << (n - 1)))];
|
|
26
|
-
};
|
|
27
|
-
export const hamming_weight = (x) => {
|
|
28
|
-
let count = 0;
|
|
29
|
-
while (x) {
|
|
30
|
-
x &= x - 1;
|
|
31
|
-
count++;
|
|
32
|
-
}
|
|
33
|
-
return count;
|
|
34
|
-
};
|
|
1
|
+
export * from './operations/index.js'
|
|
2
|
+
export * from './conversions/index.js'
|
|
3
|
+
export * from './algorithms/index.js'
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { Complex } from "../../complex/indexxx
|
|
2
|
+
import { Matrix } from '../../matrix/index.jsssss
|
|
3
|
+
|
|
4
|
+
export type LogicValue = 0 | 1 | Complex | Matrix;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Logical NOT operation.
|
|
8
|
+
*/
|
|
9
|
+
export declare const not: (
|
|
10
|
+
x: LogicValue
|
|
11
|
+
) => LogicValue;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Logical AND operation.
|
|
15
|
+
*/
|
|
16
|
+
export declare const and: (
|
|
17
|
+
...x: LogicValue[]
|
|
18
|
+
) => LogicValue;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Logical OR operation.
|
|
22
|
+
*/
|
|
23
|
+
export declare const or: (
|
|
24
|
+
...x: LogicValue[]
|
|
25
|
+
) => LogicValue;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Logical XOR operation.
|
|
29
|
+
*/
|
|
30
|
+
export declare const xor: (
|
|
31
|
+
...x: LogicValue[]
|
|
32
|
+
) => LogicValue;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Logical NAND operation.
|
|
36
|
+
*/
|
|
37
|
+
export declare const nand: (
|
|
38
|
+
...x: LogicValue[]
|
|
39
|
+
) => LogicValue;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Logical NOR operation.
|
|
43
|
+
*/
|
|
44
|
+
export declare const nor: (
|
|
45
|
+
...x: LogicValue[]
|
|
46
|
+
) => LogicValue;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Logical XNOR operation.
|
|
50
|
+
*/
|
|
51
|
+
export declare const xnor: (
|
|
52
|
+
...x: LogicValue[]
|
|
53
|
+
) => LogicValue;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export const not = x => {
|
|
2
|
+
if(x.isComplex?.()) return new x.constructor(not(x.a), not(x.b))
|
|
3
|
+
if(x.isMatrix?.()) return new x.constructor(x.rows, x.cols, x.arr.flat(1).map(not))
|
|
4
|
+
return + !x;
|
|
5
|
+
}
|
|
6
|
+
const handle_complex_and_matrix = (x, operation) => {
|
|
7
|
+
if (x.every(n => n.isComplex?.())) {
|
|
8
|
+
const Re = x.map(n => n.a);
|
|
9
|
+
const Im = x.map(n => n.b);
|
|
10
|
+
return new x[0].constructor(
|
|
11
|
+
operation(...Re),
|
|
12
|
+
operation(...Im)
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (x.every(n => n.isMatrix?.())) {
|
|
17
|
+
if (!x.every(mat => mat.rows === x[0].rows && mat.cols === x[0].cols)) {
|
|
18
|
+
return TypeError('All matrices must have the same shape');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const { rows, cols } = x[0];
|
|
22
|
+
const Y = Array.from({ length: rows }, (_, i) =>
|
|
23
|
+
Array.from({ length: cols }, (_, j) =>
|
|
24
|
+
operation(...x.map(mat => mat.arr[i][j]))
|
|
25
|
+
)
|
|
26
|
+
);
|
|
27
|
+
return new x[0].constructor(Y);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return null; // Return null if no Complex or Matrix found
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const and = (...x) => {
|
|
34
|
+
const result = handle_complex_and_matrix(x, and);
|
|
35
|
+
if (result !== null) return result;
|
|
36
|
+
return x.reduce((n, m) => (n &= m), 1);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const or = (...x) => {
|
|
40
|
+
const result = handle_complex_and_matrix(x, or);
|
|
41
|
+
if (result !== null) return result;
|
|
42
|
+
return x.reduce((n, m) => (n |= m), 0);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const xor = (...x) => {
|
|
46
|
+
const result = handle_complex_and_matrix(x, xor);
|
|
47
|
+
if (result !== null) return result;
|
|
48
|
+
return x.reduce((n, m) => (n ^= m), 0);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const nand = (...x) => not(and(...x));
|
|
52
|
+
export const nor = (...x) => not(or(...x));
|
|
53
|
+
export const xnor = (...x) => not(xor(...x));
|
|
54
|
+
|
package/src/discret/index.js
CHANGED
package/src/index.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export * from './ufunc/index.js'
|
|
2
2
|
export * from './random/index.js'
|
|
3
3
|
export * from './complex/index.js'
|
|
4
|
+
export * from './matrix/index.js'
|
|
5
|
+
export * from './typed-matrix/index.js'
|
|
6
|
+
export * from './discret/bitwise/index.js'
|
|
4
7
|
export * from './calculus/index.js'
|
|
5
8
|
export * from './signal/index.js'
|
|
6
9
|
export * from './stats/index.js'
|
|
10
|
+
|
|
File without changes
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export const matrix_constructor = (Matrix, rows, cols, element) => {
|
|
2
|
+
if (rows instanceof Matrix) {
|
|
3
|
+
arr = rows.arr;
|
|
4
|
+
rows = rows.rows;
|
|
5
|
+
cols = rows.cols;
|
|
6
|
+
}
|
|
7
|
+
else {
|
|
8
|
+
let arr = [], i, j;
|
|
9
|
+
if (rows instanceof Array) {
|
|
10
|
+
arr = rows;
|
|
11
|
+
rows = arr.length;
|
|
12
|
+
cols = arr[0].length;
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
for (i = 0; i < rows; i++) {
|
|
16
|
+
arr.push([]);
|
|
17
|
+
arr[i].push(new Array(cols));
|
|
18
|
+
for (j = 0; j < cols; j++) {
|
|
19
|
+
arr[i][j] = element[i * cols + j];
|
|
20
|
+
if (element[i * cols + j] == undefined) arr[i][j] = 0;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return [
|
|
25
|
+
rows,
|
|
26
|
+
cols,
|
|
27
|
+
arr
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { add, sub, mul } from "ziko/math/arithmetic";
|
|
2
|
+
import { pow } from "../../functions/index.js";
|
|
3
|
+
export function matrix_det(M) {
|
|
4
|
+
if (!M.isSquare) return new Error("is not square matrix");
|
|
5
|
+
if (M.rows == 1) return M.arr[0][0];
|
|
6
|
+
function determinat(M) {
|
|
7
|
+
if (M.length == 2) {
|
|
8
|
+
if (M.flat(1).some((n) => n?.isMatrix?.())) {
|
|
9
|
+
console.warn("Tensors are not completely supported yet ...");
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
return sub(mul(M[0][0],M[1][1]),mul(M[0][1],M[1][0]))
|
|
13
|
+
}
|
|
14
|
+
var answer = 0;
|
|
15
|
+
for (var i = 0; i < M.length; i++) {
|
|
16
|
+
//console.log(M[0][i]);
|
|
17
|
+
/*answer = answer.add(
|
|
18
|
+
pow(-1, i)
|
|
19
|
+
.mul(M[0][i])
|
|
20
|
+
.mul(determinat(deleteRowAndColumn(M, i)))
|
|
21
|
+
);*/
|
|
22
|
+
//const to_be_added=add(mul(pow(-1, i),mul(M[0][i],determinat(deleteRowAndColumn(M, i)))));
|
|
23
|
+
const to_be_added=add(mul(pow(-1, i),mul(M[0][i],determinat(deleteRowAndColumn(M, i)))));
|
|
24
|
+
answer=add(answer,to_be_added)
|
|
25
|
+
}
|
|
26
|
+
return answer;
|
|
27
|
+
}
|
|
28
|
+
return determinat(M.arr);
|
|
29
|
+
}
|
|
30
|
+
function deleteRowAndColumn(M, index) {
|
|
31
|
+
var temp = [];
|
|
32
|
+
for (let i = 0; i < M.length; i++) temp.push(M[i].slice(0));
|
|
33
|
+
temp.splice(0, 1);
|
|
34
|
+
for (let i = 0; i < temp.length; i++) temp[i].splice(index, 1);
|
|
35
|
+
return temp;
|
|
36
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export function matrix_inverse(M) {
|
|
2
|
+
if(M.row !== M.cols) throw Error('is not a square matrix"')
|
|
3
|
+
if (M.det === 0) throw Error("determinant should not equal 0");
|
|
4
|
+
const { arr } = M
|
|
5
|
+
if (arr.length !== arr[0].length) return;
|
|
6
|
+
var i = 0, ii = 0, j = 0, dim = arr.length, e = 0;
|
|
7
|
+
var I = [], C = [];
|
|
8
|
+
for (i = 0; i < dim; i += 1) {
|
|
9
|
+
I[I.length] = [];
|
|
10
|
+
C[C.length] = [];
|
|
11
|
+
for (j = 0; j < dim; j += 1) {
|
|
12
|
+
if (i == j) I[i][j] = 1;
|
|
13
|
+
else I[i][j] = 0;
|
|
14
|
+
C[i][j] = arr[i][j];
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
for (i = 0; i < dim; i += 1) {
|
|
18
|
+
e = C[i][i];
|
|
19
|
+
if (e == 0) {
|
|
20
|
+
for (ii = i + 1; ii < dim; ii += 1) {
|
|
21
|
+
if (C[ii][i] != 0) {
|
|
22
|
+
for (j = 0; j < dim; j++) {
|
|
23
|
+
e = C[i][j];
|
|
24
|
+
C[i][j] = C[ii][j];
|
|
25
|
+
C[ii][j] = e;
|
|
26
|
+
e = I[i][j];
|
|
27
|
+
I[i][j] = I[ii][j];
|
|
28
|
+
I[ii][j] = e;
|
|
29
|
+
}
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
e = C[i][i];
|
|
34
|
+
if (e == 0) return;
|
|
35
|
+
}
|
|
36
|
+
for (j = 0; j < dim; j++) {
|
|
37
|
+
C[i][j] = C[i][j] / e;
|
|
38
|
+
I[i][j] = I[i][j] / e;
|
|
39
|
+
}
|
|
40
|
+
for (ii = 0; ii < dim; ii++) {
|
|
41
|
+
if (ii == i) {
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
e = C[ii][i];
|
|
45
|
+
for (j = 0; j < dim; j++) {
|
|
46
|
+
C[ii][j] -= e * C[i][j];
|
|
47
|
+
I[ii][j] -= e * I[i][j];
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return new M.constructor(I);
|
|
52
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const maintain_indexes = (Matrix, oldRows) =>{
|
|
2
|
+
for (let i = 0; i < Matrix.arr.length; i++) {
|
|
3
|
+
Object.defineProperty(Matrix, i, {
|
|
4
|
+
value: Matrix.arr[i],
|
|
5
|
+
writable: true,
|
|
6
|
+
configurable: true,
|
|
7
|
+
enumerable: false
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
for (let i = Matrix.arr.length; i < oldRows; i++) {
|
|
11
|
+
delete Matrix[i];
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export function hstack(M1, M2){
|
|
2
|
+
M1 = M1.clone()
|
|
3
|
+
M2 = M2.clone()
|
|
4
|
+
if (M1.rows !== M2.rows) return;
|
|
5
|
+
let newArr = M1.arr;
|
|
6
|
+
for (let i = 0; i < M1.rows; i++)
|
|
7
|
+
for (let j = M1.cols; j < M1.cols + M2.cols; j++)
|
|
8
|
+
newArr[i][j] = M2.arr[i][j - M1.cols];
|
|
9
|
+
M1.cols += M2.cols;
|
|
10
|
+
return new M1.constructor(M1.rows, M1.cols, newArr.flat(1));
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function vstack(M1, M2){
|
|
14
|
+
M1 = M1.clone()
|
|
15
|
+
M2 = M2.clone()
|
|
16
|
+
if (M1.cols !== M2.cols) return;
|
|
17
|
+
let newArr = M1.arr;
|
|
18
|
+
for (let i = M1.rows; i < M1.rows + M2.rows; i++) {
|
|
19
|
+
newArr[i] = [];
|
|
20
|
+
for (let j = 0; j < M1.cols; j++) newArr[i][j] = M2.arr[i - M1.rows][j];
|
|
21
|
+
}
|
|
22
|
+
M1.rows += M2.rows;
|
|
23
|
+
return new M1.constructor(M1.rows, M1.cols, newArr.flat(1));
|
|
24
|
+
}
|
|
@@ -0,0 +1,557 @@
|
|
|
1
|
+
import {
|
|
2
|
+
add,
|
|
3
|
+
sub,
|
|
4
|
+
mul,
|
|
5
|
+
div,
|
|
6
|
+
modulo
|
|
7
|
+
} from 'ziko/math/arithmetic'
|
|
8
|
+
import {
|
|
9
|
+
map,
|
|
10
|
+
lerp,
|
|
11
|
+
clamp,
|
|
12
|
+
norm
|
|
13
|
+
} from 'ziko/math/utils'
|
|
14
|
+
import { Complex } from "../complex/index.js";
|
|
15
|
+
// import { arr2str } from "../../data/index.js";
|
|
16
|
+
import {
|
|
17
|
+
matrix_constructor,
|
|
18
|
+
maintain_indexes,
|
|
19
|
+
matrix_inverse,
|
|
20
|
+
matrix_det,
|
|
21
|
+
hstack,
|
|
22
|
+
vstack
|
|
23
|
+
} from "./helpers/index.js";
|
|
24
|
+
import { mapfun } from 'ziko/math/mapfun';
|
|
25
|
+
import { Random } from '../random/index.js';
|
|
26
|
+
class Matrix{
|
|
27
|
+
constructor(rows, cols, element = [] ) {
|
|
28
|
+
[
|
|
29
|
+
this.rows,
|
|
30
|
+
this.cols,
|
|
31
|
+
this.arr
|
|
32
|
+
] = matrix_constructor(Matrix, rows, cols, element);
|
|
33
|
+
maintain_indexes(this)
|
|
34
|
+
}
|
|
35
|
+
isMatrix(){
|
|
36
|
+
return true
|
|
37
|
+
}
|
|
38
|
+
clone() {
|
|
39
|
+
return new Matrix(this.rows, this.cols, this.arr.flat(1));
|
|
40
|
+
}
|
|
41
|
+
toComplex(){
|
|
42
|
+
this.arr = mapfun(
|
|
43
|
+
x => x?.isComplex?.() ? x : new Complex(x, 0),
|
|
44
|
+
...this.arr
|
|
45
|
+
)
|
|
46
|
+
maintain_indexes(this)
|
|
47
|
+
return this;
|
|
48
|
+
}
|
|
49
|
+
[Symbol.iterator]() {
|
|
50
|
+
return this.arr[Symbol.iterator]();
|
|
51
|
+
}
|
|
52
|
+
get size() {
|
|
53
|
+
return this.rows * this.cols;
|
|
54
|
+
}
|
|
55
|
+
get shape() {
|
|
56
|
+
return [this.rows, this.cols];
|
|
57
|
+
}
|
|
58
|
+
// toString(){
|
|
59
|
+
// return arr2str(this.arr,false);
|
|
60
|
+
// }
|
|
61
|
+
at(i = 0, j = undefined) {
|
|
62
|
+
if(i < 0) i += this.rows;
|
|
63
|
+
if(i < 0 || i >= this.rows) throw new Error('Row index out of bounds');
|
|
64
|
+
if(j === undefined) return this.arr[i];
|
|
65
|
+
if(j < 0) j += this.cols;
|
|
66
|
+
if(j < 0 || j >= this.cols) throw new Error('Column index out of bounds');
|
|
67
|
+
return this.arr[i][j];
|
|
68
|
+
}
|
|
69
|
+
slice(r0=0, c0=0, r1 = this.rows-1, c1 = this.cols-1) {
|
|
70
|
+
if(r1 < 0) r1 = this.rows + r1
|
|
71
|
+
if(c1 < 0 ) c1 = this.cols + c1
|
|
72
|
+
let newRow = r1 - r0,
|
|
73
|
+
newCol = c1 - c0;
|
|
74
|
+
let newArr = new Array(newCol);
|
|
75
|
+
for (let i = 0; i < newRow; i++) {
|
|
76
|
+
newArr[i] = [];
|
|
77
|
+
for (let j = 0; j < newCol; j++)
|
|
78
|
+
newArr[i][j] = this.arr[i + r0][j + c0];
|
|
79
|
+
}
|
|
80
|
+
this.arr = newArr;
|
|
81
|
+
maintain_indexes(this.rows)
|
|
82
|
+
this.rows = newRow;
|
|
83
|
+
this.cols = newCol;
|
|
84
|
+
return this;
|
|
85
|
+
}
|
|
86
|
+
reshape(newRows, newCols) {
|
|
87
|
+
if(!(newRows * newCols === this.rows * this.cols)) throw Error('size not matched');
|
|
88
|
+
const oldRows = this.rows;
|
|
89
|
+
Object.assign(this, new Matrix(newRows, newCols, this.arr.flat(1)));
|
|
90
|
+
maintain_indexes(oldRows);
|
|
91
|
+
return this;
|
|
92
|
+
}
|
|
93
|
+
get T() {
|
|
94
|
+
let transpose = [];
|
|
95
|
+
for (let i = 0; i < this.arr[0].length; i++) {
|
|
96
|
+
transpose[i] = [];
|
|
97
|
+
for (let j = 0; j < this.arr.length; j++)
|
|
98
|
+
transpose[i][j] = this.arr[j][i];
|
|
99
|
+
}
|
|
100
|
+
return new Matrix(this.cols, this.rows, transpose.flat(1));
|
|
101
|
+
}
|
|
102
|
+
get det() {
|
|
103
|
+
return matrix_det(this)
|
|
104
|
+
}
|
|
105
|
+
get inv() {
|
|
106
|
+
return matrix_inverse(this)
|
|
107
|
+
}
|
|
108
|
+
// normalize names
|
|
109
|
+
static eye(size) {
|
|
110
|
+
let result = new Matrix(size, size);
|
|
111
|
+
for (let i = 0; i < size; i++)
|
|
112
|
+
for (let j = 0; j < size; j++) i === j ? (result.arr[i][j] = 1) : (result.arr[i][j] = 0);
|
|
113
|
+
return result;
|
|
114
|
+
}
|
|
115
|
+
static zeros(rows, cols) {
|
|
116
|
+
let result = new Matrix(rows, cols);
|
|
117
|
+
for (let i = 0; i < rows; i++)
|
|
118
|
+
for (var j = 0; j < cols; j++) result.arr[i][j] = 0;
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
121
|
+
static ones(rows, cols) {
|
|
122
|
+
let result = new Matrix(rows, cols);
|
|
123
|
+
for (let i = 0; i < rows; i++)
|
|
124
|
+
for (let j = 0; j < cols; j++) result.arr[i][j] = 1;
|
|
125
|
+
return result;
|
|
126
|
+
}
|
|
127
|
+
static nums(rows, cols, number) {
|
|
128
|
+
let result = new Matrix(rows, cols);
|
|
129
|
+
for (let i = 0; i < rows; i++)
|
|
130
|
+
for (let j = 0; j < cols; j++) result.arr[i][j] = number;
|
|
131
|
+
return result;
|
|
132
|
+
}
|
|
133
|
+
static get random(){
|
|
134
|
+
return {
|
|
135
|
+
int : (r, c, a, b)=> new Matrix(
|
|
136
|
+
r,
|
|
137
|
+
c,
|
|
138
|
+
Random.sample.int(r*c, a, b)
|
|
139
|
+
),
|
|
140
|
+
float : (r, c, a,)=> new Matrix(
|
|
141
|
+
r,
|
|
142
|
+
c,
|
|
143
|
+
Random.sample.float(r*c, a, b)
|
|
144
|
+
),
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
get range(){
|
|
148
|
+
return {
|
|
149
|
+
map : (xmin, xmax, ymin, ymax) => {
|
|
150
|
+
this.arr = map(this.arr, xmin, xmax, ymin, ymax);
|
|
151
|
+
return this;
|
|
152
|
+
},
|
|
153
|
+
norm : (min, max) => {
|
|
154
|
+
this.arr = norm(this.arr, min, max);
|
|
155
|
+
return this;
|
|
156
|
+
},
|
|
157
|
+
lerp : (min, max) => {
|
|
158
|
+
this.arr = lerp(this.arr, min, max);
|
|
159
|
+
return this;
|
|
160
|
+
},
|
|
161
|
+
clamp : (min, max) => {
|
|
162
|
+
this.arr = clamp(this.arr, min, max);
|
|
163
|
+
return this;
|
|
164
|
+
},
|
|
165
|
+
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
hstack(...matrices) {
|
|
169
|
+
const M=[this, ...matrices].reduce((a,b)=>hstack(a, b));
|
|
170
|
+
Object.assign(this, M);
|
|
171
|
+
maintain_indexes(this);
|
|
172
|
+
return this;
|
|
173
|
+
}
|
|
174
|
+
vstack(...matrices){
|
|
175
|
+
const M=[this, ...matrices].reduce((a,b)=>vstack(a, b));
|
|
176
|
+
Object.assign(this, M);
|
|
177
|
+
maintain_indexes(this);
|
|
178
|
+
return this;
|
|
179
|
+
}
|
|
180
|
+
hqueue(...matrices){
|
|
181
|
+
const M=[this, ...matrices].reverse().reduce((a,b)=>hstack(a, b));
|
|
182
|
+
Object.assign(this, M);
|
|
183
|
+
maintain_indexes(this);
|
|
184
|
+
return this;
|
|
185
|
+
}
|
|
186
|
+
vqueue(...matrices){
|
|
187
|
+
const M=[this,...matrices].reverse().reduce((a, b)=>vstack(a, b));
|
|
188
|
+
Object.assign(this, M);
|
|
189
|
+
maintain_indexes(this);
|
|
190
|
+
return this;
|
|
191
|
+
}
|
|
192
|
+
forEach(fn){
|
|
193
|
+
this.arr.flat(1).forEach(fn);
|
|
194
|
+
return this;
|
|
195
|
+
}
|
|
196
|
+
forEachRow(fn){
|
|
197
|
+
this.arr.forEach(fn);
|
|
198
|
+
return this;
|
|
199
|
+
}
|
|
200
|
+
forEachCol(fn){
|
|
201
|
+
this.clone().T.forEachRow(fn);
|
|
202
|
+
return this
|
|
203
|
+
}
|
|
204
|
+
map(fn){
|
|
205
|
+
const arr = this.arr.flat(1).map(fn)
|
|
206
|
+
return new Matrix(
|
|
207
|
+
this.rows,
|
|
208
|
+
this.cols,
|
|
209
|
+
arr
|
|
210
|
+
)
|
|
211
|
+
}
|
|
212
|
+
mapRows(fn = ()=>{}){
|
|
213
|
+
this.arr = this.arr.map(fn)
|
|
214
|
+
return this;
|
|
215
|
+
}
|
|
216
|
+
mapCols(fn){
|
|
217
|
+
return this.clone().T.mapRows(fn).T;
|
|
218
|
+
}
|
|
219
|
+
sort(fn = ()=>{}){
|
|
220
|
+
const arr = this.arr.flat(1).sort(fn)
|
|
221
|
+
return new Matrix(
|
|
222
|
+
this.rows,
|
|
223
|
+
this.cols,
|
|
224
|
+
arr
|
|
225
|
+
)
|
|
226
|
+
}
|
|
227
|
+
shuffle(){
|
|
228
|
+
return this.sort(() => 0.5-Math.random())
|
|
229
|
+
}
|
|
230
|
+
sortRows(fn = ()=>{}){
|
|
231
|
+
this.arr = this.arr.map(row => row.sort(fn))
|
|
232
|
+
return this;
|
|
233
|
+
}
|
|
234
|
+
shuffleRows(){
|
|
235
|
+
return this.sortRows(() => 0.5-Math.random())
|
|
236
|
+
}
|
|
237
|
+
sortCols(fn){
|
|
238
|
+
return this.clone().T.sortRows(fn).T;
|
|
239
|
+
}
|
|
240
|
+
shuffleCols(){
|
|
241
|
+
return this.sortCols(() => 0.5-Math.random())
|
|
242
|
+
}
|
|
243
|
+
reduce(fn, initialValue){
|
|
244
|
+
const value = initialValue
|
|
245
|
+
? this.arr.flat(1).reduce(fn, initialValue)
|
|
246
|
+
: this.arr.flat(1).reduce(fn);
|
|
247
|
+
return new Matrix([[value]])
|
|
248
|
+
}
|
|
249
|
+
reduceRows(fn, initialValue){
|
|
250
|
+
const values = initialValue
|
|
251
|
+
? this.arr.map(row => row.reduce(fn, initialValue))
|
|
252
|
+
: this.arr.map(row => row.reduce(fn))
|
|
253
|
+
return new Matrix(1, this.cols, values)
|
|
254
|
+
}
|
|
255
|
+
reduceCols(fn, initialValue){
|
|
256
|
+
return this.T.reduceRows(fn, initialValue).T
|
|
257
|
+
}
|
|
258
|
+
filterRows(fn){
|
|
259
|
+
const mask = this.arr.map(n => n.some(m => fn(m)));
|
|
260
|
+
const arr = [];
|
|
261
|
+
let i;
|
|
262
|
+
for(i = 0; i < mask.length; i++)
|
|
263
|
+
if(mask[i]) arr.push(this.arr[i])
|
|
264
|
+
return new Matrix(arr)
|
|
265
|
+
}
|
|
266
|
+
filterCols(fn){
|
|
267
|
+
const arr = this.T.filterRows(fn);
|
|
268
|
+
return new Matrix(arr).T
|
|
269
|
+
}
|
|
270
|
+
every(fn){
|
|
271
|
+
return this.arr.flat(1).every(fn)
|
|
272
|
+
}
|
|
273
|
+
everyRow(fn){
|
|
274
|
+
return this.arr.map(n => n.every(fn))
|
|
275
|
+
}
|
|
276
|
+
everyCol(fn){
|
|
277
|
+
return this.T.arr.map(n => n.every(fn))
|
|
278
|
+
}
|
|
279
|
+
some(fn){
|
|
280
|
+
return this.arr.flat(1).some(fn)
|
|
281
|
+
}
|
|
282
|
+
someRow(fn){
|
|
283
|
+
return this.arr.map(n => n.some(fn))
|
|
284
|
+
}
|
|
285
|
+
someCol(fn){
|
|
286
|
+
return this.T.arr.map(n => n.some(fn))
|
|
287
|
+
}
|
|
288
|
+
// Checkers
|
|
289
|
+
get isSquare() {
|
|
290
|
+
return this.rows === this.cols;
|
|
291
|
+
}
|
|
292
|
+
get isSym() {
|
|
293
|
+
if (!this.isSquare) return false;
|
|
294
|
+
for (let i = 0; i < this.rows; i++) {
|
|
295
|
+
for (let j = i + 1; j < this.cols; j++) {
|
|
296
|
+
if (this.arr[i][j] !== this.arr[j][i]) return false;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
return true;
|
|
300
|
+
}
|
|
301
|
+
get isAntiSym() {
|
|
302
|
+
if (!this.isSquare) return false;
|
|
303
|
+
const n = this.rows;
|
|
304
|
+
for (let i = 0; i < n; i++) {
|
|
305
|
+
if (this.arr[i][i] !== 0) return false;
|
|
306
|
+
for (let j = i + 1; j < n; j++) {
|
|
307
|
+
if (this.arr[i][j] !== -this.arr[j][i]) return false;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
return true;
|
|
311
|
+
}
|
|
312
|
+
get isDiag() {
|
|
313
|
+
if (!this.isSquare) return false;
|
|
314
|
+
const n = this.rows;
|
|
315
|
+
for (let i = 0; i < n; i++) {
|
|
316
|
+
for (let j = i + 1; j < n; j++) {
|
|
317
|
+
if (this.arr[i][j] !== 0 || this.arr[j][i] !== 0) return false;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
return true;
|
|
321
|
+
}
|
|
322
|
+
get isOrtho() {
|
|
323
|
+
if (!this.isSquare) return false;
|
|
324
|
+
return this.isDiag && (this.det == 1 || this.det == -1);
|
|
325
|
+
}
|
|
326
|
+
get isIdemp() {
|
|
327
|
+
if (!this.isSquare) return false;
|
|
328
|
+
const n = this.rows;
|
|
329
|
+
const A = this.arr;
|
|
330
|
+
// Compute A * A
|
|
331
|
+
const MM = [];
|
|
332
|
+
for (let i = 0; i < n; i++) {
|
|
333
|
+
MM[i] = [];
|
|
334
|
+
for (let j = 0; j < n; j++) {
|
|
335
|
+
let sum = 0;
|
|
336
|
+
for (let k = 0; k < n; k++) {
|
|
337
|
+
sum += A[i][k] * A[k][j];
|
|
338
|
+
}
|
|
339
|
+
MM[i][j] = sum;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
// Check if A * A == A
|
|
343
|
+
for (let i = 0; i < n; i++) {
|
|
344
|
+
for (let j = 0; j < n; j++) {
|
|
345
|
+
if (MM[i][j] !== A[i][j]) return false;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
return true;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
get isUpperTri() {
|
|
352
|
+
if (!this.isSquare) return false;
|
|
353
|
+
const n = this.rows;
|
|
354
|
+
for (let i = 1; i < n; i++) {
|
|
355
|
+
for (let j = 0; j < i; j++) {
|
|
356
|
+
if (this.arr[i][j] !== 0) return false;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
return true;
|
|
360
|
+
}
|
|
361
|
+
get isLowerTri() {
|
|
362
|
+
if (!this.isSquare) return false;
|
|
363
|
+
const n = this.rows;
|
|
364
|
+
for (let i = 0; i < n - 1; i++) {
|
|
365
|
+
for (let j = i + 1; j < n; j++) {
|
|
366
|
+
if (this.arr[i][j] !== 0) return false;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
return true;
|
|
370
|
+
}
|
|
371
|
+
toPrecision(p) {
|
|
372
|
+
for (let i = 0; i < this.cols; i++)
|
|
373
|
+
for (let j = 0; j < this.rows; j++)
|
|
374
|
+
this.arr[i][j] = +this.arr[i][j].toPrecision(p);
|
|
375
|
+
return this;
|
|
376
|
+
}
|
|
377
|
+
toFixed(p) {
|
|
378
|
+
for (let i = 0; i < this.cols; i++)
|
|
379
|
+
for (let j = 0; j < this.rows; j++)
|
|
380
|
+
this.arr[i][j] = +this.arr[i][j].toFixed(p);
|
|
381
|
+
return this;
|
|
382
|
+
}
|
|
383
|
+
// max2min() {
|
|
384
|
+
// let newArr = this.arr.flat(1).max2min;
|
|
385
|
+
// return new Matrix(this.rows, this.cols, newArr);
|
|
386
|
+
// }
|
|
387
|
+
// min2max() {
|
|
388
|
+
// let newArr = this.arr.flat(1).min2max;
|
|
389
|
+
// return new Matrix(this.rows, this.cols, newArr);
|
|
390
|
+
// }
|
|
391
|
+
// count(n) {
|
|
392
|
+
// return this.arr.flat(1).count(n);
|
|
393
|
+
// }
|
|
394
|
+
splice(r0,c0,deleteCount,...items){
|
|
395
|
+
|
|
396
|
+
}
|
|
397
|
+
getRows(ri, rf = ri + 1) {
|
|
398
|
+
return this.slice(ri, 0, rf, this.cols);
|
|
399
|
+
}
|
|
400
|
+
getCols(ci, cf = ci + 1) {
|
|
401
|
+
return this.slice(0, ci, this.rows, cf);
|
|
402
|
+
}
|
|
403
|
+
#arithmetic(fn, ...matr){
|
|
404
|
+
for (let k = 0; k < matr.length; k++) {
|
|
405
|
+
if (typeof matr[k] == "number" || matr[k]?.isComplex?.()) matr[k] = Matrix.nums(this.rows, this.cols, matr[k]);
|
|
406
|
+
for (let i = 0; i < this.rows; i++)
|
|
407
|
+
for (var j = 0; j < this.cols; j++)
|
|
408
|
+
this.arr[i][j] = fn(this.arr[i][j], matr[k].arr[i][j]);
|
|
409
|
+
}
|
|
410
|
+
return new Matrix(this.rows, this.cols, this.arr.flat(1));
|
|
411
|
+
}
|
|
412
|
+
add(...matr) {
|
|
413
|
+
return this.#arithmetic(add, ...matr)
|
|
414
|
+
}
|
|
415
|
+
sub(...matr) {
|
|
416
|
+
return this.#arithmetic(sub, ...matr)
|
|
417
|
+
}
|
|
418
|
+
mul(...matr) {
|
|
419
|
+
return this.#arithmetic(mul, ...matr)
|
|
420
|
+
}
|
|
421
|
+
div(...matr) {
|
|
422
|
+
return this.#arithmetic(div, ...matr)
|
|
423
|
+
}
|
|
424
|
+
modulo(...matr) {
|
|
425
|
+
return this.#arithmetic(modulo, ...matr)
|
|
426
|
+
}
|
|
427
|
+
dot(matrix) {
|
|
428
|
+
var res = [];
|
|
429
|
+
for (var i = 0; i < this.arr.length; i++) {
|
|
430
|
+
res[i] = [];
|
|
431
|
+
for (var j = 0; j < matrix.arr[0].length; j++) {
|
|
432
|
+
res[i][j] = 0;
|
|
433
|
+
for (var k = 0; k < this.arr[0].length; k++) {
|
|
434
|
+
res[i][j] = add(
|
|
435
|
+
res[i][j],
|
|
436
|
+
mul(this.arr[i][k],matrix.arr[k][j])
|
|
437
|
+
)
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
return new Matrix(this.arr.length, matrix.arr[0].length, res.flat(1));
|
|
442
|
+
}
|
|
443
|
+
pow(n) {
|
|
444
|
+
let a = this.clone(),
|
|
445
|
+
p = this.clone();
|
|
446
|
+
for (let i = 0; i < n - 1; i++) p = p.dot(a);
|
|
447
|
+
return p;
|
|
448
|
+
}
|
|
449
|
+
sum(){
|
|
450
|
+
let S = 0;
|
|
451
|
+
for (let i = 0; i < this.rows; i++)
|
|
452
|
+
for (let j = 0; j < this.cols; j++)
|
|
453
|
+
S = add(S, this.arr[i][j]);
|
|
454
|
+
return S;
|
|
455
|
+
}
|
|
456
|
+
prod(){
|
|
457
|
+
let S = 1;
|
|
458
|
+
for (let i = 0; i < this.rows; i++)
|
|
459
|
+
for (let j = 0; j < this.cols; j++)
|
|
460
|
+
S = mul(S, this.arr[i][j]);
|
|
461
|
+
return S;
|
|
462
|
+
}
|
|
463
|
+
hasComplex(){
|
|
464
|
+
return this.arr.flat(Infinity).some((n) => n instanceof Complex);
|
|
465
|
+
}
|
|
466
|
+
get min() {
|
|
467
|
+
if (this.hasComplex()) console.error("Complex numbers are not comparable");
|
|
468
|
+
let minRow = [];
|
|
469
|
+
for (let i = 0; i < this.rows; i++)
|
|
470
|
+
minRow.push(Math.min(...this.arr[i]));
|
|
471
|
+
return Math.min(...minRow);
|
|
472
|
+
}
|
|
473
|
+
get max() {
|
|
474
|
+
if (this.hasComplex()) console.error("Complex numbers are not comparable");
|
|
475
|
+
let maxRow = [];
|
|
476
|
+
for (let i = 0; i < this.rows; i++)
|
|
477
|
+
maxRow.push(Math.max(...this.arr[i]));
|
|
478
|
+
return Math.max(...maxRow);
|
|
479
|
+
}
|
|
480
|
+
get minRows() {
|
|
481
|
+
if (this.hasComplex()) console.error("Complex numbers are not comparable");
|
|
482
|
+
let minRow = [];
|
|
483
|
+
for (let i = 0; i < this.rows; i++)
|
|
484
|
+
minRow.push(Math.min(...this.arr[i]));
|
|
485
|
+
return minRow;
|
|
486
|
+
}
|
|
487
|
+
get maxRows() {
|
|
488
|
+
if (this.hasComplex()) console.error("Complex numbers are not comparable");
|
|
489
|
+
let maxRow = [];
|
|
490
|
+
for (let i = 0; i < this.rows; i++)
|
|
491
|
+
maxRow.push(Math.max(...this.arr[i]));
|
|
492
|
+
return maxRow;
|
|
493
|
+
}
|
|
494
|
+
get minCols() {
|
|
495
|
+
if (this.hasComplex()) console.error("Complex numbers are not comparable");
|
|
496
|
+
return this.T.minRows;
|
|
497
|
+
}
|
|
498
|
+
get maxCols() {
|
|
499
|
+
if (this.hasComplex()) console.error("Complex numbers are not comparable");
|
|
500
|
+
return this.T.maxRows;
|
|
501
|
+
}
|
|
502
|
+
static fromVector(v) {
|
|
503
|
+
return new Matrix(v.length, 1, v);
|
|
504
|
+
}
|
|
505
|
+
serialize() {
|
|
506
|
+
const arr = mapfun(x => x.serialize?.() || x, ...this.arr)
|
|
507
|
+
return JSON.stringify({
|
|
508
|
+
type : 'matrix',
|
|
509
|
+
data : {
|
|
510
|
+
rows : this.rows,
|
|
511
|
+
cols : this.cols,
|
|
512
|
+
arr,
|
|
513
|
+
}
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
static deserialize(json) {
|
|
517
|
+
if (typeof json == "string") json = JSON.parse(json);
|
|
518
|
+
const {type, data} = json;
|
|
519
|
+
if(type !== 'matrix') return TypeError('Not a valid Matrix')
|
|
520
|
+
let {arr} = data;
|
|
521
|
+
arr = mapfun(x => {
|
|
522
|
+
if(typeof x === 'string') {
|
|
523
|
+
const x_obj = JSON.parse(x);
|
|
524
|
+
const {type} = x_obj
|
|
525
|
+
if(type === 'complex') return Complex.deserialize(x_obj)
|
|
526
|
+
}
|
|
527
|
+
return x
|
|
528
|
+
}, ...arr)
|
|
529
|
+
return new Matrix(arr)
|
|
530
|
+
}
|
|
531
|
+
flip(){
|
|
532
|
+
return this.flipeH().flipeV()
|
|
533
|
+
}
|
|
534
|
+
flipeH(){
|
|
535
|
+
this.arr = this.arr.map(row => [...row].reverse());
|
|
536
|
+
maintain_indexes(this);
|
|
537
|
+
return this;
|
|
538
|
+
}
|
|
539
|
+
flipeV(){
|
|
540
|
+
this.arr = this.arr.reverse();
|
|
541
|
+
maintain_indexes(this);
|
|
542
|
+
return this;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
|
|
547
|
+
const matrix=(r, c, element)=>new Matrix(r, c, element);
|
|
548
|
+
const matrix2=(...element)=>new Matrix(2, 2, element);
|
|
549
|
+
const matrix3=(...element)=>new Matrix(3, 3, element);
|
|
550
|
+
const matrix4=(...element)=>new Matrix(4, 4, element);
|
|
551
|
+
export{
|
|
552
|
+
Matrix,
|
|
553
|
+
matrix,
|
|
554
|
+
matrix2,
|
|
555
|
+
matrix3,
|
|
556
|
+
matrix4
|
|
557
|
+
}
|
package/src/random/index.js
CHANGED