kohonen-net
Version:
simple implementation of a self organizing map
93 lines (76 loc) • 2.33 kB
JavaScript
var num = require('numeric');
function random_tensor(dimensions){
return dimension(0);
function dimension(index){
let ret = [];
for(var i=0; i<dimensions[index]; i++){
if (index+1 != dimensions.length){
ret.push(dimension(index+1));
} else {
ret.push(Math.random());
}
}
return ret;
}
}
// generates a mxm matrix containing the distance from each node in a tensor of
// arebtrary shape
function neighbourMatrix(shape, distanceFn, wrapAround){
if (typeof(distanceFn) == 'undefined') { distanceFn = euclideanDistance; }
if (typeof(wrapAround) == 'undefined') { wrapAround = false; }
let totalValues = shape.reduce((p, v) => p*v, 1);
ret = [];
for (let m=0; m<totalValues;m++){
row = [];
nodeIndex = unravelIndex(m, shape);
for (let n=0; n<totalValues;n++){
distance = num.abs(num.sub(unravelIndex(n, shape), nodeIndex));
if (wrapAround) {
for(let i=0;i<shape.length;i++){
if (distance[i] > shape[i]/2) {
distance[i] = shape[i] - distance[i];
}
}
}
row.push(distanceFn(distance));
}
ret.push(row);
}
return ret;
}
function manhattanDistance(distance){
return num.sum(distance);
}
function chessBoardDistance(distance){
return num.max(distance);
}
function euclideanSquaredDistance(distance){
return num.sum(num.pow(distance, 2));
}
function euclideanDistance(distance){
return num.sqrt(euclideanSquaredDistance(distance));
}
// returns multidimentional index from flattend index
function unravelIndex(index, shape){
let mdIndex = [];
let rest = index;
for (let i=0;i<shape.length-1;i++){
mdIndex.push(Math.floor(rest/shape[i]));
rest %= shape[i];
}
mdIndex.push(rest);
return mdIndex;
}
// returns index of smallest value
function argMin(array){
return array.reduce((min, val, i, arr)=> val<arr[min]?i:min, 0);
}
module.exports.random_tensor = random_tensor;
module.exports.unravelIndex = unravelIndex;
module.exports.neighbourMatrix = neighbourMatrix;
module.exports.argMin = argMin;
// distances
module.exports.manhattanDistance = manhattanDistance;
module.exports.chessBoardDistance = chessBoardDistance;
module.exports.euclideanSquaredDistance = euclideanSquaredDistance;
module.exports.euclideanDistance = euclideanDistance;