@jsmlt/jsmlt
Version:
JavaScript Machine Learning
120 lines (102 loc) • 3.65 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.wrapSlice = wrapSlice;
exports.zipWithIndex = zipWithIndex;
exports.valueCounts = valueCounts;
exports.argMax = argMax;
exports.sample = sample;
var _random = require('./random');
var Random = _interopRequireWildcard(_random);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
/**
* Take a slice out of an array, but wrap around the beginning an end of the array. For example,
* if `begin` is -1, the last element of the input array is used as the first output element.
*
* @param {Array.<mixed>} array - Input array
* @param {number} begin Index of first array element
* @param {number} end Index of end of slice range (element with this index will itself not be
* included in output)
* @return {Array.<mixed>} Sliced array
*/
function wrapSlice(array, begin, end) {
var result = [];
for (var i = begin; i <= end; i += 1) {
var index = (i % array.length + array.length) % array.length;
result.push(array[index]);
}
return result;
}
/**
* From an input array, create a new array where each element is comprised of a 2-dimensional array
* where the first element is the original array entry and the second element is its index
*
* @param {Array.<mixed>} array Input array
* @return {Array.<Array.<mixed>>} Output array
*/
// Local imports
function zipWithIndex(array) {
return array.map(function (x, i) {
return [x, i];
});
}
/**
* Count the occurrences of the unique values in an array
*
* @param {Array.<mixed>} array Input array
* @return {Array.<Array.<mixed>>} Array where each element is a 2-dimensional array. In these 2D
* arrays, the first element corresponds to the unique array value, and the second elements
* corresponds to the number of times this value occurs in the original array
*/
function valueCounts(array) {
// Create map of counts per array value
var counts = [];
var valuesIndex = {};
var numUniqueValues = 0;
array.forEach(function (x) {
if (typeof valuesIndex[x] === 'undefined') {
valuesIndex[x] = numUniqueValues;
counts.push([x, 0]);
numUniqueValues += 1;
}
counts[valuesIndex[x]][1] += 1;
});
return counts;
}
/**
* Get array key corresponding to largest element in the array.
*
* @param {Array.<number>} array Input array
* @return {number} Index of array element with largest value
*/
function argMax(array) {
if (array.length === 0) {
return null;
}
return zipWithIndex(array).reduce(function (r, x) {
return x[0] > r[0] ? x : r;
})[1];
}
/**
* Take a random sample without replacement from an array. Uses the Fisher-Yates shuffling,
* algorithm, modified to accomodate sampling.
*
* @param {Array.<mixed>} input Input array
* @param {number} number Number of elements to sample from the input array
* @return {Array.<mixed>} Array of length {number} with values sampled from the input array
*/
function sample(input, number) {
// Copy input array
var shuffledArray = input.slice(0);
// Number of elements in the input array
var numElements = input.length;
for (var i = numElements - 1; i >= numElements - number; i -= 1) {
var index = Random.randint(0, i + 1);
var tmp = shuffledArray[index];
shuffledArray[index] = shuffledArray[i];
shuffledArray[i] = tmp;
}
// Return the sampled values
return shuffledArray.slice(numElements - number);
}