UNPKG

siafun

Version:
141 lines (140 loc) 4.91 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const _ = require("lodash"); const clusterfck = require("clusterfck"); const arrayutils_1 = require("arrayutils"); exports.QUANT_FUNCS = { IDENTITY: identity, CONSTANT: getConstant, ROUND: getRound, ORDER: getOrder, SUMMARIZE: getSummarize, SORTED_SUMMARIZE: getSortedSummarize, TRANSP_SORTED_SUMMARIZE: getTransposedSortedSummarize, ABOVE_MEAN: getAboveMean, ABOVE_STD: getAboveStd, DISCRETIZE: getDiscretize, CLUSTER: getCluster, SCALE: scale, NORMALIZE: normalize, INTERVALS: toIntervals }; function identity() { return toArrayMap(x => x); } /** maps all values of an array to the given constant */ function getConstant(value) { return toArrayMap(() => value); } /** returns a function that rounds all numbers in an array to the given precision */ function getRound(precision = 2) { return toArrayMap(_.curryRight(_.round)(precision)); } /** returns a function that maps all numbers in an array onto their index */ function getOrder() { return (values) => values.map((v, i) => i); } /** returns a function that maps all arrays in an array onto the outDims highest values */ function getSummarize(outDims) { return toMatrixMap(_.curryRight(arrayutils_1.indicesOfNMax)(outDims)); } /** returns a function that summarizes and sorts the arrays of an array */ function getSortedSummarize(outDims) { return _.flow(getSummarize(outDims), sort); } /** returns a function that maps all arrays onto the values above their average */ function getAboveMean() { return toMatrixMap((values) => { const mean = _.mean(values); return values.map((v, i) => v > mean ? i : -1).filter(i => i > -1); }); } /** returns a function that maps all arrays onto the values above their average */ function getAboveStd() { return toMatrixMap((values) => { const mean = _.mean(values); const st = std(values, mean); return values.map((v, i) => v > mean + st ? i : -1).filter(i => i > -1); }); } //TODO IS NOT REALLY SET CLASS YET, NEED TO INVERT POTENTIALLY!! function getTransposedSortedSummarize(outDims) { return _.flow(getSummarize(outDims), sort, toMatrixMap(toIntervals)); } /** returns a function that maps all numbers in an array onto a discrete segment [0,...,numValues-1] */ function getDiscretize(numValues) { return _.flow(scale, _.curryRight(multiply)(numValues), toArrayMap(_.round)); } function getCluster(numClusters) { return _.curryRight(cluster)(numClusters); } /** scales all values in an array to [0,1] */ function scale(values) { var max = _.max(values); var min = _.min(values); return values.map(v => (v - min) / (max - min)); } /** normalizes all values in an array */ function normalize(values) { var mean = _.mean(values); var std = std(values, mean); return values.map(v => (v - mean) / std); } /** maps all values onto the interval by which they are reached */ function toIntervals(values) { return values.map((v, i) => i > 0 ? v - values[i - 1] : 0); } /** clusters all values and maps them onto their cluster index */ function cluster(values, clusterCount) { var kmeans = new clusterfck.Kmeans(null); var clusters = kmeans.cluster(values, clusterCount, null, null, null); return values.map(v => kmeans.classify(v, null)); } function multiply(values, multiplier) { return values.map(v => v * multiplier); } function sort(values) { return values.map(v => _.sortBy(v)); } function std(values, mean) { return Math.sqrt(_.sum(values.map(v => Math.pow((v - mean), 2))) / values.length); } function toArrayMap(func) { return (values) => values.map(v => func(v)); } function toMatrixMap(func) { return (values) => values.map(v => func(v)); } class Quantizer { constructor(dimFuncs) { this.dimFuncs = dimFuncs; } getQuantizedPoints(points) { if (this.dimFuncs.length > 0) { points = this.dimFuncs.map((f, i) => f(points.map(p => p[i]))); points = _.zip(...points); } return points.map(p => _.flatten(p)); } /** * TODO WHERE TO PUT? * returns a map with a normalized vector for each given dymo. if reduce is true, multidimensional ones are reduced */ normalize(vectors) { //normalize the space var means = []; var vars = []; for (var i = 0; i < vectors[0].length; i++) { var currentDim = []; for (var j = 0; j < vectors.length; j++) { if (!isNaN(vectors[j][i])) { currentDim.push(vectors[j][i]); } } means[i] = _.mean(currentDim); vars[i] = std(currentDim, means[i]); } return vectors.map(v => v.map((e, i) => (e - means[i]) / vars[i])); } } exports.Quantizer = Quantizer;