{"version":3,"file":"simple-statistics.min.js","sources":["../src/sum.js","../src/mean.js","../src/sum_nth_power_deviations.js","../src/variance.js","../src/standard_deviation.js","../src/mode_sorted.js","../src/numeric_sort.js","../src/min.js","../src/max.js","../src/quantile_sorted.js","../src/quickselect.js","../src/quantile.js","../src/quantile_rank_sorted.js","../src/interquartile_range.js","../src/median.js","../src/median_absolute_deviation.js","../src/shuffle_in_place.js","../src/shuffle.js","../src/unique_count_sorted.js","../src/ckmeans.js","../src/sample_covariance.js","../src/sample_variance.js","../src/sample_standard_deviation.js","../src/combine_means.js","../src/root_mean_square.js","../src/bayesian_classifier.js","../src/perceptron.js","../src/epsilon.js","../src/factorial.js","../src/gammaln.js","../src/chi_squared_distribution_table.js","../src/kernel_density_estimation.js","../src/standard_normal_table.js","../src/error_function.js","../src/inverse_error_function.js","../src/sign.js","../src/linear_regression.js","../src/linear_regression_line.js","../src/r_squared.js","../src/mode.js","../src/mode_fast.js","../src/extent.js","../src/min_sorted.js","../src/max_sorted.js","../src/extent_sorted.js","../src/sum_simple.js","../src/product.js","../src/quantile_rank.js","../src/chunk.js","../src/sample_with_replacement.js","../src/sample.js","../src/equal_interval_breaks.js","../src/sample_correlation.js","../src/sample_skewness.js","../src/sample_kurtosis.js","../src/permutations_heap.js","../src/combinations.js","../src/combinations_replacement.js","../src/add_to_mean.js","../src/combine_variances.js","../src/geometric_mean.js","../src/harmonic_mean.js","../src/median_sorted.js","../src/subtract_from_mean.js","../src/t_test.js","../src/t_test_two_sample.js","../src/gamma.js","../src/bernoulli_distribution.js","../src/binomial_distribution.js","../src/poisson_distribution.js","../src/chi_squared_goodness_of_fit.js","../src/z_score.js","../src/cumulative_std_normal_probability.js","../src/probit.js","../src/permutation_test.js","../src/bisect.js"],"sourcesContent":["/* @flow */\n\n/**\n * Our default sum is the [Kahan-Babuska algorithm](https://pdfs.semanticscholar.org/1760/7d467cda1d0277ad272deb2113533131dc09.pdf).\n * This method is an improvement over the classical\n * [Kahan summation algorithm](https://en.wikipedia.org/wiki/Kahan_summation_algorithm).\n * It aims at computing the sum of a list of numbers while correcting for\n * floating-point errors. Traditionally, sums are calculated as many\n * successive additions, each one with its own floating-point roundoff. These\n * losses in precision add up as the number of numbers increases. This alternative\n * algorithm is more accurate than the simple way of calculating sums by simple\n * addition.\n *\n * This runs on `O(n)`, linear time in respect to the array.\n *\n * @param {Array} x input\n * @return {number} sum of all input numbers\n * @example\n * sum([1, 2, 3]); // => 6\n */\nfunction sum(x/*: Array */)/*: number */ {\n\n // If the array is empty, we needn't bother computing its sum\n if (x.length === 0) {\n return 0;\n }\n\n // Initializing the sum as the first number in the array\n var sum = x[0];\n\n // Keeping track of the floating-point error correction\n var correction = 0;\n\n var transition;\n\n for (var i = 1; i < x.length; i++) {\n transition = sum + x[i];\n\n // Here we need to update the correction in a different fashion\n // if the new absolute value is greater than the absolute sum\n if (Math.abs(sum) >= Math.abs(x[i])) {\n correction += ((sum - transition) + x[i]);\n }\n else {\n correction += ((x[i] - transition) + sum);\n }\n\n sum = transition;\n }\n\n // Returning the corrected sum\n return sum + correction;\n}\n\nexport default sum;\n","/* @flow */\n\nimport sum from './sum';\n\n/**\n * The mean, _also known as average_,\n * is the sum of all values over the number of values.\n * This is a [measure of central tendency](https://en.wikipedia.org/wiki/Central_tendency):\n * a method of finding a typical or central value of a set of numbers.\n *\n * This runs on `O(n)`, linear time in respect to the array\n *\n * @param {Array} x sample of one or more data points\n * @throws {Error} if the the length of x is less than one\n * @returns {number} mean\n * @example\n * mean([0, 10]); // => 5\n */\nfunction mean(x /*: Array */)/*: number */ {\n // The mean of no numbers is null\n if (x.length === 0) {\n throw new Error('mean requires at least one data point');\n }\n\n return sum(x) / x.length;\n}\n\nexport default mean;\n","/* @flow */\n\nimport mean from './mean';\n\n/**\n * The sum of deviations to the Nth power.\n * When n=2 it's the sum of squared deviations.\n * When n=3 it's the sum of cubed deviations.\n *\n * @param {Array} x\n * @param {number} n power\n * @returns {number} sum of nth power deviations\n *\n * @example\n * var input = [1, 2, 3];\n * // since the variance of a set is the mean squared\n * // deviations, we can calculate that with sumNthPowerDeviations:\n * sumNthPowerDeviations(input, 2) / input.length;\n */\nfunction sumNthPowerDeviations(x/*: Array */, n/*: number */)/*: number */ {\n var meanValue = mean(x),\n sum = 0,\n tempValue,\n i;\n\n // This is an optimization: when n is 2 (we're computing a number squared),\n // multiplying the number by itself is significantly faster than using\n // the Math.pow method.\n if (n === 2) {\n for (i = 0; i < x.length; i++) {\n tempValue = x[i] - meanValue;\n sum += tempValue * tempValue;\n }\n } else {\n for (i = 0; i < x.length; i++) {\n sum += Math.pow(x[i] - meanValue, n);\n }\n }\n\n return sum;\n}\n\nexport default sumNthPowerDeviations;\n","/* @flow */\n\nimport sumNthPowerDeviations from './sum_nth_power_deviations';\n\n/**\n * The [variance](http://en.wikipedia.org/wiki/Variance)\n * is the sum of squared deviations from the mean.\n *\n * This is an implementation of variance, not sample variance:\n * see the `sampleVariance` method if you want a sample measure.\n *\n * @param {Array} x a population of one or more data points\n * @returns {number} variance: a value greater than or equal to zero.\n * zero indicates that all values are identical.\n * @throws {Error} if x's length is 0\n * @example\n * variance([1, 2, 3, 4, 5, 6]); // => 2.9166666666666665\n */\nfunction variance(x/*: Array */)/*:number*/ {\n // The variance of no numbers is null\n if (x.length === 0) {\n throw new Error('variance requires at least one data point');\n }\n\n // Find the mean of squared deviations between the\n // mean value and each value.\n return sumNthPowerDeviations(x, 2) / x.length;\n}\n\nexport default variance;\n","/* @flow */\n\nimport variance from './variance';\n\n/**\n * The [standard deviation](http://en.wikipedia.org/wiki/Standard_deviation)\n * is the square root of the variance. This is also known as the population\n * standard deviation. It's useful for measuring the amount\n * of variation or dispersion in a set of values.\n *\n * Standard deviation is only appropriate for full-population knowledge: for\n * samples of a population, {@link sampleStandardDeviation} is\n * more appropriate.\n *\n * @param {Array} x input\n * @returns {number} standard deviation\n * @example\n * variance([2, 4, 4, 4, 5, 5, 7, 9]); // => 4\n * standardDeviation([2, 4, 4, 4, 5, 5, 7, 9]); // => 2\n */\nfunction standardDeviation(x /*: Array */)/*:number*/ {\n if (x.length === 1) {\n return 0;\n }\n var v = variance(x);\n return Math.sqrt(v);\n}\n\nexport default standardDeviation;\n","/* @flow */\n\n/**\n * The [mode](http://bit.ly/W5K4Yt) is the number that appears in a list the highest number of times.\n * There can be multiple modes in a list: in the event of a tie, this\n * algorithm will return the most recently seen mode.\n *\n * This is a [measure of central tendency](https://en.wikipedia.org/wiki/Central_tendency):\n * a method of finding a typical or central value of a set of numbers.\n *\n * This runs in `O(n)` because the input is sorted.\n *\n * @param {Array} sorted a sample of one or more data points\n * @returns {number} mode\n * @throws {Error} if sorted is empty\n * @example\n * modeSorted([0, 0, 1]); // => 0\n */\nfunction modeSorted(sorted /*: Array */)/*:number*/ {\n\n // Handle edge cases:\n // The mode of an empty list is undefined\n if (sorted.length === 0) {\n throw new Error('mode requires at least one data point');\n } else if (sorted.length === 1) {\n return sorted[0];\n }\n\n // This assumes it is dealing with an array of size > 1, since size\n // 0 and 1 are handled immediately. Hence it starts at index 1 in the\n // array.\n var last = sorted[0],\n // store the mode as we find new modes\n value = NaN,\n // store how many times we've seen the mode\n maxSeen = 0,\n // how many times the current candidate for the mode\n // has been seen\n seenThis = 1;\n\n // end at sorted.length + 1 to fix the case in which the mode is\n // the highest number that occurs in the sequence. the last iteration\n // compares sorted[i], which is undefined, to the highest number\n // in the series\n for (var i = 1; i < sorted.length + 1; i++) {\n // we're seeing a new number pass by\n if (sorted[i] !== last) {\n // the last number is the new mode since we saw it more\n // often than the old one\n if (seenThis > maxSeen) {\n maxSeen = seenThis;\n value = last;\n }\n seenThis = 1;\n last = sorted[i];\n // if this isn't a new number, it's one more occurrence of\n // the potential mode\n } else { seenThis++; }\n }\n return value;\n}\n\nexport default modeSorted;\n","/* @flow */\n\n/**\n * Sort an array of numbers by their numeric value, ensuring that the\n * array is not changed in place.\n *\n * This is necessary because the default behavior of .sort\n * in JavaScript is to sort arrays as string values\n *\n * [1, 10, 12, 102, 20].sort()\n * // output\n * [1, 10, 102, 12, 20]\n *\n * @param {Array} x input array\n * @return {Array} sorted array\n * @private\n * @example\n * numericSort([3, 2, 1]) // => [1, 2, 3]\n */\nfunction numericSort(x /*: Array */) /*: Array */ {\n return x\n // ensure the array is not changed in-place\n .slice()\n // comparator function that treats input as numeric\n .sort(function(a, b) {\n return a - b;\n });\n}\n\nexport default numericSort;\n","/* @flow */\n\n/**\n * The min is the lowest number in the array. This runs on `O(n)`, linear time in respect to the array\n *\n * @param {Array} x sample of one or more data points\n * @throws {Error} if the the length of x is less than one\n * @returns {number} minimum value\n * @example\n * min([1, 5, -10, 100, 2]); // => -10\n */\nfunction min(x /*: Array */)/*:number*/ {\n\n if (x.length === 0) {\n throw new Error('min requires at least one data point');\n }\n\n var value = x[0];\n for (var i = 1; i < x.length; i++) {\n // On the first iteration of this loop, min is\n // undefined and is thus made the minimum element in the array\n if (x[i] < value) {\n value = x[i];\n }\n }\n return value;\n}\n\nexport default min;\n","/* @flow */\n\n/**\n * This computes the maximum number in an array.\n *\n * This runs on `O(n)`, linear time in respect to the array\n *\n * @param {Array} x sample of one or more data points\n * @returns {number} maximum value\n * @throws {Error} if the the length of x is less than one\n * @example\n * max([1, 2, 3, 4]);\n * // => 4\n */\nfunction max(x /*: Array */) /*:number*/ {\n\n if (x.length === 0) {\n throw new Error('max requires at least one data point');\n }\n\n var value = x[0];\n for (var i = 1; i < x.length; i++) {\n // On the first iteration of this loop, max is\n // undefined and is thus made the maximum element in the array\n if (x[i] > value) {\n value = x[i];\n }\n }\n return value;\n}\n\nexport default max;\n","/* @flow */\n\n/**\n * This is the internal implementation of quantiles: when you know\n * that the order is sorted, you don't need to re-sort it, and the computations\n * are faster.\n *\n * @param {Array} x sample of one or more data points\n * @param {number} p desired quantile: a number between 0 to 1, inclusive\n * @returns {number} quantile value\n * @throws {Error} if p ix outside of the range from 0 to 1\n * @throws {Error} if x is empty\n * @example\n * quantileSorted([3, 6, 7, 8, 8, 9, 10, 13, 15, 16, 20], 0.5); // => 9\n */\nfunction quantileSorted(x /*: Array */, p /*: number */)/*: number */ {\n var idx = x.length * p;\n if (x.length === 0) {\n throw new Error('quantile requires at least one data point.');\n } else if (p < 0 || p > 1) {\n throw new Error('quantiles must be between 0 and 1');\n } else if (p === 1) {\n // If p is 1, directly return the last element\n return x[x.length - 1];\n } else if (p === 0) {\n // If p is 0, directly return the first element\n return x[0];\n } else if (idx % 1 !== 0) {\n // If p is not integer, return the next element in array\n return x[Math.ceil(idx) - 1];\n } else if (x.length % 2 === 0) {\n // If the list has even-length, we'll take the average of this number\n // and the next value, if there is one\n return (x[idx - 1] + x[idx]) / 2;\n } else {\n // Finally, in the simple case of an integer value\n // with an odd-length list, return the x value at the index.\n return x[idx];\n }\n}\n\nexport default quantileSorted;\n","/* @flow */\n\n/**\n * Rearrange items in `arr` so that all items in `[left, k]` range are the smallest.\n * The `k`-th element will have the `(k - left + 1)`-th smallest value in `[left, right]`.\n *\n * Implements Floyd-Rivest selection algorithm https://en.wikipedia.org/wiki/Floyd-Rivest_algorithm\n *\n * @param {Array} arr input array\n * @param {number} k pivot index\n * @param {number} [left] left index\n * @param {number} [right] right index\n * @returns {void} mutates input array\n * @example\n * var arr = [65, 28, 59, 33, 21, 56, 22, 95, 50, 12, 90, 53, 28, 77, 39];\n * quickselect(arr, 8);\n * // = [39, 28, 28, 33, 21, 12, 22, 50, 53, 56, 59, 65, 90, 77, 95]\n */\nfunction quickselect(arr/*: Array */, k/*: number */, left/*: ?number */, right/*: ?number */)/*: void */ {\n left = left || 0;\n right = right || (arr.length - 1);\n\n while (right > left) {\n // 600 and 0.5 are arbitrary constants chosen in the original paper to minimize execution time\n if (right - left > 600) {\n var n = right - left + 1;\n var m = k - left + 1;\n var z = Math.log(n);\n var s = 0.5 * Math.exp(2 * z / 3);\n var sd = 0.5 * Math.sqrt(z * s * (n - s) / n);\n if (m - n / 2 < 0) sd *= -1;\n var newLeft = Math.max(left, Math.floor(k - m * s / n + sd));\n var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));\n quickselect(arr, k, newLeft, newRight);\n }\n\n var t = arr[k];\n var i = left;\n var j = right;\n\n swap(arr, left, k);\n if (arr[right] > t) swap(arr, left, right);\n\n while (i < j) {\n swap(arr, i, j);\n i++;\n j--;\n while (arr[i] < t) i++;\n while (arr[j] > t) j--;\n }\n\n if (arr[left] === t) swap(arr, left, j);\n else {\n j++;\n swap(arr, j, right);\n }\n\n if (j <= k) left = j + 1;\n if (k <= j) right = j - 1;\n }\n}\n\nfunction swap(arr, i, j) {\n var tmp = arr[i];\n arr[i] = arr[j];\n arr[j] = tmp;\n}\n\nexport default quickselect;\n","/* @flow */\n\nimport quantileSorted from './quantile_sorted';\nimport quickselect from './quickselect';\n\n/**\n * The [quantile](https://en.wikipedia.org/wiki/Quantile):\n * this is a population quantile, since we assume to know the entire\n * dataset in this library. This is an implementation of the\n * [Quantiles of a Population](http://en.wikipedia.org/wiki/Quantile#Quantiles_of_a_population)\n * algorithm from wikipedia.\n *\n * Sample is a one-dimensional array of numbers,\n * and p is either a decimal number from 0 to 1 or an array of decimal\n * numbers from 0 to 1.\n * In terms of a k/q quantile, p = k/q - it's just dealing with fractions or dealing\n * with decimal values.\n * When p is an array, the result of the function is also an array containing the appropriate\n * quantiles in input order\n *\n * @param {Array} x sample of one or more numbers\n * @param {Array | number} p the desired quantile, as a number between 0 and 1\n * @returns {number} quantile\n * @example\n * quantile([3, 6, 7, 8, 8, 9, 10, 13, 15, 16, 20], 0.5); // => 9\n */\nfunction quantile(x/*: Array */, p/*: Array | number */)/*: Array | number */ {\n var copy = x.slice();\n\n if (Array.isArray(p)) {\n // rearrange elements so that each element corresponding to a requested\n // quantile is on a place it would be if the array was fully sorted\n multiQuantileSelect(copy, p);\n // Initialize the result array\n var results = [];\n // For each requested quantile\n for (var i = 0; i < p.length; i++) {\n results[i] = quantileSorted(copy, p[i]);\n }\n return results;\n } else {\n var idx = quantileIndex(copy.length, p);\n quantileSelect(copy, idx, 0, copy.length - 1);\n return quantileSorted(copy, p);\n }\n}\n\nfunction quantileSelect(arr, k, left, right) {\n if (k % 1 === 0) {\n quickselect(arr, k, left, right);\n } else {\n k = Math.floor(k);\n quickselect(arr, k, left, right);\n quickselect(arr, k + 1, k + 1, right);\n }\n}\n\nfunction multiQuantileSelect(arr, p) {\n var indices = [0];\n for (var i = 0; i < p.length; i++) {\n indices.push(quantileIndex(arr.length, p[i]));\n }\n indices.push(arr.length - 1);\n indices.sort(compare);\n\n var stack = [0, indices.length - 1];\n\n while (stack.length) {\n var r = Math.ceil(stack.pop());\n var l = Math.floor(stack.pop());\n if (r - l <= 1) continue;\n\n var m = Math.floor((l + r) / 2);\n quantileSelect(arr, indices[m], indices[l], indices[r]);\n\n stack.push(l, m, m, r);\n }\n}\n\nfunction compare(a, b) {\n return a - b;\n}\n\nfunction quantileIndex(len /*: number */, p /*: number */)/*:number*/ {\n var idx = len * p;\n if (p === 1) {\n // If p is 1, directly return the last index\n return len - 1;\n } else if (p === 0) {\n // If p is 0, directly return the first index\n return 0;\n } else if (idx % 1 !== 0) {\n // If index is not integer, return the next index in array\n return Math.ceil(idx) - 1;\n } else if (len % 2 === 0) {\n // If the list has even-length, we'll return the middle of two indices\n // around quantile to indicate that we need an average value of the two\n return idx - 0.5;\n } else {\n // Finally, in the simple case of an integer index\n // with an odd-length list, return the index\n return idx;\n }\n}\n\nexport default quantile;\n","/* @flow */\n/* eslint no-bitwise: 0 */\n\n/**\n * This function returns the quantile in which one would find the given value in\n * the given array. With a sorted array, leveraging binary search, we can find\n * this information in logarithmic time.\n *\n * @param {Array} x input\n * @returns {number} value value\n * @example\n * quantileRankSorted([1, 2, 3, 4], 3); // => 0.75\n * quantileRankSorted([1, 2, 3, 3, 4], 3); // => 0.7\n * quantileRankSorted([1, 2, 3, 4], 6); // => 1\n * quantileRankSorted([1, 2, 3, 3, 5], 4); // => 0.8\n */\nfunction quantileRankSorted(\n x /*: Array */,\n value /*: number */)/*: number */ {\n\n // Value is lesser than any value in the array\n if (value < x[0]) {\n return 0;\n }\n\n // Value is greater than any value in the array\n if (value > x[x.length - 1]) {\n return 1;\n }\n\n var l = lowerBound(x, value);\n\n // Value is not in the array\n if (x[l] !== value) {\n return l / x.length;\n }\n\n l++;\n\n var u = upperBound(x, value);\n\n // The value exists only once in the array\n if (u === l) {\n return l / x.length;\n }\n\n // Here, we are basically computing the mean of the range of indices\n // containing our searched value. But, instead, of initializing an\n // array and looping over it, there is a dedicated math formula that\n // we apply below to get the result.\n var r = u - l + 1;\n var sum = (r * (u + l)) / 2;\n var mean = sum / r;\n\n return mean / x.length;\n}\n\nfunction lowerBound(x, value) {\n var mid = 0;\n var lo = 0;\n var hi = x.length;\n\n while (lo < hi) {\n mid = (lo + hi) >>> 1;\n\n if (value <= x[mid]) {\n hi = mid;\n }\n else {\n lo = -~mid;\n }\n }\n\n return lo;\n}\n\nfunction upperBound(x, value) {\n var mid = 0;\n var lo = 0;\n var hi = x.length;\n\n while (lo < hi) {\n mid = (lo + hi) >>> 1;\n\n if (value >= x[mid]) {\n lo = -~mid;\n }\n else {\n hi = mid;\n }\n }\n\n return lo;\n}\n\nexport default quantileRankSorted;\n","/* @flow */\n\nimport quantile from './quantile';\n\n/**\n * The [Interquartile range](http://en.wikipedia.org/wiki/Interquartile_range) is\n * a measure of statistical dispersion, or how scattered, spread, or\n * concentrated a distribution is. It's computed as the difference between\n * the third quartile and first quartile.\n *\n * @param {Array} x sample of one or more numbers\n * @returns {number} interquartile range: the span between lower and upper quartile,\n * 0.25 and 0.75\n * @example\n * interquartileRange([0, 1, 2, 3]); // => 2\n */\nfunction interquartileRange(x/*: Array */) {\n // Interquartile range is the span between the upper quartile,\n // at `0.75`, and lower quartile, `0.25`\n var q1 = quantile(x, 0.75),\n q2 = quantile(x, 0.25);\n\n if (typeof q1 === 'number' && typeof q2 === 'number') {\n return q1 - q2;\n }\n}\n\nexport default interquartileRange;\n","/* @flow */\n\nimport quantile from './quantile';\n\n/**\n * The [median](http://en.wikipedia.org/wiki/Median) is\n * the middle number of a list. This is often a good indicator of 'the middle'\n * when there are outliers that skew the `mean()` value.\n * This is a [measure of central tendency](https://en.wikipedia.org/wiki/Central_tendency):\n * a method of finding a typical or central value of a set of numbers.\n *\n * The median isn't necessarily one of the elements in the list: the value\n * can be the average of two elements if the list has an even length\n * and the two central values are different.\n *\n * @param {Array} x input\n * @returns {number} median value\n * @example\n * median([10, 2, 5, 100, 2, 1]); // => 3.5\n */\nfunction median(x /*: Array */)/*: number */ {\n return +quantile(x, 0.5);\n}\n\nexport default median;\n","/* @flow */\n\nimport median from './median';\n\n/**\n * The [Median Absolute Deviation](http://en.wikipedia.org/wiki/Median_absolute_deviation) is\n * a robust measure of statistical\n * dispersion. It is more resilient to outliers than the standard deviation.\n *\n * @param {Array} x input array\n * @returns {number} median absolute deviation\n * @example\n * medianAbsoluteDeviation([1, 1, 2, 2, 4, 6, 9]); // => 1\n */\nfunction medianAbsoluteDeviation(x/*: Array */)/*: number */ {\n // The mad of nothing is null\n var medianValue = median(x),\n medianAbsoluteDeviations = [];\n\n // Make a list of absolute deviations from the median\n for (var i = 0; i < x.length; i++) {\n medianAbsoluteDeviations.push(Math.abs(x[i] - medianValue));\n }\n\n // Find the median value of that list\n return median(medianAbsoluteDeviations);\n}\n\nexport default medianAbsoluteDeviation;\n","/* @flow */\n\n/**\n * A [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle)\n * in-place - which means that it **will change the order of the original\n * array by reference**.\n *\n * This is an algorithm that generates a random [permutation](https://en.wikipedia.org/wiki/Permutation)\n * of a set.\n *\n * @param {Array} x sample of one or more numbers\n * @param {Function} [randomSource=Math.random] an optional entropy source that\n * returns numbers between 0 inclusive and 1 exclusive: the range [0, 1)\n * @returns {Array} x\n * @example\n * var x = [1, 2, 3, 4];\n * shuffleInPlace(x);\n * // x is shuffled to a value like [2, 1, 4, 3]\n */\nfunction shuffleInPlace(x/*: Array */, randomSource/*: ?Function */)/*: Array */ {\n\n // a custom random number source can be provided if you want to use\n // a fixed seed or another random number generator, like\n // [random-js](https://www.npmjs.org/package/random-js)\n randomSource = randomSource || Math.random;\n\n // store the current length of the x to determine\n // when no elements remain to shuffle.\n var length = x.length;\n\n // temporary is used to hold an item when it is being\n // swapped between indices.\n var temporary;\n\n // The index to swap at each stage.\n var index;\n\n // While there are still items to shuffle\n while (length > 0) {\n // chose a random index within the subset of the array\n // that is not yet shuffled\n index = Math.floor(randomSource() * length--);\n\n // store the value that we'll move temporarily\n temporary = x[length];\n\n // swap the value at `x[length]` with `x[index]`\n x[length] = x[index];\n x[index] = temporary;\n }\n\n return x;\n}\n\nexport default shuffleInPlace;\n","/* @flow */\n\nimport shuffleInPlace from './shuffle_in_place';\n\n/**\n * A [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle)\n * is a fast way to create a random permutation of a finite set. This is\n * a function around `shuffle_in_place` that adds the guarantee that\n * it will not modify its input.\n *\n * @param {Array} x sample of 0 or more numbers\n * @param {Function} [randomSource=Math.random] an optional entropy source that\n * returns numbers between 0 inclusive and 1 exclusive: the range [0, 1)\n * @return {Array} shuffled version of input\n * @example\n * var shuffled = shuffle([1, 2, 3, 4]);\n * shuffled; // = [2, 3, 1, 4] or any other random permutation\n */\nfunction shuffle/*::*/(x/*: Array */, randomSource/*: ?Function */) {\n // slice the original array so that it is not modified\n var sample = x.slice();\n\n // and then shuffle that shallow-copied array, in place\n return shuffleInPlace(sample.slice(), randomSource);\n}\n\nexport default shuffle;\n","/* @flow */\n\n/**\n * For a sorted input, counting the number of unique values\n * is possible in constant time and constant memory. This is\n * a simple implementation of the algorithm.\n *\n * Values are compared with `===`, so objects and non-primitive objects\n * are not handled in any special way.\n *\n * @param {Array<*>} x an array of any kind of value\n * @returns {number} count of unique values\n * @example\n * uniqueCountSorted([1, 2, 3]); // => 3\n * uniqueCountSorted([1, 1, 1]); // => 1\n */\nfunction uniqueCountSorted(x/*: Array*/)/*: number */ {\n var uniqueValueCount = 0,\n lastSeenValue;\n for (var i = 0; i < x.length; i++) {\n if (i === 0 || x[i] !== lastSeenValue) {\n lastSeenValue = x[i];\n uniqueValueCount++;\n }\n }\n return uniqueValueCount;\n}\n\nexport default uniqueCountSorted;\n","/* @flow */\n\nimport numericSort from './numeric_sort';\nimport uniqueCountSorted from './unique_count_sorted';\n\n/**\n * Create a new column x row matrix.\n *\n * @private\n * @param {number} columns\n * @param {number} rows\n * @return {Array>} matrix\n * @example\n * makeMatrix(10, 10);\n */\nfunction makeMatrix(columns, rows) {\n var matrix = [];\n for (var i = 0; i < columns; i++) {\n var column = [];\n for (var j = 0; j < rows; j++) {\n column.push(0);\n }\n matrix.push(column);\n }\n return matrix;\n}\n\n/**\n * Generates incrementally computed values based on the sums and sums of\n * squares for the data array\n *\n * @private\n * @param {number} j\n * @param {number} i\n * @param {Array} sums\n * @param {Array} sumsOfSquares\n * @return {number}\n * @example\n * ssq(0, 1, [-1, 0, 2], [1, 1, 5]);\n */\nfunction ssq(j, i, sums, sumsOfSquares) {\n var sji; // s(j, i)\n if (j > 0) {\n var muji = (sums[i] - sums[j - 1]) / (i - j + 1); // mu(j, i)\n sji = sumsOfSquares[i] - sumsOfSquares[j - 1] - (i - j + 1) * muji * muji;\n } else {\n sji = sumsOfSquares[i] - sums[i] * sums[i] / (i + 1);\n }\n if (sji < 0) {\n return 0;\n }\n return sji;\n}\n\n/**\n * Function that recursively divides and conquers computations\n * for cluster j\n *\n * @private\n * @param {number} iMin Minimum index in cluster to be computed\n * @param {number} iMax Maximum index in cluster to be computed\n * @param {number} cluster Index of the cluster currently being computed\n * @param {Array>} matrix\n * @param {Array>} backtrackMatrix\n * @param {Array} sums\n * @param {Array} sumsOfSquares\n */\nfunction fillMatrixColumn(iMin, iMax, cluster, matrix, backtrackMatrix, sums, sumsOfSquares) {\n if (iMin > iMax) {\n return;\n }\n\n // Start at midpoint between iMin and iMax\n var i = Math.floor((iMin + iMax) / 2);\n\n matrix[cluster][i] = matrix[cluster - 1][i - 1];\n backtrackMatrix[cluster][i] = i;\n\n var jlow = cluster; // the lower end for j\n\n if (iMin > cluster) {\n jlow = Math.max(jlow, backtrackMatrix[cluster][iMin - 1] || 0);\n }\n jlow = Math.max(jlow, backtrackMatrix[cluster - 1][i] || 0);\n\n var jhigh = i - 1; // the upper end for j\n if (iMax < matrix.length - 1) {\n jhigh = Math.min(jhigh, backtrackMatrix[cluster][iMax + 1] || 0);\n }\n\n var sji;\n var sjlowi;\n var ssqjlow;\n var ssqj;\n for (var j = jhigh; j >= jlow; --j) {\n sji = ssq(j, i, sums, sumsOfSquares);\n\n if (sji + matrix[cluster - 1][jlow - 1] >= matrix[cluster][i]) {\n break;\n }\n\n // Examine the lower bound of the cluster border\n sjlowi = ssq(jlow, i, sums, sumsOfSquares);\n\n ssqjlow = sjlowi + matrix[cluster - 1][jlow - 1];\n\n if (ssqjlow < matrix[cluster][i]) {\n // Shrink the lower bound\n matrix[cluster][i] = ssqjlow;\n backtrackMatrix[cluster][i] = jlow;\n }\n jlow++;\n\n ssqj = sji + matrix[cluster - 1][j - 1];\n if (ssqj < matrix[cluster][i]) {\n matrix[cluster][i] = ssqj;\n backtrackMatrix[cluster][i] = j;\n }\n }\n\n fillMatrixColumn(iMin, i - 1, cluster, matrix, backtrackMatrix, sums, sumsOfSquares);\n fillMatrixColumn(i + 1, iMax, cluster, matrix, backtrackMatrix, sums, sumsOfSquares);\n}\n\n/**\n * Initializes the main matrices used in Ckmeans and kicks\n * off the divide and conquer cluster computation strategy\n *\n * @private\n * @param {Array} data sorted array of values\n * @param {Array>} matrix\n * @param {Array>} backtrackMatrix\n */\nfunction fillMatrices(data, matrix, backtrackMatrix) {\n var nValues = matrix[0].length;\n\n // Shift values by the median to improve numeric stability\n var shift = data[Math.floor(nValues / 2)];\n\n // Cumulative sum and cumulative sum of squares for all values in data array\n var sums = [];\n var sumsOfSquares = [];\n\n // Initialize first column in matrix & backtrackMatrix\n for (var i = 0, shiftedValue; i < nValues; ++i) {\n shiftedValue = data[i] - shift;\n if (i === 0) {\n sums.push(shiftedValue);\n sumsOfSquares.push(shiftedValue * shiftedValue);\n } else {\n sums.push(sums[i - 1] + shiftedValue);\n sumsOfSquares.push(sumsOfSquares[i - 1] + shiftedValue * shiftedValue);\n }\n\n // Initialize for cluster = 0\n matrix[0][i] = ssq(0, i, sums, sumsOfSquares);\n backtrackMatrix[0][i] = 0;\n }\n\n // Initialize the rest of the columns\n var iMin;\n for (var cluster = 1; cluster < matrix.length; ++cluster) {\n if (cluster < matrix.length - 1) {\n iMin = cluster;\n } else {\n // No need to compute matrix[K-1][0] ... matrix[K-1][N-2]\n iMin = nValues - 1;\n }\n\n fillMatrixColumn(iMin, nValues - 1, cluster, matrix, backtrackMatrix, sums, sumsOfSquares);\n }\n}\n\n/**\n * Ckmeans clustering is an improvement on heuristic-based clustering\n * approaches like Jenks. The algorithm was developed in\n * [Haizhou Wang and Mingzhou Song](http://journal.r-project.org/archive/2011-2/RJournal_2011-2_Wang+Song.pdf)\n * as a [dynamic programming](https://en.wikipedia.org/wiki/Dynamic_programming) approach\n * to the problem of clustering numeric data into groups with the least\n * within-group sum-of-squared-deviations.\n *\n * Minimizing the difference within groups - what Wang & Song refer to as\n * `withinss`, or within sum-of-squares, means that groups are optimally\n * homogenous within and the data is split into representative groups.\n * This is very useful for visualization, where you may want to represent\n * a continuous variable in discrete color or style groups. This function\n * can provide groups that emphasize differences between data.\n *\n * Being a dynamic approach, this algorithm is based on two matrices that\n * store incrementally-computed values for squared deviations and backtracking\n * indexes.\n *\n * This implementation is based on Ckmeans 3.4.6, which introduced a new divide\n * and conquer approach that improved runtime from O(kn^2) to O(kn log(n)).\n *\n * Unlike the [original implementation](https://cran.r-project.org/web/packages/Ckmeans.1d.dp/index.html),\n * this implementation does not include any code to automatically determine\n * the optimal number of clusters: this information needs to be explicitly\n * provided.\n *\n * ### References\n * _Ckmeans.1d.dp: Optimal k-means Clustering in One Dimension by Dynamic\n * Programming_ Haizhou Wang and Mingzhou Song ISSN 2073-4859\n *\n * from The R Journal Vol. 3/2, December 2011\n * @param {Array} x input data, as an array of number values\n * @param {number} nClusters number of desired classes. This cannot be\n * greater than the number of values in the data array.\n * @returns {Array>} clustered input\n * @throws {Error} if the number of requested clusters is higher than the size of the data\n * @example\n * ckmeans([-1, 2, -1, 2, 4, 5, 6, -1, 2, -1], 3);\n * // The input, clustered into groups of similar numbers.\n * //= [[-1, -1, -1, -1], [2, 2, 2], [4, 5, 6]]);\n */\nfunction ckmeans(\n x/*: Array */,\n nClusters/*: number */)/*: Array> */ {\n\n if (nClusters > x.length) {\n throw new Error('cannot generate more classes than there are data values');\n }\n\n var sorted = numericSort(x),\n // we'll use this as the maximum number of clusters\n uniqueCount = uniqueCountSorted(sorted);\n\n // if all of the input values are identical, there's one cluster\n // with all of the input in it.\n if (uniqueCount === 1) {\n return [sorted];\n }\n\n // named 'S' originally\n var matrix = makeMatrix(nClusters, sorted.length),\n // named 'J' originally\n backtrackMatrix = makeMatrix(nClusters, sorted.length);\n\n // This is a dynamic programming way to solve the problem of minimizing\n // within-cluster sum of squares. It's similar to linear regression\n // in this way, and this calculation incrementally computes the\n // sum of squares that are later read.\n fillMatrices(sorted, matrix, backtrackMatrix);\n\n // The real work of Ckmeans clustering happens in the matrix generation:\n // the generated matrices encode all possible clustering combinations, and\n // once they're generated we can solve for the best clustering groups\n // very quickly.\n var clusters = [],\n clusterRight = backtrackMatrix[0].length - 1;\n\n // Backtrack the clusters from the dynamic programming matrix. This\n // starts at the bottom-right corner of the matrix (if the top-left is 0, 0),\n // and moves the cluster target with the loop.\n for (var cluster = backtrackMatrix.length - 1; cluster >= 0; cluster--) {\n\n var clusterLeft = backtrackMatrix[cluster][clusterRight];\n\n // fill the cluster from the sorted input by taking a slice of the\n // array. the backtrack matrix makes this easy - it stores the\n // indexes where the cluster should start and end.\n clusters[cluster] = sorted.slice(clusterLeft, clusterRight + 1);\n\n if (cluster > 0) {\n clusterRight = clusterLeft - 1;\n }\n }\n\n return clusters;\n}\n\nexport default ckmeans;\n","/* @flow */\n\nimport mean from './mean';\n\n/**\n * [Sample covariance](https://en.wikipedia.org/wiki/Sample_mean_and_sampleCovariance) of two datasets:\n * how much do the two datasets move together?\n * x and y are two datasets, represented as arrays of numbers.\n *\n * @param {Array} x a sample of two or more data points\n * @param {Array} y a sample of two or more data points\n * @throws {Error} if x and y do not have equal lengths\n * @throws {Error} if x or y have length of one or less\n * @returns {number} sample covariance\n * @example\n * sampleCovariance([1, 2, 3, 4, 5, 6], [6, 5, 4, 3, 2, 1]); // => -3.5\n */\nfunction sampleCovariance(x /*:Array*/, y /*:Array*/)/*:number*/ {\n\n // The two datasets must have the same length which must be more than 1\n if (x.length !== y.length) {\n throw new Error('sampleCovariance requires samples with equal lengths');\n }\n\n if (x.length < 2) {\n throw new Error('sampleCovariance requires at least two data points in each sample');\n }\n\n // determine the mean of each dataset so that we can judge each\n // value of the dataset fairly as the difference from the mean. this\n // way, if one dataset is [1, 2, 3] and [2, 3, 4], their covariance\n // does not suffer because of the difference in absolute values\n var xmean = mean(x),\n ymean = mean(y),\n sum = 0;\n\n // for each pair of values, the covariance increases when their\n // difference from the mean is associated - if both are well above\n // or if both are well below\n // the mean, the covariance increases significantly.\n for (var i = 0; i < x.length; i++) {\n sum += (x[i] - xmean) * (y[i] - ymean);\n }\n\n // this is Bessels' Correction: an adjustment made to sample statistics\n // that allows for the reduced degree of freedom entailed in calculating\n // values from samples rather than complete populations.\n var besselsCorrection = x.length - 1;\n\n // the covariance is weighted by the length of the datasets.\n return sum / besselsCorrection;\n}\n\nexport default sampleCovariance;\n","/* @flow */\n\nimport sumNthPowerDeviations from './sum_nth_power_deviations';\n\n/**\n * The [sample variance](https://en.wikipedia.org/wiki/Variance#Sample_variance)\n * is the sum of squared deviations from the mean. The sample variance\n * is distinguished from the variance by the usage of [Bessel's Correction](https://en.wikipedia.org/wiki/Bessel's_correction):\n * instead of dividing the sum of squared deviations by the length of the input,\n * it is divided by the length minus one. This corrects the bias in estimating\n * a value from a set that you don't know if full.\n *\n * References:\n * * [Wolfram MathWorld on Sample Variance](http://mathworld.wolfram.com/SampleVariance.html)\n *\n * @param {Array} x a sample of two or more data points\n * @throws {Error} if the length of x is less than 2\n * @return {number} sample variance\n * @example\n * sampleVariance([1, 2, 3, 4, 5]); // => 2.5\n */\nfunction sampleVariance(x /*: Array */)/*:number*/ {\n // The variance of no numbers is null\n if (x.length < 2) {\n throw new Error('sampleVariance requires at least two data points');\n }\n\n var sumSquaredDeviationsValue = sumNthPowerDeviations(x, 2);\n\n // this is Bessels' Correction: an adjustment made to sample statistics\n // that allows for the reduced degree of freedom entailed in calculating\n // values from samples rather than complete populations.\n var besselsCorrection = x.length - 1;\n\n // Find the mean value of that list\n return sumSquaredDeviationsValue / besselsCorrection;\n}\n\nexport default sampleVariance;\n","/* @flow */\n\nimport sampleVariance from './sample_variance';\n\n/**\n * The [sample standard deviation](http://en.wikipedia.org/wiki/Standard_deviation#Sample_standard_deviation)\n * is the square root of the sample variance.\n *\n * @param {Array} x input array\n * @returns {number} sample standard deviation\n * @example\n * sampleStandardDeviation([2, 4, 4, 4, 5, 5, 7, 9]).toFixed(2);\n * // => '2.14'\n */\nfunction sampleStandardDeviation(x/*:Array*/)/*:number*/ {\n // The standard deviation of no numbers is null\n var sampleVarianceX = sampleVariance(x);\n return Math.sqrt(sampleVarianceX);\n}\n\nexport default sampleStandardDeviation;\n","/* @flow */\n\n/**\n * When combining two lists of values for which one already knows the means,\n * one does not have to necessary recompute the mean of the combined lists in\n * linear time. They can instead use this function to compute the combined\n * mean by providing the mean & number of values of the first list and the mean\n * & number of values of the second list.\n *\n * @since 3.0.0\n * @param {number} mean1 mean of the first list\n * @param {number} n1 number of items in the first list\n * @param {number} mean2 mean of the second list\n * @param {number} n2 number of items in the second list\n * @returns {number} the combined mean\n *\n * @example\n * combineMeans(5, 3, 4, 3); // => 4.5\n */\nfunction combineMeans(mean1 /*: number*/, n1/*: number */, mean2 /*: number*/, n2/*: number */)/*: number */ {\n return (mean1 * n1 + mean2 * n2) / (n1 + n2);\n}\n\nexport default combineMeans;\n","/* @flow */\n\n/**\n * The Root Mean Square (RMS) is\n * a mean function used as a measure of the magnitude of a set\n * of numbers, regardless of their sign.\n * This is the square root of the mean of the squares of the\n * input numbers.\n * This runs on `O(n)`, linear time in respect to the array\n *\n * @param {Array} x a sample of one or more data points\n * @returns {number} root mean square\n * @throws {Error} if x is empty\n * @example\n * rootMeanSquare([-1, 1, -1, 1]); // => 1\n */\nfunction rootMeanSquare(x /*: Array */)/*:number*/ {\n if (x.length === 0) {\n throw new Error('rootMeanSquare requires at least one data point');\n }\n\n var sumOfSquares = 0;\n for (var i = 0; i < x.length; i++) {\n sumOfSquares += Math.pow(x[i], 2);\n }\n\n return Math.sqrt(sumOfSquares / x.length);\n}\n\nexport default rootMeanSquare;\n","/* @flow */\n\n/**\n * [Bayesian Classifier](http://en.wikipedia.org/wiki/Naive_Bayes_classifier)\n *\n * This is a naïve bayesian classifier that takes\n * singly-nested objects.\n *\n * @class\n * @example\n * var bayes = new BayesianClassifier();\n * bayes.train({\n * species: 'Cat'\n * }, 'animal');\n * var result = bayes.score({\n * species: 'Cat'\n * })\n * // result\n * // {\n * // animal: 1\n * // }\n */\nfunction BayesianClassifier() {\n // The number of items that are currently\n // classified in the model\n this.totalCount = 0;\n // Every item classified in the model\n this.data = {};\n}\n\n/**\n * Train the classifier with a new item, which has a single\n * dimension of Javascript literal keys and values.\n *\n * @param {Object} item an object with singly-deep properties\n * @param {string} category the category this item belongs to\n * @return {undefined} adds the item to the classifier\n */\nBayesianClassifier.prototype.train = function(item, category) {\n // If the data object doesn't have any values\n // for this category, create a new object for it.\n if (!this.data[category]) {\n this.data[category] = {};\n }\n\n // Iterate through each key in the item.\n for (var k in item) {\n var v = item[k];\n // Initialize the nested object `data[category][k][item[k]]`\n // with an object of keys that equal 0.\n if (this.data[category][k] === undefined) {\n this.data[category][k] = {};\n }\n if (this.data[category][k][v] === undefined) {\n this.data[category][k][v] = 0;\n }\n\n // And increment the key for this key/value combination.\n this.data[category][k][v]++;\n }\n\n // Increment the number of items classified\n this.totalCount++;\n};\n\n/**\n * Generate a score of how well this item matches all\n * possible categories based on its attributes\n *\n * @param {Object} item an item in the same format as with train\n * @returns {Object} of probabilities that this item belongs to a\n * given category.\n */\nBayesianClassifier.prototype.score = function(item) {\n // Initialize an empty array of odds per category.\n var odds = {}, category;\n // Iterate through each key in the item,\n // then iterate through each category that has been used\n // in previous calls to `.train()`\n for (var k in item) {\n var v = item[k];\n for (category in this.data) {\n // Create an empty object for storing key - value combinations\n // for this category.\n odds[category] = {};\n\n // If this item doesn't even have a property, it counts for nothing,\n // but if it does have the property that we're looking for from\n // the item to categorize, it counts based on how popular it is\n // versus the whole population.\n if (this.data[category][k]) {\n odds[category][k + '_' + v] = (this.data[category][k][v] || 0) / this.totalCount;\n } else {\n odds[category][k + '_' + v] = 0;\n }\n }\n }\n\n // Set up a new object that will contain sums of these odds by category\n var oddsSums = {};\n\n for (category in odds) {\n // Tally all of the odds for each category-combination pair -\n // the non-existence of a category does not add anything to the\n // score.\n oddsSums[category] = 0;\n for (var combination in odds[category]) {\n oddsSums[category] += odds[category][combination];\n }\n }\n\n return oddsSums;\n};\n\nexport default BayesianClassifier;\n","/* @flow */\n\n/**\n * This is a single-layer [Perceptron Classifier](http://en.wikipedia.org/wiki/Perceptron) that takes\n * arrays of numbers and predicts whether they should be classified\n * as either 0 or 1 (negative or positive examples).\n * @class\n * @example\n * // Create the model\n * var p = new PerceptronModel();\n * // Train the model with input with a diagonal boundary.\n * for (var i = 0; i < 5; i++) {\n * p.train([1, 1], 1);\n * p.train([0, 1], 0);\n * p.train([1, 0], 0);\n * p.train([0, 0], 0);\n * }\n * p.predict([0, 0]); // 0\n * p.predict([0, 1]); // 0\n * p.predict([1, 0]); // 0\n * p.predict([1, 1]); // 1\n */\nfunction PerceptronModel() {\n // The weights, or coefficients of the model;\n // weights are only populated when training with data.\n this.weights = [];\n // The bias term, or intercept; it is also a weight but\n // it's stored separately for convenience as it is always\n // multiplied by one.\n this.bias = 0;\n}\n\n/**\n * **Predict**: Use an array of features with the weight array and bias\n * to predict whether an example is labeled 0 or 1.\n *\n * @param {Array} features an array of features as numbers\n * @returns {number} 1 if the score is over 0, otherwise 0\n */\nPerceptronModel.prototype.predict = function(features) {\n\n // Only predict if previously trained\n // on the same size feature array(s).\n if (features.length !== this.weights.length) { return null; }\n\n // Calculate the sum of features times weights,\n // with the bias added (implicitly times one).\n var score = 0;\n for (var i = 0; i < this.weights.length; i++) {\n score += this.weights[i] * features[i];\n }\n score += this.bias;\n\n // Classify as 1 if the score is over 0, otherwise 0.\n if (score > 0) {\n return 1;\n } else {\n return 0;\n }\n};\n\n/**\n * **Train** the classifier with a new example, which is\n * a numeric array of features and a 0 or 1 label.\n *\n * @param {Array} features an array of features as numbers\n * @param {number} label either 0 or 1\n * @returns {PerceptronModel} this\n */\nPerceptronModel.prototype.train = function(features, label) {\n // Require that only labels of 0 or 1 are considered.\n if (label !== 0 && label !== 1) { return null; }\n // The length of the feature array determines\n // the length of the weight array.\n // The perceptron will continue learning as long as\n // it keeps seeing feature arrays of the same length.\n // When it sees a new data shape, it initializes.\n if (features.length !== this.weights.length) {\n this.weights = features;\n this.bias = 1;\n }\n // Make a prediction based on current weights.\n var prediction = this.predict(features);\n // Update the weights if the prediction is wrong.\n if (prediction !== label) {\n var gradient = label - prediction;\n for (var i = 0; i < this.weights.length; i++) {\n this.weights[i] += gradient * features[i];\n }\n this.bias += gradient;\n }\n return this;\n};\n\nexport default PerceptronModel;\n","/* @flow */\n\n/**\n * We use `ε`, epsilon, as a stopping criterion when we want to iterate\n * until we're \"close enough\". Epsilon is a very small number: for\n * simple statistics, that number is **0.0001**\n *\n * This is used in calculations like the binomialDistribution, in which\n * the process of finding a value is [iterative](https://en.wikipedia.org/wiki/Iterative_method):\n * it progresses until it is close enough.\n *\n * Below is an example of using epsilon in [gradient descent](https://en.wikipedia.org/wiki/Gradient_descent),\n * where we're trying to find a local minimum of a function's derivative,\n * given by the `fDerivative` method.\n *\n * @example\n * // From calculation, we expect that the local minimum occurs at x=9/4\n * var x_old = 0;\n * // The algorithm starts at x=6\n * var x_new = 6;\n * var stepSize = 0.01;\n *\n * function fDerivative(x) {\n * return 4 * Math.pow(x, 3) - 9 * Math.pow(x, 2);\n * }\n *\n * // The loop runs until the difference between the previous\n * // value and the current value is smaller than epsilon - a rough\n * // meaure of 'close enough'\n * while (Math.abs(x_new - x_old) > ss.epsilon) {\n * x_old = x_new;\n * x_new = x_old - stepSize * fDerivative(x_old);\n * }\n *\n * console.log('Local minimum occurs at', x_new);\n */\nvar epsilon = 0.0001;\n\nexport default epsilon;\n","/* @flow */\n\n/**\n * A [Factorial](https://en.wikipedia.org/wiki/Factorial), usually written n!, is the product of all positive\n * integers less than or equal to n. Often factorial is implemented\n * recursively, but this iterative approach is significantly faster\n * and simpler.\n *\n * @param {number} n input, must be an integer number 1 or greater\n * @returns {number} factorial: n!\n * @throws {Error} if n is less than 0 or not an integer\n * @example\n * factorial(5); // => 120\n */\nfunction factorial(n /*: number */)/*: number */ {\n\n // factorial is mathematically undefined for negative numbers\n if (n < 0) {\n throw new Error('factorial requires a non-negative value');\n }\n\n if (Math.floor(n) !== n) {\n throw new Error('factorial requires an integer input');\n }\n\n // typically you'll expand the factorial function going down, like\n // 5! = 5 * 4 * 3 * 2 * 1. This is going in the opposite direction,\n // counting from 2 up to the number in question, and since anything\n // multiplied by 1 is itself, the loop only needs to start at 2.\n var accumulator = 1;\n for (var i = 2; i <= n; i++) {\n // for each number up to and including the number `n`, multiply\n // the accumulator my that number.\n accumulator *= i;\n }\n return accumulator;\n}\n\nexport default factorial;\n","/* @flow */\n\n// Define series coefficients\nvar COEFFICIENTS = [\n 0.99999999999999709182,\n 57.156235665862923517,\n -59.597960355475491248,\n 14.136097974741747174,\n -0.49191381609762019978,\n 0.33994649984811888699e-4,\n 0.46523628927048575665e-4,\n -0.98374475304879564677e-4,\n 0.15808870322491248884e-3,\n -0.21026444172410488319e-3, 0.21743961811521264320e-3,\n -0.16431810653676389022e-3,\n 0.84418223983852743293e-4,\n -0.26190838401581408670e-4,\n 0.36899182659531622704e-5\n];\n\nvar g = 607 / 128;\nvar LOGSQRT2PI = Math.log(Math.sqrt(2 * Math.PI));\n\n/**\n * Compute the logarithm of the [gamma function](https://en.wikipedia.org/wiki/Gamma_function) of a value using Lanczos' approximation.\n * This function takes as input any real-value n greater than 0.\n * This function is useful for values of n too large for the normal gamma function (n > 165).\n * The code is based on Lanczo's Gamma approximation, defined [here](http://my.fit.edu/~gabdo/gamma.txt).\n *\n * @param {number} n Any real number greater than zero.\n * @returns {number} The logarithm of gamma of the input value.\n *\n * @example\n * gammaln(500); // 2605.1158503617335\n * gammaln(2.4); // 0.21685932244884043 \n */\nfunction gammaln(n /*: number */ ) /*: number */ {\n\n // Return infinity if value not in domain\n if (n <= 0) {\n return Infinity;\n }\n \n // Decrement n, because approximation is defined for n - 1\n n--;\n \n // Create series approximation\n var a = COEFFICIENTS[0];\n \n for (var i = 1; i < 15; i++) {\n a += COEFFICIENTS[i] / (n + i);\n }\n \n var tmp = g + 0.5 + n;\n \n // Return natural logarithm of gamma(n)\n return LOGSQRT2PI + Math.log(a) - tmp + (n + 0.5) * Math.log(tmp);\n}\n\nexport default gammaln;\n","/* @flow */\n\n/**\n * **Percentage Points of the χ2 (Chi-Squared) Distribution**\n *\n * The [χ2 (Chi-Squared) Distribution](http://en.wikipedia.org/wiki/Chi-squared_distribution) is used in the common\n * chi-squared tests for goodness of fit of an observed distribution to a theoretical one, the independence of two\n * criteria of classification of qualitative data, and in confidence interval estimation for a population standard\n * deviation of a normal distribution from a sample standard deviation.\n *\n * Values from Appendix 1, Table III of William W. Hines & Douglas C. Montgomery, \"Probability and Statistics in\n * Engineering and Management Science\", Wiley (1980).\n */\nvar chiSquaredDistributionTable = {\n '1': {\n '0.995': 0,\n '0.99': 0,\n '0.975': 0,\n '0.95': 0,\n '0.9': 0.02,\n '0.5': 0.45,\n '0.1': 2.71,\n '0.05': 3.84,\n '0.025': 5.02,\n '0.01': 6.63,\n '0.005': 7.88\n },\n '2': {\n '0.995': 0.01,\n '0.99': 0.02,\n '0.975': 0.05,\n '0.95': 0.1,\n '0.9': 0.21,\n '0.5': 1.39,\n '0.1': 4.61,\n '0.05': 5.99,\n '0.025': 7.38,\n '0.01': 9.21,\n '0.005': 10.6\n },\n '3': {\n '0.995': 0.07,\n '0.99': 0.11,\n '0.975': 0.22,\n '0.95': 0.35,\n '0.9': 0.58,\n '0.5': 2.37,\n '0.1': 6.25,\n '0.05': 7.81,\n '0.025': 9.35,\n '0.01': 11.34,\n '0.005': 12.84\n },\n '4': {\n '0.995': 0.21,\n '0.99': 0.3,\n '0.975': 0.48,\n '0.95': 0.71,\n '0.9': 1.06,\n '0.5': 3.36,\n '0.1': 7.78,\n '0.05': 9.49,\n '0.025': 11.14,\n '0.01': 13.28,\n '0.005': 14.86\n },\n '5': {\n '0.995': 0.41,\n '0.99': 0.55,\n '0.975': 0.83,\n '0.95': 1.15,\n '0.9': 1.61,\n '0.5': 4.35,\n '0.1': 9.24,\n '0.05': 11.07,\n '0.025': 12.83,\n '0.01': 15.09,\n '0.005': 16.75\n },\n '6': {\n '0.995': 0.68,\n '0.99': 0.87,\n '0.975': 1.24,\n '0.95': 1.64,\n '0.9': 2.2,\n '0.5': 5.35,\n '0.1': 10.65,\n '0.05': 12.59,\n '0.025': 14.45,\n '0.01': 16.81,\n '0.005': 18.55\n },\n '7': {\n '0.995': 0.99,\n '0.99': 1.25,\n '0.975': 1.69,\n '0.95': 2.17,\n '0.9': 2.83,\n '0.5': 6.35,\n '0.1': 12.02,\n '0.05': 14.07,\n '0.025': 16.01,\n '0.01': 18.48,\n '0.005': 20.28\n },\n '8': {\n '0.995': 1.34,\n '0.99': 1.65,\n '0.975': 2.18,\n '0.95': 2.73,\n '0.9': 3.49,\n '0.5': 7.34,\n '0.1': 13.36,\n '0.05': 15.51,\n '0.025': 17.53,\n '0.01': 20.09,\n '0.005': 21.96\n },\n '9': {\n '0.995': 1.73,\n '0.99': 2.09,\n '0.975': 2.7,\n '0.95': 3.33,\n '0.9': 4.17,\n '0.5': 8.34,\n '0.1': 14.68,\n '0.05': 16.92,\n '0.025': 19.02,\n '0.01': 21.67,\n '0.005': 23.59\n },\n '10': {\n '0.995': 2.16,\n '0.99': 2.56,\n '0.975': 3.25,\n '0.95': 3.94,\n '0.9': 4.87,\n '0.5': 9.34,\n '0.1': 15.99,\n '0.05': 18.31,\n '0.025': 20.48,\n '0.01': 23.21,\n '0.005': 25.19\n },\n '11': {\n '0.995': 2.6,\n '0.99': 3.05,\n '0.975': 3.82,\n '0.95': 4.57,\n '0.9': 5.58,\n '0.5': 10.34,\n '0.1': 17.28,\n '0.05': 19.68,\n '0.025': 21.92,\n '0.01': 24.72,\n '0.005': 26.76\n },\n '12': {\n '0.995': 3.07,\n '0.99': 3.57,\n '0.975': 4.4,\n '0.95': 5.23,\n '0.9': 6.3,\n '0.5': 11.34,\n '0.1': 18.55,\n '0.05': 21.03,\n '0.025': 23.34,\n '0.01': 26.22,\n '0.005': 28.3\n },\n '13': {\n '0.995': 3.57,\n '0.99': 4.11,\n '0.975': 5.01,\n '0.95': 5.89,\n '0.9': 7.04,\n '0.5': 12.34,\n '0.1': 19.81,\n '0.05': 22.36,\n '0.025': 24.74,\n '0.01': 27.69,\n '0.005': 29.82\n },\n '14': {\n '0.995': 4.07,\n '0.99': 4.66,\n '0.975': 5.63,\n '0.95': 6.57,\n '0.9': 7.79,\n '0.5': 13.34,\n '0.1': 21.06,\n '0.05': 23.68,\n '0.025': 26.12,\n '0.01': 29.14,\n '0.005': 31.32\n },\n '15': {\n '0.995': 4.6,\n '0.99': 5.23,\n '0.975': 6.27,\n '0.95': 7.26,\n '0.9': 8.55,\n '0.5': 14.34,\n '0.1': 22.31,\n '0.05': 25,\n '0.025': 27.49,\n '0.01': 30.58,\n '0.005': 32.8\n },\n '16': {\n '0.995': 5.14,\n '0.99': 5.81,\n '0.975': 6.91,\n '0.95': 7.96,\n '0.9': 9.31,\n '0.5': 15.34,\n '0.1': 23.54,\n '0.05': 26.3,\n '0.025': 28.85,\n '0.01': 32,\n '0.005': 34.27\n },\n '17': {\n '0.995': 5.7,\n '0.99': 6.41,\n '0.975': 7.56,\n '0.95': 8.67,\n '0.9': 10.09,\n '0.5': 16.34,\n '0.1': 24.77,\n '0.05': 27.59,\n '0.025': 30.19,\n '0.01': 33.41,\n '0.005': 35.72\n },\n '18': {\n '0.995': 6.26,\n '0.99': 7.01,\n '0.975': 8.23,\n '0.95': 9.39,\n '0.9': 10.87,\n '0.5': 17.34,\n '0.1': 25.99,\n '0.05': 28.87,\n '0.025': 31.53,\n '0.01': 34.81,\n '0.005': 37.16\n },\n '19': {\n '0.995': 6.84,\n '0.99': 7.63,\n '0.975': 8.91,\n '0.95': 10.12,\n '0.9': 11.65,\n '0.5': 18.34,\n '0.1': 27.2,\n '0.05': 30.14,\n '0.025': 32.85,\n '0.01': 36.19,\n '0.005': 38.58\n },\n '20': {\n '0.995': 7.43,\n '0.99': 8.26,\n '0.975': 9.59,\n '0.95': 10.85,\n '0.9': 12.44,\n '0.5': 19.34,\n '0.1': 28.41,\n '0.05': 31.41,\n '0.025': 34.17,\n '0.01': 37.57,\n '0.005': 40\n },\n '21': {\n '0.995': 8.03,\n '0.99': 8.9,\n '0.975': 10.28,\n '0.95': 11.59,\n '0.9': 13.24,\n '0.5': 20.34,\n '0.1': 29.62,\n '0.05': 32.67,\n '0.025': 35.48,\n '0.01': 38.93,\n '0.005': 41.4\n },\n '22': {\n '0.995': 8.64,\n '0.99': 9.54,\n '0.975': 10.98,\n '0.95': 12.34,\n '0.9': 14.04,\n '0.5': 21.34,\n '0.1': 30.81,\n '0.05': 33.92,\n '0.025': 36.78,\n '0.01': 40.29,\n '0.005': 42.8\n },\n '23': {\n '0.995': 9.26,\n '0.99': 10.2,\n '0.975': 11.69,\n '0.95': 13.09,\n '0.9': 14.85,\n '0.5': 22.34,\n '0.1': 32.01,\n '0.05': 35.17,\n '0.025': 38.08,\n '0.01': 41.64,\n '0.005': 44.18\n },\n '24': {\n '0.995': 9.89,\n '0.99': 10.86,\n '0.975': 12.4,\n '0.95': 13.85,\n '0.9': 15.66,\n '0.5': 23.34,\n '0.1': 33.2,\n '0.05': 36.42,\n '0.025': 39.36,\n '0.01': 42.98,\n '0.005': 45.56\n },\n '25': {\n '0.995': 10.52,\n '0.99': 11.52,\n '0.975': 13.12,\n '0.95': 14.61,\n '0.9': 16.47,\n '0.5': 24.34,\n '0.1': 34.28,\n '0.05': 37.65,\n '0.025': 40.65,\n '0.01': 44.31,\n '0.005': 46.93\n },\n '26': {\n '0.995': 11.16,\n '0.99': 12.2,\n '0.975': 13.84,\n '0.95': 15.38,\n '0.9': 17.29,\n '0.5': 25.34,\n '0.1': 35.56,\n '0.05': 38.89,\n '0.025': 41.92,\n '0.01': 45.64,\n '0.005': 48.29\n },\n '27': {\n '0.995': 11.81,\n '0.99': 12.88,\n '0.975': 14.57,\n '0.95': 16.15,\n '0.9': 18.11,\n '0.5': 26.34,\n '0.1': 36.74,\n '0.05': 40.11,\n '0.025': 43.19,\n '0.01': 46.96,\n '0.005': 49.65\n },\n '28': {\n '0.995': 12.46,\n '0.99': 13.57,\n '0.975': 15.31,\n '0.95': 16.93,\n '0.9': 18.94,\n '0.5': 27.34,\n '0.1': 37.92,\n '0.05': 41.34,\n '0.025': 44.46,\n '0.01': 48.28,\n '0.005': 50.99\n },\n '29': {\n '0.995': 13.12,\n '0.99': 14.26,\n '0.975': 16.05,\n '0.95': 17.71,\n '0.9': 19.77,\n '0.5': 28.34,\n '0.1': 39.09,\n '0.05': 42.56,\n '0.025': 45.72,\n '0.01': 49.59,\n '0.005': 52.34\n },\n '30': {\n '0.995': 13.79,\n '0.99': 14.95,\n '0.975': 16.79,\n '0.95': 18.49,\n '0.9': 20.6,\n '0.5': 29.34,\n '0.1': 40.26,\n '0.05': 43.77,\n '0.025': 46.98,\n '0.01': 50.89,\n '0.005': 53.67\n },\n '40': {\n '0.995': 20.71,\n '0.99': 22.16,\n '0.975': 24.43,\n '0.95': 26.51,\n '0.9': 29.05,\n '0.5': 39.34,\n '0.1': 51.81,\n '0.05': 55.76,\n '0.025': 59.34,\n '0.01': 63.69,\n '0.005': 66.77\n },\n '50': {\n '0.995': 27.99,\n '0.99': 29.71,\n '0.975': 32.36,\n '0.95': 34.76,\n '0.9': 37.69,\n '0.5': 49.33,\n '0.1': 63.17,\n '0.05': 67.5,\n '0.025': 71.42,\n '0.01': 76.15,\n '0.005': 79.49\n },\n '60': {\n '0.995': 35.53,\n '0.99': 37.48,\n '0.975': 40.48,\n '0.95': 43.19,\n '0.9': 46.46,\n '0.5': 59.33,\n '0.1': 74.4,\n '0.05': 79.08,\n '0.025': 83.3,\n '0.01': 88.38,\n '0.005': 91.95\n },\n '70': {\n '0.995': 43.28,\n '0.99': 45.44,\n '0.975': 48.76,\n '0.95': 51.74,\n '0.9': 55.33,\n '0.5': 69.33,\n '0.1': 85.53,\n '0.05': 90.53,\n '0.025': 95.02,\n '0.01': 100.42,\n '0.005': 104.22\n },\n '80': {\n '0.995': 51.17,\n '0.99': 53.54,\n '0.975': 57.15,\n '0.95': 60.39,\n '0.9': 64.28,\n '0.5': 79.33,\n '0.1': 96.58,\n '0.05': 101.88,\n '0.025': 106.63,\n '0.01': 112.33,\n '0.005': 116.32\n },\n '90': {\n '0.995': 59.2,\n '0.99': 61.75,\n '0.975': 65.65,\n '0.95': 69.13,\n '0.9': 73.29,\n '0.5': 89.33,\n '0.1': 107.57,\n '0.05': 113.14,\n '0.025': 118.14,\n '0.01': 124.12,\n '0.005': 128.3\n },\n '100': {\n '0.995': 67.33,\n '0.99': 70.06,\n '0.975': 74.22,\n '0.95': 77.93,\n '0.9': 82.36,\n '0.5': 99.33,\n '0.1': 118.5,\n '0.05': 124.34,\n '0.025': 129.56,\n '0.01': 135.81,\n '0.005': 140.17\n }\n};\n\nexport default chiSquaredDistributionTable;\n","/* @flow */\n\nimport interquartileRange from './interquartile_range';\nimport stddev from './sample_standard_deviation';\n\nvar SQRT_2PI = Math.sqrt(2 * Math.PI);\n\n/**\n * [Well-known kernels](https://en.wikipedia.org/wiki/Kernel_(statistics)#Kernel_functions_in_common_use)\n * @private\n */\nvar kernels /*: {[string]: (number) => number} */ = {\n /**\n * The gaussian kernel.\n * @private\n */\n gaussian: function (u) {\n return Math.exp(-0.5 * u * u) / SQRT_2PI;\n }\n};\n\n/**\n * Well known bandwidth selection methods\n * @private\n */\nvar bandwidthMethods /*: {[string]: (Array) => number} */ = {\n /**\n * The [\"normal reference distribution\"\n * rule-of-thumb](https://stat.ethz.ch/R-manual/R-devel/library/MASS/html/bandwidth.nrd.html),\n * a commonly used version of [Silverman's\n * rule-of-thumb](https://en.wikipedia.org/wiki/Kernel_density_estimation#A_rule-of-thumb_bandwidth_estimator).\n * @private\n */\n nrd: function (x /*: Array */) {\n var s = stddev(x);\n var iqr = interquartileRange(x);\n if (typeof iqr === 'number') {\n s = Math.min(s, iqr / 1.34)\n }\n return 1.06 * s * Math.pow(x.length, -0.2);\n }\n}\n\n/**\n * [Kernel density estimation](https://en.wikipedia.org/wiki/Kernel_density_estimation)\n * is a useful tool for, among other things, estimating the shape of the\n * underlying probability distribution from a sample.\n *\n * @name kernelDensityEstimation\n * @param X sample values\n * @param kernel The kernel function to use. If a function is provided, it should return non-negative values and integrate to 1. Defaults to 'gaussian'.\n * @param bandwidthMethod The \"bandwidth selection\" method to use, or a fixed bandwidth value. Defaults to \"nrd\", the commonly-used [\"normal reference distribution\" rule-of-thumb](https://stat.ethz.ch/R-manual/R-devel/library/MASS/html/bandwidth.nrd.html).\n * @returns {Function} An estimated [probability density function](https://en.wikipedia.org/wiki/Probability_density_function) for the given sample. The returned function runs in `O(X.length)`.\n */\nfunction kernelDensityEstimation(\n X /*: Array */,\n kernel /*: $Keys | ((number) => number) | void*/,\n bandwidthMethod /*: $Keys | number | void*/\n) {\n var kernelFn/*: (number) => number */;\n if (kernel === undefined) {\n kernelFn = kernels.gaussian;\n } else if (typeof kernel === 'string') {\n if (!kernels[kernel]) {\n throw new Error('Unknown kernel \"' + kernel + '\"');\n }\n kernelFn = kernels[kernel];\n } else {\n kernelFn = kernel;\n }\n\n var bandwidth;\n if (typeof bandwidthMethod === 'undefined') {\n bandwidth = bandwidthMethods.nrd(X);\n } else if (typeof bandwidthMethod === 'string') {\n if (!bandwidthMethods[bandwidthMethod]) {\n throw new Error('Unknown bandwidth method \"' + bandwidthMethod + '\"');\n }\n bandwidth = bandwidthMethods[bandwidthMethod](X);\n } else {\n bandwidth = bandwidthMethod;\n }\n\n return function (x /*: number*/) {\n var i = 0;\n var sum = 0;\n for (i = 0; i < X.length; i++) {\n sum += kernelFn((x - X[i]) / bandwidth);\n }\n return sum / bandwidth / X.length;\n }\n}\n\nexport default kernelDensityEstimation;\n","/* @flow */\n\nvar SQRT_2PI = Math.sqrt(2 * Math.PI);\n\nfunction cumulativeDistribution(z) {\n var sum = z,\n tmp = z;\n\n // 15 iterations are enough for 4-digit precision\n for (var i = 1; i < 15; i++) {\n tmp *= z * z / (2 * i + 1);\n sum += tmp;\n }\n return Math.round((0.5 + (sum / SQRT_2PI) * Math.exp(-z * z / 2)) * 1e4) / 1e4;\n}\n\n/**\n * A standard normal table, also called the unit normal table or Z table,\n * is a mathematical table for the values of Φ (phi), which are the values of\n * the cumulative distribution function of the normal distribution.\n * It is used to find the probability that a statistic is observed below,\n * above, or between values on the standard normal distribution, and by\n * extension, any normal distribution.\n *\n * The probabilities are calculated using the\n * [Cumulative distribution function](https://en.wikipedia.org/wiki/Normal_distribution#Cumulative_distribution_function).\n * The table used is the cumulative, and not cumulative from 0 to mean\n * (even though the latter has 5 digits precision, instead of 4).\n */\nvar standardNormalTable/*: Array */ = [];\n\nfor (var z = 0; z <= 3.09; z += 0.01) {\n standardNormalTable.push(cumulativeDistribution(z));\n}\n\nexport default standardNormalTable;\n","/* @flow */\n\n/**\n * **[Gaussian error function](http://en.wikipedia.org/wiki/Error_function)**\n *\n * The `errorFunction(x/(sd * Math.sqrt(2)))` is the probability that a value in a\n * normal distribution with standard deviation sd is within x of the mean.\n *\n * This function returns a numerical approximation to the exact value.\n *\n * @param {number} x input\n * @return {number} error estimation\n * @example\n * errorFunction(1).toFixed(2); // => '0.84'\n */\nfunction errorFunction(x/*: number */)/*: number */ {\n var t = 1 / (1 + 0.5 * Math.abs(x));\n var tau = t * Math.exp(-Math.pow(x, 2) -\n 1.26551223 +\n 1.00002368 * t +\n 0.37409196 * Math.pow(t, 2) +\n 0.09678418 * Math.pow(t, 3) -\n 0.18628806 * Math.pow(t, 4) +\n 0.27886807 * Math.pow(t, 5) -\n 1.13520398 * Math.pow(t, 6) +\n 1.48851587 * Math.pow(t, 7) -\n 0.82215223 * Math.pow(t, 8) +\n 0.17087277 * Math.pow(t, 9));\n if (x >= 0) {\n return 1 - tau;\n } else {\n return tau - 1;\n }\n}\n\nexport default errorFunction;\n","/* @flow */\n\n/**\n * The Inverse [Gaussian error function](http://en.wikipedia.org/wiki/Error_function)\n * returns a numerical approximation to the value that would have caused\n * `errorFunction()` to return x.\n *\n * @param {number} x value of error function\n * @returns {number} estimated inverted value\n */\nfunction inverseErrorFunction(x/*: number */)/*: number */ {\n var a = (8 * (Math.PI - 3)) / (3 * Math.PI * (4 - Math.PI));\n\n var inv = Math.sqrt(Math.sqrt(\n Math.pow(2 / (Math.PI * a) + Math.log(1 - x * x) / 2, 2) -\n Math.log(1 - x * x) / a) -\n (2 / (Math.PI * a) + Math.log(1 - x * x) / 2));\n\n if (x >= 0) {\n return inv;\n } else {\n return -inv;\n }\n}\n\nexport default inverseErrorFunction;\n","/* @flow */\n\n/**\n * [Sign](https://en.wikipedia.org/wiki/Sign_function) is a function\n * that extracts the sign of a real number\n *\n * @param {number} x input value\n * @returns {number} sign value either 1, 0 or -1\n * @throws {TypeError} if the input argument x is not a number\n * @private\n *\n * @example\n * sign(2); // => 1\n */\nfunction sign(x/*: number */)/*: number */ {\n if (typeof x === 'number') {\n if (x < 0) {\n return -1;\n } else if (x === 0) {\n return 0\n } else {\n return 1;\n }\n } else {\n throw new TypeError('not a number');\n }\n}\n\nexport default sign;\n","/* @flow */\n\n/**\n * [Simple linear regression](http://en.wikipedia.org/wiki/Simple_linear_regression)\n * is a simple way to find a fitted line\n * between a set of coordinates. This algorithm finds the slope and y-intercept of a regression line\n * using the least sum of squares.\n *\n * @param {Array>} data an array of two-element of arrays,\n * like `[[0, 1], [2, 3]]`\n * @returns {Object} object containing slope and intersect of regression line\n * @example\n * linearRegression([[0, 0], [1, 1]]); // => { m: 1, b: 0 }\n */\nfunction linearRegression(data/*: Array> */)/*: { m: number, b: number } */ {\n\n var m, b;\n\n // Store data length in a local variable to reduce\n // repeated object property lookups\n var dataLength = data.length;\n\n //if there's only one point, arbitrarily choose a slope of 0\n //and a y-intercept of whatever the y of the initial point is\n if (dataLength === 1) {\n m = 0;\n b = data[0][1];\n } else {\n // Initialize our sums and scope the `m` and `b`\n // variables that define the line.\n var sumX = 0, sumY = 0,\n sumXX = 0, sumXY = 0;\n\n // Use local variables to grab point values\n // with minimal object property lookups\n var point, x, y;\n\n // Gather the sum of all x values, the sum of all\n // y values, and the sum of x^2 and (x*y) for each\n // value.\n //\n // In math notation, these would be SS_x, SS_y, SS_xx, and SS_xy\n for (var i = 0; i < dataLength; i++) {\n point = data[i];\n x = point[0];\n y = point[1];\n\n sumX += x;\n sumY += y;\n\n sumXX += x * x;\n sumXY += x * y;\n }\n\n // `m` is the slope of the regression line\n m = ((dataLength * sumXY) - (sumX * sumY)) /\n ((dataLength * sumXX) - (sumX * sumX));\n\n // `b` is the y-intercept of the line.\n b = (sumY / dataLength) - ((m * sumX) / dataLength);\n }\n\n // Return both values as an object.\n return {\n m: m,\n b: b\n };\n}\n\n\nexport default linearRegression;\n","/* @flow */\n\n/**\n * Given the output of `linearRegression`: an object\n * with `m` and `b` values indicating slope and intercept,\n * respectively, generate a line function that translates\n * x values into y values.\n *\n * @param {Object} mb object with `m` and `b` members, representing\n * slope and intersect of desired line\n * @returns {Function} method that computes y-value at any given\n * x-value on the line.\n * @example\n * var l = linearRegressionLine(linearRegression([[0, 0], [1, 1]]));\n * l(0) // = 0\n * l(2) // = 2\n * linearRegressionLine({ b: 0, m: 1 })(1); // => 1\n * linearRegressionLine({ b: 1, m: 1 })(1); // => 2\n */\nfunction linearRegressionLine(mb/*: { b: number, m: number }*/)/*: Function */ {\n // Return a function that computes a `y` value for each\n // x value it is given, based on the values of `b` and `a`\n // that we just computed.\n return function(x) {\n return mb.b + (mb.m * x);\n };\n}\n\nexport default linearRegressionLine;\n","/* @flow */\n\n/**\n * The [R Squared](http://en.wikipedia.org/wiki/Coefficient_of_determination)\n * value of data compared with a function `f`\n * is the sum of the squared differences between the prediction\n * and the actual value.\n *\n * @param {Array>} x input data: this should be doubly-nested\n * @param {Function} func function called on `[i][0]` values within the dataset\n * @returns {number} r-squared value\n * @example\n * var samples = [[0, 0], [1, 1]];\n * var regressionLine = linearRegressionLine(linearRegression(samples));\n * rSquared(samples, regressionLine); // = 1 this line is a perfect fit\n */\nfunction rSquared(x /*: Array> */, func /*: Function */) /*: number */ {\n if (x.length < 2) { return 1; }\n\n // Compute the average y value for the actual\n // data set in order to compute the\n // _total sum of squares_\n var sum = 0, average;\n for (var i = 0; i < x.length; i++) {\n sum += x[i][1];\n }\n average = sum / x.length;\n\n // Compute the total sum of squares - the\n // squared difference between each point\n // and the average of all points.\n var sumOfSquares = 0;\n for (var j = 0; j < x.length; j++) {\n sumOfSquares += Math.pow(average - x[j][1], 2);\n }\n\n // Finally estimate the error: the squared\n // difference between the estimate and the actual data\n // value at each point.\n var err = 0;\n for (var k = 0; k < x.length; k++) {\n err += Math.pow(x[k][1] - func(x[k][0]), 2);\n }\n\n // As the error grows larger, its ratio to the\n // sum of squares increases and the r squared\n // value grows lower.\n return 1 - err / sumOfSquares;\n}\n\nexport default rSquared;\n","/* @flow */\n\nimport modeSorted from './mode_sorted';\nimport numericSort from './numeric_sort';\n\n/**\n * The [mode](http://bit.ly/W5K4Yt) is the number that appears in a list the highest number of times.\n * There can be multiple modes in a list: in the event of a tie, this\n * algorithm will return the most recently seen mode.\n *\n * This is a [measure of central tendency](https://en.wikipedia.org/wiki/Central_tendency):\n * a method of finding a typical or central value of a set of numbers.\n *\n * This runs on `O(nlog(n))` because it needs to sort the array internally\n * before running an `O(n)` search to find the mode.\n *\n * @param {Array} x input\n * @returns {number} mode\n * @example\n * mode([0, 0, 1]); // => 0\n */\nfunction mode(x /*: Array */)/*:number*/ {\n // Sorting the array lets us iterate through it below and be sure\n // that every time we see a new number it's new and we'll never\n // see the same number twice\n return modeSorted(numericSort(x));\n}\n\nexport default mode;\n","/* @flow */\n/* globals Map: false */\n\n/**\n * The [mode](http://bit.ly/W5K4Yt) is the number that appears in a list the highest number of times.\n * There can be multiple modes in a list: in the event of a tie, this\n * algorithm will return the most recently seen mode.\n *\n * modeFast uses a Map object to keep track of the mode, instead of the approach\n * used with `mode`, a sorted array. As a result, it is faster\n * than `mode` and supports any data type that can be compared with `==`.\n * It also requires a\n * [JavaScript environment with support for Map](https://kangax.github.io/compat-table/es6/#test-Map),\n * and will throw an error if Map is not available.\n *\n * This is a [measure of central tendency](https://en.wikipedia.org/wiki/Central_tendency):\n * a method of finding a typical or central value of a set of numbers.\n *\n * @param {Array<*>} x a sample of one or more data points\n * @returns {?*} mode\n * @throws {ReferenceError} if the JavaScript environment doesn't support Map\n * @throws {Error} if x is empty\n * @example\n * modeFast(['rabbits', 'rabbits', 'squirrels']); // => 'rabbits'\n */\nfunction modeFast/*::*/(x /*: Array */)/*: ?T */ {\n\n // This index will reflect the incidence of different values, indexing\n // them like\n // { value: count }\n var index = new Map();\n\n // A running `mode` and the number of times it has been encountered.\n var mode;\n var modeCount = 0;\n\n for (var i = 0; i < x.length; i++) {\n var newCount = index.get(x[i]);\n if (newCount === undefined) {\n newCount = 1;\n } else {\n newCount++;\n }\n if (newCount > modeCount) {\n mode = x[i];\n modeCount = newCount;\n }\n index.set(x[i], newCount);\n }\n\n if (modeCount === 0) {\n throw new Error('mode requires at last one data point');\n }\n\n return mode;\n}\n\nexport default modeFast;\n","/* @flow */\n\n/**\n * This computes the minimum & maximum number in an array.\n *\n * This runs on `O(n)`, linear time in respect to the array\n *\n * @param {Array} x sample of one or more data points\n * @returns {Array} minimum & maximum value\n * @throws {Error} if the the length of x is less than one\n * @example\n * extent([1, 2, 3, 4]);\n * // => [1, 4]\n */\nfunction extent(x /*: Array */) /*:Array*/ {\n\n if (x.length === 0) {\n throw new Error('extent requires at least one data point');\n }\n\n var min = x[0];\n var max = x[0];\n for (var i = 1; i < x.length; i++) {\n if (x[i] > max) {\n max = x[i];\n }\n if (x[i] < min) {\n min = x[i];\n }\n }\n return [min, max];\n}\n\nexport default extent;\n","/* @flow */\n\n/**\n * The minimum is the lowest number in the array. With a sorted array,\n * the first element in the array is always the smallest, so this calculation\n * can be done in one step, or constant time.\n *\n * @param {Array} x input\n * @returns {number} minimum value\n * @example\n * minSorted([-100, -10, 1, 2, 5]); // => -100\n */\nfunction minSorted(x /*: Array */)/*: number */ {\n return x[0];\n}\n\nexport default minSorted;\n","/* @flow */\n\n/**\n * The maximum is the highest number in the array. With a sorted array,\n * the last element in the array is always the largest, so this calculation\n * can be done in one step, or constant time.\n *\n * @param {Array} x input\n * @returns {number} maximum value\n * @example\n * maxSorted([-100, -10, 1, 2, 5]); // => 5\n */\nfunction maxSorted(x /*: Array */)/*:number*/ {\n return x[x.length - 1];\n}\n\nexport default maxSorted;\n","/* @flow */\n\n/**\n * The extent is the lowest & highest number in the array. With a sorted array,\n * the first element in the array is always the lowest while the last element is always the largest, so this calculation\n * can be done in one step, or constant time.\n *\n * @param {Array} x input\n * @returns {Array} minimum & maximum value\n * @example\n * extentSorted([-100, -10, 1, 2, 5]); // => [-100, 5]\n */\nfunction extentSorted(x /*: Array */)/*:Array*/ {\n return [x[0], x[x.length - 1]];\n}\n\nexport default extentSorted;\n","/* @flow */\n\n/**\n * The simple [sum](https://en.wikipedia.org/wiki/Summation) of an array\n * is the result of adding all numbers together, starting from zero.\n *\n * This runs on `O(n)`, linear time in respect to the array\n *\n * @param {Array} x input\n * @return {number} sum of all input numbers\n * @example\n * sumSimple([1, 2, 3]); // => 6\n */\nfunction sumSimple(x/*: Array */)/*: number */ {\n var value = 0;\n for (var i = 0; i < x.length; i++) {\n value += x[i];\n }\n return value;\n}\n\nexport default sumSimple;\n","/* @flow */\n\n/**\n * The [product](https://en.wikipedia.org/wiki/Product_(mathematics)) of an array\n * is the result of multiplying all numbers together, starting using one as the multiplicative identity.\n *\n * This runs on `O(n)`, linear time in respect to the array\n *\n * @param {Array} x input\n * @return {number} product of all input numbers\n * @example\n * product([1, 2, 3, 4]); // => 24\n */\nfunction product(x/*: Array */)/*: number */ {\n var value = 1;\n for (var i = 0; i < x.length; i++) {\n value *= x[i];\n }\n return value;\n}\n\nexport default product;\n","/* @flow */\n\nimport numericSort from './numeric_sort';\nimport quantileRankSorted from './quantile_rank_sorted';\n\n/**\n * This function returns the quantile in which one would find the given value in\n * the given array. It will require to copy and sort your array beforehand, so\n * if you know your array is already sorted, you would rather use\n * `quantileRankSorted`.\n *\n * @param {Array} x input\n * @returns {number} value value\n * @example\n * quantileRank([4, 3, 1, 2], 3); // => 0.75\n * quantileRank([4, 3, 2, 3, 1], 3); // => 0.7\n * quantileRank([2, 4, 1, 3], 6); // => 1\n * quantileRank([5, 3, 1, 2, 3], 4); // => 0.8\n */\nfunction quantileRank(\n x /*: Array */,\n value /*: number */)/*: number */ {\n\n // Cloning and sorting the array\n var sortedCopy = numericSort(x);\n\n return quantileRankSorted(sortedCopy, value);\n}\n\nexport default quantileRank;\n","/* @flow */\n\n/**\n * Split an array into chunks of a specified size. This function\n * has the same behavior as [PHP's array_chunk](http://php.net/manual/en/function.array-chunk.php)\n * function, and thus will insert smaller-sized chunks at the end if\n * the input size is not divisible by the chunk size.\n *\n * `x` is expected to be an array, and `chunkSize` a number.\n * The `x` array can contain any kind of data.\n *\n * @param {Array} x a sample\n * @param {number} chunkSize size of each output array. must be a positive integer\n * @returns {Array} a chunked array\n * @throws {Error} if chunk size is less than 1 or not an integer\n * @example\n * chunk([1, 2, 3, 4, 5, 6], 2);\n * // => [[1, 2], [3, 4], [5, 6]]\n */\nfunction chunk(x/*:Array*/, chunkSize/*:number*/)/*:?Array>*/ {\n\n // a list of result chunks, as arrays in an array\n var output = [];\n\n // `chunkSize` must be zero or higher - otherwise the loop below,\n // in which we call `start += chunkSize`, will loop infinitely.\n // So, we'll detect and throw in that case to indicate\n // invalid input.\n if (chunkSize < 1) {\n throw new Error('chunk size must be a positive number');\n }\n\n if (Math.floor(chunkSize) !== chunkSize) {\n throw new Error('chunk size must be an integer');\n }\n\n // `start` is the index at which `.slice` will start selecting\n // new array elements\n for (var start = 0; start < x.length; start += chunkSize) {\n\n // for each chunk, slice that part of the array and add it\n // to the output. The `.slice` function does not change\n // the original array.\n output.push(x.slice(start, start + chunkSize));\n }\n return output;\n}\n\nexport default chunk;\n","/* @flow */\n\n/**\n * Sampling with replacement is a type of sampling that allows the same\n * item to be picked out of a population more than once.\n *\n * @param {Array<*>} x an array of any kind of value\n * @param {number} n count of how many elements to take\n * @param {Function} [randomSource=Math.random] an optional entropy source that\n * returns numbers between 0 inclusive and 1 exclusive: the range [0, 1)\n * @return {Array} n sampled items from the population\n * @example\n * var values = [1, 2, 3, 4];\n * sampleWithReplacement(values, 2); // returns 2 random values, like [2, 4];\n */\nfunction sampleWithReplacement/*::*/(\n x/*: Array */,\n n/*: number */,\n randomSource/*: ?Function */) {\n\n if (x.length === 0) {\n return [];\n }\n\n // a custom random number source can be provided if you want to use\n // a fixed seed or another random number generator, like\n // [random-js](https://www.npmjs.org/package/random-js)\n randomSource = randomSource || Math.random;\n\n var length = x.length;\n var sample = [];\n\n for (var i = 0; i < n; i++) {\n var index = Math.floor(randomSource() * length);\n\n sample.push(x[index]);\n }\n\n return sample;\n}\n\nexport default sampleWithReplacement;\n","/* @flow */\n\nimport shuffle from './shuffle';\n\n/**\n * Create a [simple random sample](http://en.wikipedia.org/wiki/Simple_random_sample)\n * from a given array of `n` elements.\n *\n * The sampled values will be in any order, not necessarily the order\n * they appear in the input.\n *\n * @param {Array} x input array. can contain any type\n * @param {number} n count of how many elements to take\n * @param {Function} [randomSource=Math.random] an optional entropy source that\n * returns numbers between 0 inclusive and 1 exclusive: the range [0, 1)\n * @return {Array} subset of n elements in original array\n *\n * @example\n * var values = [1, 2, 4, 5, 6, 7, 8, 9];\n * sample(values, 3); // returns 3 random values, like [2, 5, 8];\n */\nfunction sample/*:: */(\n x /*: Array */,\n n /*: number */,\n randomSource /*: ?Function */) /*: Array */ {\n // shuffle the original array using a fisher-yates shuffle\n var shuffled = shuffle(x, randomSource);\n\n // and then return a subset of it - the first `n` elements.\n return shuffled.slice(0, n);\n}\n\nexport default sample;\n","/* @flow */\n\nimport max from './max';\nimport min from './min';\n\n/**\n * Given an array of x, this will find the extent of the\n * x and return an array of breaks that can be used\n * to categorize the x into a number of classes. The\n * returned array will always be 1 longer than the number of\n * classes because it includes the minimum value.\n *\n * @param {Array} x an array of number values\n * @param {number} nClasses number of desired classes\n * @returns {Array} array of class break positions\n * @example\n * equalIntervalBreaks([1, 2, 3, 4, 5, 6], 4); // => [1, 2.25, 3.5, 4.75, 6]\n */\nfunction equalIntervalBreaks(x/*: Array */, nClasses/*:number*/)/*: Array */ {\n\n if (x.length < 2) {\n return x;\n }\n\n var theMin = min(x);\n var theMax = max(x);\n\n // the first break will always be the minimum value\n // in the xset\n var breaks = [theMin];\n\n // The size of each break is the full range of the x\n // divided by the number of classes requested\n var breakSize = (theMax - theMin) / nClasses;\n\n // In the case of nClasses = 1, this loop won't run\n // and the returned breaks will be [min, max]\n for (var i = 1; i < nClasses; i++) {\n breaks.push(breaks[0] + breakSize * i);\n }\n\n // the last break will always be the\n // maximum.\n breaks.push(theMax);\n\n return breaks;\n}\n\nexport default equalIntervalBreaks;\n","/* @flow */\n\nimport sampleCovariance from './sample_covariance';\nimport sampleStandardDeviation from './sample_standard_deviation';\n\n/**\n * The [correlation](http://en.wikipedia.org/wiki/Correlation_and_dependence) is\n * a measure of how correlated two datasets are, between -1 and 1\n *\n * @param {Array} x first input\n * @param {Array} y second input\n * @returns {number} sample correlation\n * @example\n * sampleCorrelation([1, 2, 3, 4, 5, 6], [2, 2, 3, 4, 5, 60]).toFixed(2);\n * // => '0.69'\n */\nfunction sampleCorrelation(x/*: Array */, y/*: Array */)/*:number*/ {\n var cov = sampleCovariance(x, y),\n xstd = sampleStandardDeviation(x),\n ystd = sampleStandardDeviation(y);\n\n return cov / xstd / ystd;\n}\n\nexport default sampleCorrelation;\n","/* @flow */\n\nimport mean from './mean';\n\n/**\n * [Skewness](http://en.wikipedia.org/wiki/Skewness) is\n * a measure of the extent to which a probability distribution of a\n * real-valued random variable \"leans\" to one side of the mean.\n * The skewness value can be positive or negative, or even undefined.\n *\n * Implementation is based on the adjusted Fisher-Pearson standardized\n * moment coefficient, which is the version found in Excel and several\n * statistical packages including Minitab, SAS and SPSS.\n *\n * @since 4.1.0\n * @param {Array} x a sample of 3 or more data points\n * @returns {number} sample skewness\n * @throws {Error} if x has length less than 3\n * @example\n * sampleSkewness([2, 4, 6, 3, 1]); // => 0.590128656384365\n */\nfunction sampleSkewness(x /*: Array */)/*:number*/ {\n\n if (x.length < 3) {\n throw new Error('sampleSkewness requires at least three data points');\n }\n\n var meanValue = mean(x);\n var tempValue;\n var sumSquaredDeviations = 0;\n var sumCubedDeviations = 0;\n\n for (var i = 0; i < x.length; i++) {\n tempValue = x[i] - meanValue;\n sumSquaredDeviations += tempValue * tempValue;\n sumCubedDeviations += tempValue * tempValue * tempValue;\n }\n\n // this is Bessels' Correction: an adjustment made to sample statistics\n // that allows for the reduced degree of freedom entailed in calculating\n // values from samples rather than complete populations.\n var besselsCorrection = x.length - 1;\n\n // Find the mean value of that list\n var theSampleStandardDeviation = Math.sqrt(sumSquaredDeviations / besselsCorrection);\n\n var n = x.length,\n cubedS = Math.pow(theSampleStandardDeviation, 3);\n\n return n * sumCubedDeviations / ((n - 1) * (n - 2) * cubedS);\n}\n\nexport default sampleSkewness;\n","/* @flow */\n\nimport mean from './mean';\n\n/**\n * [Kurtosis](http://en.wikipedia.org/wiki/Kurtosis) is\n * a measure of the heaviness of a distribution's tails relative to its\n * variance. The kurtosis value can be positive or negative, or even undefined.\n *\n * Implementation is based on Fisher's excess kurtosis definition and uses\n * unbiased moment estimators. This is the version found in Excel and available\n * in several statistical packages, including SAS and SciPy.\n *\n * @param {Array} x a sample of 4 or more data points\n * @returns {number} sample kurtosis\n * @throws {Error} if x has length less than 4\n * @example\n * sampleKurtosis([1, 2, 2, 3, 5]); // => 1.4555765595463122\n */\nfunction sampleKurtosis(x /*: Array */)/*:number*/ {\n\n var n = x.length;\n\n if (n < 4) {\n throw new Error('sampleKurtosis requires at least four data points');\n }\n\n var meanValue = mean(x);\n var tempValue;\n var secondCentralMoment = 0;\n var fourthCentralMoment = 0;\n\n for (var i = 0; i < n; i++) {\n tempValue = x[i] - meanValue;\n secondCentralMoment += tempValue * tempValue;\n fourthCentralMoment += tempValue * tempValue * tempValue * tempValue;\n }\n\n return (n - 1) / ((n - 2) * (n - 3)) *\n (n * (n + 1) * fourthCentralMoment / (secondCentralMoment * secondCentralMoment) - 3 * (n - 1));\n}\n\nexport default sampleKurtosis;\n","/* @flow */\n\n/**\n * Implementation of [Heap's Algorithm](https://en.wikipedia.org/wiki/Heap%27s_algorithm)\n * for generating permutations.\n *\n * @param {Array} elements any type of data\n * @returns {Array} array of permutations\n */\nfunction permutationsHeap/*:: */(elements /*: Array */)/*: Array> */ {\n var indexes = new Array(elements.length);\n var permutations = [elements.slice()];\n\n for (var i = 0; i < elements.length; i++) {\n indexes[i] = 0;\n }\n\n for (i = 0; i < elements.length;) {\n if (indexes[i] < i) {\n\n // At odd indexes, swap from indexes[i] instead\n // of from the beginning of the array\n var swapFrom = 0;\n if (i % 2 !== 0) {\n swapFrom = indexes[i];\n }\n\n // swap between swapFrom and i, using\n // a temporary variable as storage.\n var temp = elements[swapFrom];\n elements[swapFrom] = elements[i];\n elements[i] = temp;\n\n permutations.push(elements.slice());\n indexes[i]++;\n i = 0;\n\n } else {\n indexes[i] = 0;\n i++;\n }\n }\n\n return permutations;\n}\n\nexport default permutationsHeap;\n","/* @flow */\n\n/**\n * Implementation of Combinations\n * Combinations are unique subsets of a collection - in this case, k x from a collection at a time.\n * https://en.wikipedia.org/wiki/Combination\n * @param {Array} x any type of data\n * @param {int} k the number of objects in each group (without replacement)\n * @returns {Array} array of permutations\n * @example\n * combinations([1, 2, 3], 2); // => [[1,2], [1,3], [2,3]]\n */\n\nfunction combinations(\n x/*: Array */,\n k/*: number */)/*: Array> */ {\n var i;\n var subI;\n var combinationList = [];\n var subsetCombinations;\n var next;\n\n for (i = 0; i < x.length; i++) {\n if (k === 1) {\n combinationList.push([x[i]])\n } else {\n subsetCombinations = combinations(x.slice( i + 1, x.length ), k - 1);\n for (subI = 0; subI < subsetCombinations.length; subI++) {\n next = subsetCombinations[subI];\n next.unshift(x[i]);\n combinationList.push(next);\n }\n }\n }\n return combinationList;\n}\n\nexport default combinations;\n","/* @flow */\n\n/**\n * Implementation of [Combinations](https://en.wikipedia.org/wiki/Combination) with replacement\n * Combinations are unique subsets of a collection - in this case, k x from a collection at a time.\n * 'With replacement' means that a given element can be chosen multiple times.\n * Unlike permutation, order doesn't matter for combinations.\n *\n * @param {Array} x any type of data\n * @param {int} k the number of objects in each group (without replacement)\n * @returns {Array} array of permutations\n * @example\n * combinationsReplacement([1, 2], 2); // => [[1, 1], [1, 2], [2, 2]]\n */\nfunction combinationsReplacement(\n x /*: Array */,\n k /*: number */)/*: Array> */ {\n\n var combinationList = [];\n\n for (var i = 0; i < x.length; i++) {\n if (k === 1) {\n // If we're requested to find only one element, we don't need\n // to recurse: just push `x[i]` onto the list of combinations.\n combinationList.push([x[i]])\n } else {\n // Otherwise, recursively find combinations, given `k - 1`. Note that\n // we request `k - 1`, so if you were looking for k=3 combinations, we're\n // requesting k=2. This -1 gets reversed in the for loop right after this\n // code, since we concatenate `x[i]` onto the selected combinations,\n // bringing `k` back up to your requested level.\n // This recursion may go many levels deep, since it only stops once\n // k=1.\n var subsetCombinations = combinationsReplacement(\n x.slice(i, x.length),\n k - 1);\n\n for (var j = 0; j < subsetCombinations.length; j++) {\n combinationList.push([x[i]]\n .concat(subsetCombinations[j]));\n }\n }\n }\n\n return combinationList;\n}\n\nexport default combinationsReplacement;\n","/* @flow */\n\n/**\n * When adding a new value to a list, one does not have to necessary\n * recompute the mean of the list in linear time. They can instead use\n * this function to compute the new mean by providing the current mean,\n * the number of elements in the list that produced it and the new\n * value to add.\n *\n * @since 2.5.0\n * @param {number} mean current mean\n * @param {number} n number of items in the list\n * @param {number} newValue the added value\n * @returns {number} the new mean\n *\n * @example\n * addToMean(14, 5, 53); // => 20.5\n */\nfunction addToMean(mean /*: number*/, n/*: number */, newValue/*: number */)/*: number */ {\n return mean + ((newValue - mean) / (n + 1));\n}\n\nexport default addToMean;\n","/* @flow */\n\nimport combineMeans from './combine_means';\n\n/**\n * When combining two lists of values for which one already knows the variances,\n * one does not have to necessary recompute the variance of the combined lists\n * in linear time. They can instead use this function to compute the combined\n * variance by providing the variance, mean & number of values of the first list\n * and the variance, mean & number of values of the second list.\n *\n * @since 3.0.0\n * @param {number} variance1 variance of the first list\n * @param {number} mean1 mean of the first list\n * @param {number} n1 number of items in the first list\n * @param {number} variance2 variance of the second list\n * @param {number} mean2 mean of the second list\n * @param {number} n2 number of items in the second list\n * @returns {number} the combined mean\n *\n * @example\n * combineVariances(14 / 3, 5, 3, 8 / 3, 4, 3); // => 47 / 12\n */\nfunction combineVariances(\n variance1 /*: number*/,\n mean1 /*: number*/,\n n1/*: number */,\n variance2 /*: number*/,\n mean2 /*: number*/,\n n2/*: number */)/*: number */ {\n\n var newMean = combineMeans(mean1, n1, mean2, n2);\n\n return (\n n1 * (variance1 + Math.pow(mean1 - newMean, 2)) +\n n2 * (variance2 + Math.pow(mean2 - newMean, 2))\n ) / (n1 + n2);\n}\n\nexport default combineVariances;\n","/* @flow */\n\n/**\n * The [Geometric Mean](https://en.wikipedia.org/wiki/Geometric_mean) is\n * a mean function that is more useful for numbers in different\n * ranges.\n *\n * This is the nth root of the input numbers multiplied by each other.\n *\n * The geometric mean is often useful for\n * **[proportional growth](https://en.wikipedia.org/wiki/Geometric_mean#Proportional_growth)**: given\n * growth rates for multiple years, like _80%, 16.66% and 42.85%_, a simple\n * mean will incorrectly estimate an average growth rate, whereas a geometric\n * mean will correctly estimate a growth rate that, over those years,\n * will yield the same end value.\n *\n * This runs on `O(n)`, linear time in respect to the array\n *\n * @param {Array} x sample of one or more data points\n * @returns {number} geometric mean\n * @throws {Error} if x is empty\n * @throws {Error} if x contains a negative number\n * @example\n * var growthRates = [1.80, 1.166666, 1.428571];\n * var averageGrowth = ss.geometricMean(growthRates);\n * var averageGrowthRates = [averageGrowth, averageGrowth, averageGrowth];\n * var startingValue = 10;\n * var startingValueMean = 10;\n * growthRates.forEach(function(rate) {\n * startingValue *= rate;\n * });\n * averageGrowthRates.forEach(function(rate) {\n * startingValueMean *= rate;\n * });\n * startingValueMean === startingValue;\n */\nfunction geometricMean(x /*: Array */)/*: number */ {\n // The mean of no numbers is null\n if (x.length === 0) {\n throw new Error('geometricMean requires at least one data point');\n }\n\n // the starting value.\n var value = 1;\n\n for (var i = 0; i < x.length; i++) {\n // the geometric mean is only valid for positive numbers\n if (x[i] <= 0) {\n throw new Error('geometricMean requires only positive numbers as input');\n }\n\n // repeatedly multiply the value by each number\n value *= x[i];\n }\n\n return Math.pow(value, 1 / x.length);\n}\n\nexport default geometricMean;\n","/* @flow */\n\n/**\n * The [Harmonic Mean](https://en.wikipedia.org/wiki/Harmonic_mean) is\n * a mean function typically used to find the average of rates.\n * This mean is calculated by taking the reciprocal of the arithmetic mean\n * of the reciprocals of the input numbers.\n *\n * This is a [measure of central tendency](https://en.wikipedia.org/wiki/Central_tendency):\n * a method of finding a typical or central value of a set of numbers.\n *\n * This runs on `O(n)`, linear time in respect to the array.\n *\n * @param {Array} x sample of one or more data points\n * @returns {number} harmonic mean\n * @throws {Error} if x is empty\n * @throws {Error} if x contains a negative number\n * @example\n * harmonicMean([2, 3]).toFixed(2) // => '2.40'\n */\nfunction harmonicMean(x /*: Array */)/*: number */ {\n // The mean of no numbers is null\n if (x.length === 0) {\n throw new Error('harmonicMean requires at least one data point');\n }\n\n var reciprocalSum = 0;\n\n for (var i = 0; i < x.length; i++) {\n // the harmonic mean is only valid for positive numbers\n if (x[i] <= 0) {\n throw new Error('harmonicMean requires only positive numbers as input');\n }\n\n reciprocalSum += 1 / x[i];\n }\n\n // divide n by the the reciprocal sum\n return x.length / reciprocalSum;\n}\n\nexport default harmonicMean;\n","/* @flow */\n\nimport quantileSorted from './quantile_sorted';\n\n/**\n * The [median](http://en.wikipedia.org/wiki/Median) is\n * the middle number of a list. This is often a good indicator of 'the middle'\n * when there are outliers that skew the `mean()` value.\n * This is a [measure of central tendency](https://en.wikipedia.org/wiki/Central_tendency):\n * a method of finding a typical or central value of a set of numbers.\n *\n * The median isn't necessarily one of the elements in the list: the value\n * can be the average of two elements if the list has an even length\n * and the two central values are different.\n *\n * @param {Array} sorted input\n * @returns {number} median value\n * @example\n * medianSorted([10, 2, 5, 100, 2, 1]); // => 52.5\n */\nfunction medianSorted(sorted /*: Array */)/*:number*/ {\n return quantileSorted(sorted, 0.5);\n}\n\nexport default medianSorted;\n","/* @flow */\n\n/**\n * When removing a value from a list, one does not have to necessary\n * recompute the mean of the list in linear time. They can instead use\n * this function to compute the new mean by providing the current mean,\n * the number of elements in the list that produced it and the value to remove.\n *\n * @since 3.0.0\n * @param {number} mean current mean\n * @param {number} n number of items in the list\n * @param {number} value the value to remove\n * @returns {number} the new mean\n *\n * @example\n * subtractFromMean(20.5, 6, 53); // => 14\n */\nfunction subtractFromMean(mean /*: number*/, n/*: number */, value/*: number */)/*: number */ {\n return ((mean * n) - value) / (n - 1);\n}\n\nexport default subtractFromMean;\n","/* @flow */\n\nimport mean from './mean';\nimport standardDeviation from './standard_deviation';\n\n/**\n * This is to compute [a one-sample t-test](https://en.wikipedia.org/wiki/Student%27s_t-test#One-sample_t-test), comparing the mean\n * of a sample to a known value, x.\n *\n * in this case, we're trying to determine whether the\n * population mean is equal to the value that we know, which is `x`\n * here. usually the results here are used to look up a\n * [p-value](http://en.wikipedia.org/wiki/P-value), which, for\n * a certain level of significance, will let you determine that the\n * null hypothesis can or cannot be rejected.\n *\n * @param {Array} x sample of one or more numbers\n * @param {number} expectedValue expected value of the population mean\n * @returns {number} value\n * @example\n * tTest([1, 2, 3, 4, 5, 6], 3.385).toFixed(2); // => '0.16'\n */\nfunction tTest(x/*: Array */, expectedValue/*: number */)/*:number*/ {\n // The mean of the sample\n var sampleMean = mean(x);\n\n // The standard deviation of the sample\n var sd = standardDeviation(x);\n\n // Square root the length of the sample\n var rootN = Math.sqrt(x.length);\n\n // returning the t value\n return (sampleMean - expectedValue) / (sd / rootN);\n}\n\nexport default tTest;\n","/* @flow */\n\nimport mean from './mean';\nimport sampleVariance from './sample_variance';\n\n/**\n * This is to compute [two sample t-test](http://en.wikipedia.org/wiki/Student's_t-test).\n * Tests whether \"mean(X)-mean(Y) = difference\", (\n * in the most common case, we often have `difference == 0` to test if two samples\n * are likely to be taken from populations with the same mean value) with\n * no prior knowledge on standard deviations of both samples\n * other than the fact that they have the same standard deviation.\n *\n * Usually the results here are used to look up a\n * [p-value](http://en.wikipedia.org/wiki/P-value), which, for\n * a certain level of significance, will let you determine that the\n * null hypothesis can or cannot be rejected.\n *\n * `diff` can be omitted if it equals 0.\n *\n * [This is used to confirm or deny](http://www.monarchlab.org/Lab/Research/Stats/2SampleT.aspx)\n * a null hypothesis that the two populations that have been sampled into\n * `sampleX` and `sampleY` are equal to each other.\n *\n * @param {Array} sampleX a sample as an array of numbers\n * @param {Array} sampleY a sample as an array of numbers\n * @param {number} [difference=0]\n * @returns {number|null} test result\n *\n * @example\n * tTestTwoSample([1, 2, 3, 4], [3, 4, 5, 6], 0); // => -2.1908902300206643\n */\nfunction tTestTwoSample(\n sampleX/*: Array */,\n sampleY/*: Array */,\n difference/*: ?number */)/*: ?number */ {\n var n = sampleX.length,\n m = sampleY.length;\n\n // If either sample doesn't actually have any values, we can't\n // compute this at all, so we return `null`.\n if (!n || !m) { return null; }\n\n // default difference (mu) is zero\n if (!difference) {\n difference = 0;\n }\n\n var meanX = mean(sampleX),\n meanY = mean(sampleY),\n sampleVarianceX = sampleVariance(sampleX),\n sampleVarianceY = sampleVariance(sampleY);\n\n if (typeof meanX === 'number' &&\n typeof meanY === 'number' &&\n typeof sampleVarianceX === 'number' &&\n typeof sampleVarianceY === 'number') {\n var weightedVariance = ((n - 1) * sampleVarianceX +\n (m - 1) * sampleVarianceY) / (n + m - 2);\n\n return (meanX - meanY - difference) /\n Math.sqrt(weightedVariance * (1 / n + 1 / m));\n }\n}\n\nexport default tTestTwoSample;\n","/* @flow */\n\nimport factorial from './factorial';\n\n/**\n * Compute the [gamma function](https://en.wikipedia.org/wiki/Gamma_function) of a value using Nemes' approximation.\n * The gamma of n is equivalent to (n-1)!, but unlike the factorial function, gamma is defined for all real n except zero \n * and negative integers (where NaN is returned). Note, the gamma function is also well-defined for complex numbers, \n * though this implementation currently does not handle complex numbers as input values.\n * Nemes' approximation is defined [here](https://arxiv.org/abs/1003.6020) as Theorem 2.2.\n * Negative values use [Euler's reflection formula](https://en.wikipedia.org/wiki/Gamma_function#Properties) for computation.\n *\n * @param {number} n Any real number except for zero and negative integers.\n * @returns {number} The gamma of the input value.\n *\n * @example\n * gamma(11.5); // 11899423.084037038\n * gamma(-11.5); // 2.29575810481609e-8 \n * gamma(5); // 24 \n */\nfunction gamma(n /*: number */ ) /*: number */ {\n\n if (isInteger(n)) {\n if (n <= 0) {\n // gamma not defined for zero or negative integers\n return NaN;\n } else {\n // use factorial for integer inputs \n return factorial(n - 1);\n }\n }\n\n // Decrement n, because approximation is defined for n - 1\n n--;\n\n\n if (n < 0) {\n // Use Euler's reflection formula for negative inputs\n // see: https://en.wikipedia.org/wiki/Gamma_function#Properties\n return Math.PI / (Math.sin(Math.PI * -n) * gamma(-n));\n\n } else {\n // Nemes' expansion approximation\n var seriesCoefficient = Math.pow((n / Math.E), n) * Math.sqrt(2 * Math.PI * (n + (1 / 6)));\n\n var seriesDenom = n + 1 / 4;\n\n var seriesExpansion = (1 +\n (1 / 144) / Math.pow(seriesDenom, 2) -\n (1 / 12960) / Math.pow(seriesDenom, 3) -\n (257 / 207360) / Math.pow(seriesDenom, 4) -\n (52 / 2612736) / Math.pow(seriesDenom, 5) +\n (5741173 / 9405849600) / Math.pow(seriesDenom, 6) +\n (37529 / 18811699200) / Math.pow(seriesDenom, 7));\n\n return seriesCoefficient * seriesExpansion;\n }\n\n}\n\nfunction isInteger(value) {\n return typeof value === 'number' &&\n isFinite(value) &&\n Math.floor(value) === value;\n}\n\nexport default gamma;\n","/* @flow */\n\n/**\n * The [Bernoulli distribution](http://en.wikipedia.org/wiki/Bernoulli_distribution)\n * is the probability discrete\n * distribution of a random variable which takes value 1 with success\n * probability `p` and value 0 with failure\n * probability `q` = 1 - `p`. It can be used, for example, to represent the\n * toss of a coin, where \"1\" is defined to mean \"heads\" and \"0\" is defined\n * to mean \"tails\" (or vice versa). It is\n * a special case of a Binomial Distribution\n * where `n` = 1.\n *\n * @param {number} p input value, between 0 and 1 inclusive\n * @returns {number[]} values of bernoulli distribution at this point\n * @throws {Error} if p is outside 0 and 1\n * @example\n * bernoulliDistribution(0.3); // => [0.7, 0.3]\n */\nfunction bernoulliDistribution(p/*: number */) /*: number[] */ {\n // Check that `p` is a valid probability (0 ≤ p ≤ 1)\n if (p < 0 || p > 1 ) {\n throw new Error('bernoulliDistribution requires probability to be between 0 and 1 inclusive');\n }\n\n return [1 - p, p];\n}\n\nexport default bernoulliDistribution;\n","/* @flow */\n\nimport epsilon from './epsilon';\n\n/**\n * The [Binomial Distribution](http://en.wikipedia.org/wiki/Binomial_distribution) is the discrete probability\n * distribution of the number of successes in a sequence of n independent yes/no experiments, each of which yields\n * success with probability `probability`. Such a success/failure experiment is also called a Bernoulli experiment or\n * Bernoulli trial; when trials = 1, the Binomial Distribution is a Bernoulli Distribution.\n *\n * @param {number} trials number of trials to simulate\n * @param {number} probability\n * @returns {number[]} output\n */\nfunction binomialDistribution(\n trials/*: number */,\n probability/*: number */)/*: ?number[] */ {\n // Check that `p` is a valid probability (0 ≤ p ≤ 1),\n // that `n` is an integer, strictly positive.\n if (probability < 0 || probability > 1 ||\n trials <= 0 || trials % 1 !== 0) {\n return undefined;\n }\n\n // We initialize `x`, the random variable, and `accumulator`, an accumulator\n // for the cumulative distribution function to 0. `distribution_functions`\n // is the object we'll return with the `probability_of_x` and the\n // `cumulativeProbability_of_x`, as well as the calculated mean &\n // variance. We iterate until the `cumulativeProbability_of_x` is\n // within `epsilon` of 1.0.\n var x = 0,\n cumulativeProbability = 0,\n cells = [],\n binomialCoefficient = 1;\n\n // This algorithm iterates through each potential outcome,\n // until the `cumulativeProbability` is very close to 1, at\n // which point we've defined the vast majority of outcomes\n do {\n // a [probability mass function](https://en.wikipedia.org/wiki/Probability_mass_function)\n cells[x] = binomialCoefficient *\n Math.pow(probability, x) * Math.pow(1 - probability, trials - x);\n cumulativeProbability += cells[x];\n x++;\n binomialCoefficient = binomialCoefficient * (trials - x + 1) / x;\n // when the cumulativeProbability is nearly 1, we've calculated\n // the useful range of this distribution\n } while (cumulativeProbability < 1 - epsilon);\n\n return cells;\n}\n\nexport default binomialDistribution;\n","/* @flow */\n\nimport epsilon from './epsilon';\n\n/**\n * The [Poisson Distribution](http://en.wikipedia.org/wiki/Poisson_distribution)\n * is a discrete probability distribution that expresses the probability\n * of a given number of events occurring in a fixed interval of time\n * and/or space if these events occur with a known average rate and\n * independently of the time since the last event.\n *\n * The Poisson Distribution is characterized by the strictly positive\n * mean arrival or occurrence rate, `λ`.\n *\n * @param {number} lambda location poisson distribution\n * @returns {number[]} values of poisson distribution at that point\n */\nfunction poissonDistribution(lambda/*: number */) /*: ?number[] */ {\n // Check that lambda is strictly positive\n if (lambda <= 0) { return undefined; }\n\n // our current place in the distribution\n var x = 0,\n // and we keep track of the current cumulative probability, in\n // order to know when to stop calculating chances.\n cumulativeProbability = 0,\n // the calculated cells to be returned\n cells = [],\n factorialX = 1;\n\n // This algorithm iterates through each potential outcome,\n // until the `cumulativeProbability` is very close to 1, at\n // which point we've defined the vast majority of outcomes\n do {\n // a [probability mass function](https://en.wikipedia.org/wiki/Probability_mass_function)\n cells[x] = (Math.exp(-lambda) * Math.pow(lambda, x)) / factorialX;\n cumulativeProbability += cells[x];\n x++;\n factorialX *= x;\n // when the cumulativeProbability is nearly 1, we've calculated\n // the useful range of this distribution\n } while (cumulativeProbability < 1 - epsilon);\n\n return cells;\n}\n\nexport default poissonDistribution;\n","/* @flow */\n\nimport chiSquaredDistributionTable from './chi_squared_distribution_table';\nimport mean from './mean';\n\n/**\n * The [χ2 (Chi-Squared) Goodness-of-Fit Test](http://en.wikipedia.org/wiki/Goodness_of_fit#Pearson.27s_chi-squared_test)\n * uses a measure of goodness of fit which is the sum of differences between observed and expected outcome frequencies\n * (that is, counts of observations), each squared and divided by the number of observations expected given the\n * hypothesized distribution. The resulting χ2 statistic, `chiSquared`, can be compared to the chi-squared distribution\n * to determine the goodness of fit. In order to determine the degrees of freedom of the chi-squared distribution, one\n * takes the total number of observed frequencies and subtracts the number of estimated parameters. The test statistic\n * follows, approximately, a chi-square distribution with (k − c) degrees of freedom where `k` is the number of non-empty\n * cells and `c` is the number of estimated parameters for the distribution.\n *\n * @param {Array} data\n * @param {Function} distributionType a function that returns a point in a distribution:\n * for instance, binomial, bernoulli, or poisson\n * @param {number} significance\n * @returns {number} chi squared goodness of fit\n * @example\n * // Data from Poisson goodness-of-fit example 10-19 in William W. Hines & Douglas C. Montgomery,\n * // \"Probability and Statistics in Engineering and Management Science\", Wiley (1980).\n * var data1019 = [\n * 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n * 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n * 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n * 2, 2, 2, 2, 2, 2, 2, 2, 2,\n * 3, 3, 3, 3\n * ];\n * ss.chiSquaredGoodnessOfFit(data1019, ss.poissonDistribution, 0.05); //= false\n */\nfunction chiSquaredGoodnessOfFit(\n data/*: Array */,\n distributionType/*: Function */,\n significance/*: number */)/*: boolean */ {\n // Estimate from the sample data, a weighted mean.\n var inputMean = mean(data),\n // Calculated value of the χ2 statistic.\n chiSquared = 0,\n // Degrees of freedom, calculated as (number of class intervals -\n // number of hypothesized distribution parameters estimated - 1)\n degreesOfFreedom,\n // Number of hypothesized distribution parameters estimated, expected to be supplied in the distribution test.\n // Lose one degree of freedom for estimating `lambda` from the sample data.\n c = 1,\n // The hypothesized distribution.\n // Generate the hypothesized distribution.\n hypothesizedDistribution = distributionType(inputMean),\n observedFrequencies = [],\n expectedFrequencies = [],\n k;\n\n // Create an array holding a histogram from the sample data, of\n // the form `{ value: numberOfOcurrences }`\n for (var i = 0; i < data.length; i++) {\n if (observedFrequencies[data[i]] === undefined) {\n observedFrequencies[data[i]] = 0;\n }\n observedFrequencies[data[i]]++;\n }\n\n // The histogram we created might be sparse - there might be gaps\n // between values. So we iterate through the histogram, making\n // sure that instead of undefined, gaps have 0 values.\n for (i = 0; i < observedFrequencies.length; i++) {\n if (observedFrequencies[i] === undefined) {\n observedFrequencies[i] = 0;\n }\n }\n\n // Create an array holding a histogram of expected data given the\n // sample size and hypothesized distribution.\n for (k in hypothesizedDistribution) {\n if (k in observedFrequencies) {\n expectedFrequencies[+k] = hypothesizedDistribution[k] * data.length;\n }\n }\n\n // Working backward through the expected frequencies, collapse classes\n // if less than three observations are expected for a class.\n // This transformation is applied to the observed frequencies as well.\n for (k = expectedFrequencies.length - 1; k >= 0; k--) {\n if (expectedFrequencies[k] < 3) {\n expectedFrequencies[k - 1] += expectedFrequencies[k];\n expectedFrequencies.pop();\n\n observedFrequencies[k - 1] += observedFrequencies[k];\n observedFrequencies.pop();\n }\n }\n\n // Iterate through the squared differences between observed & expected\n // frequencies, accumulating the `chiSquared` statistic.\n for (k = 0; k < observedFrequencies.length; k++) {\n chiSquared += Math.pow(\n observedFrequencies[k] - expectedFrequencies[k], 2) /\n expectedFrequencies[k];\n }\n\n // Calculate degrees of freedom for this test and look it up in the\n // `chiSquaredDistributionTable` in order to\n // accept or reject the goodness-of-fit of the hypothesized distribution.\n degreesOfFreedom = observedFrequencies.length - c - 1;\n return chiSquaredDistributionTable[degreesOfFreedom][significance] < chiSquared;\n}\n\nexport default chiSquaredGoodnessOfFit;\n","/* @flow */\n\n/**\n * The [Z-Score, or Standard Score](http://en.wikipedia.org/wiki/Standard_score).\n *\n * The standard score is the number of standard deviations an observation\n * or datum is above or below the mean. Thus, a positive standard score\n * represents a datum above the mean, while a negative standard score\n * represents a datum below the mean. It is a dimensionless quantity\n * obtained by subtracting the population mean from an individual raw\n * score and then dividing the difference by the population standard\n * deviation.\n *\n * The z-score is only defined if one knows the population parameters;\n * if one only has a sample set, then the analogous computation with\n * sample mean and sample standard deviation yields the\n * Student's t-statistic.\n *\n * @param {number} x\n * @param {number} mean\n * @param {number} standardDeviation\n * @return {number} z score\n * @example\n * zScore(78, 80, 5); // => -0.4\n */\nfunction zScore(x/*:number*/, mean/*:number*/, standardDeviation/*:number*/)/*:number*/ {\n return (x - mean) / standardDeviation;\n}\n\nexport default zScore;\n","/* @flow */\n\nimport standardNormalTable from './standard_normal_table';\n\n/**\n * **[Cumulative Standard Normal Probability](http://en.wikipedia.org/wiki/Standard_normal_table)**\n *\n * Since probability tables cannot be\n * printed for every normal distribution, as there are an infinite variety\n * of normal distributions, it is common practice to convert a normal to a\n * standard normal and then use the standard normal table to find probabilities.\n *\n * You can use `.5 + .5 * errorFunction(x / Math.sqrt(2))` to calculate the probability\n * instead of looking it up in a table.\n *\n * @param {number} z\n * @returns {number} cumulative standard normal probability\n */\nfunction cumulativeStdNormalProbability(z /*:number */)/*:number */ {\n\n // Calculate the position of this value.\n var absZ = Math.abs(z),\n // Each row begins with a different\n // significant digit: 0.5, 0.6, 0.7, and so on. Each value in the table\n // corresponds to a range of 0.01 in the input values, so the value is\n // multiplied by 100.\n index = Math.min(Math.round(absZ * 100), standardNormalTable.length - 1);\n\n // The index we calculate must be in the table as a positive value,\n // but we still pay attention to whether the input is positive\n // or negative, and flip the output value as a last step.\n if (z >= 0) {\n return standardNormalTable[index];\n } else {\n // due to floating-point arithmetic, values in the table with\n // 4 significant figures can nevertheless end up as repeating\n // fractions when they're computed here.\n return +(1 - standardNormalTable[index]).toFixed(4);\n }\n}\n\nexport default cumulativeStdNormalProbability;\n","/* @flow */\n\nimport epsilon from './epsilon';\nimport inverseErrorFunction from './inverse_error_function';\n\n/**\n * The [Probit](http://en.wikipedia.org/wiki/Probit)\n * is the inverse of cumulativeStdNormalProbability(),\n * and is also known as the normal quantile function.\n *\n * It returns the number of standard deviations from the mean\n * where the p'th quantile of values can be found in a normal distribution.\n * So, for example, probit(0.5 + 0.6827/2) ≈ 1 because 68.27% of values are\n * normally found within 1 standard deviation above or below the mean.\n *\n * @param {number} p\n * @returns {number} probit\n */\nfunction probit(p /*: number */)/*: number */ {\n if (p === 0) {\n p = epsilon;\n } else if (p >= 1) {\n p = 1 - epsilon;\n }\n return Math.sqrt(2) * inverseErrorFunction(2 * p - 1);\n}\n\nexport default probit;\n","/* @flow */\n\nimport mean from './mean';\nimport shuffleInPlace from './shuffle_in_place';\n\n/**\n * Conducts a [permutation test](https://en.wikipedia.org/wiki/Resampling_(statistics)#Permutation_tests)\n * to determine if two data sets are *significantly* different from each other, using\n * the difference of means between the groups as the test statistic. \n * The function allows for the following hypotheses:\n * - two_tail = Null hypothesis: the two distributions are equal.\n * - greater = Null hypothesis: observations from sampleX tend to be smaller than those from sampleY.\n * - less = Null hypothesis: observations from sampleX tend to be greater than those from sampleY.\n * [Learn more about one-tail vs two-tail tests.](https://en.wikipedia.org/wiki/One-_and_two-tailed_tests)\n *\n * @param {Array} sampleX first dataset (e.g. treatment data)\n * @param {Array} sampleY second dataset (e.g. control data)\n * @param {string} alternative alternative hypothesis, either 'two_sided' (default), 'greater', or 'less'\n * @param {number} k number of values in permutation distribution. \n * @returns {number} p-value The probability of observing the difference between groups (as or more extreme than what we did), assuming the null hypothesis.\n *\n * @example\n * var control = [2, 5, 3, 6, 7, 2, 5];\n * var treatment = [20, 5, 13, 12, 7, 2, 2];\n * permutationTest(control, treatment); // ~0.1324 \n */\nfunction permutationTest(\n sampleX/*: Array */,\n sampleY/*: Array */,\n alternative/*: string */,\n k/*: number */)/*: ?number */ {\n // Set default arguments\n if (k === undefined) {\n k = 10000;\n }\n if (alternative === undefined) {\n alternative = 'two_side';\n }\n if (alternative !== 'two_side' && alternative !== 'greater' && alternative !== 'less') {\n throw new Error('`alternative` must be either \\'two_side\\', \\'greater\\', or \\'less\\'');\n }\n\n // init pValue\n var pValue;\n\n // get means for each sample\n var meanX = mean(sampleX);\n var meanY = mean(sampleY);\n\n // calculate initial test statistic. This will be our point of comparison with\n // the generated test statistics.\n var testStatistic = meanX - meanY;\n\n // create test-statistic distribution\n var testStatDsn = new Array(k);\n \n // combine datsets so we can easily shuffle later\n var allData = sampleX.concat(sampleY);\n var midIndex = Math.floor(allData.length / 2);\n \n for (var i = 0; i < k; i++) {\n \n // 1. shuffle data assignments\n shuffleInPlace(allData);\n var permLeft = allData.slice(0, midIndex);\n var permRight = allData.slice(midIndex, allData.length);\n\n // 2.re-calculate test statistic\n var permTestStatistic = mean(permLeft) - mean(permRight);\n\n // 3. store test statistic to build test statistic distribution\n testStatDsn[i] = permTestStatistic;\n }\n\n // Calculate p-value depending on alternative\n // For this test, we calculate the percentage of 'extreme' test statistics (subject to our hypothesis)\n // more info on permutation test p-value calculations: https://onlinecourses.science.psu.edu/stat464/node/35\n var numExtremeTStats = 0;\n if (alternative === 'two_side') {\n for (i = 0; i <= k; i++) {\n if (Math.abs(testStatDsn[i]) >= Math.abs(testStatistic)) {\n numExtremeTStats += 1;\n }\n }\n } else if (alternative === 'greater') {\n for (i = 0; i <= k; i++) {\n if (testStatDsn[i] >= testStatistic) {\n numExtremeTStats += 1;\n }\n }\n } else { // alternative === 'less'\n for (i = 0; i <= k; i++) {\n if (testStatDsn[i] <= testStatistic) {\n numExtremeTStats += 1;\n }\n }\n }\n\n pValue = numExtremeTStats / k;\n \n return pValue;\n \n}\n\nexport default permutationTest;\n","/* @flow */\n\nimport sign from './sign';\n\n/**\n * [Bisection method](https://en.wikipedia.org/wiki/Bisection_method) is a root-finding\n * method that repeatedly bisects an interval to find the root.\n *\n * This function returns a numerical approximation to the exact value.\n *\n * @param {Function} func input function\n * @param {number} start - start of interval\n * @param {number} end - end of interval\n * @param {number} maxIterations - the maximum number of iterations\n * @param {number} errorTolerance - the error tolerance\n * @returns {number} estimated root value\n * @throws {TypeError} Argument func must be a function\n *\n * @example\n * bisect(Math.cos,0,4,100,0.003); // => 1.572265625\n */\nfunction bisect(\n func/*: (x: any) => number */,\n start/*: number */,\n end/*: number */,\n maxIterations/*: number */,\n errorTolerance/*: number */)/*:number*/ {\n\n if (typeof func !== 'function') throw new TypeError('func must be a function');\n\n for (var i = 0; i < maxIterations; i++) {\n var output = (start + end) / 2;\n\n if (func(output) === 0 || Math.abs((end - start) / 2) < errorTolerance) {\n return output;\n }\n\n if (sign(func(output)) === sign(func(start))) {\n start = output;\n } else {\n end = output;\n }\n }\n\n throw new Error('maximum number of iterations exceeded');\n}\n\nexport default bisect;\n"],"names":["sum","x","length","transition","correction","i","Math","abs","mean","Error","sumNthPowerDeviations","n","tempValue","meanValue","pow","variance","standardDeviation","v","sqrt","modeSorted","sorted","last","value","NaN","maxSeen","seenThis","numericSort","slice","sort","a","b","min","max","quantileSorted","p","idx","ceil","quickselect","arr","k","left","right","m","z","log","s","exp","sd","floor","t","j","swap","tmp","quantile","copy","Array","isArray","indices","push","quantileIndex","compare","stack","r","pop","l","quantileSelect","multiQuantileSelect","results","len","quantileRankSorted","mid","lo","hi","lowerBound","u","upperBound","interquartileRange","q1","q2","median","medianAbsoluteDeviation","medianValue","medianAbsoluteDeviations","shuffleInPlace","randomSource","random","temporary","index","shuffle","uniqueCountSorted","lastSeenValue","uniqueValueCount","makeMatrix","columns","rows","matrix","column","ssq","sums","sumsOfSquares","sji","muji","fillMatrixColumn","iMin","iMax","cluster","backtrackMatrix","jlow","ssqjlow","ssqj","jhigh","sampleCovariance","y","xmean","ymean","sampleVariance","sampleStandardDeviation","sampleVarianceX","combineMeans","mean1","n1","mean2","n2","rootMeanSquare","sumOfSquares","BayesianClassifier","this","totalCount","data","PerceptronModel","weights","bias","prototype","train","item","category","undefined","score","odds","oddsSums","combination","predict","features","label","prediction","gradient","epsilon","factorial","accumulator","COEFFICIENTS","LOGSQRT2PI","PI","chiSquaredDistributionTable","1","0.995","0.99","0.975","0.95","0.9","0.5","0.1","0.05","0.025","0.01","0.005","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","40","50","60","70","80","90","100","SQRT_2PI","kernels","gaussian","bandwidthMethods","nrd","stddev","iqr","kernelDensityEstimation","X","kernel","bandwidthMethod","kernelFn","bandwidth","cumulativeDistribution","round","standardNormalTable","errorFunction","tau","inverseErrorFunction","inv","sign","TypeError","dataLength","point","sumX","sumY","sumXX","sumXY","mb","func","average","err","mode","Map","modeCount","newCount","get","set","chunkSize","output","start","sample","nClusters","shiftedValue","nValues","shift","fillMatrices","clusters","clusterRight","clusterLeft","nClasses","theMin","theMax","breaks","breakSize","sumSquaredDeviations","sumCubedDeviations","besselsCorrection","theSampleStandardDeviation","secondCentralMoment","fourthCentralMoment","elements","indexes","permutations","swapFrom","temp","combinations","subI","subsetCombinations","next","combinationList","unshift","combinationsReplacement","concat","newValue","variance1","variance2","newMean","reciprocalSum","expectedValue","sampleX","sampleY","difference","meanX","meanY","sampleVarianceY","weightedVariance","gamma","isFinite","sin","seriesDenom","E","Infinity","g","trials","probability","cumulativeProbability","cells","binomialCoefficient","lambda","factorialX","distributionType","significance","degreesOfFreedom","chiSquared","hypothesizedDistribution","observedFrequencies","expectedFrequencies","absZ","toFixed","alternative","testStatistic","testStatDsn","allData","midIndex","permLeft","permRight","permTestStatistic","numExtremeTStats","end","maxIterations","errorTolerance"],"mappings":"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"}