spreadsheet
typeScript/javascript spreadsheet parser, with formulas.
git clone https://git.vogt.world/spreadsheet.git
Log | Files | README.md
← All files
name: dist/Formulas/Statistical.js
-rw-r--r--
82814
   1"use strict";
   2exports.__esModule = true;
   3var ArgsChecker_1 = require("../Utilities/ArgsChecker");
   4var CriteriaFunctionFactory_1 = require("../Utilities/CriteriaFunctionFactory");
   5var Filter_1 = require("../Utilities/Filter");
   6var TypeConverter_1 = require("../Utilities/TypeConverter");
   7var Errors_1 = require("../Errors");
   8var Math_1 = require("./Math");
   9var MathHelpers_1 = require("../Utilities/MathHelpers");
  10var MoreUtils_1 = require("../Utilities/MoreUtils");
  11/**
  12 * Calculates the sum of squares of deviations based on a sample.
  13 * @param values - The values or ranges of the sample.
  14 * @returns {number} sum of squares of deviations
  15 * @constructor
  16 */
  17var DEVSQ = function () {
  18    var values = [];
  19    for (var _i = 0; _i < arguments.length; _i++) {
  20        values[_i] = arguments[_i];
  21    }
  22    ArgsChecker_1.ArgsChecker.checkAtLeastLength(values, 1, "DEVSQ");
  23    var range = Filter_1.Filter.flattenAndThrow(values);
  24    var result = 0;
  25    var count = 0;
  26    for (var i = 0; i < range.length; i++) {
  27        result = result + TypeConverter_1.TypeConverter.valueToNumber(range[i]);
  28        count++;
  29    }
  30    var mean = result / count;
  31    result = 0;
  32    for (var i = 0; i < range.length; i++) {
  33        result += Math.pow((TypeConverter_1.TypeConverter.valueToNumber(range[i]) - mean), 2);
  34    }
  35    return result;
  36};
  37exports.DEVSQ = DEVSQ;
  38/**
  39 * Returns the median value in a numeric dataset.
  40 * @param values - The value(s) or range(s) to consider when calculating the median value.
  41 * @returns {number} the median value of the dataset
  42 * @constructor
  43 */
  44var MEDIAN = function () {
  45    var values = [];
  46    for (var _i = 0; _i < arguments.length; _i++) {
  47        values[_i] = arguments[_i];
  48    }
  49    ArgsChecker_1.ArgsChecker.checkAtLeastLength(values, 1, "MEDIAN");
  50    var sortedArray = [];
  51    values.forEach(function (currentValue) {
  52        if (currentValue instanceof Array) {
  53            if (currentValue.length === 0) {
  54                throw new Errors_1.RefError("Reference does not exist.");
  55            }
  56            var filtered = Filter_1.Filter.filterOutStringValues(currentValue);
  57            sortedArray = sortedArray.concat(filtered);
  58        }
  59        else {
  60            sortedArray.push(TypeConverter_1.TypeConverter.valueToNumber(currentValue));
  61        }
  62    });
  63    sortedArray = sortedArray.sort(function (a, b) {
  64        var aN = TypeConverter_1.TypeConverter.valueToNumber(a);
  65        var bN = TypeConverter_1.TypeConverter.valueToNumber(b);
  66        return aN - bN;
  67    });
  68    if (sortedArray.length === 1) {
  69        return TypeConverter_1.TypeConverter.valueToNumber(sortedArray[0]);
  70    }
  71    if (sortedArray.length === 0) {
  72        throw new Errors_1.NumError("MEDIAN has no valid input data.");
  73    }
  74    // even number of values
  75    if (sortedArray.length % 2 === 0) {
  76        if (sortedArray.length === 2) {
  77            return AVERAGE(sortedArray[0], sortedArray[1]);
  78        }
  79        var top_1 = sortedArray[sortedArray.length / 2];
  80        var bottom = sortedArray[(sortedArray.length / 2) - 1];
  81        return AVERAGE(top_1, bottom);
  82    }
  83    else {
  84        // odd number of values
  85        return sortedArray[Math.round(sortedArray.length / 2) - 1];
  86    }
  87};
  88exports.MEDIAN = MEDIAN;
  89/**
  90 * Returns the numerical average value in a dataset, ignoring text.
  91 * @param values - The values or ranges to consider when calculating the average value.
  92 * @returns {number} the average value of this dataset.
  93 * @constructor
  94 */
  95var AVERAGE = function () {
  96    var values = [];
  97    for (var _i = 0; _i < arguments.length; _i++) {
  98        values[_i] = arguments[_i];
  99    }
 100    ArgsChecker_1.ArgsChecker.checkAtLeastLength(values, 1, "AVERAGE");
 101    var result = 0;
 102    var count = 0;
 103    for (var i = 0; i < values.length; i++) {
 104        if (values[i] instanceof Array) {
 105            if (values[i].length === 0) {
 106                throw new Errors_1.RefError("Reference does not exist.");
 107            }
 108            var filtered = Filter_1.Filter.filterOutStringValues(values[i]);
 109            result = result + Math_1.SUM.apply(this, filtered);
 110            count += filtered.length;
 111        }
 112        else {
 113            result = result + TypeConverter_1.TypeConverter.valueToNumber(values[i]);
 114            count++;
 115        }
 116    }
 117    return result / count;
 118};
 119exports.AVERAGE = AVERAGE;
 120/**
 121 * Calculates the average of the magnitudes of deviations of data from a dataset's mean.
 122 * @param values - The value(s) or range(s)
 123 * @returns {number} average of the magnitudes of deviations of data from a dataset's mean
 124 * @constructor
 125 */
 126var AVEDEV = function () {
 127    var values = [];
 128    for (var _i = 0; _i < arguments.length; _i++) {
 129        values[_i] = arguments[_i];
 130    }
 131    ArgsChecker_1.ArgsChecker.checkAtLeastLength(values, 1, "AVEDEV");
 132    // Sort to array-values, and non-array-values
 133    var arrayValues = [];
 134    var nonArrayValues = [];
 135    for (var i = 0; i < values.length; i++) {
 136        var X = values[i];
 137        if (X instanceof Array) {
 138            if (X.length === 0) {
 139                throw new Errors_1.RefError("Reference does not exist.");
 140            }
 141            arrayValues.push(X);
 142        }
 143        else {
 144            nonArrayValues.push(TypeConverter_1.TypeConverter.valueToNumber(X));
 145        }
 146    }
 147    // Remove string values from array-values, but not from non-array-values, and concat.
 148    var flatValues = Filter_1.Filter.filterOutStringValues(Filter_1.Filter.flatten(arrayValues)).map(function (value) {
 149        return TypeConverter_1.TypeConverter.valueToNumber(value);
 150    }).concat(nonArrayValues);
 151    // Calculating mean
 152    var result = 0;
 153    var count = 0;
 154    for (var i = 0; i < flatValues.length; i++) {
 155        result = result + TypeConverter_1.TypeConverter.valueToNumber(flatValues[i]);
 156        count++;
 157    }
 158    if (count === 0) {
 159        throw new Errors_1.DivZeroError("Evaluation of function AVEDEV caused a devide by zero error.");
 160    }
 161    var mean = result / count;
 162    for (var i = 0; i < flatValues.length; i++) {
 163        flatValues[i] = Math_1.ABS(TypeConverter_1.TypeConverter.valueToNumber(flatValues[i]) - mean);
 164    }
 165    return Math_1.SUM(flatValues) / flatValues.length;
 166};
 167exports.AVEDEV = AVEDEV;
 168/**
 169 * Returns the numerical average value in a dataset, coercing text values in ranges to 0 values.
 170 * @param values - value(s) or range(s) to consider when calculating the average value.
 171 * @returns {number} the numerical average value in a dataset
 172 * @constructor
 173 */
 174var AVERAGEA = function () {
 175    var values = [];
 176    for (var _i = 0; _i < arguments.length; _i++) {
 177        values[_i] = arguments[_i];
 178    }
 179    ArgsChecker_1.ArgsChecker.checkAtLeastLength(values, 1, "AVERAGEA");
 180    var result = 0;
 181    var count = 0;
 182    for (var i = 0; i < values.length; i++) {
 183        if (values[i] instanceof Array) {
 184            if (values[i].length === 0) {
 185                throw new Errors_1.RefError("Reference does not exist.");
 186            }
 187            var filtered = Filter_1.Filter.stringValuesToZeros(values[i]);
 188            result = result + Math_1.SUM.apply(this, filtered);
 189            count += filtered.length;
 190        }
 191        else {
 192            result = result + TypeConverter_1.TypeConverter.valueToNumber(values[i]);
 193            count++;
 194        }
 195    }
 196    if (count === 0) {
 197        throw new Errors_1.DivZeroError("Evaluation of function AVEDEV caused a devide by zero error.");
 198    }
 199    return result / count;
 200};
 201exports.AVERAGEA = AVERAGEA;
 202/**
 203 * Calculates r, the Pearson product-moment correlation coefficient of a dataset. Any text encountered in the arguments
 204 * will be ignored. CORREL is synonymous with PEARSON.
 205 * @param dataY - The range representing the array or matrix of dependent data.
 206 * @param dataX - The range representing the array or matrix of independent data.
 207 * @returns {number} the Pearson product-moment correlation coefficient.
 208 * @constructor
 209 */
 210var CORREL = function (dataY, dataX) {
 211    ArgsChecker_1.ArgsChecker.checkLength(arguments, 2, "CORREL");
 212    if (!Array.isArray(dataY)) {
 213        dataY = [dataY];
 214    }
 215    if (!Array.isArray(dataX)) {
 216        dataX = [dataX];
 217    }
 218    if (dataY.length !== dataX.length) {
 219        throw new Errors_1.NAError("CORREL has mismatched argument count " + dataY + " vs " + dataX + ".");
 220    }
 221    var arr1 = Filter_1.Filter.filterOutNonNumberValues(Filter_1.Filter.flattenAndThrow(dataY));
 222    var arr2 = Filter_1.Filter.filterOutNonNumberValues(Filter_1.Filter.flattenAndThrow(dataX));
 223    var stdevArr1 = MathHelpers_1.stdev(arr1, 1);
 224    var stdevArr2 = MathHelpers_1.stdev(arr2, 1);
 225    if (stdevArr1 === 0 || stdevArr2 === 0) {
 226        throw new Errors_1.DivZeroError("Evaluation of function CORREL caused a divide by zero error.");
 227    }
 228    return MathHelpers_1.covariance(arr1, arr2) / stdevArr1 / stdevArr2;
 229};
 230exports.CORREL = CORREL;
 231/**
 232 * Calculates r, the Pearson product-moment correlation coefficient of a dataset. Any text encountered in the arguments
 233 * will be ignored. PEARSON is synonymous with CORREL.
 234 * @param dataY - The range representing the array or matrix of dependent data.
 235 * @param dataX - The range representing the array or matrix of independent data.
 236 * @returns {number} the Pearson product-moment correlation coefficient.
 237 * @constructor
 238 */
 239var PEARSON = function (dataY, dataX) {
 240    ArgsChecker_1.ArgsChecker.checkLength(arguments, 2, "PEARSON");
 241    return CORREL.apply(this, [dataY, dataX]);
 242};
 243exports.PEARSON = PEARSON;
 244/**
 245 * Returns the value of the exponential distribution function with a specified lambda at a specified value.
 246 * @param x - The input to the exponential distribution function. If cumulative is TRUE then EXPONDIST returns
 247 * the cumulative probability of all values up to x.
 248 * @param lambda - The lambda to specify the exponential distribution function.
 249 * @param cumulative - Whether to use the exponential cumulative distribution.
 250 * @returns {number} value of the exponential distribution function.
 251 * @constructor
 252 */
 253var EXPONDIST = function (x, lambda, cumulative) {
 254    ArgsChecker_1.ArgsChecker.checkLength(arguments, 3, "EXPONDIST");
 255    function cdf(x, rate) {
 256        return x < 0 ? 0 : 1 - Math.exp(-rate * x);
 257    }
 258    function pdf(x, rate) {
 259        return x < 0 ? 0 : rate * Math.exp(-rate * x);
 260    }
 261    x = TypeConverter_1.TypeConverter.firstValueAsNumber(x);
 262    lambda = TypeConverter_1.TypeConverter.firstValueAsNumber(lambda);
 263    cumulative = TypeConverter_1.TypeConverter.firstValueAsBoolean(cumulative);
 264    return (cumulative) ? cdf(x, lambda) : pdf(x, lambda);
 265};
 266exports.EXPONDIST = EXPONDIST;
 267/**
 268 * Calculates the left-tailed F probability distribution (degree of diversity) for two data sets with given input x.
 269 * Alternately called Fisher-Snedecor distribution or Snecdor's F distribution.
 270 * @param x - The input to the F probability distribution function. The value at which to evaluate the function.
 271 * Must be a positive number.
 272 * @param degreesFreedom1 - The numerator degrees of freedom.
 273 * @param degreesFreedom2 - The denominator degrees of freedom.
 274 * @param cumulative - Logical value that determines the form of the function. If true returns the cumulative
 275 * distribution function. If false returns the probability density function.
 276 * @returns {number|boolean} left-tailed F probability distribution
 277 * @constructor
 278 * TODO: This function should be stricter in its return type.
 279 */
 280var FDIST$LEFTTAILED = function (x, degreesFreedom1, degreesFreedom2, cumulative) {
 281    ArgsChecker_1.ArgsChecker.checkLength(arguments, 4, "FDIST$LEFTTAILED");
 282    x = TypeConverter_1.TypeConverter.firstValueAsNumber(x);
 283    if (x < 0) {
 284        throw new Errors_1.NumError("Function F.DIST parameter 1 value is " + x + ". It should be greater than or equal to 0.");
 285    }
 286    var d1 = TypeConverter_1.TypeConverter.firstValueAsNumber(degreesFreedom1);
 287    var d2 = TypeConverter_1.TypeConverter.firstValueAsNumber(degreesFreedom2);
 288    var cum = TypeConverter_1.TypeConverter.firstValueAsBoolean(cumulative);
 289    return (cum) ? MathHelpers_1.cdf(x, d1, d2) : MathHelpers_1.pdf(x, d1, d2);
 290};
 291exports.FDIST$LEFTTAILED = FDIST$LEFTTAILED;
 292/**
 293 * Returns the inverse of the (right-tailed) F probability distribution. If p = FDIST(x,...), then FINV(p,...) = x. The
 294 * F distribution can be used in an F-test that compares the degree of variability in two data sets.
 295 * @param probability - A probability associated with the F cumulative distribution.
 296 * @param degFreedom1 - Required. The numerator degrees of freedom.
 297 * @param degFreedom2 - Required. The denominator degrees of freedom.
 298 * @returns {number} inverse of the (right-tailed) F probability distribution
 299 * @constructor
 300 */
 301var FINV = function (probability, degFreedom1, degFreedom2) {
 302    ArgsChecker_1.ArgsChecker.checkLength(arguments, 3, "FINV");
 303    probability = TypeConverter_1.TypeConverter.firstValueAsNumber(probability);
 304    if (probability <= 0.0 || probability > 1.0) {
 305        throw new Errors_1.NumError("Function FINV parameter 1 value is " + probability
 306            + ". It should be greater than or equal to 0, and less than 1.");
 307    }
 308    var d1 = TypeConverter_1.TypeConverter.firstValueAsNumber(degFreedom1);
 309    var d2 = TypeConverter_1.TypeConverter.firstValueAsNumber(degFreedom2);
 310    return MathHelpers_1.inv(1.0 - probability, d1, d2);
 311};
 312exports.FINV = FINV;
 313/**
 314 * Returns the Fisher transformation of a specified value.
 315 * @param value - The value for which to calculate the Fisher transformation.
 316 * @returns {number} Fisher transformation
 317 * @constructor
 318 */
 319var FISHER = function (value) {
 320    ArgsChecker_1.ArgsChecker.checkLength(arguments, 1, "FISHER");
 321    var x = TypeConverter_1.TypeConverter.firstValueAsNumber(value);
 322    if (x <= -1 || x >= 1) {
 323        throw new Errors_1.NumError("Function FISHER parameter 1 value is " + x + ". Valid values are between -1 and 1 exclusive.");
 324    }
 325    return Math.log((1 + x) / (1 - x)) / 2;
 326};
 327exports.FISHER = FISHER;
 328/**
 329 * Returns the inverse Fisher transformation of a specified value.
 330 * @param value - The value for which to calculate the inverse Fisher transformation.
 331 * @returns {number} inverse Fisher transformation
 332 * @constructor
 333 */
 334var FISHERINV = function (value) {
 335    ArgsChecker_1.ArgsChecker.checkLength(arguments, 1, "FISHERINV");
 336    var y = TypeConverter_1.TypeConverter.firstValueAsNumber(value);
 337    var e2y = Math.exp(2 * y);
 338    return (e2y - 1) / (e2y + 1);
 339};
 340exports.FISHERINV = FISHERINV;
 341/**
 342 * Returns the maximum value in a numeric dataset.
 343 * @param values - The values or range(s) to consider when calculating the maximum value.
 344 * @returns {number} the maximum value of the dataset
 345 * @constructor
 346 */
 347var MAX = function () {
 348    var values = [];
 349    for (var _i = 0; _i < arguments.length; _i++) {
 350        values[_i] = arguments[_i];
 351    }
 352    ArgsChecker_1.ArgsChecker.checkAtLeastLength(values, 1, "MAX");
 353    var maxSoFar = -Infinity;
 354    for (var i = 0; i < values.length; i++) {
 355        if (values[i] instanceof Array) {
 356            if (values[i].length === 0) {
 357                throw new Errors_1.RefError("Reference does not exist.");
 358            }
 359            var filtered = Filter_1.Filter.filterOutStringValues(values[i]);
 360            if (filtered.length !== 0) {
 361                maxSoFar = Math.max(MAX.apply(this, filtered), maxSoFar);
 362            }
 363        }
 364        else {
 365            maxSoFar = Math.max(TypeConverter_1.TypeConverter.valueToNumber(values[i]), maxSoFar);
 366        }
 367    }
 368    return maxSoFar;
 369};
 370exports.MAX = MAX;
 371/**
 372 * Returns the maximum numeric value in a dataset.
 373 * @param values - The value(s) or range(s) to consider when calculating the maximum value.
 374 * @returns {number} maximum value of the dataset
 375 * @constructor
 376 */
 377var MAXA = function () {
 378    var values = [];
 379    for (var _i = 0; _i < arguments.length; _i++) {
 380        values[_i] = arguments[_i];
 381    }
 382    ArgsChecker_1.ArgsChecker.checkAtLeastLength(values, 1, "MAXA");
 383    var maxSoFar = -Infinity;
 384    var filteredValues = Filter_1.Filter.stringValuesToZeros(values);
 385    for (var i = 0; i < filteredValues.length; i++) {
 386        if (filteredValues[i] instanceof Array) {
 387            if (values[i].length === 0) {
 388                throw new Errors_1.RefError("Reference does not exist.");
 389            }
 390            var filtered = Filter_1.Filter.stringValuesToZeros(filteredValues[i]);
 391            if (filtered.length !== 0) {
 392                maxSoFar = Math.max(MAXA.apply(this, filtered), maxSoFar);
 393            }
 394        }
 395        else {
 396            maxSoFar = Math.max(TypeConverter_1.TypeConverter.valueToNumber(filteredValues[i]), maxSoFar);
 397        }
 398    }
 399    return maxSoFar;
 400};
 401exports.MAXA = MAXA;
 402/**
 403 * Returns the minimum value in a numeric dataset.
 404 * @param values - The value(s) or range(s) to consider when calculating the minimum value.
 405 * @returns {number} the minimum value of the dataset
 406 * @constructor
 407 */
 408var MIN = function () {
 409    var values = [];
 410    for (var _i = 0; _i < arguments.length; _i++) {
 411        values[_i] = arguments[_i];
 412    }
 413    ArgsChecker_1.ArgsChecker.checkAtLeastLength(values, 1, "MIN");
 414    var minSoFar = Infinity;
 415    for (var i = 0; i < values.length; i++) {
 416        if (values[i] instanceof Array) {
 417            if (values[i].length === 0) {
 418                throw new Errors_1.RefError("Reference does not exist.");
 419            }
 420            var filtered = Filter_1.Filter.filterOutStringValues(values[i]);
 421            if (filtered.length !== 0) {
 422                minSoFar = Math.min(MIN.apply(this, filtered), minSoFar);
 423            }
 424        }
 425        else {
 426            minSoFar = Math.min(TypeConverter_1.TypeConverter.valueToNumber(values[i]), minSoFar);
 427        }
 428    }
 429    return minSoFar;
 430};
 431exports.MIN = MIN;
 432/**
 433 * Returns the minimum numeric value in a dataset.
 434 * @param values - The value(s) or range(s) to consider when calculating the minimum value.
 435 * @returns {number} the minimum value in the dataset
 436 * @constructor
 437 */
 438var MINA = function () {
 439    var values = [];
 440    for (var _i = 0; _i < arguments.length; _i++) {
 441        values[_i] = arguments[_i];
 442    }
 443    ArgsChecker_1.ArgsChecker.checkAtLeastLength(values, 1, "MINA");
 444    return MIN.apply(this, values);
 445};
 446exports.MINA = MINA;
 447/**
 448 * Returns the average of a range depending on criteria.
 449 * @param criteriaRange - The range to check against criterion.
 450 * @param criterion - The pattern or test to apply to criteria_range.
 451 * @param averageRange - [optional] The range to average. If not included, criteria_range is used for the
 452 * average instead.
 453 * @returns {number}
 454 * @constructor
 455 * TODO: This needs to also accept a third parameter "average_range"
 456 */
 457var AVERAGEIF = function (criteriaRange, criterion, averageRange) {
 458    ArgsChecker_1.ArgsChecker.checkLength(arguments, 2, "AVERAGEIF");
 459    var range = Filter_1.Filter.flatten(criteriaRange);
 460    var criteriaEvaluation = CriteriaFunctionFactory_1.CriteriaFunctionFactory.createCriteriaFunction(criterion);
 461    var result = 0;
 462    var count = 0;
 463    for (var i = 0; i < range.length; i++) {
 464        var val = TypeConverter_1.TypeConverter.valueToNumber(range[i]);
 465        if (criteriaEvaluation(val)) {
 466            result = result + val;
 467            count++;
 468        }
 469    }
 470    if (count === 0) {
 471        throw new Errors_1.DivZeroError("Evaluation of function AVERAGEIF caused a divide by zero error.");
 472    }
 473    return result / count;
 474};
 475exports.AVERAGEIF = AVERAGEIF;
 476/**
 477 * Returns the a count of the number of numeric values in a dataset.
 478 * @param values - The values or ranges to consider when counting.
 479 * @returns {number} number of numeric values in a dataset.
 480 * @constructor
 481 */
 482var COUNT = function () {
 483    var values = [];
 484    for (var _i = 0; _i < arguments.length; _i++) {
 485        values[_i] = arguments[_i];
 486    }
 487    ArgsChecker_1.ArgsChecker.checkAtLeastLength(values, 1, "COUNT");
 488    var count = 0;
 489    for (var i = 0; i < values.length; i++) {
 490        if (values[i] instanceof Array) {
 491            if (values[i].length > 0) {
 492                count += COUNT.apply(this, values[i]);
 493            }
 494        }
 495        else if (TypeConverter_1.TypeConverter.canCoerceToNumber(values[i])) {
 496            count++;
 497        }
 498    }
 499    return count;
 500};
 501exports.COUNT = COUNT;
 502/**
 503 * Returns the a count of the number of values in a dataset.
 504 * @param values - The values or ranges to consider when counting.
 505 * @returns {number} number of values in a dataset.
 506 * @constructor
 507 */
 508var COUNTA = function () {
 509    var values = [];
 510    for (var _i = 0; _i < arguments.length; _i++) {
 511        values[_i] = arguments[_i];
 512    }
 513    ArgsChecker_1.ArgsChecker.checkAtLeastLength(values, 1, "COUNTA");
 514    var count = 0;
 515    for (var i = 0; i < values.length; i++) {
 516        if (values[i] instanceof Array) {
 517            if (values[i].length > 0) {
 518                count += COUNTA.apply(this, values[i]);
 519            }
 520            else {
 521                count++;
 522            }
 523        }
 524        else {
 525            count++;
 526        }
 527    }
 528    return count;
 529};
 530exports.COUNTA = COUNTA;
 531/**
 532 * Returns the value at a given percentile of a set of data.
 533 * @param data -  The array or range containing the dataset to consider.
 534 * @param percent - percentile to be calculated and returned.
 535 * @returns {number}
 536 * @constructor
 537 */
 538var PERCENTILE = function (data, percent) {
 539    ArgsChecker_1.ArgsChecker.checkLength(arguments, 2, "PERCENTILE");
 540    var p = TypeConverter_1.TypeConverter.firstValueAsNumber(percent);
 541    if (p < 0 || p > 1) {
 542        throw new Errors_1.NumError("Function PERCENTILE parameter 2 value " + p + " is out of range.");
 543    }
 544    var range = Filter_1.Filter.flattenAndThrow(data).sort(function (a, b) {
 545        return a - b;
 546    }).map(function (value) {
 547        return TypeConverter_1.TypeConverter.valueToNumber(value);
 548    });
 549    var n = range.length;
 550    var l = p * (n - 1);
 551    var fl = Math.floor(l);
 552    return MathHelpers_1.cleanFloat((l === fl) ? range[l] : range[fl] + (l - fl) * (range[fl + 1] - range[fl]));
 553};
 554exports.PERCENTILE = PERCENTILE;
 555/**
 556 * Returns a value nearest to a specified quartile of a set of data.
 557 * @param data -  The array or range containing the set of data to consider.
 558 * @param quartile - Which quartile value to return. 0 returns 0 percent mark, 1 returns 25 percent mark, 2 returns 50
 559 * percent mark, 3 returns 75 percent mark, 4 returns 100 percent mark.
 560 * @constructor
 561 */
 562var QUARTILE = function (data, quartile) {
 563    ArgsChecker_1.ArgsChecker.checkLength(arguments, 2, "QUARTILE");
 564    var q = TypeConverter_1.TypeConverter.firstValueAsNumber(quartile);
 565    if (q < 0 || q > 4) {
 566        throw new Errors_1.NumError("Function QUARTILE parameter 2 value " + q + " is out of range.");
 567    }
 568    var range = Filter_1.Filter.flattenAndThrow(data).sort(function (a, b) {
 569        return a - b;
 570    }).map(function (value) {
 571        return TypeConverter_1.TypeConverter.valueToNumber(value);
 572    });
 573    switch (q) {
 574        case 0:
 575            return PERCENTILE(range, 0);
 576        case 1:
 577            return PERCENTILE(range, 0.25);
 578        case 2:
 579            return PERCENTILE(range, 0.5);
 580        case 3:
 581            return PERCENTILE(range, 0.75);
 582        case 4:
 583            return PERCENTILE(range, 1);
 584    }
 585};
 586exports.QUARTILE = QUARTILE;
 587/**
 588 * Calculates the standard deviation of a range, ignoring string values, regardless of whether they can be converted to
 589 * numbers.
 590 * @param values - Range of sample.
 591 * @returns {number}
 592 * @constructor
 593 */
 594var STDEV = function () {
 595    var values = [];
 596    for (var _i = 0; _i < arguments.length; _i++) {
 597        values[_i] = arguments[_i];
 598    }
 599    ArgsChecker_1.ArgsChecker.checkAtLeastLength(arguments, 1, "STDEV");
 600    var range = Filter_1.Filter.flattenAndThrow(values);
 601    var n = range.length;
 602    var sigma = 0;
 603    var count = 0;
 604    var mean = AVERAGE(range);
 605    for (var i = 0; i < n; i++) {
 606        var value = TypeConverter_1.TypeConverter.firstValue(range[i]);
 607        if (typeof value !== "string") {
 608            sigma += Math.pow(TypeConverter_1.TypeConverter.valueToNumber(value) - mean, 2);
 609            count++;
 610        }
 611    }
 612    return Math.sqrt(sigma / (count - 1));
 613};
 614exports.STDEV = STDEV;
 615/**
 616 * Calculates the standard deviation of a range, converting string values to numbers, if possible. If a value cannot
 617 * be converted to a number, formula will throw a value error.
 618 * @param values - Range of sample.
 619 * @returns {number}
 620 * @constructor
 621 */
 622var STDEVA = function () {
 623    var values = [];
 624    for (var _i = 0; _i < arguments.length; _i++) {
 625        values[_i] = arguments[_i];
 626    }
 627    ArgsChecker_1.ArgsChecker.checkAtLeastLength(arguments, 1, "STDEVA");
 628    var range = Filter_1.Filter.flattenAndThrow(values).map(function (value) {
 629        return TypeConverter_1.TypeConverter.firstValueAsNumber(value);
 630    });
 631    var n = range.length;
 632    var sigma = 0;
 633    var m = MathHelpers_1.mean(range);
 634    for (var i = 0; i < n; i++) {
 635        sigma += Math.pow(range[i] - m, 2);
 636    }
 637    return Math.sqrt(sigma / (n - 1));
 638};
 639exports.STDEVA = STDEVA;
 640/**
 641 * Calculates the standard deviation of an entire population, ignoring string values, regardless of whether they can be
 642 * converted to numbers.
 643 * @param values - Entire sample.
 644 * @returns {number}
 645 * @constructor
 646 */
 647var STDEVP = function () {
 648    var values = [];
 649    for (var _i = 0; _i < arguments.length; _i++) {
 650        values[_i] = arguments[_i];
 651    }
 652    ArgsChecker_1.ArgsChecker.checkAtLeastLength(arguments, 1, "STDEVP");
 653    var range = Filter_1.Filter.flattenAndThrow(values);
 654    var n = range.length;
 655    var sigma = 0;
 656    var count = 0;
 657    var m = AVERAGE(range);
 658    for (var i = 0; i < n; i++) {
 659        var value = TypeConverter_1.TypeConverter.firstValue(range[i]);
 660        if (typeof value !== "string") {
 661            sigma += Math.pow(value - m, 2);
 662            count++;
 663        }
 664    }
 665    return Math.sqrt(sigma / count);
 666};
 667exports.STDEVP = STDEVP;
 668/**
 669 * Calculates the standard deviation of an entire population, including text and boolean values, if possible. If a value
 670 * cannot be converted to a number, formula will throw a value error.
 671 * @param values - Entire sample.
 672 * @returns {number}
 673 * @constructor
 674 */
 675var STDEVPA = function () {
 676    var values = [];
 677    for (var _i = 0; _i < arguments.length; _i++) {
 678        values[_i] = arguments[_i];
 679    }
 680    ArgsChecker_1.ArgsChecker.checkAtLeastLength(arguments, 1, "STDEVPA");
 681    var range = Filter_1.Filter.flattenAndThrow(values).map(function (value) {
 682        return TypeConverter_1.TypeConverter.firstValueAsNumber(value);
 683    });
 684    var n = range.length;
 685    var sigma = 0;
 686    var count = 0;
 687    var m = AVERAGE(range);
 688    for (var i = 0; i < n; i++) {
 689        var value = TypeConverter_1.TypeConverter.firstValue(range[i]);
 690        if (typeof value !== "string") {
 691            sigma += Math.pow(value - m, 2);
 692            count++;
 693        }
 694    }
 695    return Math.sqrt(sigma / count);
 696};
 697exports.STDEVPA = STDEVPA;
 698/**
 699 * Returns the mean value of a range excluding some percentage of the range on the high and low ends of the range.
 700 * @param range - Array or range to consider.
 701 * @param percent - The portion of the data to exclude on both ends of the range.
 702 * @returns {number}
 703 * @constructor
 704 */
 705var TRIMMEAN = function (range, percent) {
 706    ArgsChecker_1.ArgsChecker.checkLength(arguments, 2, "TRIMMEAN");
 707    var p = TypeConverter_1.TypeConverter.firstValueAsNumber(percent);
 708    if (p < 0) {
 709        throw new Errors_1.NumError("Function TRIMMEAN parameter 2 value is " + p + ". It should be greater than or equal to 0.");
 710    }
 711    if (p >= 1) {
 712        throw new Errors_1.NumError("Function TRIMMEAN parameter 2 value is " + p + ". It should be less than 1.");
 713    }
 714    var data = Filter_1.Filter.flattenAndThrow(range).sort(function (a, b) {
 715        return a - b;
 716    }).map(function (value) {
 717        return TypeConverter_1.TypeConverter.valueToNumber(value);
 718    });
 719    if (data.length === 0) {
 720        throw new Errors_1.RefError("TRIMMEAN has no valid input data.");
 721    }
 722    var trim = Math_1.FLOOR(data.length * p, 2) / 2;
 723    var tmp = data.slice(trim, data.length);
 724    return MathHelpers_1.mean(tmp.slice(0, tmp.length - trim));
 725};
 726exports.TRIMMEAN = TRIMMEAN;
 727/**
 728 * Returns the slope of the line calculated from linear regression of a range. Any text values passed in will be ignored
 729 * @param rangeY - The range or array representing the dependent data.
 730 * @param rangeX - The range or array representing the independent data.
 731 * @constructor
 732 */
 733var SLOPE = function (rangeY, rangeX) {
 734    ArgsChecker_1.ArgsChecker.checkLength(arguments, 2, "SLOPE");
 735    var dataX = Filter_1.Filter.flattenAndThrow(rangeX).filter(function (value) {
 736        return typeof value !== "string";
 737    }).map(function (value) {
 738        return TypeConverter_1.TypeConverter.valueToNumber(value);
 739    });
 740    var dataY = Filter_1.Filter.flattenAndThrow(rangeY).filter(function (value) {
 741        return typeof value !== "string";
 742    }).map(function (value) {
 743        return TypeConverter_1.TypeConverter.valueToNumber(value);
 744    });
 745    if (dataX.length !== dataY.length) {
 746        throw new Errors_1.NAError("SLOPE has mismatched argument count " + dataX.length + " vs " + dataY.length + ".");
 747    }
 748    var xmean = MathHelpers_1.mean(dataX);
 749    var ymean = MathHelpers_1.mean(dataY);
 750    var n = dataX.length;
 751    var num = 0;
 752    var den = 0;
 753    for (var i = 0; i < n; i++) {
 754        num += (dataX[i] - xmean) * (dataY[i] - ymean);
 755        den += Math.pow(dataX[i] - xmean, 2);
 756    }
 757    if (den === 0) {
 758        throw new Errors_1.DivZeroError("Evaluation of function SLOPE caused a divide by zero error.");
 759    }
 760    return num / den;
 761};
 762exports.SLOPE = SLOPE;
 763/**
 764 * Returns the normalized equivalent of a random variable given mean and standard deviation of the distribution.
 765 * @param value - Value to be standardized.
 766 * @param meanValue - Arithmetic mean of the distribution
 767 * @param std - The standard deviation of the distribution or range.
 768 * @returns {number}
 769 * @constructor
 770 */
 771var STANDARDIZE = function (value, meanValue, std) {
 772    ArgsChecker_1.ArgsChecker.checkLength(arguments, 3, "STANDARDIZE");
 773    value = TypeConverter_1.TypeConverter.firstValueAsNumber(value);
 774    meanValue = TypeConverter_1.TypeConverter.firstValueAsNumber(meanValue);
 775    std = TypeConverter_1.TypeConverter.firstValueAsNumber(std);
 776    if (std <= 0) {
 777        throw new Errors_1.NumError("Function STANDARDIZE parameter 3 value is " + std + ". It should be greater than 0.");
 778    }
 779    return (value - meanValue) / std;
 780};
 781exports.STANDARDIZE = STANDARDIZE;
 782/**
 783 * Returns the Nth smallest value in the range, ignoring text values.
 784 * @param range -  Range or data-set to consider.
 785 * @param n - N in 'Nth'.
 786 * @constructor
 787 */
 788var SMALL = function (range, n) {
 789    ArgsChecker_1.ArgsChecker.checkLength(arguments, 2, "SMALL");
 790    var data = Filter_1.Filter.flattenAndThrow(range).filter(function (value) {
 791        return typeof value != "string";
 792    }).map(function (value) {
 793        return TypeConverter_1.TypeConverter.valueToNumber(value);
 794    }).sort(function (a, b) {
 795        return a - b;
 796    });
 797    if (n > data.length || n < 1) {
 798        throw new Errors_1.NumError("Function SMALL parameter 2 value " + n + " is out of range.");
 799    }
 800    return data[n - 1];
 801};
 802exports.SMALL = SMALL;
 803/**
 804 * Returns the Nth largest value in the range, ignoring text values.
 805 * @param range -  Range or data-set to consider.
 806 * @param n - N in 'Nth'.
 807 * @constructor
 808 */
 809var LARGE = function (range, n) {
 810    ArgsChecker_1.ArgsChecker.checkLength(arguments, 2, "LARGE");
 811    var data = Filter_1.Filter.flattenAndThrow(range).filter(function (value) {
 812        return typeof value != "string";
 813    }).map(function (value) {
 814        return TypeConverter_1.TypeConverter.valueToNumber(value);
 815    }).sort(function (a, b) {
 816        return b - a;
 817    });
 818    if (n > data.length || n < 1) {
 819        throw new Errors_1.NumError("Function LARGE parameter 2 value " + n + " is out of range.");
 820    }
 821    return data[n - 1];
 822};
 823exports.LARGE = LARGE;
 824/**
 825 * Returns the kurtosis of a data set or range. Ignores text values.
 826 * @param values - data set or range to calculate. Must be at least 4 values.
 827 * @returns {number}
 828 * @constructor
 829 */
 830var KURT = function () {
 831    var values = [];
 832    for (var _i = 0; _i < arguments.length; _i++) {
 833        values[_i] = arguments[_i];
 834    }
 835    ArgsChecker_1.ArgsChecker.checkAtLeastLength(values, 4, "KURT");
 836    var range = Filter_1.Filter.flattenAndThrow(values).filter(function (value) {
 837        return typeof value !== "string";
 838    }).map(function (value) {
 839        return TypeConverter_1.TypeConverter.valueToNumber(value);
 840    });
 841    if (range.length < 4) {
 842        throw new Errors_1.DivZeroError("KURT requires more values in range. Expected: 4, found: " + range.length + ".");
 843    }
 844    var m = MathHelpers_1.mean(range);
 845    var n = range.length;
 846    var sigma = 0;
 847    for (var i = 0; i < n; i++) {
 848        sigma += Math.pow(range[i] - m, 4);
 849    }
 850    sigma = sigma / Math.pow(MathHelpers_1.stdev(range, true), 4);
 851    return ((n * (n + 1)) / ((n - 1) * (n - 2) * (n - 3))) * sigma - 3 * (n - 1) * (n - 1) / ((n - 2) * (n - 3));
 852};
 853exports.KURT = KURT;
 854/**
 855 * Calculates the y-value at which a line will intersect the y-axis by using known x-values and y-values. Any text
 856 * values will be ignored.
 857 * @param rangeY - Dependent range of values.
 858 * @param rangeX - Independent range of values.
 859 * @returns {number}
 860 * @constructor
 861 */
 862var INTERCEPT = function (rangeY, rangeX) {
 863    ArgsChecker_1.ArgsChecker.checkLength(arguments, 2, "INTERCEPT");
 864    var dataX = Filter_1.Filter.flattenAndThrow(rangeX).filter(function (value) {
 865        return typeof value !== "string";
 866    }).map(function (value) {
 867        return TypeConverter_1.TypeConverter.valueToNumber(value);
 868    });
 869    var dataY = Filter_1.Filter.flattenAndThrow(rangeY).filter(function (value) {
 870        return typeof value !== "string";
 871    }).map(function (value) {
 872        return TypeConverter_1.TypeConverter.valueToNumber(value);
 873    });
 874    if (dataX.length !== dataY.length) {
 875        throw new Errors_1.NAError("INTERCEPT has mismatched argument count " + dataX.length + " vs " + dataY.length + ".");
 876    }
 877    var xMean = MathHelpers_1.mean(dataX);
 878    var yMean = MathHelpers_1.mean(dataY);
 879    var n = dataX.length;
 880    var num = 0;
 881    var den = 0;
 882    for (var i = 0; i < n; i++) {
 883        num += (dataX[i] - xMean) * (dataY[i] - yMean);
 884        den += Math.pow(dataX[i] - xMean, 2);
 885    }
 886    if (den === 0) {
 887        throw new Errors_1.DivZeroError("Evaluation of function INTERCEPT caused a divide by zero error.");
 888    }
 889    var b = num / den;
 890    return yMean - b * xMean;
 891};
 892exports.INTERCEPT = INTERCEPT;
 893/**
 894 * Calculates the a future value using existing x-values and y-values. Any text values will be ignored.
 895 * @param x - The data point for which you would like to predict the value.
 896 * @param rangeY - Dependent range of values.
 897 * @param rangeX - Independent range of values.
 898 * @returns {number}
 899 * @constructor
 900 * TODO: This formula will fail to parse since the first argument is followed by an argument that is an array.
 901 * TODO (continued) This is a known issue.
 902 */
 903var FORECAST = function (x, rangeY, rangeX) {
 904    ArgsChecker_1.ArgsChecker.checkLength(arguments, 3, "FORECAST");
 905    x = TypeConverter_1.TypeConverter.firstValueAsNumber(x);
 906    var dataX = Filter_1.Filter.flattenAndThrow(rangeX).filter(function (value) {
 907        return typeof value !== "string";
 908    }).map(function (value) {
 909        return TypeConverter_1.TypeConverter.valueToNumber(value);
 910    });
 911    var dataY = Filter_1.Filter.flattenAndThrow(rangeY).filter(function (value) {
 912        return typeof value !== "string";
 913    }).map(function (value) {
 914        return TypeConverter_1.TypeConverter.valueToNumber(value);
 915    });
 916    if (dataX.length !== dataY.length) {
 917        throw new Errors_1.NAError("FORECAST has mismatched argument count " + dataX.length + " vs " + dataY.length + ".");
 918    }
 919    var xMean = MathHelpers_1.mean(dataX);
 920    var yMean = MathHelpers_1.mean(dataY);
 921    var n = dataX.length;
 922    var num = 0;
 923    var den = 0;
 924    for (var i = 0; i < n; i++) {
 925        num += (dataX[i] - xMean) * (dataY[i] - yMean);
 926        den += Math.pow(dataX[i] - xMean, 2);
 927    }
 928    if (den === 0) {
 929        throw new Errors_1.DivZeroError("Evaluation of function FORECAST caused a divide by zero error.");
 930    }
 931    var b = num / den;
 932    var a = yMean - b * xMean;
 933    return a + b * x;
 934};
 935exports.FORECAST = FORECAST;
 936/**
 937 * Returns the Poisson distribution for the given number. Functions the same as POISSON.DIST.
 938 * @param x - Number to use.
 939 * @param meanValue - The middle value for the Poisson distribution.
 940 * @param cumulative - [OPTIONAL] - 0 calculates the density function, 1 calculates the distribution. Defaults to 0.
 941 * @returns {number}
 942 * @constructor
 943 */
 944var POISSON = function (x, meanValue, cumulative) {
 945    ArgsChecker_1.ArgsChecker.checkLengthWithin(arguments, 2, 3, "POISSON");
 946    x = TypeConverter_1.TypeConverter.firstValueAsNumber(x);
 947    meanValue = TypeConverter_1.TypeConverter.firstValueAsNumber(meanValue);
 948    cumulative = (cumulative === undefined) ? 0 : TypeConverter_1.TypeConverter.firstValueAsNumber(cumulative);
 949    if (x < 0) {
 950        throw new Errors_1.NumError("Function POISSON parameter 1 value is " + x + ". It should be greater than or equal to 0.");
 951    }
 952    if (meanValue < 0) {
 953        throw new Errors_1.NumError("Function POISSON parameter 2 value is " + x + ". It should be greater than or equal to 0.");
 954    }
 955    function factorial(n) {
 956        return n < 0 ? NaN : MathHelpers_1.gammafn(n + 1);
 957    }
 958    function poissonPDF(k, l) {
 959        return Math.pow(l, k) * Math.exp(-l) / factorial(k);
 960    }
 961    function poissonCDF(x, l) {
 962        var sumarr = [], k = 0;
 963        if (x < 0)
 964            return 0;
 965        for (; k <= x; k++) {
 966            sumarr.push(poissonPDF(k, l));
 967        }
 968        return MathHelpers_1.sum(sumarr);
 969    }
 970    ;
 971    return (cumulative) ? poissonCDF(x, meanValue) : poissonPDF(x, meanValue);
 972};
 973exports.POISSON = POISSON;
 974/**
 975 * Returns the percentage rank (percentile) of the given value in a sample. Functions the same as PERCENTRANK.INC.
 976 * @param data - The array or range of data in the sample.
 977 * @param x - The value.
 978 * @param significance - [OPTIONAL] - The number of significant digits to use in the calculation. Defaults to 3.
 979 * @returns {number}
 980 * @constructor
 981 */
 982var PERCENTRANK = function (data, x, significance) {
 983    ArgsChecker_1.ArgsChecker.checkLengthWithin(arguments, 2, 3, "PERCENTRANK");
 984    data = Filter_1.Filter.flattenAndThrow(data).map(TypeConverter_1.TypeConverter.valueToNumber).sort(function (a, b) {
 985        return a - b;
 986    });
 987    x = TypeConverter_1.TypeConverter.firstValueAsNumber(x);
 988    var uniques = Filter_1.Filter.unique(data);
 989    var n = data.length;
 990    var m = uniques.length;
 991    if (x < uniques[0] || x > uniques[m - 1]) {
 992        throw new Errors_1.NAError("PERCENTRANK does not have valid input data.");
 993    }
 994    if (m === 1 && uniques[0] === x) {
 995        return 1;
 996    }
 997    significance = (typeof significance === 'undefined') ? 3 : TypeConverter_1.TypeConverter.firstValueAsNumber(significance);
 998    var power = Math.pow(10, significance);
 999    var result = 0;
1000    var match = false;
1001    var i = 0;
1002    while (!match && i < m) {
1003        if (x === uniques[i]) {
1004            result = data.indexOf(uniques[i]) / (n - 1);
1005            match = true;
1006        }
1007        else if (x >= uniques[i] && (x < uniques[i + 1] || i === m - 1)) {
1008            result = (data.indexOf(uniques[i]) + (x - uniques[i]) / (uniques[i + 1] - uniques[i])) / (n - 1);
1009            match = true;
1010        }
1011        i++;
1012    }
1013    var v = Math.floor(result * power) / power;
1014    if (isNaN(v)) {
1015        throw new Errors_1.NAError("PERCENTRANK does not have valid input data.");
1016    }
1017    return v;
1018};
1019exports.PERCENTRANK = PERCENTRANK;
1020/**
1021 * Returns the percentage rank (percentile) from 0 to 1 exclusive for a value in a sample.
1022 * @param data - The array or range of data in the sample.
1023 * @param x - The value
1024 * @param significance - [OPTIONAL] - The number of significant digits to use in the calculation. Defaults to 3.
1025 * @returns {number}
1026 * @constructor
1027 */
1028var PERCENTRANK$EXC = function (data, x, significance) {
1029    ArgsChecker_1.ArgsChecker.checkLengthWithin(arguments, 2, 3, "PERCENTRANK.EXC");
1030    data = Filter_1.Filter.flattenAndThrow(data).map(TypeConverter_1.TypeConverter.valueToNumber).sort(function (a, b) {
1031        return a - b;
1032    });
1033    x = TypeConverter_1.TypeConverter.firstValueAsNumber(x);
1034    var uniques = Filter_1.Filter.unique(data);
1035    var n = data.length;
1036    var m = uniques.length;
1037    if (x < uniques[0] || x > uniques[m - 1]) {
1038        throw new Errors_1.NAError("PERCENTRANK.EXC does not have valid input data.");
1039    }
1040    if (m === 1 && uniques[0] === x) {
1041        return 1;
1042    }
1043    significance = (typeof significance === 'undefined') ? 3 : TypeConverter_1.TypeConverter.firstValueAsNumber(significance);
1044    var power = Math.pow(10, significance);
1045    var result = 0;
1046    var match = false;
1047    var i = 0;
1048    while (!match && i < m) {
1049        if (x === uniques[i]) {
1050            result = (data.indexOf(uniques[i]) + 1) / (n + 1);
1051            match = true;
1052        }
1053        else if (x >= uniques[i] && (x < uniques[i + 1] || i === m - 1)) {
1054            result = (data.indexOf(uniques[i]) + 1 + (x - uniques[i]) / (uniques[i + 1] - uniques[i])) / (n + 1);
1055            match = true;
1056        }
1057        i++;
1058    }
1059    var v = Math.floor(result * power) / power;
1060    if (isNaN(v)) {
1061        throw new Errors_1.NAError("PERCENTRANK.EXC does not have valid input data.");
1062    }
1063    return v;
1064};
1065exports.PERCENTRANK$EXC = PERCENTRANK$EXC;
1066/**
1067 * Returns the inverse of the standard normal distribution for the given number.
1068 * @param probability - The probability value.
1069 * @returns {number}
1070 * @constructor
1071 */
1072var NORMSINV = function (probability) {
1073    ArgsChecker_1.ArgsChecker.checkLength(arguments, 1, "NORMSINV");
1074    probability = TypeConverter_1.TypeConverter.firstValueAsNumber(probability);
1075    function erfc(x) {
1076        return 1 - MathHelpers_1.erf(x);
1077    }
1078    function erfcinv(p) {
1079        var j = 0;
1080        var x, err, t, pp;
1081        if (p >= 2)
1082            return -100;
1083        if (p <= 0)
1084            return 100;
1085        pp = (p < 1) ? p : 2 - p;
1086        t = Math.sqrt(-2 * Math.log(pp / 2));
1087        x = -0.70711 * ((2.30753 + t * 0.27061) /
1088            (1 + t * (0.99229 + t * 0.04481)) - t);
1089        for (; j < 2; j++) {
1090            err = erfc(x) - pp;
1091            x += err / (1.12837916709551257 * Math.exp(-x * x) - x * err);
1092        }
1093        return (p < 1) ? x : -x;
1094    }
1095    function inv(p, mean, std) {
1096        return -1.41421356237309505 * std * erfcinv(2 * p) + mean;
1097    }
1098    if (probability <= 0 || probability >= 1) {
1099        throw new Errors_1.NumError("Function NORMSINV parameter 1 value is " + probability +
1100            ". Valid values are between 0 and 1 exclusive.");
1101    }
1102    return inv(probability, 0, 1);
1103};
1104exports.NORMSINV = NORMSINV;
1105function _cdf(x, mValue, stdVal) {
1106    return 0.5 * (1 + MathHelpers_1.erf((x - mValue) / Math.sqrt(2 * stdVal * stdVal)));
1107}
1108function _pdf(x, meanVal, std) {
1109    return Math.exp(-0.5 * Math.log(2 * Math.PI) -
1110        Math.log(std) - Math.pow(x - meanVal, 2) / (2 * std * std));
1111}
1112/**
1113 * Returns the standard normal cumulative distribution for the given number.
1114 * @param z - Value to use in calculation.
1115 * @returns {number}
1116 * @constructor
1117 */
1118var NORMSDIST = function (z) {
1119    ArgsChecker_1.ArgsChecker.checkLength(arguments, 1, "NORMSDIST");
1120    z = TypeConverter_1.TypeConverter.firstValueAsNumber(z);
1121    return _cdf(z, 0, 1);
1122};
1123exports.NORMSDIST = NORMSDIST;
1124/**
1125 * Returns the normal distribution for the given number in the distribution.
1126 * @param x - Value to use.
1127 * @param meanValue - The mean value of the distribution.
1128 * @param standDev - The standard deviation of the distribution.
1129 * @param cumulative - 0 calculates the density function, 1 calculates the distribution.
1130 * @returns {number}
1131 * @constructor
1132 */
1133var NORMDIST = function (x, meanValue, standDev, cumulative) {
1134    ArgsChecker_1.ArgsChecker.checkLength(arguments, 4, "NORMDIST");
1135    x = TypeConverter_1.TypeConverter.firstValueAsNumber(x);
1136    meanValue = TypeConverter_1.TypeConverter.firstValueAsNumber(meanValue);
1137    standDev = TypeConverter_1.TypeConverter.firstValueAsNumber(standDev);
1138    cumulative = TypeConverter_1.TypeConverter.firstValueAsNumber(cumulative);
1139    if (standDev <= 0) {
1140        throw new Errors_1.NumError("Function NORMDIST parameter 3 value should be greater than 0. It is " + standDev + ".");
1141    }
1142    return (cumulative === 0) ? _pdf(x, meanValue, standDev) : _cdf(x, meanValue, standDev);
1143};
1144exports.NORMDIST = NORMDIST;
1145/**
1146 * Returns the inverse of the normal distribution for the given number in the distribution.
1147 * @param probability - Number in the distribution.
1148 * @param meanVal - The mean value in the normal distribution.
1149 * @param standDev - The standard deviation of the normal distribution.
1150 * @returns {number}
1151 * @constructor
1152 */
1153var NORMINV = function (probability, meanVal, standDev) {
1154    ArgsChecker_1.ArgsChecker.checkLength(arguments, 3, "NORMINV");
1155    function erf(x) {
1156        var cof = [-1.3026537197817094, 6.4196979235649026e-1, 1.9476473204185836e-2,
1157            -9.561514786808631e-3, -9.46595344482036e-4, 3.66839497852761e-4,
1158            4.2523324806907e-5, -2.0278578112534e-5, -1.624290004647e-6,
1159            1.303655835580e-6, 1.5626441722e-8, -8.5238095915e-8,
1160            6.529054439e-9, 5.059343495e-9, -9.91364156e-10,
1161            -2.27365122e-10, 9.6467911e-11, 2.394038e-12,
1162            -6.886027e-12, 8.94487e-13, 3.13092e-13,
1163            -1.12708e-13, 3.81e-16, 7.106e-15,
1164            -1.523e-15, -9.4e-17, 1.21e-16,
1165            -2.8e-17];
1166        var j = cof.length - 1;
1167        var isneg = false;
1168        var d = 0;
1169        var dd = 0;
1170        var t, ty, tmp, res;
1171        if (x < 0) {
1172            x = -x;
1173            isneg = true;
1174        }
1175        t = 2 / (2 + x);
1176        ty = 4 * t - 2;
1177        for (; j > 0; j--) {
1178            tmp = d;
1179            d = ty * d - dd + cof[j];
1180            dd = tmp;
1181        }
1182        res = t * Math.exp(-x * x + 0.5 * (cof[0] + ty * d) - dd);
1183        return isneg ? res - 1 : 1 - res;
1184    }
1185    function erfc(x) {
1186        return 1 - erf(x);
1187    }
1188    function erfcinv(p) {
1189        var j = 0;
1190        var x, err, t, pp;
1191        if (p >= 2)
1192            return -100;
1193        if (p <= 0)
1194            return 100;
1195        pp = (p < 1) ? p : 2 - p;
1196        t = Math.sqrt(-2 * Math.log(pp / 2));
1197        x = -0.70711 * ((2.30753 + t * 0.27061) /
1198            (1 + t * (0.99229 + t * 0.04481)) - t);
1199        for (; j < 2; j++) {
1200            err = erfc(x) - pp;
1201            x += err / (1.12837916709551257 * Math.exp(-x * x) - x * err);
1202        }
1203        return (p < 1) ? x : -x;
1204    }
1205    function inv(p, meanVal, std) {
1206        return -1.41421356237309505 * std * erfcinv(2 * p) + meanVal;
1207    }
1208    probability = TypeConverter_1.TypeConverter.firstValueAsNumber(probability);
1209    meanVal = TypeConverter_1.TypeConverter.firstValueAsNumber(meanVal);
1210    standDev = TypeConverter_1.TypeConverter.firstValueAsNumber(standDev);
1211    if (probability <= 0 || probability >= 1) {
1212        throw new Errors_1.NumError("Function NORMINV parameter 1 value is " + probability +
1213            ". Valid values are between 0 and 1 exclusive.");
1214    }
1215    if (standDev <= 0) {
1216        throw new Errors_1.NumError("Function NORMINV parameter 3 value is " + standDev + ". It should be greater than 0.");
1217    }
1218    return inv(probability, meanVal, standDev);
1219};
1220exports.NORMINV = NORMINV;
1221/**
1222 * Returns the negative binomial distribution.
1223 * @param k - The value returned for unsuccessful tests.
1224 * @param r - The value returned for successful tests.
1225 * @param p - The probability of the success of an attempt, between 0 and 1 inclusively.
1226 * @returns {number}
1227 * @constructor
1228 */
1229var NEGBINOMDIST = function (k, r, p) {
1230    ArgsChecker_1.ArgsChecker.checkLength(arguments, 3, "NEGBINOMDIST");
1231    function _gammaln(x) {
1232        var j = 0;
1233        var cof = [
1234            76.18009172947146, -86.50532032941677, 24.01409824083091,
1235            -1.231739572450155, 0.1208650973866179e-2, -0.5395239384953e-5
1236        ];
1237        var ser = 1.000000000190015;
1238        var xx, y, tmp;
1239        tmp = (y = xx = x) + 5.5;
1240        tmp -= (xx + 0.5) * Math.log(tmp);
1241        for (; j < 6; j++)
1242            ser += cof[j] / ++y;
1243        return Math.log(2.5066282746310005 * ser / xx) - tmp;
1244    }
1245    function _combinationln(n, m) {
1246        return _factorialln(n) - _factorialln(m) - _factorialln(n - m);
1247    }
1248    function _factorialln(n) {
1249        return n < 0 ? NaN : _gammaln(n + 1);
1250    }
1251    function _factorial(n) {
1252        return n < 0 ? NaN : MathHelpers_1.gammafn(n + 1);
1253    }
1254    function _combination(n, m) {
1255        return (n > 170 || m > 170)
1256            ? Math.exp(_combinationln(n, m))
1257            : (_factorial(n) / _factorial(m)) / _factorial(n - m);
1258    }
1259    function _pdf(k, r, p) {
1260        return k !== (k | 0)
1261            ? 0
1262            : k < 0
1263                ? 0
1264                : _combination(k + r - 1, r - 1) * Math.pow(1 - p, k) * Math.pow(p, r);
1265    }
1266    k = TypeConverter_1.TypeConverter.firstValueAsNumber(k);
1267    r = TypeConverter_1.TypeConverter.firstValueAsNumber(r);
1268    p = TypeConverter_1.TypeConverter.firstValueAsNumber(p);
1269    if (k < 1) {
1270        throw new Errors_1.NumError("Function NEGBINOMDIST parameter 1 value is " + k + ". Should be greater than 0.");
1271    }
1272    if (r < 1) {
1273        throw new Errors_1.NumError("Function NEGBINOMDIST parameter 2 value is " + r + ". Should be greater than 0.");
1274    }
1275    if (p < 0 || p > 1) {
1276        throw new Errors_1.NumError("Function NEGBINOMDIST parameter 3 value is " + p +
1277            ". Valid values are between 0 and 1 inclusive.");
1278    }
1279    return _pdf(k, r, p);
1280};
1281exports.NEGBINOMDIST = NEGBINOMDIST;
1282/**
1283 * Returns the geometric mean of a sample.
1284 * @param values - The numerical arguments or ranges that represent a random sample.
1285 * @returns {number}
1286 * @constructor
1287 */
1288var GEOMEAN = function () {
1289    var values = [];
1290    for (var _i = 0; _i < arguments.length; _i++) {
1291        values[_i] = arguments[_i];
1292    }
1293    ArgsChecker_1.ArgsChecker.checkAtLeastLength(arguments, 1, "GEOMEAN");
1294    function _product(arr) {
1295        var prod = 1;
1296        var i = arr.length;
1297        while (--i >= 0) {
1298            prod *= arr[i];
1299        }
1300        return prod;
1301    }
1302    values = Filter_1.Filter.flattenAndThrow(values).map(TypeConverter_1.TypeConverter.valueToNumber).map(function (value) {
1303        if (value <= 0) {
1304            throw new Errors_1.NumError("GEOMEAN requires inputs greater than 0, but one of the values entered is " + value + ".");
1305        }
1306        return value;
1307    });
1308    return Math.pow(_product(values), 1 / values.length);
1309};
1310exports.GEOMEAN = GEOMEAN;
1311/**
1312 * Returns the harmonic mean of a data set.
1313 * @param values - The numerical arguments or ranges that represent a sample.
1314 * @returns {number}
1315 * @constructor
1316 */
1317var HARMEAN = function () {
1318    var values = [];
1319    for (var _i = 0; _i < arguments.length; _i++) {
1320        values[_i] = arguments[_i];
1321    }
1322    ArgsChecker_1.ArgsChecker.checkAtLeastLength(arguments, 1, "HARMEAN");
1323    var range = Filter_1.Filter.flattenAndThrow(values).map(TypeConverter_1.TypeConverter.valueToNumber).map(function (value) {
1324        if (value <= 0) {
1325            throw new Errors_1.NumError("HARMEAN requires inputs greater than 0, but one of the values entered is " + value + ".");
1326        }
1327        return value;
1328    });
1329    var n = range.length;
1330    var den = 0;
1331    for (var i = 0; i < n; i++) {
1332        den += 1 / range[i];
1333    }
1334    return n / den;
1335};
1336exports.HARMEAN = HARMEAN;
1337/**
1338 * Returns the (1-alpha) confidence interval for a normal distribution.
1339 * @param alpha - The level of the confidence interval
1340 * @param standDev - The standard deviation for the total population
1341 * @param size - The size of the population.
1342 * @returns {number}
1343 * @constructor
1344 */
1345var CONFIDENCE = function (alpha, standDev, size) {
1346    ArgsChecker_1.ArgsChecker.checkLength(arguments, 3, "CONFIDENCE");
1347    alpha = TypeConverter_1.TypeConverter.firstValueAsNumber(alpha);
1348    standDev = TypeConverter_1.TypeConverter.firstValueAsNumber(standDev);
1349    size = TypeConverter_1.TypeConverter.firstValueAsNumber(size);
1350    if (alpha <= 0 || alpha >= 1) {
1351        throw new Errors_1.NumError("Function CONFIDENCE parameter 1 value is " + alpha
1352            + ". Valid values are between 0 and 1 exclusively.");
1353    }
1354    if (standDev <= 0) {
1355        throw new Errors_1.NumError("Function CONFIDENCE parameter 2 value is " + standDev + ". It should be greater than 0.");
1356    }
1357    if (size <= 0) {
1358        throw new Errors_1.NumError("Function CONFIDENCE parameter 3 value is " + size + ". It should be at least 1.");
1359    }
1360    function _erfc(x) {
1361        return 1 - MathHelpers_1.erf(x);
1362    }
1363    function _erfcinv(p) {
1364        var j = 0;
1365        var x, err, t, pp;
1366        if (p >= 2)
1367            return -100;
1368        if (p <= 0)
1369            return 100;
1370        pp = (p < 1) ? p : 2 - p;
1371        t = Math.sqrt(-2 * Math.log(pp / 2));
1372        x = -0.70711 * ((2.30753 + t * 0.27061) /
1373            (1 + t * (0.99229 + t * 0.04481)) - t);
1374        for (; j < 2; j++) {
1375            err = _erfc(x) - pp;
1376            x += err / (1.12837916709551257 * Math.exp(-x * x) - x * err);
1377        }
1378        return (p < 1) ? x : -x;
1379    }
1380    function _normalInv(p, m, std) {
1381        return -1.41421356237309505 * std * _erfcinv(2 * p) + m;
1382    }
1383    function _sumsqerr(arr) {
1384        var m = MathHelpers_1.mean(arr);
1385        var sum = 0;
1386        var i = arr.length;
1387        var tmp;
1388        while (--i >= 0) {
1389            tmp = arr[i] - m;
1390            sum += tmp * tmp;
1391        }
1392        return sum;
1393    }
1394    function _variance(arr, flag) {
1395        return _sumsqerr(arr) / (arr.length - (flag ? 1 : 0));
1396    }
1397    function _normalci() {
1398        var values = [];
1399        for (var _i = 0; _i < arguments.length; _i++) {
1400            values[_i] = arguments[_i];
1401        }
1402        var ans = new Array(2);
1403        var change;
1404        if (values.length === 4) {
1405            change = Math.abs(_normalInv(values[1] / 2, 0, 1) *
1406                values[2] / Math.sqrt(values[3]));
1407        }
1408        else {
1409            change = Math.abs(_normalInv(values[1] / 2, 0, 1) *
1410                Math.sqrt(_variance(arguments[2])) / Math.sqrt(values[2].length));
1411        }
1412        ans[0] = values[0] - change;
1413        ans[1] = values[0] + change;
1414        return ans;
1415    }
1416    return _normalci(1, alpha, standDev, size)[1] - 1;
1417};
1418exports.CONFIDENCE = CONFIDENCE;
1419/**
1420 * Returns the individual term binomial distribution probability.
1421 * @param successes - The number of successes in a set of trials.
1422 * @param trials - The number of independent trials.
1423 * @param probability - The probability of success on each trial.
1424 * @param cumulative - 0 calculates the probability of a single event, 1 calculates the cumulative probability.
1425 * @returns {number}
1426 * @constructor
1427 */
1428var BINOMDIST = function (successes, trials, probability, cumulative) {
1429    ArgsChecker_1.ArgsChecker.checkLength(arguments, 4, "BINOMDIST");
1430    successes = TypeConverter_1.TypeConverter.firstValueAsNumber(successes);
1431    trials = TypeConverter_1.TypeConverter.firstValueAsNumber(trials);
1432    probability = TypeConverter_1.TypeConverter.firstValueAsNumber(probability);
1433    cumulative = TypeConverter_1.TypeConverter.firstValueAsNumber(cumulative);
1434    function _binomialCDF(x, n, p) {
1435        var binomarr = [], k = 0;
1436        if (x < 0) {
1437            return 0;
1438        }
1439        if (x < n) {
1440            for (; k <= x; k++) {
1441                binomarr[k] = _binomialPDF(k, n, p);
1442            }
1443            return MathHelpers_1.sum(binomarr);
1444        }
1445        return 1;
1446    }
1447    function _combination(n, m) {
1448        // make sure n or m don't exceed the upper limit of usable values
1449        return (n > 170 || m > 170)
1450            ? Math.exp(_combinationln(n, m))
1451            : (_factorial(n) / _factorial(m)) / _factorial(n - m);
1452    }
1453    function _factorial(n) {
1454        return n < 0 ? NaN : MathHelpers_1.gammafn(n + 1);
1455    }
1456    function _factorialln(n) {
1457        return n < 0 ? NaN : MathHelpers_1.gammaln(n + 1);
1458    }
1459    function _combinationln(n, m) {
1460        return _factorialln(n) - _factorialln(m) - _factorialln(n - m);
1461    }
1462    function _binomialPDF(k, n, p) {
1463        return (p === 0 || p === 1) ?
1464            ((n * p) === k ? 1 : 0) :
1465            _combination(n, k) * Math.pow(p, k) * Math.pow(1 - p, n - k);
1466    }
1467    if (trials < 0) {
1468        throw new Errors_1.NumError("Function BINOMDIST parameter 2 value is " + trials + ", but should be greater than 0.");
1469    }
1470    if (trials < successes) {
1471        throw new Errors_1.NumError("Function BINOMDIST parameter 1 value is " + trials
1472            + ". It should be less than or equal to value of Function BINOMDIST parameter 2 with " + successes + ".");
1473    }
1474    if (probability > 1 || probability < 0) {
1475        throw new Errors_1.NumError("Function BINOMDIST parameter 3 value is " + probability
1476            + ", but should be between 0 and 1 inclusive.");
1477    }
1478    return (cumulative) ? _binomialCDF(successes, trials, probability) : _binomialPDF(successes, trials, probability);
1479};
1480exports.BINOMDIST = BINOMDIST;
1481/**
1482 * Returns the covariance of the product of paired deviations.
1483 * @param dataY - The first range of data.
1484 * @param dataX - The second range of data.
1485 * @returns {number}
1486 * @constructor
1487 */
1488var COVAR = function (dataY, dataX) {
1489    ArgsChecker_1.ArgsChecker.checkLength(arguments, 2, "COVAR");
1490    dataY = Filter_1.Filter.flattenAndThrow(dataY).map(TypeConverter_1.TypeConverter.valueToNumber);
1491    dataX = Filter_1.Filter.flattenAndThrow(dataX).map(TypeConverter_1.TypeConverter.valueToNumber);
1492    if (dataX.length !== dataY.length) {
1493        throw new Errors_1.NAError("COlet has mismatched argument count " + dataY.length + " vs " + dataX.length + ".");
1494    }
1495    var mean1 = MathHelpers_1.mean(dataY);
1496    var mean2 = MathHelpers_1.mean(dataX);
1497    var result = 0;
1498    var n = dataY.length;
1499    for (var i = 0; i < n; i++) {
1500        result += (dataY[i] - mean1) * (dataX[i] - mean2);
1501    }
1502    return result / n;
1503};
1504exports.COVAR = COVAR;
1505/**
1506 * Returns the values of the Weibull distribution for the given number.
1507 * @param x - Number to use in calculation.
1508 * @param shape - The Alpha parameter of the Weibull distribution. Should be greater than 0.
1509 * @param scale - The Beta parameter of the Weibull distribution. Should be greater than 0.
1510 * @param cumulative - Indicates the type of function: If 0 the form of the function is calculated, if 1 then the
1511 * distribution is calculated.
1512 * @returns {number}
1513 * @constructor
1514 */
1515var WEIBULL = function (x, shape, scale, cumulative) {
1516    ArgsChecker_1.ArgsChecker.checkLength(arguments, 4, "WEIBULL");
1517    x = TypeConverter_1.TypeConverter.firstValueAsNumber(x);
1518    if (x < 0) {
1519        throw new Errors_1.NumError("Function WEIBULL parameter 1 value is " + x + ", but should be greater than or equal to 0.");
1520    }
1521    shape = TypeConverter_1.TypeConverter.firstValueAsNumber(shape);
1522    if (shape <= 0) {
1523        throw new Errors_1.NumError("Function WEIBULL parameter 2 value is " + shape + ", but should be greater than 0.");
1524    }
1525    scale = TypeConverter_1.TypeConverter.firstValueAsNumber(scale);
1526    if (scale <= 0) {
1527        throw new Errors_1.NumError("Function WEIBULL parameter 2 value is " + scale + ", but should be greater than 0.");
1528    }
1529    cumulative = TypeConverter_1.TypeConverter.firstValueAsNumber(cumulative);
1530    return (cumulative) ? 1 - Math.exp(-Math.pow(x / scale, shape)) : Math.pow(x, shape - 1)
1531        * Math.exp(-Math.pow(x / scale, shape)) * shape / Math.pow(scale, shape);
1532};
1533exports.WEIBULL = WEIBULL;
1534/**
1535 * Estimate the variance based on the entire population. Text will be converted to numbers, if possible.
1536 * @param values - Values of population.
1537 * @returns {number}
1538 * @constructor
1539 */
1540var VARPA = function () {
1541    var values = [];
1542    for (var _i = 0; _i < arguments.length; _i++) {
1543        values[_i] = arguments[_i];
1544    }
1545    ArgsChecker_1.ArgsChecker.checkAtLeastLength(arguments, 1, "VARPA");
1546    var range = Filter_1.Filter.flattenAndThrow(values).map(TypeConverter_1.TypeConverter.valueToNumber);
1547    var n = range.length;
1548    if (n < 2) {
1549        throw new Errors_1.DivZeroError("Evaluation of function VARP caused a divide by zero error.");
1550    }
1551    var sigma = 0;
1552    var count = 0;
1553    var mean = AVERAGEA(range);
1554    for (var i = 0; i < n; i++) {
1555        var el = range[i];
1556        if (typeof el === 'number') {
1557            sigma += Math.pow(el - mean, 2);
1558        }
1559        else if (el === true) {
1560            sigma += Math.pow(1 - mean, 2);
1561        }
1562        else {
1563            sigma += Math.pow(0 - mean, 2);
1564        }
1565        if (el !== null) {
1566            count++;
1567        }
1568    }
1569    return sigma / count;
1570};
1571exports.VARPA = VARPA;
1572/**
1573 * Estimate the variance based on the entire population.
1574 * @param values - Values of entire population.
1575 * @returns {number}
1576 * @constructor
1577 */
1578var VARP = function () {
1579    var values = [];
1580    for (var _i = 0; _i < arguments.length; _i++) {
1581        values[_i] = arguments[_i];
1582    }
1583    ArgsChecker_1.ArgsChecker.checkAtLeastLength(arguments, 1, "VARP");
1584    var range = Filter_1.Filter.flattenAndThrow(values).map(TypeConverter_1.TypeConverter.valueToNumber);
1585    var n = range.length;
1586    if (n < 2) {
1587        throw new Errors_1.DivZeroError("Evaluation of function VARP caused a divide by zero error.");
1588    }
1589    var sigma = 0;
1590    var count = 0;
1591    var mean = AVERAGE(range);
1592    for (var i = 0; i < n; i++) {
1593        sigma += Math.pow(range[i] - mean, 2);
1594        count++;
1595    }
1596    return sigma / count;
1597};
1598exports.VARP = VARP;
1599/**
1600 * Estimate the variance based on a sample.
1601 * @param values
1602 * @returns {number}
1603 * @constructor
1604 */
1605var VARA = function () {
1606    var values = [];
1607    for (var _i = 0; _i < arguments.length; _i++) {
1608        values[_i] = arguments[_i];
1609    }
1610    ArgsChecker_1.ArgsChecker.checkAtLeastLength(arguments, 1, "VARA");
1611    var range = Filter_1.Filter.flattenAndThrow(values).map(TypeConverter_1.TypeConverter.valueToNumber);
1612    var n = range.length;
1613    if (n < 2) {
1614        throw new Errors_1.DivZeroError("Evaluation of function VARA caused a divide by zero error.");
1615    }
1616    var sigma = 0;
1617    var count = 0;
1618    var mean = AVERAGEA(range);
1619    for (var i = 0; i < n; i++) {
1620        var el = range[i];
1621        if (typeof el === 'number') {
1622            sigma += Math.pow(el - mean, 2);
1623        }
1624        else if (el === true) {
1625            sigma += Math.pow(1 - mean, 2);
1626        }
1627        else {
1628            sigma += Math.pow(0 - mean, 2);
1629        }
1630        if (el !== null) {
1631            count++;
1632        }
1633    }
1634    return sigma / (count - 1);
1635};
1636exports.VARA = VARA;
1637/**
1638 * Estimate the variance based on a sample.
1639 * @param values - Values in sample.
1640 * @constructor
1641 */
1642var VAR = function () {
1643    var values = [];
1644    for (var _i = 0; _i < arguments.length; _i++) {
1645        values[_i] = arguments[_i];
1646    }
1647    ArgsChecker_1.ArgsChecker.checkAtLeastLength(arguments, 1, "VAR");
1648    var range = Filter_1.Filter.flattenAndThrow(values).map(TypeConverter_1.TypeConverter.valueToNumber);
1649    var n = range.length;
1650    if (n < 2) {
1651        throw new Errors_1.DivZeroError("Evaluation of function let caused a divide by zero error.");
1652    }
1653    var sigma = 0;
1654    var count = 0;
1655    var mean = AVERAGE(range);
1656    for (var i = 0; i < n; i++) {
1657        sigma += Math.pow(range[i] - mean, 2);
1658        count++;
1659    }
1660    return sigma / (count - 1);
1661};
1662exports.VAR = VAR;
1663/**
1664 * Returns the number of permutations for a given number of objects.
1665 * @param total - The total number of objects
1666 * @param objects - The number of objects in each permutation.
1667 * @returns {number}
1668 * @constructor
1669 */
1670var PERMUT = function (total, objects) {
1671    ArgsChecker_1.ArgsChecker.checkLength(arguments, 2, "PERMUT");
1672    total = TypeConverter_1.TypeConverter.firstValueAsNumber(total);
1673    objects = TypeConverter_1.TypeConverter.firstValueAsNumber(objects);
1674    if (total < objects) {
1675        throw new Errors_1.NumError("Function PERMUT parameter 2 value is " + objects +
1676            ", should be less than or equal to value of Function PERMUT parameter 1 of " + objects + ".");
1677    }
1678    var memoizeFact = [];
1679    function _fact(value) {
1680        var n = Math.floor(value);
1681        if (n === 0 || n === 1) {
1682            return 1;
1683        }
1684        else if (memoizeFact[n] > 0) {
1685            return memoizeFact[n];
1686        }
1687        else {
1688            memoizeFact[n] = _fact(n - 1) * n;
1689            return memoizeFact[n];
1690        }
1691    }
1692    return _fact(total) / _fact(total - objects);
1693};
1694exports.PERMUT = PERMUT;
1695/**
1696 * Returns the square of the Pearson correlation coefficient based on the given values.
1697 * @param rangeY - An array or range of data points.
1698 * @param rangeX - An array or range of data points.
1699 * @returns {number}
1700 * @constructor
1701 */
1702var RSQ = function (rangeY, rangeX) {
1703    ArgsChecker_1.ArgsChecker.checkLength(arguments, 2, "RSQ");
1704    if (!Array.isArray(rangeY)) {
1705        rangeY = [rangeY];
1706    }
1707    if (!Array.isArray(rangeX)) {
1708        rangeX = [rangeX];
1709    }
1710    var dataX = Filter_1.Filter.flattenAndThrow(rangeX).map(TypeConverter_1.TypeConverter.valueToNumber);
1711    var dataY = Filter_1.Filter.flattenAndThrow(rangeY).map(TypeConverter_1.TypeConverter.valueToNumber);
1712    if (dataX.length !== dataY.length) {
1713        throw new Errors_1.NAError("SLOPE has mismatched argument count " + dataX.length + " vs " + dataY.length + ".");
1714    }
1715    if (dataY.length === 1 && dataX.length === 1) {
1716        throw new Errors_1.DivZeroError("Evaluation of function RSQ caused a divide by zero error.");
1717    }
1718    return Math.pow(PEARSON(dataX, dataY), 2);
1719};
1720exports.RSQ = RSQ;
1721/**
1722 * Returns the skewness of a distribution.
1723 * @param values - The numerical values or range.
1724 * @returns {number}
1725 * @constructor
1726 */
1727var SKEW = function () {
1728    var values = [];
1729    for (var _i = 0; _i < arguments.length; _i++) {
1730        values[_i] = arguments[_i];
1731    }
1732    ArgsChecker_1.ArgsChecker.checkAtLeastLength(arguments, 1, "SKEW");
1733    var range = Filter_1.Filter.flattenAndThrow(values).map(TypeConverter_1.TypeConverter.valueToNumber);
1734    var n = range.length;
1735    if (n < 3) {
1736        throw new Errors_1.DivZeroError("SKEW requires at least 3 data points.");
1737    }
1738    var meanValue = MathHelpers_1.mean(range);
1739    var sigma = 0;
1740    for (var i = 0; i < n; i++) {
1741        sigma += Math.pow(range[i] - meanValue, 3);
1742    }
1743    var d = ((n - 1) * (n - 2) * Math.pow(MathHelpers_1.stdev(range, true), 3));
1744    if (d === 0) {
1745        throw new Errors_1.DivZeroError("Evaluation of function SKEW caused a divide by zero error.");
1746    }
1747    return n * sigma / d;
1748};
1749exports.SKEW = SKEW;
1750/**
1751 * Returns the standard error of the predicted y value for each x in the regression. Text values will be ignored.
1752 * @param rangeY - An array or range of data points.
1753 * @param rangeX - An array or range of data points.
1754 * @returns {number}
1755 * @constructor
1756 */
1757var STEYX = function (rangeY, rangeX) {
1758    ArgsChecker_1.ArgsChecker.checkLength(arguments, 2, "STEYX");
1759    if (!Array.isArray(rangeY)) {
1760        rangeY = [rangeY];
1761    }
1762    if (!Array.isArray(rangeX)) {
1763        rangeX = [rangeX];
1764    }
1765    var dataX = Filter_1.Filter.flattenAndThrow(rangeX).filter(function (value) {
1766        return typeof value !== "string";
1767    }).map(TypeConverter_1.TypeConverter.valueToNumber);
1768    var dataY = Filter_1.Filter.flattenAndThrow(rangeY).filter(function (value) {
1769        return typeof value !== "string";
1770    }).map(TypeConverter_1.TypeConverter.valueToNumber);
1771    if (dataX.length !== dataY.length) {
1772        throw new Errors_1.NAError("STEYX has mismatched argument count " + dataX.length + " vs " + dataY.length + ".");
1773    }
1774    if (dataY.length === 2 && dataX.length === 2) {
1775        throw new Errors_1.DivZeroError("Evaluation of function STEYX caused a divide by zero error.");
1776    }
1777    var xmean = MathHelpers_1.mean(dataX);
1778    var ymean = MathHelpers_1.mean(dataY);
1779    var n = dataX.length;
1780    var lft = 0;
1781    var num = 0;
1782    var den = 0;
1783    for (var i = 0; i < n; i++) {
1784        lft += Math.pow(dataY[i] - ymean, 2);
1785        num += (dataX[i] - xmean) * (dataY[i] - ymean);
1786        den += Math.pow(dataX[i] - xmean, 2);
1787    }
1788    return Math.sqrt((lft - num * num / den) / (n - 2));
1789};
1790exports.STEYX = STEYX;
1791/**
1792 * Returns the probability that values in a range are between two limits. Data is the array or range of data in the
1793 * sample.
1794 * @param range - The array or range of data in the sample.
1795 * @param probability - The array or range of the corresponding probabilities
1796 * @param start - The start value of the interval whose probabilities are to be summed.
1797 * @param end - [OPTIONAL] - The end value of the interval whose probabilities are to be summed. If this parameter is
1798 * missing, the probability for the start value is calculated
1799 * @returns {number}
1800 * @constructor
1801 */
1802var PROB = function (range, probability, start, end) {
1803    ArgsChecker_1.ArgsChecker.checkLengthWithin(arguments, 3, 4, "PROB");
1804    range = Filter_1.Filter.flattenAndThrow(range);
1805    probability = Filter_1.Filter.flattenAndThrow(probability);
1806    if (range.length !== probability.length) {
1807        throw new Errors_1.NAError("PROB has mismatched argument count " + range.length + " vs " + probability.length + ".");
1808    }
1809    var sum = Math_1.SUM(probability);
1810    if (sum <= 0 || sum > 1) {
1811        throw new Errors_1.ValueError("Function PROB parameter 2 should sum to 1, but sums to " + sum + ".");
1812    }
1813    start = TypeConverter_1.TypeConverter.firstValueAsNumber(start);
1814    end = (end === undefined) ? start : TypeConverter_1.TypeConverter.firstValueAsNumber(end);
1815    if (start === end) {
1816        return (range.indexOf(start) >= 0) ? probability[range.indexOf(start)] : 0;
1817    }
1818    var sorted = range.sort(function (a, b) {
1819        return a - b;
1820    });
1821    var n = sorted.length;
1822    var result = 0;
1823    for (var i = 0; i < n; i++) {
1824        if (sorted[i] >= start && sorted[i] <= end) {
1825            result += probability[range.indexOf(sorted[i])];
1826        }
1827    }
1828    return result;
1829};
1830exports.PROB = PROB;
1831/**
1832 * Returns the most commonly occurring value in a range.
1833 * @param values - Range(s) or values to consider.
1834 * @returns {number}
1835 * @constructor
1836 */
1837var MODE = function () {
1838    var values = [];
1839    for (var _i = 0; _i < arguments.length; _i++) {
1840        values[_i] = arguments[_i];
1841    }
1842    ArgsChecker_1.ArgsChecker.checkAtLeastLength(arguments, 1, "MODE");
1843    var range = Filter_1.Filter.flattenAndThrow(values).map(TypeConverter_1.TypeConverter.valueToNumber);
1844    var n = range.length;
1845    var count = {};
1846    var maxItems = [];
1847    var max = 0;
1848    var currentItem;
1849    for (var i = 0; i < n; i++) {
1850        currentItem = range[i];
1851        count[currentItem] = count[currentItem] ? count[currentItem] + 1 : 1;
1852        if (count[currentItem] > max) {
1853            max = count[currentItem];
1854            maxItems = [];
1855        }
1856        if (count[currentItem] === max) {
1857            maxItems[maxItems.length] = currentItem;
1858        }
1859    }
1860    if (max === 1 && range.length !== 1) {
1861        throw new Errors_1.NAError("MODE cannot produce a result because no values occur more than once.");
1862    }
1863    return maxItems[0];
1864};
1865exports.MODE = MODE;
1866/**
1867 * Returns the position of a given entry in the entire list, measured either from top to bottom or bottom to top.
1868 * @param value - Value to find the rank of.
1869 * @param data - Values or range of the data-set.
1870 * @param isAscending - [OPTIONAL] The type of rank: 0 to rank from the highest, 1 to rank from the lowest. Defaults to
1871 * 0.
1872 * @returns {number}
1873 * @constructor
1874 */
1875var RANK = function (value, data, isAscending) {
1876    ArgsChecker_1.ArgsChecker.checkLengthWithin(arguments, 2, 3, "RANK");
1877    value = TypeConverter_1.TypeConverter.firstValueAsNumber(value);
1878    var range = Filter_1.Filter.flattenAndThrow(data).map(TypeConverter_1.TypeConverter.valueToNumber);
1879    isAscending = (typeof isAscending === 'undefined') ? false : isAscending;
1880    var sort = (isAscending) ? function (a, b) {
1881        return a - b;
1882    } : function (a, b) {
1883        return b - a;
1884    };
1885    range = range.sort(sort);
1886    var rangeIndex = range.indexOf(value);
1887    if (rangeIndex === -1) {
1888        throw new Errors_1.NAError("RANK can't produce a result because parameter 1 is not in the dataset.");
1889    }
1890    return range.indexOf(value) + 1;
1891};
1892exports.RANK = RANK;
1893/**
1894 * Returns the position of a given entry in the entire list, measured either from top to bottom or bottom to top. If
1895 * more than one value exists in the same data-set, the average range of the values will be returned.
1896 * @param value - Value to find the rank of.
1897 * @param data - Values or range of the data-set.
1898 * @param isAscending - [OPTIONAL] The type of rank: 0 to rank from the highest, 1 to rank from the lowest. Defaults to
1899 * 0.
1900 * @returns {number}
1901 * @constructor
1902 */
1903var RANK$AVG = function (value, data, isAscending) {
1904    ArgsChecker_1.ArgsChecker.checkLengthWithin(arguments, 2, 3, "RANK.AVG");
1905    value = TypeConverter_1.TypeConverter.firstValueAsNumber(value);
1906    var range = Filter_1.Filter.flattenAndThrow(data).map(TypeConverter_1.TypeConverter.valueToNumber);
1907    function _countIn(range, value) {
1908        var result = 0;
1909        for (var i = 0; i < range.length; i++) {
1910            if (range[i] === value) {
1911                result++;
1912            }
1913        }
1914        return result;
1915    }
1916    isAscending = (typeof isAscending === 'undefined') ? false : isAscending;
1917    var sort = (isAscending) ? function (a, b) {
1918        return a - b;
1919    } : function (a, b) {
1920        return b - a;
1921    };
1922    range = range.sort(sort);
1923    var rangeIndex = range.indexOf(value);
1924    if (rangeIndex === -1) {
1925        throw new Errors_1.NAError("RANK.AVG can't produce a result because parameter 1 is not in the dataset.");
1926    }
1927    var count = _countIn(range, value);
1928    return (count > 1) ? (2 * rangeIndex + count + 1) / 2 : rangeIndex + 1;
1929};
1930exports.RANK$AVG = RANK$AVG;
1931/**
1932 * Returns the position of a given entry in the entire list, measured either from top to bottom or bottom to top. If
1933 * there is more than one entry of the same value in the dataset, the top rank of the entries will be returned.
1934 * @param value - Value to find the rank of.
1935 * @param data - Values or range of the data-set.
1936 * @param isAscending - [OPTIONAL] The type of rank: 0 to rank from the highest, 1 to rank from the lowest. Defaults to
1937 * 0.
1938 * @returns {number}
1939 * @constructor
1940 */
1941var RANK$EQ = function (value, data, isAscending) {
1942    ArgsChecker_1.ArgsChecker.checkLengthWithin(arguments, 2, 3, "RANK.EQ");
1943    value = TypeConverter_1.TypeConverter.firstValueAsNumber(value);
1944    var range = Filter_1.Filter.flattenAndThrow(data).map(TypeConverter_1.TypeConverter.valueToNumber);
1945    isAscending = (typeof isAscending === 'undefined') ? false : isAscending;
1946    var sort = (isAscending) ? function (a, b) {
1947        return a - b;
1948    } : function (a, b) {
1949        return b - a;
1950    };
1951    range = range.sort(sort);
1952    var rangeIndex = range.indexOf(value);
1953    if (rangeIndex === -1) {
1954        throw new Errors_1.NAError("RANK.EQ can't produce a result because parameter 1 is not in the dataset.");
1955    }
1956    return range.indexOf(value) + 1;
1957};
1958exports.RANK$EQ = RANK$EQ;
1959/**
1960 * Returns the cumulative lognormal distribution for the given number.
1961 * @param x - The probability value.
1962 * @param meanValue - The mean value of the standard logarithmic distribution.
1963 * @param standardDev - The standard deviation of the standard logarithmic distribution.
1964 * @returns {number}
1965 * @constructor
1966 */
1967var LOGNORMDIST = function (x, meanValue, standardDev) {
1968    ArgsChecker_1.ArgsChecker.checkLength(arguments, 3, "LOGNORMDIST");
1969    x = TypeConverter_1.TypeConverter.firstValueAsNumber(x);
1970    meanValue = TypeConverter_1.TypeConverter.firstValueAsNumber(meanValue);
1971    standardDev = TypeConverter_1.TypeConverter.firstValueAsNumber(standardDev);
1972    if (x <= 0) {
1973        throw new Errors_1.NumError("Function LOGNORMDIST parameter 1 value is " + x + ", but should be greater than 0.");
1974    }
1975    if (standardDev <= 0) {
1976        throw new Errors_1.NumError("Function LOGNORMDIST parameter 3 value is " + standardDev + ", but should be greater than 0.");
1977    }
1978    var a = (Math.log(x) - meanValue) / Math.sqrt(2 * standardDev * standardDev);
1979    return 0.5 + 0.5 * MathHelpers_1.erf(a);
1980};
1981exports.LOGNORMDIST = LOGNORMDIST;
1982/**
1983 * Returns the t-distribution for the given number.
1984 * @param x - Value to use in calculation.
1985 * @param degreesOfFreedom - The number of degrees of freedom for the t-distribution.
1986 * @param tails - 1 returns the one-tailed test, 2 returns the two-tailed test.
1987 * @returns {number}
1988 * @constructor
1989 */
1990var TDIST = function (x, degreesOfFreedom, tails) {
1991    ArgsChecker_1.ArgsChecker.checkLength(arguments, 3, "TDIST");
1992    x = TypeConverter_1.TypeConverter.firstValueAsNumber(x);
1993    degreesOfFreedom = TypeConverter_1.TypeConverter.firstValueAsNumber(degreesOfFreedom);
1994    tails = TypeConverter_1.TypeConverter.firstValueAsNumber(tails);
1995    if (tails < 1 || tails > 2) {
1996        throw new Errors_1.NumError("Function TDIST parameter 3 value is " + tails +
1997            ", but valid values are between 1 and 2, inclusively.");
1998    }
1999    if (degreesOfFreedom < 1) {
2000        throw new Errors_1.NumError("Function TDIST parameter 2 value is " + degreesOfFreedom +
2001            ", but it should be greater than or equal to 1.");
2002    }
2003    if (x < 0) {
2004        throw new Errors_1.NumError("Function TDIST parameter 1 value is " + x + ", but it should be greater than or equal to 0.");
2005    }
2006    function _betacf(x, a, b) {
2007        var fpmin = 1e-30;
2008        var m = 1;
2009        var qab = a + b;
2010        var qap = a + 1;
2011        var qam = a - 1;
2012        var c = 1;
2013        var d = 1 - qab * x / qap;
2014        var m2, aa, del, h;
2015        if (Math.abs(d) < fpmin)
2016            d = fpmin;
2017        d = 1 / d;
2018        h = d;
2019        for (; m <= 100; m++) {
2020            m2 = 2 * m;
2021            aa = m * (b - m) * x / ((qam + m2) * (a + m2));
2022            d = 1 + aa * d;
2023            if (Math.abs(d) < fpmin)
2024                d = fpmin;
2025            c = 1 + aa / c;
2026            if (Math.abs(c) < fpmin)
2027                c = fpmin;
2028            d = 1 / d;
2029            h *= d * c;
2030            aa = -(a + m) * (qab + m) * x / ((a + m2) * (qap + m2));
2031            d = 1 + aa * d;
2032            if (Math.abs(d) < fpmin)
2033                d = fpmin;
2034            c = 1 + aa / c;
2035            if (Math.abs(c) < fpmin)
2036                c = fpmin;
2037            d = 1 / d;
2038            del = d * c;
2039            h *= del;
2040            if (Math.abs(del - 1.0) < 3e-7)
2041                break;
2042        }
2043        return h;
2044    }
2045    function _ibeta(x, a, b) {
2046        var bt = (x === 0 || x === 1) ? 0 :
2047            Math.exp(MathHelpers_1.gammaln(a + b) - MathHelpers_1.gammaln(a) -
2048                MathHelpers_1.gammaln(b) + a * Math.log(x) + b *
2049                Math.log(1 - x));
2050        if (x < 0 || x > 1)
2051            return 0;
2052        if (x < (a + 1) / (a + b + 2))
2053            return bt * _betacf(x, a, b) / a;
2054        return 1 - bt * _betacf(1 - x, b, a) / b;
2055    }
2056    function _studenttCDF(x, dof) {
2057        var dof2 = dof / 2;
2058        return _ibeta((x + Math.sqrt(x * x + dof)) /
2059            (2 * Math.sqrt(x * x + dof)), dof2, dof2);
2060    }
2061    return tails * (1 - _studenttCDF(x, degreesOfFreedom));
2062};
2063exports.TDIST = TDIST;
2064/**
2065 * Returns the hypergeometric distribution. X is the number of results achieved in the random sample.
2066 * @param numberOfSuccesses - The number of results achieved in the random sample.
2067 * @param numberOfDraws - The size of the random sample.
2068 * @param successesInPop - The number of possible results in the total population.
2069 * @param populationSize - The size of the total population.
2070 * @returns {number}
2071 * @constructor
2072 */
2073var HYPGEOMDIST = function (numberOfSuccesses, numberOfDraws, successesInPop, populationSize) {
2074    ArgsChecker_1.ArgsChecker.checkLength(arguments, 4, "HYPGEOMDIST");
2075    numberOfSuccesses = TypeConverter_1.TypeConverter.firstValueAsNumber(numberOfSuccesses);
2076    numberOfDraws = TypeConverter_1.TypeConverter.firstValueAsNumber(numberOfDraws);
2077    if (numberOfSuccesses > numberOfDraws) {
2078        throw new Errors_1.NumError("HYPGEOMDIST parameter 1 value is " + numberOfSuccesses
2079            + ", but should be less than or equal to parameter 2 with " + numberOfDraws + ".");
2080    }
2081    if (numberOfSuccesses < 0) {
2082        throw new Errors_1.NumError("HYPGEOMDIST parameter 1 value is " + numberOfSuccesses
2083            + ", but should be greater than or equal to 0.");
2084    }
2085    if (numberOfSuccesses < (numberOfDraws + successesInPop - populationSize)) {
2086        throw new Errors_1.NumError("HYPGEOMDIST parameter 1 value is " + numberOfSuccesses
2087            + ", but should be greater than or equal to " + (numberOfDraws + successesInPop - populationSize) + ".");
2088    }
2089    successesInPop = TypeConverter_1.TypeConverter.firstValueAsNumber(successesInPop);
2090    populationSize = TypeConverter_1.TypeConverter.firstValueAsNumber(populationSize);
2091    return Math_1.COMBIN(successesInPop, numberOfSuccesses) *
2092        Math_1.COMBIN(populationSize - successesInPop, numberOfDraws - numberOfSuccesses) /
2093        Math_1.COMBIN(populationSize, numberOfDraws);
2094};
2095exports.HYPGEOMDIST = HYPGEOMDIST;
2096/**
2097 * Returns the two-tailed P value of a z test with standard distribution.
2098 * @param range - Te array of the data.
2099 * @param value - The value to be tested.
2100 * @param stdDev - [OPTIONAL] The standard deviation of the total population. If this argument is missing, the standard
2101 * deviation of the sample is processed.
2102 * @returns {number}
2103 * @constructor
2104 */
2105var ZTEST = function (range, value, stdDev) {
2106    ArgsChecker_1.ArgsChecker.checkLengthWithin(arguments, 2, 3, "ZTEST");
2107    range = Filter_1.Filter.flattenAndThrow(range);
2108    value = TypeConverter_1.TypeConverter.firstValueAsNumber(value);
2109    var sd = MoreUtils_1.isUndefined(stdDev) ? STDEV(range) : TypeConverter_1.TypeConverter.firstValueAsNumber(stdDev);
2110    return 1 - NORMSDIST((AVERAGE(range) - value) / (sd / Math.sqrt(range.length)));
2111};
2112exports.ZTEST = ZTEST;