I'm ignoring SUMIF() and SUMIFS() for the moment; so this should complete all the applicable Math/Trig functions;so the subset SERIESSUM() function and RANDBETWEEN() should complete Math/Trig (#2586)

This commit is contained in:
Mark Baker 2022-02-13 12:50:05 +01:00 committed by GitHub
parent c9d1df8554
commit e3b7cb5f9d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 83 additions and 15 deletions

View File

@ -597,7 +597,7 @@ class MathTrig
* @param int $min Minimal value * @param int $min Minimal value
* @param int $max Maximal value * @param int $max Maximal value
* *
* @return float|int|string Random number * @return array|float|int|string Random number
*/ */
public static function RAND($min = 0, $max = 0) public static function RAND($min = 0, $max = 0)
{ {
@ -679,7 +679,7 @@ class MathTrig
* @param mixed $m Step * @param mixed $m Step
* @param mixed[] $args An array of coefficients for the Data Series * @param mixed[] $args An array of coefficients for the Data Series
* *
* @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 SERIESSUM($x, $n, $m, ...$args) public static function SERIESSUM($x, $n, $m, ...$args)
{ {

View File

@ -2,11 +2,14 @@
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig; namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Exception;
use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Functions;
class Random class Random
{ {
use ArrayEnabled;
/** /**
* RAND. * RAND.
* *
@ -21,12 +24,20 @@ class Random
* RANDBETWEEN. * RANDBETWEEN.
* *
* @param mixed $min Minimal value * @param mixed $min Minimal value
* Or can be an array of values
* @param mixed $max Maximal value * @param mixed $max Maximal value
* Or can be an array of values
* *
* @return float|int|string Random number * @return array|float|int|string Random number
* 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 randBetween($min, $max) public static function randBetween($min, $max)
{ {
if (is_array($min) || is_array($max)) {
return self::evaluateArrayArguments([self::class, __FUNCTION__], $min, $max);
}
try { try {
$min = (int) Helpers::validateNumericNullBool($min); $min = (int) Helpers::validateNumericNullBool($min);
$max = (int) Helpers::validateNumericNullBool($max); $max = (int) Helpers::validateNumericNullBool($max);

View File

@ -2,11 +2,14 @@
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig; namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
use PhpOffice\PhpSpreadsheet\Calculation\Exception; use PhpOffice\PhpSpreadsheet\Calculation\Exception;
use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Functions;
class SeriesSum class SeriesSum
{ {
use ArrayEnabled;
/** /**
* SERIESSUM. * SERIESSUM.
* *
@ -17,10 +20,14 @@ class SeriesSum
* @param mixed $m Step * @param mixed $m Step
* @param mixed[] $args An array of coefficients for the Data Series * @param mixed[] $args An array of coefficients for the Data Series
* *
* @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 evaluate($x, $n, $m, ...$args) public static function evaluate($x, $n, $m, ...$args)
{ {
if (is_array($x) || is_array($n) || is_array($m)) {
return self::evaluateArrayArgumentsSubset([self::class, __FUNCTION__], 3, $x, $n, $m, ...$args);
}
try { try {
$x = Helpers::validateNumericNullSubstitution($x, 0); $x = Helpers::validateNumericNullSubstitution($x, 0);
$n = Helpers::validateNumericNullSubstitution($n, 0); $n = Helpers::validateNumericNullSubstitution($n, 0);

View File

@ -52,17 +52,17 @@ class Subtotal
/** @var callable[] */ /** @var callable[] */
private const CALL_FUNCTIONS = [ private const CALL_FUNCTIONS = [
1 => [Statistical\Averages::class, 'average'], 1 => [Statistical\Averages::class, 'average'], // 1 and 101
[Statistical\Counts::class, 'COUNT'], // 2 [Statistical\Counts::class, 'COUNT'], // 2 and 102
[Statistical\Counts::class, 'COUNTA'], // 3 [Statistical\Counts::class, 'COUNTA'], // 3 and 103
[Statistical\Maximum::class, 'max'], // 4 [Statistical\Maximum::class, 'max'], // 4 and 104
[Statistical\Minimum::class, 'min'], // 5 [Statistical\Minimum::class, 'min'], // 5 and 105
[Operations::class, 'product'], // 6 [Operations::class, 'product'], // 6 and 106
[Statistical\StandardDeviations::class, 'STDEV'], // 7 [Statistical\StandardDeviations::class, 'STDEV'], // 7 and 107
[Statistical\StandardDeviations::class, 'STDEVP'], // 8 [Statistical\StandardDeviations::class, 'STDEVP'], // 8 and 108
[Sum::class, 'sumIgnoringStrings'], // 9 [Sum::class, 'sumIgnoringStrings'], // 9 and 109
[Statistical\Variances::class, 'VAR'], // 10 [Statistical\Variances::class, 'VAR'], // 10 and 110
[Statistical\Variances::class, 'VARP'], // 11 [Statistical\Variances::class, 'VARP'], // 111 and 111
]; ];
/** /**

View File

@ -2,6 +2,8 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
class RandBetweenTest extends AllSetupTeardown class RandBetweenTest extends AllSetupTeardown
{ {
/** /**
@ -43,4 +45,30 @@ class RandBetweenTest extends AllSetupTeardown
{ {
return require 'tests/data/Calculation/MathTrig/RANDBETWEEN.php'; return require 'tests/data/Calculation/MathTrig/RANDBETWEEN.php';
} }
/**
* @dataProvider providerRandBetweenArray
*/
public function testRandBetweenArray(
int $expectedRows,
int $expectedColumns,
string $argument1,
string $argument2
): void {
$calculation = Calculation::getInstance();
$formula = "=RandBetween({$argument1}, {$argument2})";
$result = $calculation->_calculateFormulaValue($formula);
self::assertIsArray($result);
self::assertCount($expectedRows, $result);
self::assertIsArray($result[0]);
self::assertCount($expectedColumns, $result[0]);
}
public function providerRandBetweenArray(): array
{
return [
'row/column vectors' => [2, 2, '{1, 10}', '{10; 100}'],
];
}
} }

View File

@ -2,6 +2,7 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Functions;
class SeriesSumTest extends AllSetupTeardown class SeriesSumTest extends AllSetupTeardown
@ -43,4 +44,25 @@ class SeriesSumTest extends AllSetupTeardown
{ {
return require 'tests/data/Calculation/MathTrig/SERIESSUM.php'; return require 'tests/data/Calculation/MathTrig/SERIESSUM.php';
} }
/**
* @dataProvider providerSeriesSumArray
*/
public function testSeriesSumArray(array $expectedResult, string $x, string $n, string $m, string $values): void
{
$calculation = Calculation::getInstance();
$formula = "=SERIESSUM({$x}, {$n}, {$m}, {$values})";
$result = $calculation->_calculateFormulaValue($formula);
self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14);
}
public function providerSeriesSumArray(): array
{
return [
'row vector #1' => [[[3780, 756]], '5', '{1, 0}', '1', '{1, 1, 0, 1, 1}'],
'column vector #1' => [[[54], [3780]], '{2; 5}', '1', '1', '{1, 1, 0, 1, 1}'],
'matrix #1' => [[[54, 27], [3780, 756]], '{2; 5}', '{1, 0}', '1', '{1, 1, 0, 1, 1}'],
];
}
} }