From f1cb75eaec798c096e781062469b89191239cecf Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Tue, 15 Feb 2022 14:41:17 +0100 Subject: [PATCH] Start work on Array-enabling the Statistical functions (#2588) --- phpstan-baseline.neon | 5 -- .../Calculation/Statistical.php | 48 ++++++------- .../Calculation/Statistical/Confidence.php | 18 +++-- .../Statistical/Distributions/Beta.php | 43 ++++++++---- .../Statistical/Distributions/Binomial.php | 62 ++++++++++++----- .../Statistical/Distributions/ChiSquared.php | 51 ++++++++++---- .../Statistical/Distributions/Exponential.php | 16 +++-- .../Statistical/Distributions/F.php | 18 +++-- .../Statistical/Distributions/Fisher.php | 21 ++++-- .../Statistical/Distributions/Gamma.php | 48 +++++++++---- .../Distributions/HyperGeometric.php | 27 ++++++-- .../Statistical/Distributions/LogNormal.php | 44 ++++++++---- .../Distributions/StandardNormal.php | 13 +++- .../Calculation/Statistical/Permutations.php | 25 +++++-- .../Calculation/Statistical/Standardize.php | 22 ++++-- .../Calculation/Statistical/Trends.php | 12 +++- .../Functions/Statistical/BetaDistTest.php | 25 +++++++ .../Functions/Statistical/BetaInvTest.php | 25 +++++++ .../Statistical/BinomDistRangeTest.php | 29 ++++++++ .../Functions/Statistical/BinomDistTest.php | 29 ++++++++ .../Functions/Statistical/BinomInvTest.php | 29 ++++++++ .../Statistical/ChiDistLeftTailTest.php | 27 ++++++++ .../Statistical/ChiDistRightTailTest.php | 27 ++++++++ .../Statistical/ChiInvLeftTailTest.php | 27 ++++++++ .../Statistical/ChiInvRightTailTest.php | 27 ++++++++ .../Functions/Statistical/ConfidenceTest.php | 28 ++++++++ .../Functions/Statistical/ExponDistTest.php | 27 ++++++++ .../Functions/Statistical/FDistTest.php | 29 ++++++++ .../Functions/Statistical/FisherInvTest.php | 23 +++++++ .../Functions/Statistical/FisherTest.php | 23 +++++++ .../Functions/Statistical/ForecastTest.php | 22 ++++++ .../Functions/Statistical/GammaDistTest.php | 29 ++++++++ .../Functions/Statistical/GammaInvTest.php | 29 ++++++++ .../Functions/Statistical/GammaLnTest.php | 23 +++++++ .../Functions/Statistical/GammaTest.php | 23 +++++++ .../Functions/Statistical/GaussTest.php | 26 +++++++ .../Functions/Statistical/HypGeomDistTest.php | 35 ++++++++++ .../Functions/Statistical/LogInvTest.php | 25 +++++++ .../Statistical/LogNormDist2Test.php | 29 ++++++++ .../Functions/Statistical/LogNormDistTest.php | 29 ++++++++ .../Statistical/NegBinomDistTest.php | 29 ++++++++ .../Functions/Statistical/PermutTest.php | 69 +++++++++++++++++++ .../Statistical/PermutationATest.php | 69 +++++++++++++++++++ .../Functions/Statistical/StandardizeTest.php | 22 ++++++ 44 files changed, 1169 insertions(+), 138 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index abe95ccf..4142c995 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1015,11 +1015,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/Beta.php - - - message: "#^Static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Distributions\\\\Beta\\:\\:regularizedIncompleteBeta\\(\\) is unused\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/Beta.php - - message: "#^Constant PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Distributions\\\\ChiSquared\\:\\:MAX_ITERATIONS is unused\\.$#" count: 1 diff --git a/src/PhpSpreadsheet/Calculation/Statistical.php b/src/PhpSpreadsheet/Calculation/Statistical.php index d43a85f9..937afbdf 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical.php +++ b/src/PhpSpreadsheet/Calculation/Statistical.php @@ -130,7 +130,7 @@ class Statistical * @param mixed $rMin * @param mixed $rMax * - * @return float|string + * @return array|float|string */ public static function BETADIST($value, $alpha, $beta, $rMin = 0, $rMax = 1) { @@ -153,7 +153,7 @@ class Statistical * @param float $rMin Minimum value * @param float $rMax Maximum value * - * @return float|string + * @return array|float|string */ public static function BETAINV($probability, $alpha, $beta, $rMin = 0, $rMax = 1) { @@ -179,7 +179,7 @@ class Statistical * @param mixed $probability Probability of success on each trial * @param mixed $cumulative * - * @return float|string + * @return array|float|string */ public static function BINOMDIST($value, $trials, $probability, $cumulative) { @@ -199,7 +199,7 @@ class Statistical * @param float $value Value for the function * @param float $degrees degrees of freedom * - * @return float|string + * @return array|float|string */ public static function CHIDIST($value, $degrees) { @@ -219,7 +219,7 @@ class Statistical * @param float $probability Probability for the function * @param float $degrees degrees of freedom * - * @return float|string + * @return array|float|string */ public static function CHIINV($probability, $degrees) { @@ -240,7 +240,7 @@ class Statistical * @param float $stdDev Standard Deviation * @param float $size * - * @return float|string + * @return array|float|string */ public static function CONFIDENCE($alpha, $stdDev, $size) { @@ -415,7 +415,7 @@ class Statistical * @param float $probability probability of a success on each trial * @param float $alpha criterion value * - * @return int|string + * @return array|int|string */ public static function CRITBINOM($trials, $probability, $alpha) { @@ -460,7 +460,7 @@ class Statistical * @param float $lambda The parameter value * @param bool $cumulative * - * @return float|string + * @return array|float|string */ public static function EXPONDIST($value, $lambda, $cumulative) { @@ -486,7 +486,7 @@ class Statistical * @param bool $cumulative If cumulative is TRUE, F.DIST returns the cumulative distribution function; * if FALSE, it returns the probability density function. * - * @return float|string + * @return array|float|string */ public static function FDIST2($value, $u, $v, $cumulative) { @@ -507,7 +507,7 @@ class Statistical * * @param float $value * - * @return float|string + * @return array|float|string */ public static function FISHER($value) { @@ -528,7 +528,7 @@ class Statistical * * @param float $value * - * @return float|string + * @return array|float|string */ public static function FISHERINV($value) { @@ -549,7 +549,7 @@ class Statistical * @param mixed $yValues array of mixed Data Series Y * @param mixed $xValues of mixed Data Series X * - * @return bool|float|string + * @return array|bool|float|string */ public static function FORECAST($xValue, $yValues, $xValues) { @@ -568,7 +568,7 @@ class Statistical * * @param float $value * - * @return float|string The result, or a string containing an error + * @return array|float|string The result, or a string containing an error */ public static function GAMMAFunction($value) { @@ -590,7 +590,7 @@ class Statistical * @param float $b Parameter to the distribution * @param bool $cumulative * - * @return float|string + * @return array|float|string */ public static function GAMMADIST($value, $a, $b, $cumulative) { @@ -611,7 +611,7 @@ class Statistical * @param float $alpha Parameter to the distribution * @param float $beta Parameter to the distribution * - * @return float|string + * @return array|float|string */ public static function GAMMAINV($probability, $alpha, $beta) { @@ -630,7 +630,7 @@ class Statistical * * @param float $value * - * @return float|string + * @return array|float|string */ public static function GAMMALN($value) { @@ -650,7 +650,7 @@ class Statistical * * @param float $value * - * @return float|string The result, or a string containing an error + * @return array|float|string The result, or a string containing an error */ public static function GAUSS($value) { @@ -742,7 +742,7 @@ class Statistical * @param mixed $populationSuccesses Number of successes in the population * @param mixed $populationNumber Population size * - * @return float|string + * @return array|float|string */ public static function HYPGEOMDIST($sampleSuccesses, $sampleNumber, $populationSuccesses, $populationNumber) { @@ -879,7 +879,7 @@ class Statistical * @param float $mean * @param float $stdDev * - * @return float|string The result, or a string containing an error + * @return array|float|string The result, or a string containing an error * * @TODO Try implementing P J Acklam's refinement algorithm for greater * accuracy if I can get my head round the mathematics @@ -905,7 +905,7 @@ class Statistical * @param float $mean * @param float $stdDev * - * @return float|string The result, or a string containing an error + * @return array|float|string The result, or a string containing an error */ public static function LOGNORMDIST($value, $mean, $stdDev) { @@ -928,7 +928,7 @@ class Statistical * @param float $stdDev * @param bool $cumulative * - * @return float|string The result, or a string containing an error + * @return array|float|string The result, or a string containing an error */ public static function LOGNORMDIST2($value, $mean, $stdDev, $cumulative = false) { @@ -1131,7 +1131,7 @@ class Statistical * @param mixed $successes Threshold number of Successes * @param mixed $probability Probability of success on each trial * - * @return float|string The result, or a string containing an error + * @return array|float|string The result, or a string containing an error */ public static function NEGBINOMDIST($failures, $successes, $probability) { @@ -1308,7 +1308,7 @@ class Statistical * @param int $numObjs Number of different objects * @param int $numInSet Number of objects in each permutation * - * @return float|int|string Number of permutations, or a string containing an error + * @return array|float|int|string Number of permutations, or a string containing an error */ public static function PERMUT($numObjs, $numInSet) { @@ -1480,7 +1480,7 @@ class Statistical * @param float $mean Mean Value * @param float $stdDev Standard Deviation * - * @return float|string Standardized value, or a string containing an error + * @return array|float|string Standardized value, or a string containing an error */ public static function STANDARDIZE($value, $mean, $stdDev) { diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Confidence.php b/src/PhpSpreadsheet/Calculation/Statistical/Confidence.php index c59c3a9e..8f1a0018 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Confidence.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Confidence.php @@ -2,27 +2,35 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Functions; class Confidence { + use ArrayEnabled; + /** * CONFIDENCE. * * Returns the confidence interval for a population mean * * @param mixed $alpha As a float + * Or can be an array of values * @param mixed $stdDev Standard Deviation as a float + * Or can be an array of values * @param mixed $size As an integer + * Or can be an array of values * - * @return float|string + * @return array|float|string + * If an array of numbers is passed as an argument, then the returned result will also be an array + * with the same dimensions */ public static function CONFIDENCE($alpha, $stdDev, $size) { - $alpha = Functions::flattenSingleValue($alpha); - $stdDev = Functions::flattenSingleValue($stdDev); - $size = Functions::flattenSingleValue($size); + if (is_array($alpha) || is_array($stdDev) || is_array($size)) { + return self::evaluateArrayArguments([self::class, __FUNCTION__], $alpha, $stdDev, $size); + } try { $alpha = StatisticalValidations::validateFloat($alpha); @@ -36,6 +44,6 @@ class Confidence return Functions::NAN(); } - return Distributions\StandardNormal::inverse(1 - $alpha / 2) * $stdDev / sqrt($size); + return Functions::scalar(Distributions\StandardNormal::inverse(1 - $alpha / 2) * $stdDev / sqrt($size)); } } diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Beta.php b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Beta.php index 63e6eb4d..0c6131dd 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Beta.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Beta.php @@ -2,11 +2,14 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions; +use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Functions; class Beta { + use ArrayEnabled; + private const MAX_ITERATIONS = 256; private const LOG_GAMMA_X_MAX_VALUE = 2.55e305; @@ -19,20 +22,28 @@ class Beta * Returns the beta distribution. * * @param mixed $value Float value at which you want to evaluate the distribution + * Or can be an array of values * @param mixed $alpha Parameter to the distribution as a float + * Or can be an array of values * @param mixed $beta Parameter to the distribution as a float + * Or can be an array of values * @param mixed $rMin as an float + * Or can be an array of values * @param mixed $rMax as an float + * Or can be an array of values * - * @return float|string + * @return array|float|string + * If an array of numbers is passed as an argument, then the returned result will also be an array + * with the same dimensions */ public static function distribution($value, $alpha, $beta, $rMin = 0.0, $rMax = 1.0) { - $value = Functions::flattenSingleValue($value); - $alpha = Functions::flattenSingleValue($alpha); - $beta = Functions::flattenSingleValue($beta); - $rMin = ($rMin === null) ? 0.0 : Functions::flattenSingleValue($rMin); - $rMax = ($rMax === null) ? 1.0 : Functions::flattenSingleValue($rMax); + if (is_array($value) || is_array($alpha) || is_array($beta) || is_array($rMin) || is_array($rMax)) { + return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $alpha, $beta, $rMin, $rMax); + } + + $rMin = $rMin ?? 0.0; + $rMax = $rMax ?? 1.0; try { $value = DistributionValidations::validateFloat($value); @@ -65,20 +76,28 @@ class Beta * Returns the inverse of the Beta distribution. * * @param mixed $probability Float probability at which you want to evaluate the distribution + * Or can be an array of values * @param mixed $alpha Parameter to the distribution as a float + * Or can be an array of values * @param mixed $beta Parameter to the distribution as a float + * Or can be an array of values * @param mixed $rMin Minimum value as a float + * Or can be an array of values * @param mixed $rMax Maximum value as a float + * Or can be an array of values * - * @return float|string + * @return array|float|string + * If an array of numbers is passed as an argument, then the returned result will also be an array + * with the same dimensions */ public static function inverse($probability, $alpha, $beta, $rMin = 0.0, $rMax = 1.0) { - $probability = Functions::flattenSingleValue($probability); - $alpha = Functions::flattenSingleValue($alpha); - $beta = Functions::flattenSingleValue($beta); - $rMin = ($rMin === null) ? 0.0 : Functions::flattenSingleValue($rMin); - $rMax = ($rMax === null) ? 1.0 : Functions::flattenSingleValue($rMax); + if (is_array($probability) || is_array($alpha) || is_array($beta) || is_array($rMin) || is_array($rMax)) { + return self::evaluateArrayArguments([self::class, __FUNCTION__], $probability, $alpha, $beta, $rMin, $rMax); + } + + $rMin = $rMin ?? 0.0; + $rMax = $rMax ?? 1.0; try { $probability = DistributionValidations::validateProbability($probability); diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Binomial.php b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Binomial.php index 9631236a..d188f2af 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Binomial.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Binomial.php @@ -2,12 +2,15 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions; +use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Combinations; class Binomial { + use ArrayEnabled; + /** * BINOMDIST. * @@ -18,17 +21,23 @@ class Binomial * babies born are male. * * @param mixed $value Integer number of successes in trials + * Or can be an array of values * @param mixed $trials Integer umber of trials + * Or can be an array of values * @param mixed $probability Probability of success on each trial as a float + * Or can be an array of values * @param mixed $cumulative Boolean value indicating if we want the cdf (true) or the pdf (false) + * Or can be an array of values * - * @return float|string + * @return array|float|string + * If an array of numbers is passed as an argument, then the returned result will also be an array + * with the same dimensions */ public static function distribution($value, $trials, $probability, $cumulative) { - $value = Functions::flattenSingleValue($value); - $trials = Functions::flattenSingleValue($trials); - $probability = Functions::flattenSingleValue($probability); + if (is_array($value) || is_array($trials) || is_array($probability) || is_array($cumulative)) { + return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $trials, $probability, $cumulative); + } try { $value = DistributionValidations::validateInt($value); @@ -58,19 +67,26 @@ class Binomial * of trials falling into a specified range. * * @param mixed $trials Integer number of trials + * Or can be an array of values * @param mixed $probability Probability of success on each trial as a float + * Or can be an array of values * @param mixed $successes The integer number of successes in trials + * Or can be an array of values * @param mixed $limit Upper limit for successes in trials as null, or an integer * If null, then this will indicate the same as the number of Successes + * Or can be an array of values * - * @return float|string + * @return array|float|string + * If an array of numbers is passed as an argument, then the returned result will also be an array + * with the same dimensions */ public static function range($trials, $probability, $successes, $limit = null) { - $trials = Functions::flattenSingleValue($trials); - $probability = Functions::flattenSingleValue($probability); - $successes = Functions::flattenSingleValue($successes); - $limit = ($limit === null) ? $successes : Functions::flattenSingleValue($limit); + if (is_array($trials) || is_array($probability) || is_array($successes) || is_array($limit)) { + return self::evaluateArrayArguments([self::class, __FUNCTION__], $trials, $probability, $successes, $limit); + } + + $limit = $limit ?? $successes; try { $trials = DistributionValidations::validateInt($trials); @@ -107,19 +123,24 @@ class Binomial * variable. Like the binomial, trials are assumed to be independent. * * @param mixed $failures Number of Failures as an integer + * Or can be an array of values * @param mixed $successes Threshold number of Successes as an integer + * Or can be an array of values * @param mixed $probability Probability of success on each trial as a float + * Or can be an array of values * - * @return float|string The result, or a string containing an error + * @return array|float|string The result, or a string containing an error + * If an array of numbers is passed as an argument, then the returned result will also be an array + * with the same dimensions * * TODO Add support for the cumulative flag not present for NEGBINOMDIST, but introduced for NEGBINOM.DIST * The cumulative default should be false to reflect the behaviour of NEGBINOMDIST */ public static function negative($failures, $successes, $probability) { - $failures = Functions::flattenSingleValue($failures); - $successes = Functions::flattenSingleValue($successes); - $probability = Functions::flattenSingleValue($probability); + if (is_array($failures) || is_array($successes) || is_array($probability)) { + return self::evaluateArrayArguments([self::class, __FUNCTION__], $failures, $successes, $probability); + } try { $failures = DistributionValidations::validateInt($failures); @@ -143,22 +164,27 @@ class Binomial } /** - * CRITBINOM. + * BINOM.INV. * * Returns the smallest value for which the cumulative binomial distribution is greater * than or equal to a criterion value * * @param mixed $trials number of Bernoulli trials as an integer + * Or can be an array of values * @param mixed $probability probability of a success on each trial as a float + * Or can be an array of values * @param mixed $alpha criterion value as a float + * Or can be an array of values * - * @return int|string + * @return array|int|string + * If an array of numbers is passed as an argument, then the returned result will also be an array + * with the same dimensions */ public static function inverse($trials, $probability, $alpha) { - $trials = Functions::flattenSingleValue($trials); - $probability = Functions::flattenSingleValue($probability); - $alpha = Functions::flattenSingleValue($alpha); + if (is_array($trials) || is_array($probability) || is_array($alpha)) { + return self::evaluateArrayArguments([self::class, __FUNCTION__], $trials, $probability, $alpha); + } try { $trials = DistributionValidations::validateInt($trials); diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/ChiSquared.php b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/ChiSquared.php index 5165d639..4ccae932 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/ChiSquared.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/ChiSquared.php @@ -2,11 +2,14 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions; +use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Functions; class ChiSquared { + use ArrayEnabled; + private const MAX_ITERATIONS = 256; private const EPS = 2.22e-16; @@ -17,14 +20,19 @@ class ChiSquared * Returns the one-tailed probability of the chi-squared distribution. * * @param mixed $value Float value for which we want the probability + * Or can be an array of values * @param mixed $degrees Integer degrees of freedom + * Or can be an array of values * - * @return float|string + * @return array|float|string + * If an array of numbers is passed as an argument, then the returned result will also be an array + * with the same dimensions */ public static function distributionRightTail($value, $degrees) { - $value = Functions::flattenSingleValue($value); - $degrees = Functions::flattenSingleValue($degrees); + if (is_array($value) || is_array($degrees)) { + return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $degrees); + } try { $value = DistributionValidations::validateFloat($value); @@ -53,16 +61,21 @@ class ChiSquared * Returns the one-tailed probability of the chi-squared distribution. * * @param mixed $value Float value for which we want the probability + * Or can be an array of values * @param mixed $degrees Integer degrees of freedom + * Or can be an array of values * @param mixed $cumulative Boolean value indicating if we want the cdf (true) or the pdf (false) + * Or can be an array of values * - * @return float|string + * @return array|float|string + * If an array of numbers is passed as an argument, then the returned result will also be an array + * with the same dimensions */ public static function distributionLeftTail($value, $degrees, $cumulative) { - $value = Functions::flattenSingleValue($value); - $degrees = Functions::flattenSingleValue($degrees); - $cumulative = Functions::flattenSingleValue($cumulative); + if (is_array($value) || is_array($degrees) || is_array($cumulative)) { + return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $degrees, $cumulative); + } try { $value = DistributionValidations::validateFloat($value); @@ -97,14 +110,19 @@ class ChiSquared * Returns the inverse of the right-tailed probability of the chi-squared distribution. * * @param mixed $probability Float probability at which you want to evaluate the distribution + * Or can be an array of values * @param mixed $degrees Integer degrees of freedom + * Or can be an array of values * - * @return float|string + * @return array|float|string + * If an array of numbers is passed as an argument, then the returned result will also be an array + * with the same dimensions */ public static function inverseRightTail($probability, $degrees) { - $probability = Functions::flattenSingleValue($probability); - $degrees = Functions::flattenSingleValue($degrees); + if (is_array($probability) || is_array($degrees)) { + return self::evaluateArrayArguments([self::class, __FUNCTION__], $probability, $degrees); + } try { $probability = DistributionValidations::validateProbability($probability); @@ -133,14 +151,19 @@ class ChiSquared * Returns the inverse of the left-tailed probability of the chi-squared distribution. * * @param mixed $probability Float probability at which you want to evaluate the distribution + * Or can be an array of values * @param mixed $degrees Integer degrees of freedom + * Or can be an array of values * - * @return float|string + * @return array|float|string + * If an array of numbers is passed as an argument, then the returned result will also be an array + * with the same dimensions */ public static function inverseLeftTail($probability, $degrees) { - $probability = Functions::flattenSingleValue($probability); - $degrees = Functions::flattenSingleValue($degrees); + if (is_array($probability) || is_array($degrees)) { + return self::evaluateArrayArguments([self::class, __FUNCTION__], $probability, $degrees); + } try { $probability = DistributionValidations::validateProbability($probability); @@ -193,7 +216,7 @@ class ChiSquared $degrees = self::degrees($rows, $columns); - $result = self::distributionRightTail($result, $degrees); + $result = Functions::scalar(self::distributionRightTail($result, $degrees)); return $result; } diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Exponential.php b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Exponential.php index b3fd9460..ca55857e 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Exponential.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Exponential.php @@ -2,11 +2,14 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions; +use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Functions; class Exponential { + use ArrayEnabled; + /** * EXPONDIST. * @@ -15,16 +18,21 @@ class Exponential * use EXPONDIST to determine the probability that the process takes at most 1 minute. * * @param mixed $value Float value for which we want the probability + * Or can be an array of values * @param mixed $lambda The parameter value as a float + * Or can be an array of values * @param mixed $cumulative Boolean value indicating if we want the cdf (true) or the pdf (false) + * Or can be an array of values * - * @return float|string + * @return array|float|string + * If an array of numbers is passed as an argument, then the returned result will also be an array + * with the same dimensions */ public static function distribution($value, $lambda, $cumulative) { - $value = Functions::flattenSingleValue($value); - $lambda = Functions::flattenSingleValue($lambda); - $cumulative = Functions::flattenSingleValue($cumulative); + if (is_array($value) || is_array($lambda) || is_array($cumulative)) { + return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $lambda, $cumulative); + } try { $value = DistributionValidations::validateFloat($value); diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/F.php b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/F.php index 54b1950d..0fd0aab3 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/F.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/F.php @@ -2,11 +2,14 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions; +use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Functions; class F { + use ArrayEnabled; + /** * F.DIST. * @@ -16,18 +19,23 @@ class F * if the variability in the females is different from that found in the males. * * @param mixed $value Float value for which we want the probability + * Or can be an array of values * @param mixed $u The numerator degrees of freedom as an integer + * Or can be an array of values * @param mixed $v The denominator degrees of freedom as an integer + * Or can be an array of values * @param mixed $cumulative Boolean value indicating if we want the cdf (true) or the pdf (false) + * Or can be an array of values * - * @return float|string + * @return array|float|string + * If an array of numbers is passed as an argument, then the returned result will also be an array + * with the same dimensions */ public static function distribution($value, $u, $v, $cumulative) { - $value = Functions::flattenSingleValue($value); - $u = Functions::flattenSingleValue($u); - $v = Functions::flattenSingleValue($v); - $cumulative = Functions::flattenSingleValue($cumulative); + if (is_array($value) || is_array($u) || is_array($v) || is_array($cumulative)) { + return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $u, $v, $cumulative); + } try { $value = DistributionValidations::validateFloat($value); diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Fisher.php b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Fisher.php index 923bf02d..8d1b5ce6 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Fisher.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Fisher.php @@ -2,11 +2,14 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions; +use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Functions; class Fisher { + use ArrayEnabled; + /** * FISHER. * @@ -15,12 +18,17 @@ class Fisher * testing on the correlation coefficient. * * @param mixed $value Float value for which we want the probability + * Or can be an array of values * - * @return float|string + * @return array|float|string + * If an array of numbers is passed as an argument, then the returned result will also be an array + * with the same dimensions */ public static function distribution($value) { - $value = Functions::flattenSingleValue($value); + if (is_array($value)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $value); + } try { DistributionValidations::validateFloat($value); @@ -43,12 +51,17 @@ class Fisher * FISHERINV(y) = x. * * @param mixed $probability Float probability at which you want to evaluate the distribution + * Or can be an array of values * - * @return float|string + * @return array|float|string + * If an array of numbers is passed as an argument, then the returned result will also be an array + * with the same dimensions */ public static function inverse($probability) { - $probability = Functions::flattenSingleValue($probability); + if (is_array($probability)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $probability); + } try { DistributionValidations::validateFloat($probability); diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Gamma.php b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Gamma.php index 2c6ed670..adf53428 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Gamma.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Gamma.php @@ -2,23 +2,31 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions; +use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Functions; class Gamma extends GammaBase { + use ArrayEnabled; + /** * GAMMA. * * Return the gamma function value. * * @param mixed $value Float value for which we want the probability + * Or can be an array of values * - * @return float|string The result, or a string containing an error + * @return array|float|string The result, or a string containing an error + * If an array of numbers is passed as an argument, then the returned result will also be an array + * with the same dimensions */ public static function gamma($value) { - $value = Functions::flattenSingleValue($value); + if (is_array($value)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $value); + } try { $value = DistributionValidations::validateFloat($value); @@ -39,17 +47,23 @@ class Gamma extends GammaBase * Returns the gamma distribution. * * @param mixed $value Float Value at which you want to evaluate the distribution + * Or can be an array of values * @param mixed $a Parameter to the distribution as a float + * Or can be an array of values * @param mixed $b Parameter to the distribution as a float + * Or can be an array of values * @param mixed $cumulative Boolean value indicating if we want the cdf (true) or the pdf (false) + * Or can be an array of values * - * @return float|string + * @return array|float|string + * If an array of numbers is passed as an argument, then the returned result will also be an array + * with the same dimensions */ public static function distribution($value, $a, $b, $cumulative) { - $value = Functions::flattenSingleValue($value); - $a = Functions::flattenSingleValue($a); - $b = Functions::flattenSingleValue($b); + if (is_array($value) || is_array($a) || is_array($b) || is_array($cumulative)) { + return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $a, $b, $cumulative); + } try { $value = DistributionValidations::validateFloat($value); @@ -73,16 +87,21 @@ class Gamma extends GammaBase * Returns the inverse of the Gamma distribution. * * @param mixed $probability Float probability at which you want to evaluate the distribution + * Or can be an array of values * @param mixed $alpha Parameter to the distribution as a float + * Or can be an array of values * @param mixed $beta Parameter to the distribution as a float + * Or can be an array of values * - * @return float|string + * @return array|float|string + * If an array of numbers is passed as an argument, then the returned result will also be an array + * with the same dimensions */ public static function inverse($probability, $alpha, $beta) { - $probability = Functions::flattenSingleValue($probability); - $alpha = Functions::flattenSingleValue($alpha); - $beta = Functions::flattenSingleValue($beta); + if (is_array($probability) || is_array($alpha) || is_array($beta)) { + return self::evaluateArrayArguments([self::class, __FUNCTION__], $probability, $alpha, $beta); + } try { $probability = DistributionValidations::validateProbability($probability); @@ -105,12 +124,17 @@ class Gamma extends GammaBase * Returns the natural logarithm of the gamma function. * * @param mixed $value Float Value at which you want to evaluate the distribution + * Or can be an array of values * - * @return float|string + * @return array|float|string + * If an array of numbers is passed as an argument, then the returned result will also be an array + * with the same dimensions */ public static function ln($value) { - $value = Functions::flattenSingleValue($value); + if (is_array($value)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $value); + } try { $value = DistributionValidations::validateFloat($value); diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/HyperGeometric.php b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/HyperGeometric.php index fe30c087..bb7adf7b 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/HyperGeometric.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/HyperGeometric.php @@ -2,12 +2,15 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions; +use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Combinations; class HyperGeometric { + use ArrayEnabled; + /** * HYPGEOMDIST. * @@ -15,18 +18,32 @@ class HyperGeometric * sample successes, given the sample size, population successes, and population size. * * @param mixed $sampleSuccesses Integer number of successes in the sample + * Or can be an array of values * @param mixed $sampleNumber Integer size of the sample + * Or can be an array of values * @param mixed $populationSuccesses Integer number of successes in the population + * Or can be an array of values * @param mixed $populationNumber Integer population size + * Or can be an array of values * - * @return float|string + * @return array|float|string + * If an array of numbers is passed as an argument, then the returned result will also be an array + * with the same dimensions */ public static function distribution($sampleSuccesses, $sampleNumber, $populationSuccesses, $populationNumber) { - $sampleSuccesses = Functions::flattenSingleValue($sampleSuccesses); - $sampleNumber = Functions::flattenSingleValue($sampleNumber); - $populationSuccesses = Functions::flattenSingleValue($populationSuccesses); - $populationNumber = Functions::flattenSingleValue($populationNumber); + if ( + is_array($sampleSuccesses) || is_array($sampleNumber) || + is_array($populationSuccesses) || is_array($populationNumber) + ) { + return self::evaluateArrayArguments( + [self::class, __FUNCTION__], + $sampleSuccesses, + $sampleNumber, + $populationSuccesses, + $populationNumber + ); + } try { $sampleSuccesses = DistributionValidations::validateInt($sampleSuccesses); diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/LogNormal.php b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/LogNormal.php index e1523773..4bf2e0c5 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/LogNormal.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/LogNormal.php @@ -2,11 +2,14 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions; +use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Functions; class LogNormal { + use ArrayEnabled; + /** * LOGNORMDIST. * @@ -14,16 +17,21 @@ class LogNormal * with parameters mean and standard_dev. * * @param mixed $value Float value for which we want the probability + * Or can be an array of values * @param mixed $mean Mean value as a float + * Or can be an array of values * @param mixed $stdDev Standard Deviation as a float + * Or can be an array of values * - * @return float|string The result, or a string containing an error + * @return array|float|string The result, or a string containing an error + * If an array of numbers is passed as an argument, then the returned result will also be an array + * with the same dimensions */ public static function cumulative($value, $mean, $stdDev) { - $value = Functions::flattenSingleValue($value); - $mean = Functions::flattenSingleValue($mean); - $stdDev = Functions::flattenSingleValue($stdDev); + if (is_array($value) || is_array($mean) || is_array($stdDev)) { + return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $mean, $stdDev); + } try { $value = DistributionValidations::validateFloat($value); @@ -47,18 +55,23 @@ class LogNormal * with parameters mean and standard_dev. * * @param mixed $value Float value for which we want the probability + * Or can be an array of values * @param mixed $mean Mean value as a float + * Or can be an array of values * @param mixed $stdDev Standard Deviation as a float + * Or can be an array of values * @param mixed $cumulative Boolean value indicating if we want the cdf (true) or the pdf (false) + * Or can be an array of values * - * @return float|string The result, or a string containing an error + * @return array|float|string The result, or a string containing an error + * If an array of numbers is passed as an argument, then the returned result will also be an array + * with the same dimensions */ public static function distribution($value, $mean, $stdDev, $cumulative = false) { - $value = Functions::flattenSingleValue($value); - $mean = Functions::flattenSingleValue($mean); - $stdDev = Functions::flattenSingleValue($stdDev); - $cumulative = Functions::flattenSingleValue($cumulative); + if (is_array($value) || is_array($mean) || is_array($stdDev) || is_array($cumulative)) { + return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $mean, $stdDev, $cumulative); + } try { $value = DistributionValidations::validateFloat($value); @@ -87,10 +100,15 @@ class LogNormal * Returns the inverse of the lognormal cumulative distribution * * @param mixed $probability Float probability for which we want the value + * Or can be an array of values * @param mixed $mean Mean Value as a float + * Or can be an array of values * @param mixed $stdDev Standard Deviation as a float + * Or can be an array of values * - * @return float|string The result, or a string containing an error + * @return array|float|string The result, or a string containing an error + * If an array of numbers is passed as an argument, then the returned result will also be an array + * with the same dimensions * * @TODO Try implementing P J Acklam's refinement algorithm for greater * accuracy if I can get my head round the mathematics @@ -98,9 +116,9 @@ class LogNormal */ public static function inverse($probability, $mean, $stdDev) { - $probability = Functions::flattenSingleValue($probability); - $mean = Functions::flattenSingleValue($mean); - $stdDev = Functions::flattenSingleValue($stdDev); + if (is_array($probability) || is_array($mean) || is_array($stdDev)) { + return self::evaluateArrayArguments([self::class, __FUNCTION__], $probability, $mean, $stdDev); + } try { $probability = DistributionValidations::validateProbability($probability); diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/StandardNormal.php b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/StandardNormal.php index d10f02a5..9f1796e9 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/StandardNormal.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/StandardNormal.php @@ -2,12 +2,15 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions; +use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Averages; use PhpOffice\PhpSpreadsheet\Calculation\Statistical\StandardDeviations; class StandardNormal { + use ArrayEnabled; + /** * NORMSDIST. * @@ -62,12 +65,18 @@ class StandardNormal * the mean and z standard deviations from the mean. * * @param mixed $value + * Or can be an array of values * - * @return float|string The result, or a string containing an error + * @return array|float|string The result, or a string containing an error + * If an array of numbers is passed as an argument, then the returned result will also be an array + * with the same dimensions */ public static function gauss($value) { - $value = Functions::flattenSingleValue($value); + if (is_array($value)) { + return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $value); + } + if (!is_numeric($value)) { return Functions::VALUE(); } diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Permutations.php b/src/PhpSpreadsheet/Calculation/Statistical/Permutations.php index 272a8a53..7696878e 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Permutations.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Permutations.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\MathTrig; @@ -9,6 +10,8 @@ use PhpOffice\PhpSpreadsheet\Shared\IntOrFloat; class Permutations { + use ArrayEnabled; + /** * PERMUT. * @@ -19,14 +22,19 @@ class Permutations * for lottery-style probability calculations. * * @param mixed $numObjs Integer number of different objects + * Or can be an array of values * @param mixed $numInSet Integer number of objects in each permutation + * Or can be an array of values * - * @return float|int|string Number of permutations, or a string containing an error + * @return array|float|int|string Number of permutations, or a string containing an error + * If an array of numbers is passed as an argument, then the returned result will also be an array + * with the same dimensions */ public static function PERMUT($numObjs, $numInSet) { - $numObjs = Functions::flattenSingleValue($numObjs); - $numInSet = Functions::flattenSingleValue($numInSet); + if (is_array($numObjs) || is_array($numInSet)) { + return self::evaluateArrayArguments([self::class, __FUNCTION__], $numObjs, $numInSet); + } try { $numObjs = StatisticalValidations::validateInt($numObjs); @@ -50,14 +58,19 @@ class Permutations * that can be selected from the total objects. * * @param mixed $numObjs Integer number of different objects + * Or can be an array of values * @param mixed $numInSet Integer number of objects in each permutation + * Or can be an array of values * - * @return float|int|string Number of permutations, or a string containing an error + * @return array|float|int|string Number of permutations, or a string containing an error + * If an array of numbers is passed as an argument, then the returned result will also be an array + * with the same dimensions */ public static function PERMUTATIONA($numObjs, $numInSet) { - $numObjs = Functions::flattenSingleValue($numObjs); - $numInSet = Functions::flattenSingleValue($numInSet); + if (is_array($numObjs) || is_array($numInSet)) { + return self::evaluateArrayArguments([self::class, __FUNCTION__], $numObjs, $numInSet); + } try { $numObjs = StatisticalValidations::validateInt($numObjs); diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Standardize.php b/src/PhpSpreadsheet/Calculation/Statistical/Standardize.php index 2f3c58e7..13240cc2 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Standardize.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Standardize.php @@ -2,27 +2,35 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Functions; class Standardize extends StatisticalValidations { + use ArrayEnabled; + /** * STANDARDIZE. * * Returns a normalized value from a distribution characterized by mean and standard_dev. * - * @param float $value Value to normalize - * @param float $mean Mean Value - * @param float $stdDev Standard Deviation + * @param array|float $value Value to normalize + * Or can be an array of values + * @param array|float $mean Mean Value + * Or can be an array of values + * @param array|float $stdDev Standard Deviation + * Or can be an array of values * - * @return float|string Standardized value, or a string containing an error + * @return array|float|string Standardized value, or a string containing an error + * If an array of numbers is passed as an argument, then the returned result will also be an array + * with the same dimensions */ public static function execute($value, $mean, $stdDev) { - $value = Functions::flattenSingleValue($value); - $mean = Functions::flattenSingleValue($mean); - $stdDev = Functions::flattenSingleValue($stdDev); + if (is_array($value) || is_array($mean) || is_array($stdDev)) { + return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $mean, $stdDev); + } try { $value = self::validateFloat($value); diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Trends.php b/src/PhpSpreadsheet/Calculation/Statistical/Trends.php index 93724a8c..a43926fa 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Trends.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Trends.php @@ -2,12 +2,15 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Shared\Trend\Trend; class Trends { + use ArrayEnabled; + private static function filterTrendValues(array &$array1, array &$array2): void { foreach ($array1 as $key => $value) { @@ -108,14 +111,19 @@ class Trends * The predicted value is a y-value for a given x-value. * * @param mixed $xValue Float value of X for which we want to find Y + * Or can be an array of values * @param mixed $yValues array of mixed Data Series Y * @param mixed $xValues of mixed Data Series X * - * @return bool|float|string + * @return array|bool|float|string + * If an array of numbers is passed as an argument, then the returned result will also be an array + * with the same dimensions */ public static function FORECAST($xValue, $yValues, $xValues) { - $xValue = Functions::flattenSingleValue($xValue); + if (is_array($xValue)) { + return self::evaluateArrayArgumentsSubset([self::class, __FUNCTION__], 1, $xValue, $yValues, $xValues); + } try { $xValue = StatisticalValidations::validateFloat($xValue); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BetaDistTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BetaDistTest.php index 03d03372..02f05c54 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BetaDistTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BetaDistTest.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; @@ -28,4 +29,28 @@ class BetaDistTest extends TestCase { return require 'tests/data/Calculation/Statistical/BETADIST.php'; } + + /** + * @dataProvider providerBetaDistArray + */ + public function testBetaDistArray(array $expectedResult, string $argument1, string $argument2, string $argument3): void + { + $calculation = Calculation::getInstance(); + + $formula = "=BETADIST({$argument1}, {$argument2}, {$argument3})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerBetaDistArray(): array + { + return [ + 'row/column vectors' => [ + [[0.25846539810299873, 0.05696312425682317], [0.3698138247709718, 0.10449584381010533]], + '0.25', + '{5, 7.5}', + '{10; 12}', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BetaInvTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BetaInvTest.php index d82008ab..ba3705a1 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BetaInvTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BetaInvTest.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; @@ -28,4 +29,28 @@ class BetaInvTest extends TestCase { return require 'tests/data/Calculation/Statistical/BETAINV.php'; } + + /** + * @dataProvider providerBetaInvArray + */ + public function testBetaInvArray(array $expectedResult, string $argument1, string $argument2, string $argument3): void + { + $calculation = Calculation::getInstance(); + + $formula = "=BETAINV({$argument1}, {$argument2}, {$argument3})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerBetaInvArray(): array + { + return [ + 'row/column vectors' => [ + [[0.24709953547, 0.346789605377], [0.215382947588, 0.307844847105]], + '0.25', + '{5, 7.5}', + '{10; 12}', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomDistRangeTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomDistRangeTest.php index 6d53aed3..da617fab 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomDistRangeTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomDistRangeTest.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; @@ -28,4 +29,32 @@ class BinomDistRangeTest extends TestCase { return require 'tests/data/Calculation/Statistical/BINOMDISTRANGE.php'; } + + /** + * @dataProvider providerBinomDistRangeArray + */ + public function testBinomDistRangeArray( + array $expectedResult, + string $trials, + string $probabilities, + string $successes + ): void { + $calculation = Calculation::getInstance(); + + $formula = "=BINOM.DIST.RANGE({$trials}, {$probabilities}, {$successes})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerBinomDistRangeArray(): array + { + return [ + 'row/column vectors' => [ + [[0.17303466796875, 0.01153564453125], [0.258103609085083, 0.1032414436340332]], + '{7; 12}', + '0.25', + '{3, 5}', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomDistTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomDistTest.php index 5c4b8d16..94689538 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomDistTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomDistTest.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; @@ -28,4 +29,32 @@ class BinomDistTest extends TestCase { return require 'tests/data/Calculation/Statistical/BINOMDIST.php'; } + + /** + * @dataProvider providerBinomDistArray + */ + public function testBinomDistArray( + array $expectedResult, + string $values, + string $trials, + string $probabilities + ): void { + $calculation = Calculation::getInstance(); + + $formula = "=BINOMDIST({$values}, {$trials}, {$probabilities}, false)"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerBinomDistArray(): array + { + return [ + 'row/column vectors' => [ + [[0.17303466796875, 0.01153564453125], [0.258103609085083, 0.1032414436340332]], + '{3, 5}', + '{7; 12}', + '0.25', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomInvTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomInvTest.php index 88a37ede..6ea2b55b 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomInvTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomInvTest.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; @@ -28,4 +29,32 @@ class BinomInvTest extends TestCase { return require 'tests/data/Calculation/Statistical/BINOMINV.php'; } + + /** + * @dataProvider providerBinomInvArray + */ + public function testBinomInvArray( + array $expectedResult, + string $trials, + string $probabilities, + string $alphas + ): void { + $calculation = Calculation::getInstance(); + + $formula = "=BINOM.INV({$trials}, {$probabilities}, {$alphas})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerBinomInvArray(): array + { + return [ + 'row/column vectors' => [ + [[32, 53], [25, 44]], + '100', + '{0.3, 0.5}', + '{0.7; 0.12}', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiDistLeftTailTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiDistLeftTailTest.php index 7955fcec..eb334b25 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiDistLeftTailTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiDistLeftTailTest.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; @@ -28,4 +29,30 @@ class ChiDistLeftTailTest extends TestCase { return require 'tests/data/Calculation/Statistical/CHIDISTLeftTail.php'; } + + /** + * @dataProvider providerChiDistLeftTailArray + */ + public function testChiDistLeftTailArray(array $expectedResult, string $values, string $degrees): void + { + $calculation = Calculation::getInstance(); + + $formula = "=CHISQ.DIST({$values}, {$degrees}, false)"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerChiDistLeftTailArray(): array + { + return [ + 'row/column vectors' => [ + [ + [0.0925081978822616, 0.12204152134938745, 0.0881791375107928], + [0.007059977723446427, 0.03340047144527138, 0.07814672592526599], + ], + '{3, 5, 8}', + '{7; 12}', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiDistRightTailTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiDistRightTailTest.php index edf275ec..5cd210ef 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiDistRightTailTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiDistRightTailTest.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; @@ -28,4 +29,30 @@ class ChiDistRightTailTest extends TestCase { return require 'tests/data/Calculation/Statistical/CHIDISTRightTail.php'; } + + /** + * @dataProvider providerChiDistRightTailArray + */ + public function testChiDistRightTailArray(array $expectedResult, string $values, string $degrees): void + { + $calculation = Calculation::getInstance(); + + $formula = "=CHISQ.DIST.RT({$values}, {$degrees})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerChiDistRightTailArray(): array + { + return [ + 'row/column vectors' => [ + [ + [0.8850022316431506, 0.6599632296942824, 0.33259390259930777], + [0.9955440192247521, 0.9579789618046938, 0.7851303870304048], + ], + '{3, 5, 8}', + '{7; 12}', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiInvLeftTailTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiInvLeftTailTest.php index 0911449d..c4fe1e94 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiInvLeftTailTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiInvLeftTailTest.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; @@ -34,4 +35,30 @@ class ChiInvLeftTailTest extends TestCase { return require 'tests/data/Calculation/Statistical/CHIINVLeftTail.php'; } + + /** + * @dataProvider providerChiInvLeftTailArray + */ + public function testChiInvLeftTailArray(array $expectedResult, string $probabilities, string $degrees): void + { + $calculation = Calculation::getInstance(); + + $formula = "=CHISQ.INV({$probabilities}, {$degrees})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerChiInvLeftTailArray(): array + { + return [ + 'row/column vectors' => [ + [ + [5.0816470296362795, 6.345811195521517, 1.508898337422818], + [9.61151737996991, 11.34032237742413, 4.0773397083341045], + ], + '{0.35, 0.5, 0.018}', + '{7; 12}', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiInvRightTailTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiInvRightTailTest.php index 29ef161f..629466e2 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiInvRightTailTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiInvRightTailTest.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; @@ -34,4 +35,30 @@ class ChiInvRightTailTest extends TestCase { return require 'tests/data/Calculation/Statistical/CHIINVRightTail.php'; } + + /** + * @dataProvider providerChiInvRightTailArray + */ + public function testChiInvRightTailArray(array $expectedResult, string $probabilities, string $degrees): void + { + $calculation = Calculation::getInstance(); + + $formula = "=CHISQ.INV.RT({$probabilities}, {$degrees})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerChiInvRightTailArray(): array + { + return [ + 'row/column vectors' => [ + [ + [7.8061229155968075, 6.345811195521517, 100.0], + [13.266097125199911, 11.34032237742413, 24.388802783239434], + ], + '{0.35, 0.5, 0.018}', + '{7; 12}', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ConfidenceTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ConfidenceTest.php index 3e43234a..b7a4607c 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ConfidenceTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ConfidenceTest.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; @@ -28,4 +29,31 @@ class ConfidenceTest extends TestCase { return require 'tests/data/Calculation/Statistical/CONFIDENCE.php'; } + + /** + * @dataProvider providerConfidenceArray + */ + public function testConfidenceArray(array $expectedResult, string $alpha, string $stdDev, string $size): void + { + $calculation = Calculation::getInstance(); + + $formula = "=CONFIDENCE({$alpha}, {$stdDev}, {$size})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerConfidenceArray(): array + { + return [ + 'row/column vectors' => [ + [ + [0.33261691811208144, 0.6929519127335031, 1.3859038254670062], + [0.2351956783344234, 0.48999099653004874, 0.9799819930600975], + ], + '0.05', + '{1.2, 2.5, 5}', + '{50; 100}', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ExponDistTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ExponDistTest.php index 200ab14c..0d80aa35 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ExponDistTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ExponDistTest.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; @@ -28,4 +29,30 @@ class ExponDistTest extends TestCase { return require 'tests/data/Calculation/Statistical/EXPONDIST.php'; } + + /** + * @dataProvider providerExponDistArray + */ + public function testExponDistArray(array $expectedResult, string $values, string $lambdas): void + { + $calculation = Calculation::getInstance(); + + $formula = "=EXPONDIST({$values}, {$lambdas}, false)"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerExponDistArray(): array + { + return [ + 'row/column vectors' => [ + [ + [1.646434908282079, 0.6693904804452895, 0.2721538598682374], + [1.353352832366127, 0.06737946999085467, 0.003354626279025118], + ], + '{0.2, 0.5, 0.8}', + '{3; 10}', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FDistTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FDistTest.php index 525247f6..97af9cf8 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FDistTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FDistTest.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; @@ -22,4 +23,32 @@ class FDistTest extends TestCase { return require 'tests/data/Calculation/Statistical/FDIST.php'; } + + /** + * @dataProvider providerFDistArray + */ + public function testFDistArray(array $expectedResult, string $values, string $u, string $v): void + { + $calculation = Calculation::getInstance(); + + $formula = "=F.DIST({$values}, {$u}, {$v}, false)"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerFDistArray(): array + { + return [ + 'row/column vectors' => [ + [ + [0.005510833927217306, 0.005917159763313607, 0.006191501336451844], + [0.0033829117335328167, 0.00291545189504373, 0.0024239018640028246], + [0.0027880880388152654, 0.002128148956848886, 0.0015205263468794615], + ], + '12', + '{1, 2, 5}', + '{2; 4; 5}', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FisherInvTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FisherInvTest.php index 05fac316..44f9c348 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FisherInvTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FisherInvTest.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; @@ -29,4 +30,26 @@ class FisherInvTest extends TestCase { return require 'tests/data/Calculation/Statistical/FISHERINV.php'; } + + /** + * @dataProvider providerFisherArray + */ + public function testFisherArray(array $expectedResult, string $values): void + { + $calculation = Calculation::getInstance(); + + $formula = "=FISHERINV({$values})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerFisherArray(): array + { + return [ + 'row vector' => [ + [[-0.7162978701990245, 0.197375320224904, 0.6351489523872873, 0.9051482536448664]], + '{-0.9, 0.2, 0.75, 1.5}', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FisherTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FisherTest.php index c3dc631d..a3750b6f 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FisherTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FisherTest.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; @@ -29,4 +30,26 @@ class FisherTest extends TestCase { return require 'tests/data/Calculation/Statistical/FISHER.php'; } + + /** + * @dataProvider providerFisherArray + */ + public function testFisherArray(array $expectedResult, string $values): void + { + $calculation = Calculation::getInstance(); + + $formula = "=FISHER({$values})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerFisherArray(): array + { + return [ + 'row vector' => [ + [[-1.4722194895832204, 0.2027325540540821, 0.9729550745276566]], + '{-0.9, 0.2, 0.75}', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ForecastTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ForecastTest.php index 80c46b43..7f190093 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ForecastTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ForecastTest.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; @@ -28,4 +29,25 @@ class ForecastTest extends TestCase { return require 'tests/data/Calculation/Statistical/FORECAST.php'; } + + /** + * @dataProvider providerForecastArray + */ + public function testForecastArray(array $expectedResult, string $testValues, string $yValues, string $xValues): void + { + $calculation = Calculation::getInstance(); + + $formula = "=FORECAST({$testValues}, {$yValues}, {$xValues})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerForecastArray(): array + { + return [ + 'row vector' => [[[-11.047619047619047, 22.95238095238095, 42.38095238095237]], '{-2, 5, 9}', '{3, 7, 15, 20, 22, 27}', '{1, 2, 3, 4, 5, 6}'], + 'column vector' => [[[-11.047619047619047], [22.95238095238095], [42.38095238095237]], '{-2; 5; 9}', '{3, 7, 15, 20, 22, 27}', '{1, 2, 3, 4, 5, 6}'], + 'matrix' => [[[-11.047619047619047, 22.95238095238095], [42.38095238095237, 15.66666666666666]], '{-2, 5; 9, 3.5}', '{3, 7, 15, 20, 22, 27}', '{1, 2, 3, 4, 5, 6}'], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaDistTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaDistTest.php index 2d90afc6..3ed71725 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaDistTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaDistTest.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; @@ -28,4 +29,32 @@ class GammaDistTest extends TestCase { return require 'tests/data/Calculation/Statistical/GAMMADIST.php'; } + + /** + * @dataProvider providerGammaDistArray + */ + public function testGammaDistArray(array $expectedResult, string $values, string $alpha, string $beta): void + { + $calculation = Calculation::getInstance(); + + $formula = "=GAMMA.DIST({$values}, {$alpha}, {$beta}, false)"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerGammaDistArray(): array + { + return [ + 'row/column vectors' => [ + [ + [0.0012393760883331792, 0.007436256529999079, 0.0669263087699917], + [0.012446767091965986, 0.03734030127589798, 0.04200783893538521], + [0.018143590657882503, 0.043544617578918025, 0.02508169972545678], + ], + '12', + '{1, 2, 5}', + '{2; 4; 5}', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaInvTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaInvTest.php index f845d07c..d3e7c13c 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaInvTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaInvTest.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; @@ -28,4 +29,32 @@ class GammaInvTest extends TestCase { return require 'tests/data/Calculation/Statistical/GAMMAINV.php'; } + + /** + * @dataProvider providerGammaInvArray + */ + public function testGammaInvArray(array $expectedResult, string $values, string $alpha, string $beta): void + { + $calculation = Calculation::getInstance(); + + $formula = "=GAMMA.INV({$values}, {$alpha}, {$beta})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerGammaInvArray(): array + { + return [ + 'row/column vectors' => [ + [ + [2.772588722239782, 5.38526905777939, 12.548861396889375], + [5.545177444479563, 10.77053811555878, 25.09772279377875], + [6.931471805599453, 13.463172644448473, 31.372153492223436], + ], + '0.75', + '{1, 2, 5}', + '{2; 4; 5}', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaLnTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaLnTest.php index 73dfe23a..5b444e80 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaLnTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaLnTest.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; @@ -29,4 +30,26 @@ class GammaLnTest extends TestCase { return require 'tests/data/Calculation/Statistical/GAMMALN.php'; } + + /** + * @dataProvider providerGammaLnArray + */ + public function testGammaLnArray(array $expectedResult, string $values): void + { + $calculation = Calculation::getInstance(); + + $formula = "=GAMMALN({$values})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerGammaLnArray(): array + { + return [ + 'matrix' => [ + [['#NUM!', 1.5240638224308496], [0.20328095143131059, 2.8813232759012433]], + '{-1.5, 0.2; 0.75, 4.8}', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaTest.php index abf92866..8372ab32 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaTest.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; @@ -23,4 +24,26 @@ class GammaTest extends TestCase { return require 'tests/data/Calculation/Statistical/GAMMA.php'; } + + /** + * @dataProvider providerGammaArray + */ + public function testGammaArray(array $expectedResult, string $values): void + { + $calculation = Calculation::getInstance(); + + $formula = "=GAMMA({$values})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerGammaArray(): array + { + return [ + 'matrix' => [ + [[2.363271800901467, 4.590843711999102], [1.2254167024651963, 17.837861981813575]], + '{-1.5, 0.2; 0.75, 4.8}', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GaussTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GaussTest.php index 596a608f..0914b829 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GaussTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GaussTest.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; @@ -23,4 +24,29 @@ class GaussTest extends TestCase { return require 'tests/data/Calculation/Statistical/GAUSS.php'; } + + /** + * @dataProvider providerGaussArray + */ + public function testGaussArray(array $expectedResult, string $values): void + { + $calculation = Calculation::getInstance(); + + $formula = "=GAUSS({$values})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerGaussArray(): array + { + return [ + 'matrix' => [ + [ + [-0.4331927987311418, -0.28814460141660325, 0.07925970943910299], + [0.27337264762313174, 0.39435022633314465, 0.5], + ], + '{-1.5, -0.8, 0.2; 0.75, 1.25, 12.5}', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/HypGeomDistTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/HypGeomDistTest.php index 1fa02440..ecd7218d 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/HypGeomDistTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/HypGeomDistTest.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; @@ -22,4 +23,38 @@ class HypGeomDistTest extends TestCase { return require 'tests/data/Calculation/Statistical/HYPGEOMDIST.php'; } + + /** + * @dataProvider providerHypGeomDistArray + */ + public function testHypGeomDistArray( + array $expectedResult, + string $sampleSuccesses, + string $sampleNumber, + string $populationSuccesses, + string $populationNumber + ): void { + $calculation = Calculation::getInstance(); + + $formula = "=HYPGEOMDIST({$sampleSuccesses}, {$sampleNumber}, {$populationSuccesses}, {$populationNumber})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerHypGeomDistArray(): array + { + return [ + 'row/column vectors' => [ + [ + [0.03230668326324188, 0.11602444697599835, 2.7420710766783583E-5], + [0.00015615400269340616, 0.1000501002971324, 0.02508542192762165], + [7.763976978296478E-9, 0.0013573140575961775, 0.17007598410538344], + ], + '{5, 11, 18}', + '32', + '{28; 42; 57}', + '100', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogInvTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogInvTest.php index 8371707d..0ae547b8 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogInvTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogInvTest.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; @@ -22,4 +23,28 @@ class LogInvTest extends TestCase { return require 'tests/data/Calculation/Statistical/LOGINV.php'; } + + /** + * @dataProvider providerLogInvArray + */ + public function testLogInvArray(array $expectedResult, string $probabilities, string $mean, string $stdDev): void + { + $calculation = Calculation::getInstance(); + + $formula = "=LOGINV({$probabilities}, {$mean}, {$stdDev})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerLogInvArray(): array + { + return [ + 'row/column vectors' => [ + [[54.598150033144236, 403.4287934927351]], + '0.5', + '{4, 6}', + '7', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogNormDist2Test.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogNormDist2Test.php index 8954ad7d..3d2fac44 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogNormDist2Test.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogNormDist2Test.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; @@ -22,4 +23,32 @@ class LogNormDist2Test extends TestCase { return require 'tests/data/Calculation/Statistical/LOGNORMDIST2.php'; } + + /** + * @dataProvider providerLogNormDist2Array + */ + public function testLogNormDist2Array(array $expectedResult, string $values, string $mean, string $stdDev): void + { + $calculation = Calculation::getInstance(); + + $formula = "=LOGNORM.DIST({$values}, {$mean}, {$stdDev}, true)"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerLogNormDist2Array(): array + { + return [ + 'row/column vectors' => [ + [ + [0.20185593420695913, 0.34805905738890675, 0.47717995703671096], + [0.06641711479920787, 0.24102205723753728, 0.45897407661978173], + [8.579368431449463E-5, 0.03941233670471267, 0.398378394299419], + ], + '12', + '{10, 6, 3}', + '{9; 5; 2}', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogNormDistTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogNormDistTest.php index 51679c21..7fbac2f8 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogNormDistTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogNormDistTest.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; @@ -22,4 +23,32 @@ class LogNormDistTest extends TestCase { return require 'tests/data/Calculation/Statistical/LOGNORMDIST.php'; } + + /** + * @dataProvider providerLogNormDistArray + */ + public function testLogNormDistArray(array $expectedResult, string $values, string $mean, string $stdDev): void + { + $calculation = Calculation::getInstance(); + + $formula = "=LOGNORMDIST({$values}, {$mean}, {$stdDev})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerLogNormDistArray(): array + { + return [ + 'row/column vectors' => [ + [ + [0.20185593420695913, 0.34805905738890675, 0.47717995703671096], + [0.06641711479920787, 0.24102205723753728, 0.45897407661978173], + [8.579368431449463E-5, 0.03941233670471267, 0.398378394299419], + ], + '12', + '{10, 6, 3}', + '{9; 5; 2}', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NegBinomDistTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NegBinomDistTest.php index d7c7bc53..2e73f810 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NegBinomDistTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NegBinomDistTest.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; @@ -28,4 +29,32 @@ class NegBinomDistTest extends TestCase { return require 'tests/data/Calculation/Statistical/NEGBINOMDIST.php'; } + + /** + * @dataProvider providerNegBinomDistArray + */ + public function testNegBinomDistArray( + array $expectedResult, + string $failures, + string $successes, + string $probabilities + ): void { + $calculation = Calculation::getInstance(); + + $formula = "=NEGBINOMDIST({$failures}, {$successes}, {$probabilities})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerNegBinomDistArray(): array + { + return [ + 'row/column vectors' => [ + [[0.07508468627929688, 0.04301726818084717], [0.04503981303423643, 0.05629976629279554]], + '{7; 12}', + '{3, 5}', + '0.25', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PermutTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PermutTest.php index 10a4f709..1e2401a5 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PermutTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PermutTest.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; @@ -28,4 +29,72 @@ class PermutTest extends TestCase { return require 'tests/data/Calculation/Statistical/PERMUT.php'; } + + /** + * @dataProvider providerPermutArray + */ + public function testPermutArray(array $expectedResult, string $argument1, string $argument2): void + { + $calculation = Calculation::getInstance(); + + $formula = "=PERMUT({$argument1},{$argument2})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerPermutArray(): array + { + return [ + 'first argument row vector' => [ + [[336, 60]], + '{8, 5}', + '3', + ], + 'first argument column vector' => [ + [[336], [60]], + '{8; 5}', + '3', + ], + 'first argument matrix' => [ + [[336, 60], [6, 210]], + '{8, 5; 3, 7}', + '3', + ], + 'second argument row vector' => [ + [[1716, 1235520]], + '13', + '{3, 6}', + ], + 'second argument column vector' => [ + [[1716], [1235520]], + '13', + '{3; 6}', + ], + 'second argument matrix' => [ + [[1716, 1235520], [17160, 51891840]], + '13', + '{3, 6; 4, 8}', + ], + 'A row and a column vector' => [ + [ + [95040, 11880, 1320, 132], + [30240, 5040, 720, 90], + [6720, 1680, 336, 56], + [720, 360, 120, 30], + ], + '{12; 10; 8; 6}', + '{5, 4, 3, 2}', + ], + 'Two row vectors' => [ + [[95040, 5040, 336, 30]], + '{12, 10, 8, 6}', + '{5, 4, 3, 2}', + ], + 'Two column vectors' => [ + [[95040], [5040], [336], [30]], + '{12; 10; 8; 6}', + '{5; 4; 3; 2}', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PermutationATest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PermutationATest.php index ac052e42..e1c8835e 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PermutationATest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PermutationATest.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Permutations; use PHPUnit\Framework\TestCase; @@ -28,4 +29,72 @@ class PermutationATest extends TestCase { return require 'tests/data/Calculation/Statistical/PERMUTATIONA.php'; } + + /** + * @dataProvider providerPermutationAArray + */ + public function testPermutationAArray(array $expectedResult, string $argument1, string $argument2): void + { + $calculation = Calculation::getInstance(); + + $formula = "=PERMUTATIONA({$argument1},{$argument2})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerPermutationAArray(): array + { + return [ + 'first argument row vector' => [ + [[512, 125]], + '{8, 5}', + '3', + ], + 'first argument column vector' => [ + [[512], [125]], + '{8; 5}', + '3', + ], + 'first argument matrix' => [ + [[512, 125], [27, 343]], + '{8, 5; 3, 7}', + '3', + ], + 'second argument row vector' => [ + [[2197, 4826809]], + '13', + '{3, 6}', + ], + 'second argument column vector' => [ + [[2197], [4826809]], + '13', + '{3; 6}', + ], + 'second argument matrix' => [ + [[2197, 4826809], [28561, 815730721]], + '13', + '{3, 6; 4, 8}', + ], + 'A row and a column vector' => [ + [ + [248832, 20736, 1728, 144], + [100000, 10000, 1000, 100], + [32768, 4096, 512, 64], + [7776, 1296, 216, 36], + ], + '{12; 10; 8; 6}', + '{5, 4, 3, 2}', + ], + 'Two row vectors' => [ + [[248832, 10000, 512, 36]], + '{12, 10, 8, 6}', + '{5, 4, 3, 2}', + ], + 'Two column vectors' => [ + [[248832], [10000], [512], [36]], + '{12; 10; 8; 6}', + '{5; 4; 3; 2}', + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StandardizeTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StandardizeTest.php index a1d02b12..2177cee5 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StandardizeTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StandardizeTest.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Statistical; use PHPUnit\Framework\TestCase; @@ -22,4 +23,25 @@ class StandardizeTest extends TestCase { return require 'tests/data/Calculation/Statistical/STANDARDIZE.php'; } + + /** + * @dataProvider providerStandardizeArray + */ + public function testStandardizeArray(array $expectedResult, string $argument1, string $argument2, string $argument3): void + { + $calculation = Calculation::getInstance(); + + $formula = "=STANDARDIZE({$argument1}, {$argument2}, {$argument3})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); + } + + public function providerStandardizeArray(): array + { + return [ + 'row vector' => [[[-1.6666666666666667, -4.6666666666666667, -7.333333333333333, -10, -11.333333333333334]], '{12.5, 8, 4, 0, -2}', '15', '1.5'], + 'column vector' => [[[0.25], [0.0], [-1.0]], '{5.5; 5; 3}', '5.0', '2.0'], + 'matrix' => [[[0.25, -1.0], [-1.75, -2.75]], '{5.5, 3; 1.5, -0.5}', '5.0', '2.0'], + ]; + } }