Skip to content

Commit 94562bf

Browse files
author
MarkBaker
committed
Converting Statistical functions to be array-enabled (phase #2)
1 parent f1cb75e commit 94562bf

File tree

4 files changed

+82
-10
lines changed

4 files changed

+82
-10
lines changed

src/PhpSpreadsheet/Calculation/Statistical.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -1155,7 +1155,7 @@ public static function NEGBINOMDIST($failures, $successes, $probability)
11551155
* @param mixed $stdDev Standard Deviation
11561156
* @param mixed $cumulative
11571157
*
1158-
* @return float|string The result, or a string containing an error
1158+
* @return array|float|string The result, or a string containing an error
11591159
*/
11601160
public static function NORMDIST($value, $mean, $stdDev, $cumulative)
11611161
{
@@ -1176,7 +1176,7 @@ public static function NORMDIST($value, $mean, $stdDev, $cumulative)
11761176
* @param mixed $mean Mean Value
11771177
* @param mixed $stdDev Standard Deviation
11781178
*
1179-
* @return float|string The result, or a string containing an error
1179+
* @return array|float|string The result, or a string containing an error
11801180
*/
11811181
public static function NORMINV($probability, $mean, $stdDev)
11821182
{

src/PhpSpreadsheet/Calculation/Statistical/Distributions/Normal.php

+22-8
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@
22

33
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions;
44

5+
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
56
use PhpOffice\PhpSpreadsheet\Calculation\Engineering;
67
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
78
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
89

910
class Normal
1011
{
12+
use ArrayEnabled;
13+
1114
public const SQRT2PI = 2.5066282746310005024157652848110452530069867406099;
1215

1316
/**
@@ -18,17 +21,23 @@ class Normal
1821
* testing.
1922
*
2023
* @param mixed $value Float value for which we want the probability
24+
* Or can be an array of values
2125
* @param mixed $mean Mean value as a float
26+
* Or can be an array of values
2227
* @param mixed $stdDev Standard Deviation as a float
28+
* Or can be an array of values
2329
* @param mixed $cumulative Boolean value indicating if we want the cdf (true) or the pdf (false)
30+
* Or can be an array of values
2431
*
25-
* @return float|string The result, or a string containing an error
32+
* @return array|float|string The result, or a string containing an error
33+
* If an array of numbers is passed as an argument, then the returned result will also be an array
34+
* with the same dimensions
2635
*/
2736
public static function distribution($value, $mean, $stdDev, $cumulative)
2837
{
29-
$value = Functions::flattenSingleValue($value);
30-
$mean = Functions::flattenSingleValue($mean);
31-
$stdDev = Functions::flattenSingleValue($stdDev);
38+
if (is_array($value) || is_array($mean) || is_array($stdDev) || is_array($cumulative)) {
39+
return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $mean, $stdDev, $cumulative);
40+
}
3241

3342
try {
3443
$value = DistributionValidations::validateFloat($value);
@@ -56,16 +65,21 @@ public static function distribution($value, $mean, $stdDev, $cumulative)
5665
* Returns the inverse of the normal cumulative distribution for the specified mean and standard deviation.
5766
*
5867
* @param mixed $probability Float probability for which we want the value
68+
* Or can be an array of values
5969
* @param mixed $mean Mean Value as a float
70+
* Or can be an array of values
6071
* @param mixed $stdDev Standard Deviation as a float
72+
* Or can be an array of values
6173
*
62-
* @return float|string The result, or a string containing an error
74+
* @return array|float|string The result, or a string containing an error
75+
* If an array of numbers is passed as an argument, then the returned result will also be an array
76+
* with the same dimensions
6377
*/
6478
public static function inverse($probability, $mean, $stdDev)
6579
{
66-
$probability = Functions::flattenSingleValue($probability);
67-
$mean = Functions::flattenSingleValue($mean);
68-
$stdDev = Functions::flattenSingleValue($stdDev);
80+
if (is_array($probability) || is_array($mean) || is_array($stdDev)) {
81+
return self::evaluateArrayArguments([self::class, __FUNCTION__], $probability, $mean, $stdDev);
82+
}
6983

7084
try {
7185
$probability = DistributionValidations::validateProbability($probability);

tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormDistTest.php

+29
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
44

5+
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
56
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
67
use PHPUnit\Framework\TestCase;
78

@@ -22,4 +23,32 @@ public function providerNORMDIST(): array
2223
{
2324
return require 'tests/data/Calculation/Statistical/NORMDIST.php';
2425
}
26+
27+
/**
28+
* @dataProvider providerNormDistArray
29+
*/
30+
public function testNormDistArray(array $expectedResult, string $values, string $mean, string $stdDev): void
31+
{
32+
$calculation = Calculation::getInstance();
33+
34+
$formula = "=NORMDIST({$values}, {$mean}, {$stdDev}, false)";
35+
$result = $calculation->_calculateFormulaValue($formula);
36+
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
37+
}
38+
39+
public function providerNormDistArray(): array
40+
{
41+
return [
42+
'row/column vectors' => [
43+
[
44+
[0.04324582990797181, 0.03549422283581691, 0.026885636057682592],
45+
[0.07365402806066465, 0.038837210996642585, 0.015790031660178828],
46+
[0.12098536225957167, 0.0022159242059690033, 7.991870553452737E-6],
47+
],
48+
'12',
49+
'{10, 6, 3}',
50+
'{9; 5; 2}',
51+
],
52+
];
53+
}
2554
}

tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormInvTest.php

+29
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
44

5+
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
56
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
67
use PHPUnit\Framework\TestCase;
78

@@ -22,4 +23,32 @@ public function providerNORMINV(): array
2223
{
2324
return require 'tests/data/Calculation/Statistical/NORMINV.php';
2425
}
26+
27+
/**
28+
* @dataProvider providerNormInvArray
29+
*/
30+
public function testNormInvArray(array $expectedResult, string $probabilities, string $mean, string $stdDev): void
31+
{
32+
$calculation = Calculation::getInstance();
33+
34+
$formula = "=NORMINV({$probabilities}, {$mean}, {$stdDev})";
35+
$result = $calculation->_calculateFormulaValue($formula);
36+
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
37+
}
38+
39+
public function providerNormInvArray(): array
40+
{
41+
return [
42+
'row/column vectors' => [
43+
[
44+
[2.651020499553155, 4.651020499553155],
45+
[1.9765307493297324, 3.9765307493297324],
46+
[-0.7214282515639576, 1.2785717484360424],
47+
],
48+
'0.25',
49+
'{4, 6}',
50+
'{2; 3; 7}',
51+
],
52+
];
53+
}
2554
}

0 commit comments

Comments
 (0)