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 $max Maximal value
*
* @return float|int|string Random number
* @return array|float|int|string Random number
*/
public static function RAND($min = 0, $max = 0)
{
@ -679,7 +679,7 @@ class MathTrig
* @param mixed $m Step
* @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)
{

View File

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

View File

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

View File

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

View File

@ -2,6 +2,8 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
class RandBetweenTest extends AllSetupTeardown
{
/**
@ -43,4 +45,30 @@ class RandBetweenTest extends AllSetupTeardown
{
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;
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
class SeriesSumTest extends AllSetupTeardown
@ -43,4 +44,25 @@ class SeriesSumTest extends AllSetupTeardown
{
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}'],
];
}
}