-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmath.js
165 lines (138 loc) · 4.04 KB
/
math.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
/*
* A bunch of stuff
*/
function vectorSum(v1, c, v2) {
var result = [];
for (var i = 0; i < v1.length; i++)
result[i] = v1[i] + c * v2[i];
return result;
}
/**
* Prints a matrix in row,column format
*/
function matrixPrint(matrix) {
for (var i = 0; i < matrix.length; i++) {
console.log(matrix[i]);
}
}
function zeroes(r, c) {
var m = [];
for (var i = 0; i < r; i++) {
m[i] = [];
for (var j = 0; j < c; j++)
m[i][j] = 0;
}
return m;
}
//Basic matrix operations
function transpose(m) {
var result = zeroes(m[0].length, m.length);
for (var r = 0; r < result.length; r++) {
for(var c = 0; c < result[0].length; c++) {
result[r][c] = m[c][r];
}
}
return result;
}
function matrixMult(m1,m2) {
if(m1[0].length != m2.length)
throw "Matrix dimension mismatch. Cannot multiply";
var result = zeroes(m1.length,m2[0].length);
for(var r = 0; r<result.length; r++) {
for(var c = 0; c<result[0].length; c++) {
result[r][c]=mMultHelper(m1,m2,r,c);
}
}
return result;
}
function mMultHelper(m1,m2,r,c) { //does dot producting BS
var result = 0;
for(var i = 0; i<m1.length; i++)
result += m1[r][i]*m2[i][c];
return result;
}
//probably will never be used
function rowProduct(m,r) {
var result = 1;
for(var i = 0; i<m[0].length; i++)
result *= m[r][i];
return result;
}
function colProduct(m,c) {
var result = 1;
for(var i = 0; i<m.length; i++)
result *= m[i][c];
return result;
}
/** indexed row,column
* DOES NOT DO ANY LEGITIMACY CHECKS OR ANYTHING
* @param {Object} matrix
*/
function gaussianElimination1(matrix) {
matrix = matrix.slice(0); //shallow copy (it's cool cause it's ints)
for(var i = 0; i<matrix.length; i++) {//each row get the first coeffecient
var temp = gElHelper1(matrix[i]),
p = temp[0],
a = temp[1];
for(var j = 0; j<matrix.length; j++) { //remove from other rows
var b = matrix[j][p];
if(b != 0 && i != j)
matrix[j] = vectorSum(matrix[j],-b/a,matrix[i]);
}
}
//This part assumes that you end up with something in almost row echelon form (coeffecients may not be 1)
var result = [],
numVars = matrix[0].length-1;
for(var i = 0; i<numVars; i++) { //grabbing the results
result[i] = matrix[i][numVars]/matrix[i][i];
}
return result;
}
//Helper function returns the first position of a nonzero coeffecient and the coefficient itself
function gElHelper1(vector) {
for(var i = 0; i<vector.length; i++)
if(vector[i] != 0)
return [i,vector[i]];
return -1
}
function gaussianElimination(matrix) {
matrix = matrix.slice(0);
var numRows = matrix.length,
numCols = matrix[0].length,
sol = [];
//matrixPrint(matrix);
for(var c = 0; c<numRows; c++) {
var iMax = gElHelper(matrix,c);
if(matrix[iMax][c] == 0)
throw "Matrix is singular"
swapRows(matrix,c,iMax);
for(var d = c+1; d<numRows; d++) {
var mult = matrix[d][c]/matrix[c][c];
matrix[d] = vectorSum(matrix[d],-mult,matrix[c]);
}
}
for(var r = 0; r<numRows; r++) {
var i = numRows-r-1;
for(var s = r+1; s<numRows; s++) {
var mult = -matrix[s][i]/matrix[r][i]
matrix[s] = vectorSum(matrix[s],mult,matrix[r]);
}
sol.push(matrix[r][numCols-1]/matrix[r][i]);
}
return sol.reverse();
}
//Helper function finds the pos of the max in the column
function gElHelper(matrix,c) {
var iMax = 0;
for(var i = c; i<matrix.length; i++) {
if(Math.abs(matrix[i][c])>Math.abs(matrix[iMax][c]))
iMax = i;
}
return iMax
}
function swapRows(matrix,r0,r1) {
var i = matrix[r0];
matrix[r0]=matrix[r1];
matrix[r1]=i;
return matrix;
}