-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmatrix.js
169 lines (155 loc) · 5.25 KB
/
matrix.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
import Vector from "./vector.js";
import * as BinaryField from "./binaryField.js";
export default class Matrix {
/**
* Internal matrix property as a 2-dim number array.
* @type {number[][]}
* @private
*/
matrix;
/**
* @param {number[][]|Vector} matrix
* A 2-dimensional array for initializing Matrix.
* If matrix is Vector, initialize as single row matrix.
*/
constructor(matrix) {
if (matrix instanceof Vector) {
return new Matrix(new Array(matrix.getVec()));
}
this.matrix = matrix;
}
/**
* Performs matrix addition (this + matrix).
* @param {Matrix|Vector} matrix
* Another matrix to be added. If matrix is of
* Vector type, it is converted to single row matrix.
* @returns {Matrix}
* A newly created sum result matrix.
*/
add(matrix) {
if (matrix instanceof Vector) {
this.add(new Matrix(matrix));
}
if (this.rowCount() != matrix.rowCount() || this.colCount() != matrix.colCount()) {
throw "Invalid matrix addition: " + this.rowCount() + " x " + this.colCount()
+ " + " + matrix.rowCount() + " x " + matrix.colCount();
}
let res = new Array(this.rowCount());
for (let i = 0; i < this.rowCount(); i++) {
res[i] = new Array(this.colCount());
for (let j = 0; j < this.colCount(); j++) {
res[i][j] = BinaryField.add(this.matrix[i][j], matrix.getMatrix()[i][j]);
}
}
return new Matrix(res);
}
/**
* Performs matrix multiplication (this * matrix).
* @param {Matrix|Vector} matrix
* matrix that will be added to this. matrix is of Vector type,
* it is converted to single row Matrix.
* @returns {Matrix}
* A newly created multiplication result matrix.
*/
mul(matrix) {
if (matrix instanceof Vector) {
this.mul(new Matrix(matrix));
}
if (this.colCount() != matrix.rowCount()) {
throw "Invalid matrix multiplication: " + this.rowCount() + " x " + this.colCount()
+ " * " + matrix.rowCount() + " x " + matrix.colCount();
}
let res = new Array(this.rowCount());
for (let i = 0; i < this.rowCount(); i++) {
res[i] = new Array(matrix.colCount());
for (let j = 0; j < matrix.colCount(); j++) {
res[i][j] = 0;
for (let k = 0; k < this.colCount(); k++) { // this.colCount() == matrix.rowCount();
res[i][j] = BinaryField.add(res[i][j], BinaryField.mul(this.matrix[i][k], matrix.getMatrix()[k][j]));
}
}
}
return new Matrix(res);
}
/**
* Gets the number of rows in matrix.
* @returns {number}
* number of rows.
*/
rowCount() {
return this.matrix.length;
}
/**
* Gets the number of columns in matrix.
* @returns {number}
* number of columns.
*/
colCount() {
if (this.matrix.length > 0) {
return this.matrix[0].length;
}
return 0;
}
/**
* Gets internal matrix array.
* @return {number[][]}
* Internal matrix array.
*/
getMatrix() {
return this.matrix;
}
/**
* Constructs a new identity matrix of dim size.
* @param {number} dim
* Identity matrix dimensions (row and column count).
* @returns {Matrix}
* Identity matrix.
*/
static buildIdentityMatrix(dim) {
let res = new Array(dim);
for (let i = 0; i < dim; i++) {
res[i] = new Array(dim);
for (let j = 0; j < dim; j++) {
if (i === j) {
res[i][j] = 1;
} else {
res[i][j] = 0;
}
}
}
return new Matrix(res);
}
/**
* Joins (concatenates) matrix to this instance side by side [this, matrix].
* Example: [[1,1][0,1]] join [[0,0][1,1]] = [[1,1,0,0][0,1,1,1]].
* @param {Matrix} matrix
* matrix that will be concatenated to this. matrix will be on the right.
* @returns {Matrix}
* New instance of joined matrices.
*/
join(matrix) {
if (matrix.rowCount() != this.rowCount()) {
throw "Invalid matrix join operation: " + this.rowCount() + " and " + matrix.rowCount() + " rows.";
}
let res = new Array(this.rowCount());
for (let [index, row] of this.getMatrix().entries()) {
res[index] = row.concat(matrix.getMatrix()[index]);
}
return new Matrix(res);
}
/**
* Vertically join matrices, similar to horizontal join {@link Matrix#join}.
* This instance matrix goes on top.
* @param {Matrix} matrix matrix that will be joined to the bottom of this.
*/
verticalJoin(matrix) {
if (matrix.colCount() != this.colCount()) {
throw "Invalid matrix vertical join operation: " + this.colCount() + " and " + matrix.colCount() + " columns.";
}
let res = this.matrix.slice();
for (let row of matrix.getMatrix()) {
res.push(row);
}
return new Matrix(res);
}
}