UNPKG

@jsmlt/jsmlt

Version:

JavaScript Machine Learning

120 lines (102 loc) 3.65 kB
'use strict'; 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); }