Extract Permutation functions from the Statistical class into a dedicated Permutations class (#1851)
* Extract Permutation functions from the Statistical class into a dedicated Permutations class Retain the original methods in the Statistical class as stubs for BC, but deprecate them. They will be removed for PHPSpreadsheet v2 Note that unit tests still point to the Statistical class stubs; these should be modified to use the Permutations class directly when the stubs are removed Also provided a basic implementationof the PERMUTATIONA() Function
This commit is contained in:
parent
e824caf857
commit
42ecc270ec
|
|
@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
|
||||||
|
|
||||||
- Implemented DataBar for conditional formatting in Xlsx, providing read/write and creation of (type, value, direction, fills, border, axis position, color settings) as DataBar options in Excel. [#1754](https://github.com/PHPOffice/PhpSpreadsheet/pull/1754)
|
- Implemented DataBar for conditional formatting in Xlsx, providing read/write and creation of (type, value, direction, fills, border, axis position, color settings) as DataBar options in Excel. [#1754](https://github.com/PHPOffice/PhpSpreadsheet/pull/1754)
|
||||||
- Alignment for ODS Writer [#1796](https://github.com/PHPOffice/PhpSpreadsheet/issues/1796)
|
- Alignment for ODS Writer [#1796](https://github.com/PHPOffice/PhpSpreadsheet/issues/1796)
|
||||||
|
- Basic implementation of the PERMUTATIONA() Statistical Function
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1932,12 +1932,12 @@ class Calculation
|
||||||
],
|
],
|
||||||
'PERMUT' => [
|
'PERMUT' => [
|
||||||
'category' => Category::CATEGORY_STATISTICAL,
|
'category' => Category::CATEGORY_STATISTICAL,
|
||||||
'functionCall' => [Statistical::class, 'PERMUT'],
|
'functionCall' => [Statistical\Permutations::class, 'PERMUT'],
|
||||||
'argumentCount' => '2',
|
'argumentCount' => '2',
|
||||||
],
|
],
|
||||||
'PERMUTATIONA' => [
|
'PERMUTATIONA' => [
|
||||||
'category' => Category::CATEGORY_STATISTICAL,
|
'category' => Category::CATEGORY_STATISTICAL,
|
||||||
'functionCall' => [Functions::class, 'DUMMY'],
|
'functionCall' => [Statistical\Permutations::class, 'PERMUTATIONA'],
|
||||||
'argumentCount' => '2',
|
'argumentCount' => '2',
|
||||||
],
|
],
|
||||||
'PHONETIC' => [
|
'PHONETIC' => [
|
||||||
|
|
|
||||||
|
|
@ -2923,6 +2923,8 @@ class Statistical
|
||||||
* combinations, for which the internal order is not significant. Use this function
|
* combinations, for which the internal order is not significant. Use this function
|
||||||
* for lottery-style probability calculations.
|
* for lottery-style probability calculations.
|
||||||
*
|
*
|
||||||
|
* @Deprecated 2.0.0 Use the PERMUT() method in the Statistical\Permutations class instead
|
||||||
|
*
|
||||||
* @param int $numObjs Number of different objects
|
* @param int $numObjs Number of different objects
|
||||||
* @param int $numInSet Number of objects in each permutation
|
* @param int $numInSet Number of objects in each permutation
|
||||||
*
|
*
|
||||||
|
|
@ -2930,19 +2932,7 @@ class Statistical
|
||||||
*/
|
*/
|
||||||
public static function PERMUT($numObjs, $numInSet)
|
public static function PERMUT($numObjs, $numInSet)
|
||||||
{
|
{
|
||||||
$numObjs = Functions::flattenSingleValue($numObjs);
|
return Statistical\Permutations::PERMUT($numObjs, $numInSet);
|
||||||
$numInSet = Functions::flattenSingleValue($numInSet);
|
|
||||||
|
|
||||||
if ((is_numeric($numObjs)) && (is_numeric($numInSet))) {
|
|
||||||
$numInSet = floor($numInSet);
|
|
||||||
if ($numObjs < $numInSet) {
|
|
||||||
return Functions::NAN();
|
|
||||||
}
|
|
||||||
|
|
||||||
return round(MathTrig::FACT($numObjs) / MathTrig::FACT($numObjs - $numInSet));
|
|
||||||
}
|
|
||||||
|
|
||||||
return Functions::VALUE();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
|
||||||
|
|
||||||
|
class Permutations
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* PERMUT.
|
||||||
|
*
|
||||||
|
* Returns the number of permutations for a given number of objects that can be
|
||||||
|
* selected from number objects. A permutation is any set or subset of objects or
|
||||||
|
* events where internal order is significant. Permutations are different from
|
||||||
|
* combinations, for which the internal order is not significant. Use this function
|
||||||
|
* for lottery-style probability calculations.
|
||||||
|
*
|
||||||
|
* @param int $numObjs Number of different objects
|
||||||
|
* @param int $numInSet Number of objects in each permutation
|
||||||
|
*
|
||||||
|
* @return int|string Number of permutations, or a string containing an error
|
||||||
|
*/
|
||||||
|
public static function PERMUT($numObjs, $numInSet)
|
||||||
|
{
|
||||||
|
$numObjs = Functions::flattenSingleValue($numObjs);
|
||||||
|
$numInSet = Functions::flattenSingleValue($numInSet);
|
||||||
|
|
||||||
|
if ((is_numeric($numObjs)) && (is_numeric($numInSet))) {
|
||||||
|
$numInSet = floor($numInSet);
|
||||||
|
if ($numObjs < $numInSet) {
|
||||||
|
return Functions::NAN();
|
||||||
|
}
|
||||||
|
|
||||||
|
return round(MathTrig::FACT($numObjs) / MathTrig::FACT($numObjs - $numInSet));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Functions::VALUE();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PERMUTATIONA.
|
||||||
|
*
|
||||||
|
* Returns the number of permutations for a given number of objects (with repetitions)
|
||||||
|
* that can be selected from the total objects.
|
||||||
|
*
|
||||||
|
* @param int $numObjs Number of different objects
|
||||||
|
* @param int $numInSet Number of objects in each permutation
|
||||||
|
*
|
||||||
|
* @return int|string Number of permutations, or a string containing an error
|
||||||
|
*/
|
||||||
|
public static function PERMUTATIONA($numObjs, $numInSet)
|
||||||
|
{
|
||||||
|
$numObjs = Functions::flattenSingleValue($numObjs);
|
||||||
|
$numInSet = Functions::flattenSingleValue($numInSet);
|
||||||
|
|
||||||
|
if ((is_numeric($numObjs)) && (is_numeric($numInSet))) {
|
||||||
|
$numObjs = floor($numObjs);
|
||||||
|
$numInSet = floor($numInSet);
|
||||||
|
if ($numObjs < 0 || $numInSet < 0) {
|
||||||
|
return Functions::NAN();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $numObjs ** $numInSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Functions::VALUE();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Permutations;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class PermutationATest extends TestCase
|
||||||
|
{
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider providerPERMUT
|
||||||
|
*
|
||||||
|
* @param mixed $expectedResult
|
||||||
|
*/
|
||||||
|
public function testPERMUT($expectedResult, ...$args): void
|
||||||
|
{
|
||||||
|
$result = Permutations::PERMUTATIONA(...$args);
|
||||||
|
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function providerPERMUT()
|
||||||
|
{
|
||||||
|
return require 'tests/data/Calculation/Statistical/PERMUTATIONA.php';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -45,6 +45,10 @@ return [
|
||||||
10068347520,
|
10068347520,
|
||||||
49, 6,
|
49, 6,
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
'#NUM!',
|
||||||
|
2, 3,
|
||||||
|
],
|
||||||
[
|
[
|
||||||
'#NUM!',
|
'#NUM!',
|
||||||
1, 2,
|
1, 2,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
5,
|
||||||
|
5, 1,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
2,
|
||||||
|
2.2, 1.1,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
5,
|
||||||
|
5.1, 1.9,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
1,
|
||||||
|
1, 2,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'#NUM!',
|
||||||
|
-1, 2,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'#VALUE!',
|
||||||
|
49, 'NaN',
|
||||||
|
],
|
||||||
|
];
|
||||||
Loading…
Reference in New Issue