Mon 21 Jul 22:43:21 CEST 2025
This commit is contained in:
parent
56fc374b00
commit
399f34cdd9
646
js/ml/math.js
Normal file
646
js/ml/math.js
Normal file
|
@ -0,0 +1,646 @@
|
|||
/**
|
||||
* Created by joonkukang on 2014. 1. 12..
|
||||
*/
|
||||
var m = module.exports;
|
||||
|
||||
m.randn = function() {
|
||||
// generate random guassian distribution number. (mean : 0, standard deviation : 1)
|
||||
var v1, v2, s;
|
||||
|
||||
do {
|
||||
v1 = 2 * Math.random() - 1; // -1.0 ~ 1.0 까지의 값
|
||||
v2 = 2 * Math.random() - 1; // -1.0 ~ 1.0 까지의 값
|
||||
s = v1 * v1 + v2 * v2;
|
||||
} while (s >= 1 || s == 0);
|
||||
|
||||
s = Math.sqrt( (-2 * Math.log(s)) / s );
|
||||
return v1 * s;
|
||||
}
|
||||
|
||||
m.shape = function(mat) {
|
||||
var row = mat.length;
|
||||
var col = mat[0].length;
|
||||
return [row,col];
|
||||
};
|
||||
|
||||
m.addVec = function(vec1, vec2) {
|
||||
if(vec1.length === vec2.length) {
|
||||
var result = [];
|
||||
var i;
|
||||
for(i=0;i<vec1.length;i++)
|
||||
result.push(vec1[i]+vec2[i]);
|
||||
return result;
|
||||
} else {
|
||||
throw new Error("Length Error : not same.")
|
||||
}
|
||||
}
|
||||
|
||||
m.minusVec = function(vec1,vec2) {
|
||||
if(vec1.length === vec2.length) {
|
||||
var result = [];
|
||||
var i;
|
||||
for(i=0;i<vec1.length;i++)
|
||||
result.push(vec1[i]-vec2[i]);
|
||||
return result;
|
||||
} else {
|
||||
throw new Error("Length Error : not same.")
|
||||
}
|
||||
};
|
||||
|
||||
m.addMatScalar = function(mat,scalar) {
|
||||
var row = m.shape(mat)[0];
|
||||
var col = m.shape(mat)[1];
|
||||
var i , j,result = [];
|
||||
for(i=0 ; i<row ; i++) {
|
||||
var rowVec = [];
|
||||
for(j=0 ; j<col ; j++) {
|
||||
rowVec.push(mat[i][j] + scalar);
|
||||
}
|
||||
result.push(rowVec);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
m.addMatVec = function(mat,vec) {
|
||||
if(mat[0].length === vec.length) {
|
||||
var result = [];
|
||||
var i;
|
||||
for(i=0;i<mat.length;i++)
|
||||
result.push(m.addVec(mat[i],vec));
|
||||
return result;
|
||||
} else {
|
||||
throw new Error("Length Error : not same.")
|
||||
}
|
||||
}
|
||||
|
||||
m.minusMatVec = function(mat,vec) {
|
||||
if(mat[0].length === vec.length) {
|
||||
var result = [];
|
||||
var i;
|
||||
for(i=0;i<mat.length;i++)
|
||||
result.push(m.minusVec(mat[i],vec));
|
||||
return result;
|
||||
} else {
|
||||
throw new Error("Length Error : not same.")
|
||||
}
|
||||
}
|
||||
|
||||
m.addMat = function (mat1, mat2) {
|
||||
if ((mat1.length === mat2.length) && (mat1[0].length === mat2[0].length)) {
|
||||
var result = new Array(mat1.length);
|
||||
for (var i = 0; i < mat1.length; i++) {
|
||||
result[i] = new Array(mat1[i].length);
|
||||
for (var j = 0; j < mat1[i].length; j++) {
|
||||
result[i][j] = mat1[i][j] + mat2[i][j];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
throw new Error('Matrix mismatch.');
|
||||
}
|
||||
};
|
||||
|
||||
m.minusMat = function(mat1, mat2) {
|
||||
if ((mat1.length === mat2.length) && (mat1[0].length === mat2[0].length)) {
|
||||
var result = new Array(mat1.length);
|
||||
for (var i = 0; i < mat1.length; i++) {
|
||||
result[i] = new Array(mat1[i].length);
|
||||
for (var j = 0; j < mat1[i].length; j++) {
|
||||
result[i][j] = mat1[i][j] - mat2[i][j];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
throw new Error('Matrix mismatch.');
|
||||
}
|
||||
}
|
||||
|
||||
m.transpose = function (mat) {
|
||||
var result = new Array(mat[0].length);
|
||||
for (var i = 0; i < mat[0].length; i++) {
|
||||
result[i] = new Array(mat.length);
|
||||
for (var j = 0; j < mat.length; j++) {
|
||||
result[i][j] = mat[j][i];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
m.dotVec = function (vec1, vec2) {
|
||||
if (vec1.length === vec2.length) {
|
||||
var result = 0;
|
||||
for (var i = 0; i < vec1.length; i++) {
|
||||
result += vec1[i] * vec2[i];
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
throw new Error("Vector mismatch");
|
||||
}
|
||||
};
|
||||
|
||||
m.outerVec = function (vec1,vec2) {
|
||||
var mat1 = m.transpose([vec1]);
|
||||
var mat2 = [vec2];
|
||||
return m.mulMat(mat1,mat2);
|
||||
};
|
||||
|
||||
m.mulVecScalar = function(vec,scalar) {
|
||||
var i, result = [];
|
||||
for(i=0;i<vec.length;i++)
|
||||
result.push(vec[i]*scalar);
|
||||
return result;
|
||||
};
|
||||
|
||||
m.mulMatScalar = function(mat,scalar) {
|
||||
var row = m.shape(mat)[0];
|
||||
var col = m.shape(mat)[1];
|
||||
var i , j,result = [];
|
||||
for(i=0 ; i<row ; i++) {
|
||||
var rowVec = [];
|
||||
for(j=0 ; j<col ; j++) {
|
||||
rowVec.push(mat[i][j] * scalar);
|
||||
}
|
||||
result.push(rowVec);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
m.mulMatElementWise = function(mat1, mat2) {
|
||||
if (mat1.length === mat2.length && mat1[0].length === mat2[0].length) {
|
||||
var result = new Array(mat1.length);
|
||||
|
||||
for (var x = 0; x < mat1.length; x++) {
|
||||
result[x] = new Array(mat1[0].length);
|
||||
}
|
||||
|
||||
for (var i = 0; i < result.length; i++) {
|
||||
for (var j = 0; j < result[i].length; j++) {
|
||||
result[i][j] = mat1[i][j] * mat2[i][j]
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
throw new Error("Matrix shape error : not same");
|
||||
}
|
||||
};
|
||||
|
||||
m.mulMat = function (mat1, mat2) {
|
||||
if (mat1[0].length === mat2.length) {
|
||||
var result = new Array(mat1.length);
|
||||
|
||||
for (var x = 0; x < mat1.length; x++) {
|
||||
result[x] = new Array(mat2[0].length);
|
||||
}
|
||||
|
||||
|
||||
var mat2_T = m.transpose(mat2);
|
||||
for (var i = 0; i < result.length; i++) {
|
||||
for (var j = 0; j < result[i].length; j++) {
|
||||
result[i][j] = m.dotVec(mat1[i],mat2_T[j]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
throw new Error("Array mismatch");
|
||||
}
|
||||
};
|
||||
|
||||
m.sumVec = function(vec) {
|
||||
var sum = 0;
|
||||
var i = vec.length;
|
||||
while (i--) {
|
||||
sum += vec[i];
|
||||
}
|
||||
return sum;
|
||||
};
|
||||
|
||||
m.sumMat = function(mat) {
|
||||
var sum = 0;
|
||||
var i = mat.length;
|
||||
while (i--) {
|
||||
for(var j=0;j<mat[0].length;j++)
|
||||
sum += mat[i][j];
|
||||
}
|
||||
return sum;
|
||||
};
|
||||
|
||||
m.sumMatAxis = function(mat,axis) {
|
||||
// default axis 0;
|
||||
// axis 0 : mean of col vector . axis 1 : mean of row vector
|
||||
if(axis === 1) {
|
||||
var row = m.shape(mat)[0];
|
||||
var i ;
|
||||
var result = [];
|
||||
for(i=0 ; i<row; i++)
|
||||
result.push(m.sumVec(mat[i]));
|
||||
return result;
|
||||
} else {
|
||||
mat_T = m.transpose(mat);
|
||||
return m.sumMatAxis(mat_T,1);
|
||||
}
|
||||
};
|
||||
|
||||
m.meanVec = function(vec) {
|
||||
return 1. * m.sumVec(vec) / vec.length;
|
||||
};
|
||||
|
||||
m.meanMat = function(mat) {
|
||||
var row = mat.length;
|
||||
var col = mat[0].length;
|
||||
return 1. * m.sumMat(mat) / (row * col);
|
||||
};
|
||||
|
||||
m.meanMatAxis = function(mat,axis) {
|
||||
// default axis 0;
|
||||
// axis 0 : mean of col vector . axis 1 : mean of row vector
|
||||
if(axis === 1) {
|
||||
var row = m.shape(mat)[0];
|
||||
var i ;
|
||||
var result = [];
|
||||
for(i=0 ; i<row; i++)
|
||||
result.push(m.meanVec(mat[i]));
|
||||
return result;
|
||||
} else {
|
||||
mat_T = m.transpose(mat);
|
||||
return m.meanMatAxis(mat_T,1);
|
||||
}
|
||||
};
|
||||
|
||||
m.squareVec = function(vec) {
|
||||
var squareVec = [];
|
||||
var i;
|
||||
for(i=0;i<vec.length;i++) {
|
||||
squareVec.push(vec[i]*vec[i]);
|
||||
}
|
||||
return squareVec;
|
||||
};
|
||||
|
||||
m.squareMat = function(mat) {
|
||||
var squareMat = [];
|
||||
var i;
|
||||
for(i=0;i<mat.length;i++) {
|
||||
squareMat.push(m.squareVec(mat[i]));
|
||||
}
|
||||
return squareMat;
|
||||
};
|
||||
|
||||
m.minVec = function(vec) {
|
||||
var min = vec[0];
|
||||
var i = vec.length;
|
||||
while (i--) {
|
||||
if (vec[i] < min)
|
||||
min = vec[i];
|
||||
}
|
||||
return min;
|
||||
};
|
||||
|
||||
m.maxVec = function(vec) {
|
||||
var max = vec[0];
|
||||
var i = vec.length;
|
||||
while (i--) {
|
||||
if (vec[i] > max)
|
||||
max = vec[i];
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
m.minMat = function(mat) {
|
||||
var min = mat[0][0];
|
||||
var i = mat.length;
|
||||
while (i--) {
|
||||
for(var j=0;j<mat[0].length;j++) {
|
||||
if(mat[i][j] < min)
|
||||
min = mat[i][j];
|
||||
}
|
||||
}
|
||||
return min;
|
||||
};
|
||||
|
||||
m.maxMat = function(mat) {
|
||||
var max = mat[0][0];
|
||||
var i = mat.length;
|
||||
while (i--) {
|
||||
for(var j=0;j<mat[0].length;j++) {
|
||||
if(mat[i][j] < max)
|
||||
max = mat[i][j];
|
||||
}
|
||||
}
|
||||
return max;
|
||||
};
|
||||
|
||||
m.zeroVec = function(n) {
|
||||
var vec = [];
|
||||
while(vec.length < n)
|
||||
vec.push(0);
|
||||
return vec;
|
||||
};
|
||||
|
||||
m.zeroMat = function(row,col) {
|
||||
var mat = [];
|
||||
while(mat.length < row)
|
||||
mat.push(m.zeroVec(col));
|
||||
return mat;
|
||||
};
|
||||
|
||||
m.oneVec = function(n) {
|
||||
var vec = [];
|
||||
while(vec.length < n)
|
||||
vec.push(1);
|
||||
return vec;
|
||||
};
|
||||
|
||||
m.oneMat = function(row,col) {
|
||||
var mat = [];
|
||||
while(mat.length < row)
|
||||
mat.push(m.oneVec(col));
|
||||
return mat;
|
||||
};
|
||||
|
||||
m.randVec = function(n,lower,upper) {
|
||||
lower = (typeof lower !== 'undefined') ? lower : 0;
|
||||
upper = (typeof upper !== 'undefined') ? upper : 1;
|
||||
var vec = [];
|
||||
while(vec.length < n)
|
||||
vec.push(lower + (upper-lower) * Math.random());
|
||||
return vec;
|
||||
};
|
||||
|
||||
m.randMat = function(row,col,lower,upper) {
|
||||
lower = (typeof lower !== 'undefined') ? lower : 0;
|
||||
upper = (typeof upper !== 'undefined') ? upper : 1;
|
||||
var mat = [];
|
||||
while(mat.length < row)
|
||||
mat.push(m.randVec(col,lower,upper));
|
||||
return mat;
|
||||
};
|
||||
|
||||
m.randnVec = function(n,mean,sigma) {
|
||||
var vec = [];
|
||||
while(vec.length < n)
|
||||
vec.push(mean+sigma* m.randn());
|
||||
return vec;
|
||||
};
|
||||
|
||||
m.randnMat = function(row,col,mean,sigma) {
|
||||
var mat = [];
|
||||
while(mat.length < row)
|
||||
mat.push(m.randnVec(col,mean,sigma));
|
||||
return mat;
|
||||
};
|
||||
|
||||
m.identity = function (n) {
|
||||
var result = new Array(n);
|
||||
|
||||
for (var i = 0; i < n ; i++) {
|
||||
result[i] = new Array(n);
|
||||
for (var j = 0; j < n; j++) {
|
||||
result[i][j] = (i === j) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
m.sigmoid = function(x) {
|
||||
var sigmoid = (1. / (1 + Math.exp(-x)))
|
||||
if(sigmoid ==1) {
|
||||
// console.warn("Something Wrong!! Sigmoid Function returns 1. Probably javascript float precision problem?\nSlightly Controlled value to 1 - 1e-14")
|
||||
sigmoid = 0.99999999999999; // Javascript Float Precision Problem.. This is a limit of javascript.
|
||||
} else if(sigmoid ==0) {
|
||||
// console.warn("Something Wrong!! Sigmoid Function returns 0. Probably javascript float precision problem?\nSlightly Controlled value to 1e-14")
|
||||
sigmoid = 1e-14;
|
||||
}
|
||||
return sigmoid; // sigmoid cannot be 0 or 1;;
|
||||
};
|
||||
|
||||
m.dSigmoid = function(x){
|
||||
a = m.sigmoid(x);
|
||||
return a * (1. - a);
|
||||
};
|
||||
|
||||
m.probToBinaryMat = function(mat) {
|
||||
var row = m.shape(mat)[0];
|
||||
var col = m.shape(mat)[1];
|
||||
var i,j;
|
||||
var result = [];
|
||||
|
||||
for(i=0;i<row;i++) {
|
||||
var rowVec = [];
|
||||
for(j=0;j<col;j++) {
|
||||
if(Math.random() < mat[i][j])
|
||||
rowVec.push(1);
|
||||
else
|
||||
rowVec.push(0);
|
||||
}
|
||||
result.push(rowVec);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
m.activateVec = function(vec,activation) {
|
||||
var i, result = [];
|
||||
for(i=0;i<vec.length;i++)
|
||||
result.push(activation(vec[i]));
|
||||
return result;
|
||||
};
|
||||
|
||||
m.activateMat = function(mat,activation) {
|
||||
var row = m.shape(mat)[0];
|
||||
var col = m.shape(mat)[1];
|
||||
var i, j,result = [];
|
||||
for(i=0;i<row;i++) {
|
||||
var rowVec = [];
|
||||
for(j=0;j<col;j++)
|
||||
rowVec.push(activation(mat[i][j]));
|
||||
result.push(rowVec);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
m.activateTwoVec = function(vec1, vec2,activation) {
|
||||
if (vec1.length === vec2.length) {
|
||||
var result = new Array(vec1.length);
|
||||
for (var i = 0; i < result.length; i++) {
|
||||
result[i] = activation(vec1[i],vec2[i]);
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
throw new Error("Matrix shape error : not same");
|
||||
}
|
||||
};
|
||||
|
||||
m.activateTwoMat = function(mat1, mat2,activation) {
|
||||
if (mat1.length === mat2.length && mat1[0].length === mat2[0].length) {
|
||||
var result = new Array(mat1.length);
|
||||
|
||||
for (var x = 0; x < mat1.length; x++) {
|
||||
result[x] = new Array(mat1[0].length);
|
||||
}
|
||||
|
||||
for (var i = 0; i < result.length; i++) {
|
||||
for (var j = 0; j < result[i].length; j++) {
|
||||
result[i][j] = activation(mat1[i][j],mat2[i][j]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
throw new Error("Matrix shape error : not same");
|
||||
}
|
||||
};
|
||||
|
||||
m.fillVec = function(n,value) {
|
||||
var vec = [];
|
||||
while(vec.length < n)
|
||||
vec.push(value);
|
||||
return vec;
|
||||
};
|
||||
|
||||
m.fillMat = function(row,col,value) {
|
||||
var mat = [];
|
||||
while(mat.length < row) {
|
||||
var rowVec = [];
|
||||
while(rowVec.length < col)
|
||||
rowVec.push(value);
|
||||
mat.push(rowVec);
|
||||
}
|
||||
return mat;
|
||||
};
|
||||
|
||||
m.softmaxVec = function(vec) {
|
||||
var max = m.maxVec(vec);
|
||||
var preSoftmaxVec = m.activateVec(vec,function(x) {return Math.exp(x - max);})
|
||||
return m.activateVec(preSoftmaxVec,function(x) {return x/ m.sumVec(preSoftmaxVec)})
|
||||
};
|
||||
|
||||
m.softmaxMat = function(mat) {
|
||||
var result=[], i;
|
||||
for(i=0 ; i<mat.length ; i++)
|
||||
result.push(m.softmaxVec(mat[i]));
|
||||
return result;
|
||||
};
|
||||
|
||||
m.randInt = function(min,max) {
|
||||
var rand = Math.random() * (max - min + 0.9999) + min
|
||||
return Math.floor(rand);
|
||||
}
|
||||
|
||||
m.normalizeVec = function(vec) {
|
||||
var i;
|
||||
var newVec = [],tot = 0;
|
||||
for(i=0; i<vec.length; i++)
|
||||
tot += vec[i];
|
||||
for(i=0; i<vec.length;i++)
|
||||
newVec.push(1.*vec[i]/tot);
|
||||
return newVec;
|
||||
};
|
||||
|
||||
m.euclidean = function(x1,x2) {
|
||||
var i;
|
||||
var distance = 0;
|
||||
for(i=0 ; i<x1.length; i++) {
|
||||
var dx = x1[i] - x2[i];
|
||||
distance += dx * dx;
|
||||
}
|
||||
return Math.sqrt(distance);
|
||||
};
|
||||
|
||||
m.pearson = function(x, y)
|
||||
{
|
||||
var xy = [];
|
||||
var x2 = [];
|
||||
var y2 = [];
|
||||
|
||||
for(var i=0; i<x.length; i++)
|
||||
{
|
||||
xy.push(x[i] * y[i]);
|
||||
x2.push(x[i] * x[i]);
|
||||
y2.push(y[i] * y[i]);
|
||||
}
|
||||
|
||||
var sum_x = 0;
|
||||
var sum_y = 0;
|
||||
var sum_xy = 0;
|
||||
var sum_x2 = 0;
|
||||
var sum_y2 = 0;
|
||||
|
||||
for(var i=0; i<x.length; i++)
|
||||
{
|
||||
sum_x += x[i];
|
||||
sum_y += y[i];
|
||||
sum_xy += xy[i];
|
||||
sum_x2 += x2[i];
|
||||
sum_y2 += y2[i];
|
||||
}
|
||||
|
||||
var step1 = (x.length * sum_xy) - (sum_x * sum_y);
|
||||
var step2 = (x.length * sum_x2) - (sum_x * sum_x);
|
||||
var step3 = (x.length * sum_y2) - (sum_y * sum_y);
|
||||
var step4 = Math.sqrt(step2 * step3);
|
||||
var answer = step1 / step4;
|
||||
|
||||
return answer;
|
||||
};
|
||||
|
||||
m.getNormVec = function(vec) {
|
||||
var i;
|
||||
var sqsum = 0;
|
||||
for(i=0; i<vec.length; i++)
|
||||
sqsum += vec[i] * vec[i];
|
||||
return Math.sqrt(sqsum);
|
||||
}
|
||||
|
||||
m.gaussian = function(x, sigma) {
|
||||
sigma = sigma || 10.0;
|
||||
return Math.exp(-1.*x*x/(2*sigma*sigma));
|
||||
}
|
||||
|
||||
m.meanVecs = function(vecs) {
|
||||
var sum = m.zeroVec(vecs[0].length);
|
||||
var i;
|
||||
for(i=0; i<vecs.length; i++)
|
||||
sum = m.addVec(sum,vecs[i]);
|
||||
return m.activateVec(sum,function(x) {return 1.*x/vecs.length;});
|
||||
};
|
||||
|
||||
m.covarianceVecs = function(vecs) {
|
||||
var mat = m.zeroMat(vecs[0].length,vecs[0].length);
|
||||
var meanVec = m.meanVecs(vecs);
|
||||
var i;
|
||||
for(i=0; i<vecs.length; i++) {
|
||||
var a = m.minusVec(vecs[i],meanVec);
|
||||
mat = m.addMat(mat, m.mulMat(m.transpose([a]),[a]));
|
||||
}
|
||||
return m.activateMat(mat,function(x) { return 1.*x/(vecs.length-1);});
|
||||
};
|
||||
|
||||
m.shuffle = function(arr){
|
||||
var o = [];
|
||||
for(var i=0;i<arr.length;i++)
|
||||
o.push(arr[i]); // deep copy
|
||||
for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
|
||||
return o;
|
||||
};
|
||||
|
||||
m.range = function(start, end, step) {
|
||||
var ret = [];
|
||||
if(typeof step === "undefined")
|
||||
step = 1;
|
||||
if(typeof end === "undefined") {
|
||||
end = start;
|
||||
start = 0;
|
||||
}
|
||||
for(var i=start;i<end;i+=step)
|
||||
ret.push(i);
|
||||
return ret;
|
||||
};
|
||||
// For CRBM
|
||||
/*
|
||||
m.phi = function(mat,vec,low,high) {
|
||||
var i;
|
||||
var result = [];
|
||||
for(i=0;i<mat.length;i++) {
|
||||
result.push(m.activateTwoVec(mat[i],vec,function(x,y){return low+(high-low)* m.sigmoid(x*y);}))
|
||||
}
|
||||
return result;
|
||||
}
|
||||
*/
|
Loading…
Reference in New Issue
Block a user