Implementation of MS Excel's LOGNORM.DIST(), NORM.S.DIST(), F.DIST(), GAUSS() and GAMMA() functions (#1588)
* `GAUSS()` and `GAMMA()`, `NORM.S.DIST()`, `LOGNORM.DIST()` and `F.DIST()` function implementations, and further unit tests for a number of the statistical functions Co-authored-by: Adrien Crivelli <adrien.crivelli@gmail.com>
This commit is contained in:
		
							parent
							
								
									e084e89698
								
							
						
					
					
						commit
						57213deb64
					
				@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
 | 
			
		||||
 | 
			
		||||
### Added
 | 
			
		||||
 | 
			
		||||
- Nothing.
 | 
			
		||||
- Implementation of the Excel `LOGNORM.DIST()`, `NORM.S.DIST()`, `GAMMA()` and `GAUSS()` functions. [#1588](https://github.com/PHPOffice/PhpSpreadsheet/pull/1588)
 | 
			
		||||
 | 
			
		||||
### Changed
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -996,7 +996,7 @@ class Calculation
 | 
			
		||||
        ],
 | 
			
		||||
        'F.DIST' => [
 | 
			
		||||
            'category' => Category::CATEGORY_STATISTICAL,
 | 
			
		||||
            'functionCall' => [Functions::class, 'DUMMY'],
 | 
			
		||||
            'functionCall' => [Statistical::class, 'FDIST2'],
 | 
			
		||||
            'argumentCount' => '4',
 | 
			
		||||
        ],
 | 
			
		||||
        'F.DIST.RT' => [
 | 
			
		||||
@ -1133,7 +1133,7 @@ class Calculation
 | 
			
		||||
        ],
 | 
			
		||||
        'GAMMA' => [
 | 
			
		||||
            'category' => Category::CATEGORY_STATISTICAL,
 | 
			
		||||
            'functionCall' => [Functions::class, 'DUMMY'],
 | 
			
		||||
            'functionCall' => [Statistical::class, 'GAMMAFunction'],
 | 
			
		||||
            'argumentCount' => '1',
 | 
			
		||||
        ],
 | 
			
		||||
        'GAMMADIST' => [
 | 
			
		||||
@ -1168,7 +1168,7 @@ class Calculation
 | 
			
		||||
        ],
 | 
			
		||||
        'GAUSS' => [
 | 
			
		||||
            'category' => Category::CATEGORY_STATISTICAL,
 | 
			
		||||
            'functionCall' => [Functions::class, 'DUMMY'],
 | 
			
		||||
            'functionCall' => [Statistical::class, 'GAUSS'],
 | 
			
		||||
            'argumentCount' => '1',
 | 
			
		||||
        ],
 | 
			
		||||
        'GCD' => [
 | 
			
		||||
@ -1577,7 +1577,7 @@ class Calculation
 | 
			
		||||
        ],
 | 
			
		||||
        'LOGNORM.DIST' => [
 | 
			
		||||
            'category' => Category::CATEGORY_STATISTICAL,
 | 
			
		||||
            'functionCall' => [Functions::class, 'DUMMY'],
 | 
			
		||||
            'functionCall' => [Statistical::class, 'LOGNORMDIST2'],
 | 
			
		||||
            'argumentCount' => '4',
 | 
			
		||||
        ],
 | 
			
		||||
        'LOGNORM.INV' => [
 | 
			
		||||
@ -1782,7 +1782,7 @@ class Calculation
 | 
			
		||||
        ],
 | 
			
		||||
        'NORM.S.DIST' => [
 | 
			
		||||
            'category' => Category::CATEGORY_STATISTICAL,
 | 
			
		||||
            'functionCall' => [Functions::class, 'DUMMY'],
 | 
			
		||||
            'functionCall' => [Statistical::class, 'NORMSDIST2'],
 | 
			
		||||
            'argumentCount' => '1,2',
 | 
			
		||||
        ],
 | 
			
		||||
        'NORMSINV' => [
 | 
			
		||||
@ -3131,8 +3131,8 @@ class Calculation
 | 
			
		||||
            }
 | 
			
		||||
            //    Return strings wrapped in quotes
 | 
			
		||||
            return self::FORMULA_STRING_QUOTE . $value . self::FORMULA_STRING_QUOTE;
 | 
			
		||||
        //    Convert numeric errors to NaN error
 | 
			
		||||
        } elseif ((is_float($value)) && ((is_nan($value)) || (is_infinite($value)))) {
 | 
			
		||||
            //    Convert numeric errors to NaN error
 | 
			
		||||
            return Functions::NAN();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -3774,22 +3774,22 @@ class Calculation
 | 
			
		||||
        $pCellParent = ($pCell !== null) ? $pCell->getWorksheet() : null;
 | 
			
		||||
 | 
			
		||||
        $regexpMatchString = '/^(' . self::CALCULATION_REGEXP_FUNCTION .
 | 
			
		||||
                                '|' . self::CALCULATION_REGEXP_CELLREF .
 | 
			
		||||
                                '|' . self::CALCULATION_REGEXP_NUMBER .
 | 
			
		||||
                                '|' . self::CALCULATION_REGEXP_STRING .
 | 
			
		||||
                                '|' . self::CALCULATION_REGEXP_OPENBRACE .
 | 
			
		||||
                                '|' . self::CALCULATION_REGEXP_NAMEDRANGE .
 | 
			
		||||
                                '|' . self::CALCULATION_REGEXP_ERROR .
 | 
			
		||||
                                ')/sui';
 | 
			
		||||
            '|' . self::CALCULATION_REGEXP_CELLREF .
 | 
			
		||||
            '|' . self::CALCULATION_REGEXP_NUMBER .
 | 
			
		||||
            '|' . self::CALCULATION_REGEXP_STRING .
 | 
			
		||||
            '|' . self::CALCULATION_REGEXP_OPENBRACE .
 | 
			
		||||
            '|' . self::CALCULATION_REGEXP_NAMEDRANGE .
 | 
			
		||||
            '|' . self::CALCULATION_REGEXP_ERROR .
 | 
			
		||||
            ')/sui';
 | 
			
		||||
 | 
			
		||||
        //    Start with initialisation
 | 
			
		||||
        $index = 0;
 | 
			
		||||
        $stack = new Stack();
 | 
			
		||||
        $output = [];
 | 
			
		||||
        $expectingOperator = false; //    We use this test in syntax-checking the expression to determine when a
 | 
			
		||||
                                                    //        - is a negation or + is a positive operator rather than an operation
 | 
			
		||||
        //        - is a negation or + is a positive operator rather than an operation
 | 
			
		||||
        $expectingOperand = false; //    We use this test in syntax-checking the expression to determine whether an operand
 | 
			
		||||
                                                    //        should be null in a function call
 | 
			
		||||
        //        should be null in a function call
 | 
			
		||||
 | 
			
		||||
        // IF branch pruning
 | 
			
		||||
        // currently pending storeKey (last item of the storeKeysStack
 | 
			
		||||
@ -4172,7 +4172,7 @@ class Calculation
 | 
			
		||||
                    ((preg_match('/^' . self::CALCULATION_REGEXP_CELLREF . '.*/Ui', substr($formula, $index), $match)) &&
 | 
			
		||||
                        ($output[count($output) - 1]['type'] == 'Cell Reference') ||
 | 
			
		||||
                        (preg_match('/^' . self::CALCULATION_REGEXP_NAMEDRANGE . '.*/miu', substr($formula, $index), $match)) &&
 | 
			
		||||
                            ($output[count($output) - 1]['type'] == 'Named Range' || $output[count($output) - 1]['type'] == 'Value')
 | 
			
		||||
                        ($output[count($output) - 1]['type'] == 'Named Range' || $output[count($output) - 1]['type'] == 'Value')
 | 
			
		||||
                    )) {
 | 
			
		||||
                    while ($stack->count() > 0 &&
 | 
			
		||||
                        ($o2 = $stack->last()) &&
 | 
			
		||||
@ -4951,7 +4951,7 @@ class Calculation
 | 
			
		||||
        } else {
 | 
			
		||||
            if ((Functions::getCompatibilityMode() != Functions::COMPATIBILITY_OPENOFFICE) &&
 | 
			
		||||
                ((is_string($operand1) && !is_numeric($operand1) && strlen($operand1) > 0) ||
 | 
			
		||||
                 (is_string($operand2) && !is_numeric($operand2) && strlen($operand2) > 0))) {
 | 
			
		||||
                    (is_string($operand2) && !is_numeric($operand2) && strlen($operand2) > 0))) {
 | 
			
		||||
                $result = Functions::VALUE();
 | 
			
		||||
            } else {
 | 
			
		||||
                //    If we're dealing with non-matrix operations, execute the necessary operation
 | 
			
		||||
@ -4980,7 +4980,7 @@ class Calculation
 | 
			
		||||
 | 
			
		||||
                            return false;
 | 
			
		||||
                        }
 | 
			
		||||
                            $result = $operand1 / $operand2;
 | 
			
		||||
                        $result = $operand1 / $operand2;
 | 
			
		||||
 | 
			
		||||
                        break;
 | 
			
		||||
                    //    Power
 | 
			
		||||
 | 
			
		||||
@ -779,7 +779,7 @@ class Statistical
 | 
			
		||||
    /**
 | 
			
		||||
     * BETAINV.
 | 
			
		||||
     *
 | 
			
		||||
     * Returns the inverse of the beta distribution.
 | 
			
		||||
     * Returns the inverse of the Beta distribution.
 | 
			
		||||
     *
 | 
			
		||||
     * @param float $probability Probability at which you want to evaluate the distribution
 | 
			
		||||
     * @param float $alpha Parameter to the distribution
 | 
			
		||||
@ -1475,6 +1475,62 @@ class Statistical
 | 
			
		||||
        return Functions::VALUE();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static function betaFunction($a, $b)
 | 
			
		||||
    {
 | 
			
		||||
        return (self::gamma($a) * self::gamma($b)) / self::gamma($a + $b);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static function regularizedIncompleteBeta($value, $a, $b)
 | 
			
		||||
    {
 | 
			
		||||
        return self::incompleteBeta($value, $a, $b) / self::betaFunction($a, $b);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * F.DIST.
 | 
			
		||||
     *
 | 
			
		||||
     *    Returns the F probability distribution.
 | 
			
		||||
     *    You can use this function to determine whether two data sets have different degrees of diversity.
 | 
			
		||||
     *    For example, you can examine the test scores of men and women entering high school, and determine
 | 
			
		||||
     *        if the variability in the females is different from that found in the males.
 | 
			
		||||
     *
 | 
			
		||||
     * @param float $value Value of the function
 | 
			
		||||
     * @param int $u The numerator degrees of freedom
 | 
			
		||||
     * @param int $v The denominator degrees of freedom
 | 
			
		||||
     * @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
 | 
			
		||||
     */
 | 
			
		||||
    public static function FDIST2($value, $u, $v, $cumulative)
 | 
			
		||||
    {
 | 
			
		||||
        $value = Functions::flattenSingleValue($value);
 | 
			
		||||
        $u = Functions::flattenSingleValue($u);
 | 
			
		||||
        $v = Functions::flattenSingleValue($v);
 | 
			
		||||
        $cumulative = Functions::flattenSingleValue($cumulative);
 | 
			
		||||
 | 
			
		||||
        if (is_numeric($value) && is_numeric($u) && is_numeric($v)) {
 | 
			
		||||
            if ($value < 0 || $u < 1 || $v < 1) {
 | 
			
		||||
                return Functions::NAN();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $cumulative = (bool) $cumulative;
 | 
			
		||||
            $u = (int) $u;
 | 
			
		||||
            $v = (int) $v;
 | 
			
		||||
 | 
			
		||||
            if ($cumulative) {
 | 
			
		||||
                $adjustedValue = ($u * $value) / ($u * $value + $v);
 | 
			
		||||
 | 
			
		||||
                return self::incompleteBeta($adjustedValue, $u / 2, $v / 2);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return (self::gamma(($v + $u) / 2) / (self::gamma($u / 2) * self::gamma($v / 2))) *
 | 
			
		||||
                (($u / $v) ** ($u / 2)) *
 | 
			
		||||
                (($value ** (($u - 2) / 2)) / ((1 + ($u / $v) * $value) ** (($u + $v) / 2)));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return Functions::VALUE();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * FISHER.
 | 
			
		||||
     *
 | 
			
		||||
@ -1556,6 +1612,27 @@ class Statistical
 | 
			
		||||
        return $bestFitLinear->getValueOfYForX($xValue);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * GAMMA.
 | 
			
		||||
     *
 | 
			
		||||
     * Return the gamma function value.
 | 
			
		||||
     *
 | 
			
		||||
     * @param float $value
 | 
			
		||||
     *
 | 
			
		||||
     * @return float|string The result, or a string containing an error
 | 
			
		||||
     */
 | 
			
		||||
    public static function GAMMAFunction($value)
 | 
			
		||||
    {
 | 
			
		||||
        $value = Functions::flattenSingleValue($value);
 | 
			
		||||
        if (!is_numeric($value)) {
 | 
			
		||||
            return Functions::VALUE();
 | 
			
		||||
        } elseif ((((int) $value) == ((float) $value)) && $value <= 0.0) {
 | 
			
		||||
            return Functions::NAN();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return self::gamma($value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * GAMMADIST.
 | 
			
		||||
     *
 | 
			
		||||
@ -1593,7 +1670,7 @@ class Statistical
 | 
			
		||||
    /**
 | 
			
		||||
     * GAMMAINV.
 | 
			
		||||
     *
 | 
			
		||||
     * Returns the inverse of the beta distribution.
 | 
			
		||||
     * Returns the inverse of the Gamma distribution.
 | 
			
		||||
     *
 | 
			
		||||
     * @param float $probability Probability at which you want to evaluate the distribution
 | 
			
		||||
     * @param float $alpha Parameter to the distribution
 | 
			
		||||
@ -1677,6 +1754,26 @@ class Statistical
 | 
			
		||||
        return Functions::VALUE();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * GAUSS.
 | 
			
		||||
     *
 | 
			
		||||
     * Calculates the probability that a member of a standard normal population will fall between
 | 
			
		||||
     *     the mean and z standard deviations from the mean.
 | 
			
		||||
     *
 | 
			
		||||
     * @param float $value
 | 
			
		||||
     *
 | 
			
		||||
     * @return float|string The result, or a string containing an error
 | 
			
		||||
     */
 | 
			
		||||
    public static function GAUSS($value)
 | 
			
		||||
    {
 | 
			
		||||
        $value = Functions::flattenSingleValue($value);
 | 
			
		||||
        if (!is_numeric($value)) {
 | 
			
		||||
            return Functions::VALUE();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return self::NORMDIST($value, 0, 1, true) - 0.5;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * GEOMEAN.
 | 
			
		||||
     *
 | 
			
		||||
@ -2117,6 +2214,42 @@ class Statistical
 | 
			
		||||
        return Functions::VALUE();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * LOGNORM.DIST.
 | 
			
		||||
     *
 | 
			
		||||
     * Returns the lognormal distribution of x, where ln(x) is normally distributed
 | 
			
		||||
     * with parameters mean and standard_dev.
 | 
			
		||||
     *
 | 
			
		||||
     * @param float $value
 | 
			
		||||
     * @param float $mean
 | 
			
		||||
     * @param float $stdDev
 | 
			
		||||
     * @param bool $cumulative
 | 
			
		||||
     *
 | 
			
		||||
     * @return float|string The result, or a string containing an error
 | 
			
		||||
     */
 | 
			
		||||
    public static function LOGNORMDIST2($value, $mean, $stdDev, $cumulative = false)
 | 
			
		||||
    {
 | 
			
		||||
        $value = Functions::flattenSingleValue($value);
 | 
			
		||||
        $mean = Functions::flattenSingleValue($mean);
 | 
			
		||||
        $stdDev = Functions::flattenSingleValue($stdDev);
 | 
			
		||||
        $cumulative = (bool) Functions::flattenSingleValue($cumulative);
 | 
			
		||||
 | 
			
		||||
        if ((is_numeric($value)) && (is_numeric($mean)) && (is_numeric($stdDev))) {
 | 
			
		||||
            if (($value <= 0) || ($stdDev <= 0)) {
 | 
			
		||||
                return Functions::NAN();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ($cumulative === true) {
 | 
			
		||||
                return self::NORMSDIST2((log($value) - $mean) / $stdDev, true);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return (1 / (sqrt(2 * M_PI) * $stdDev * $value)) *
 | 
			
		||||
                exp(0 - ((log($value) - $mean) ** 2 / (2 * $stdDev ** 2)));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return Functions::VALUE();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * MAX.
 | 
			
		||||
     *
 | 
			
		||||
@ -2623,10 +2756,36 @@ class Statistical
 | 
			
		||||
    public static function NORMSDIST($value)
 | 
			
		||||
    {
 | 
			
		||||
        $value = Functions::flattenSingleValue($value);
 | 
			
		||||
        if (!is_numeric($value)) {
 | 
			
		||||
            return Functions::VALUE();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return self::NORMDIST($value, 0, 1, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * NORM.S.DIST.
 | 
			
		||||
     *
 | 
			
		||||
     * Returns the standard normal cumulative distribution function. The distribution has
 | 
			
		||||
     * a mean of 0 (zero) and a standard deviation of one. Use this function in place of a
 | 
			
		||||
     * table of standard normal curve areas.
 | 
			
		||||
     *
 | 
			
		||||
     * @param float $value
 | 
			
		||||
     * @param bool $cumulative
 | 
			
		||||
     *
 | 
			
		||||
     * @return float|string The result, or a string containing an error
 | 
			
		||||
     */
 | 
			
		||||
    public static function NORMSDIST2($value, $cumulative)
 | 
			
		||||
    {
 | 
			
		||||
        $value = Functions::flattenSingleValue($value);
 | 
			
		||||
        if (!is_numeric($value)) {
 | 
			
		||||
            return Functions::VALUE();
 | 
			
		||||
        }
 | 
			
		||||
        $cumulative = (bool) Functions::flattenSingleValue($cumulative);
 | 
			
		||||
 | 
			
		||||
        return self::NORMDIST($value, 0, 1, $cumulative);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * NORMSINV.
 | 
			
		||||
     *
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,25 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
 | 
			
		||||
 | 
			
		||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
 | 
			
		||||
use PHPUnit\Framework\TestCase;
 | 
			
		||||
 | 
			
		||||
class FDist2Test extends TestCase
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @dataProvider providerFDIST2
 | 
			
		||||
     *
 | 
			
		||||
     * @param mixed $expectedResult
 | 
			
		||||
     */
 | 
			
		||||
    public function testFDIST2($expectedResult, ...$args): void
 | 
			
		||||
    {
 | 
			
		||||
        $result = Statistical::FDIST2(...$args);
 | 
			
		||||
        self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function providerFDIST2(): array
 | 
			
		||||
    {
 | 
			
		||||
        return require 'tests/data/Calculation/Statistical/FDIST2.php';
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,26 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
 | 
			
		||||
 | 
			
		||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
 | 
			
		||||
use PHPUnit\Framework\TestCase;
 | 
			
		||||
 | 
			
		||||
class GammaTest extends TestCase
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @dataProvider providerGAMMA
 | 
			
		||||
     *
 | 
			
		||||
     * @param mixed $expectedResult
 | 
			
		||||
     * @param mixed $testValue
 | 
			
		||||
     */
 | 
			
		||||
    public function testGAMMA($expectedResult, $testValue): void
 | 
			
		||||
    {
 | 
			
		||||
        $result = Statistical::GAMMAFunction($testValue);
 | 
			
		||||
        self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function providerGAMMA(): array
 | 
			
		||||
    {
 | 
			
		||||
        return require 'tests/data/Calculation/Statistical/GAMMA.php';
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,26 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
 | 
			
		||||
 | 
			
		||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
 | 
			
		||||
use PHPUnit\Framework\TestCase;
 | 
			
		||||
 | 
			
		||||
class GaussTest extends TestCase
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @dataProvider providerGAUSS
 | 
			
		||||
     *
 | 
			
		||||
     * @param mixed $expectedResult
 | 
			
		||||
     * @param mixed $testValue
 | 
			
		||||
     */
 | 
			
		||||
    public function testGAUSS($expectedResult, $testValue): void
 | 
			
		||||
    {
 | 
			
		||||
        $result = Statistical::GAUSS($testValue);
 | 
			
		||||
        self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function providerGAUSS(): array
 | 
			
		||||
    {
 | 
			
		||||
        return require 'tests/data/Calculation/Statistical/GAUSS.php';
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,25 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
 | 
			
		||||
 | 
			
		||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
 | 
			
		||||
use PHPUnit\Framework\TestCase;
 | 
			
		||||
 | 
			
		||||
class LogNormDist2Test extends TestCase
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @dataProvider providerLOGNORMDIST2
 | 
			
		||||
     *
 | 
			
		||||
     * @param mixed $expectedResult
 | 
			
		||||
     */
 | 
			
		||||
    public function testLOGNORMDIST2($expectedResult, ...$args): void
 | 
			
		||||
    {
 | 
			
		||||
        $result = Statistical::LOGNORMDIST2(...$args);
 | 
			
		||||
        self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function providerLOGNORMDIST2(): array
 | 
			
		||||
    {
 | 
			
		||||
        return require 'tests/data/Calculation/Statistical/LOGNORMDIST2.php';
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,25 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
 | 
			
		||||
 | 
			
		||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
 | 
			
		||||
use PHPUnit\Framework\TestCase;
 | 
			
		||||
 | 
			
		||||
class LogNormDistTest extends TestCase
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @dataProvider providerLOGNORMDIST
 | 
			
		||||
     *
 | 
			
		||||
     * @param mixed $expectedResult
 | 
			
		||||
     */
 | 
			
		||||
    public function testLOGNORMDIST($expectedResult, ...$args): void
 | 
			
		||||
    {
 | 
			
		||||
        $result = Statistical::LOGNORMDIST(...$args);
 | 
			
		||||
        self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function providerLOGNORMDIST(): array
 | 
			
		||||
    {
 | 
			
		||||
        return require 'tests/data/Calculation/Statistical/LOGNORMDIST.php';
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,25 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
 | 
			
		||||
 | 
			
		||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
 | 
			
		||||
use PHPUnit\Framework\TestCase;
 | 
			
		||||
 | 
			
		||||
class NormDistTest extends TestCase
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @dataProvider providerNORMDIST
 | 
			
		||||
     *
 | 
			
		||||
     * @param mixed $expectedResult
 | 
			
		||||
     */
 | 
			
		||||
    public function testNORMDIST($expectedResult, ...$args): void
 | 
			
		||||
    {
 | 
			
		||||
        $result = Statistical::NORMDIST(...$args);
 | 
			
		||||
        self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function providerNORMDIST(): array
 | 
			
		||||
    {
 | 
			
		||||
        return require 'tests/data/Calculation/Statistical/NORMDIST.php';
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,25 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
 | 
			
		||||
 | 
			
		||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
 | 
			
		||||
use PHPUnit\Framework\TestCase;
 | 
			
		||||
 | 
			
		||||
class NormInvTest extends TestCase
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @dataProvider providerNORMINV
 | 
			
		||||
     *
 | 
			
		||||
     * @param mixed $expectedResult
 | 
			
		||||
     */
 | 
			
		||||
    public function testNORMINV($expectedResult, ...$args): void
 | 
			
		||||
    {
 | 
			
		||||
        $result = Statistical::NORMINV(...$args);
 | 
			
		||||
        self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function providerNORMINV()
 | 
			
		||||
    {
 | 
			
		||||
        return require 'tests/data/Calculation/Statistical/NORMINV.php';
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,25 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
 | 
			
		||||
 | 
			
		||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
 | 
			
		||||
use PHPUnit\Framework\TestCase;
 | 
			
		||||
 | 
			
		||||
class NormSDist2Test extends TestCase
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @dataProvider providerNORMSDIST2
 | 
			
		||||
     *
 | 
			
		||||
     * @param mixed $expectedResult
 | 
			
		||||
     */
 | 
			
		||||
    public function testNORMSDIST2($expectedResult, ...$args): void
 | 
			
		||||
    {
 | 
			
		||||
        $result = Statistical::NORMSDIST2(...$args);
 | 
			
		||||
        self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function providerNORMSDIST2(): array
 | 
			
		||||
    {
 | 
			
		||||
        return require 'tests/data/Calculation/Statistical/NORMSDIST2.php';
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,26 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
 | 
			
		||||
 | 
			
		||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
 | 
			
		||||
use PHPUnit\Framework\TestCase;
 | 
			
		||||
 | 
			
		||||
class NormSDistTest extends TestCase
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @dataProvider providerNORMSDIST
 | 
			
		||||
     *
 | 
			
		||||
     * @param mixed $expectedResult
 | 
			
		||||
     * @param mixed $testValue
 | 
			
		||||
     */
 | 
			
		||||
    public function testNORMSDIST($expectedResult, $testValue): void
 | 
			
		||||
    {
 | 
			
		||||
        $result = Statistical::NORMSDIST($testValue);
 | 
			
		||||
        self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function providerNORMSDIST(): array
 | 
			
		||||
    {
 | 
			
		||||
        return require 'tests/data/Calculation/Statistical/NORMSDIST.php';
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,26 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
 | 
			
		||||
 | 
			
		||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
 | 
			
		||||
use PHPUnit\Framework\TestCase;
 | 
			
		||||
 | 
			
		||||
class NormSInvTest extends TestCase
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @dataProvider providerNORMSINV
 | 
			
		||||
     *
 | 
			
		||||
     * @param mixed $expectedResult
 | 
			
		||||
     * @param mixed $testValue
 | 
			
		||||
     */
 | 
			
		||||
    public function testNORMSINV($expectedResult, $testValue): void
 | 
			
		||||
    {
 | 
			
		||||
        $result = Statistical::NORMSINV($testValue);
 | 
			
		||||
        self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function providerNORMSINV(): array
 | 
			
		||||
    {
 | 
			
		||||
        return require 'tests/data/Calculation/Statistical/NORMSINV.php';
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,25 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
 | 
			
		||||
 | 
			
		||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
 | 
			
		||||
use PHPUnit\Framework\TestCase;
 | 
			
		||||
 | 
			
		||||
class StandardizeTest extends TestCase
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @dataProvider providerSTANDARDIZE
 | 
			
		||||
     *
 | 
			
		||||
     * @param mixed $expectedResult
 | 
			
		||||
     */
 | 
			
		||||
    public function testSTANDARDIZE($expectedResult, ...$args): void
 | 
			
		||||
    {
 | 
			
		||||
        $result = Statistical::STANDARDIZE(...$args);
 | 
			
		||||
        self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function providerSTANDARDIZE(): array
 | 
			
		||||
    {
 | 
			
		||||
        return require 'tests/data/Calculation/Statistical/STANDARDIZE.php';
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								tests/data/Calculation/Statistical/FDIST2.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								tests/data/Calculation/Statistical/FDIST2.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
return [
 | 
			
		||||
    [0.0012237917087, 15.2069, 6, 4, false],
 | 
			
		||||
    [0.99000004300276, 15.2069, 6, 4, true],
 | 
			
		||||
    [0.0241472644208, 5, 1, 2, false],
 | 
			
		||||
    [0.84515425472852, 5, 1, 2, true],
 | 
			
		||||
    [0.0006669496615, 65, 2, 1, false],
 | 
			
		||||
    [0.9126295943339, 65, 2, 1, true],
 | 
			
		||||
    [4.7306581130012E-6, 65, 8, 5, false],
 | 
			
		||||
    [0.99987479238344, 65, 8, 5, true],
 | 
			
		||||
    [0.0017323823929, 7.5, 13, 8, false],
 | 
			
		||||
    [0.9961476916638, 7.5, 13, 8, true],
 | 
			
		||||
    ['#NUM!', -1, 1, 2, false],
 | 
			
		||||
    ['#NUM!', -1, 0.5, 2, false],
 | 
			
		||||
    ['#VALUE!', 'NAN', 1, 2, false],
 | 
			
		||||
];
 | 
			
		||||
							
								
								
									
										13
									
								
								tests/data/Calculation/Statistical/GAMMA.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								tests/data/Calculation/Statistical/GAMMA.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,13 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
return [
 | 
			
		||||
    [1.329340388179, 2.5],
 | 
			
		||||
    [0.267865934620, -3.75],
 | 
			
		||||
    [9.513507698669, 0.1],
 | 
			
		||||
    [1.0, 1.0],
 | 
			
		||||
    [0.886226925453, 1.5],
 | 
			
		||||
    [17.837861981813, 4.8],
 | 
			
		||||
    [52.342777784553, 5.5],
 | 
			
		||||
    ['#NUM!', -1],
 | 
			
		||||
    ['#VALUE!', 'NAN'],
 | 
			
		||||
];
 | 
			
		||||
							
								
								
									
										10
									
								
								tests/data/Calculation/Statistical/GAUSS.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								tests/data/Calculation/Statistical/GAUSS.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,10 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
return [
 | 
			
		||||
    [0.4772498680518, 2],
 | 
			
		||||
    [-0.4999997133484, -5],
 | 
			
		||||
    [0.0, 0],
 | 
			
		||||
    [0.0398278372770, 0.1],
 | 
			
		||||
    [0.4937903346742, 2.5],
 | 
			
		||||
    ['#VALUE!', 'NAN'],
 | 
			
		||||
];
 | 
			
		||||
							
								
								
									
										9
									
								
								tests/data/Calculation/Statistical/LOGNORMDIST.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								tests/data/Calculation/Statistical/LOGNORMDIST.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
return[
 | 
			
		||||
    [0.0390835557068, 4, 3.5, 1.2],
 | 
			
		||||
    [0.066417114799, 12, 10, 5],
 | 
			
		||||
    ['#NUM!', -1.1, -2.2, 3.3],
 | 
			
		||||
    ['#NUM!', 1.1, -2.2, -3.3],
 | 
			
		||||
    ['#VALUE!', 'NAN', 0.1, 0.2],
 | 
			
		||||
];
 | 
			
		||||
							
								
								
									
										23
									
								
								tests/data/Calculation/Statistical/LOGNORMDIST2.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								tests/data/Calculation/Statistical/LOGNORMDIST2.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,23 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
return[
 | 
			
		||||
    [0.0390835557068, 4, 3.5, 1.2, true],
 | 
			
		||||
    [0.0176175966818, 4, 3.5, 1.2, false],
 | 
			
		||||
    [0.0162328457851, 0.5, 10, 5, true],
 | 
			
		||||
    [0.0162104821842, 0.5, 10, 5, false],
 | 
			
		||||
    [0.0664171147992, 12, 10, 5, true],
 | 
			
		||||
    [0.0021488646273, 12, 10, 5, false],
 | 
			
		||||
    [0.0201708646513, 8, 7, 2.4, true],
 | 
			
		||||
    [0.0025400389694, 8, 7, 2.4, false],
 | 
			
		||||
    [0.0390835557068, 4, 3.5, 1.2, true],
 | 
			
		||||
    [0.0176175966818, 4, 3.5, 1.2, false],
 | 
			
		||||
    [0.0847348867430, 3, 2.5, 1.02, true],
 | 
			
		||||
    [0.0507335863525, 3, 2.5, 1.02, false],
 | 
			
		||||
    [0.2618068896629, 1.1, 2.2, 3.3, true],
 | 
			
		||||
    [0.0896756593248, 1.1, 2.2, 3.3, false],
 | 
			
		||||
    [0.7566441984111, 1.1, -2.2, 3.3, true],
 | 
			
		||||
    [0.0862879718374, 1.1, -2.2, 3.3, false],
 | 
			
		||||
    ['#NUM!', -1.1, -2.2, 3.3, true],
 | 
			
		||||
    ['#NUM!', 1.1, -2.2, -3.3, true],
 | 
			
		||||
    ['#VALUE!', 'NAN', 0.1, 0.2, true],
 | 
			
		||||
];
 | 
			
		||||
							
								
								
									
										11
									
								
								tests/data/Calculation/Statistical/NORMDIST.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								tests/data/Calculation/Statistical/NORMDIST.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,11 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
return [
 | 
			
		||||
    [0.9087887802741, 42, 40, 1.5, true],
 | 
			
		||||
    [0.109340049784, 42, 40, 1.5, false],
 | 
			
		||||
    [0.0176032663382, 50, 40, 20, false],
 | 
			
		||||
    [0.2524925375469, 0.8, 1, 0.3, true],
 | 
			
		||||
    [0.8413447460685, 68, 65.5, 2.5, true],
 | 
			
		||||
    ['#NUM!', 42, 40, -1.5, true],
 | 
			
		||||
    ['#VALUE!', 42, 'ALPHA', 1.5, true],
 | 
			
		||||
];
 | 
			
		||||
							
								
								
									
										11
									
								
								tests/data/Calculation/Statistical/NORMINV.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								tests/data/Calculation/Statistical/NORMINV.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,11 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
return [
 | 
			
		||||
    [42.000002008416, 0.908789, 40, 1.5],
 | 
			
		||||
    [5.50669420572, 0.6, 5, 2],
 | 
			
		||||
    [63.813775624441, 0.25, 65.5, 2.5],
 | 
			
		||||
    ['#NUM!', -0.5, 2.2, 3.3],
 | 
			
		||||
    ['#NUM!', 1.5, 2.2, 3.3],
 | 
			
		||||
    ['#NUM!', 0.5, 2.2, -3.3],
 | 
			
		||||
    ['#VALUE!', 'NAN', 0.1, 0.2],
 | 
			
		||||
];
 | 
			
		||||
							
								
								
									
										12
									
								
								tests/data/Calculation/Statistical/NORMSDIST.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								tests/data/Calculation/Statistical/NORMSDIST.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
return [
 | 
			
		||||
    [0.908788780274, 1.333333333333],
 | 
			
		||||
    [0.788144601416, 0.8],
 | 
			
		||||
    [0.841344746068, 1.0],
 | 
			
		||||
    [0.158655253931, -1.0],
 | 
			
		||||
    [0.066807201269, -1.5],
 | 
			
		||||
    [0.5, 0],
 | 
			
		||||
    [0.989275889978, 2.3],
 | 
			
		||||
    ['#VALUE!', 'NAN'],
 | 
			
		||||
];
 | 
			
		||||
							
								
								
									
										17
									
								
								tests/data/Calculation/Statistical/NORMSDIST2.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								tests/data/Calculation/Statistical/NORMSDIST2.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
return [
 | 
			
		||||
    [0.908788780274, 1.333333333333, true],
 | 
			
		||||
    [0.164010074676, 1.333333333333, false],
 | 
			
		||||
    [0.352065326764, 0.5, false],
 | 
			
		||||
    [0.788144601416, 0.8, true],
 | 
			
		||||
    [0.841344746068, 1.0, true],
 | 
			
		||||
    [0.158655253931, -1.0, true],
 | 
			
		||||
    [0.066807201269, -1.5, true],
 | 
			
		||||
    [0.129517595666, -1.5, false],
 | 
			
		||||
    [0.5, 0, true],
 | 
			
		||||
    [0.398942280401, 0, false],
 | 
			
		||||
    [0.989275889978, 2.3, true],
 | 
			
		||||
    [0.028327037742, 2.3, false],
 | 
			
		||||
    ['#VALUE!', 'NAN', true],
 | 
			
		||||
];
 | 
			
		||||
							
								
								
									
										8
									
								
								tests/data/Calculation/Statistical/NORMSINV.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								tests/data/Calculation/Statistical/NORMSINV.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,8 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
return [
 | 
			
		||||
    [1.33333467227723, 0.908789],
 | 
			
		||||
    [-0.67448975022342, 0.25],
 | 
			
		||||
    [0.12566134687610, 0.55],
 | 
			
		||||
    [1.28155156414015, 0.9],
 | 
			
		||||
];
 | 
			
		||||
							
								
								
									
										12
									
								
								tests/data/Calculation/Statistical/STANDARDIZE.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								tests/data/Calculation/Statistical/STANDARDIZE.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
return [
 | 
			
		||||
    [1.333333333333, 42, 40, 1.5],
 | 
			
		||||
    [0.25, 5.5, 5, 2],
 | 
			
		||||
    [20, 5.5, 1.5, 0.2],
 | 
			
		||||
    [-2.0, 12, 15, 1.5],
 | 
			
		||||
    [-0.4, -2, 0, 5],
 | 
			
		||||
    [-0.676, 63.81, 65.5, 2.5],
 | 
			
		||||
    ['#NUM!', 1.1, -2.2, -3.3],
 | 
			
		||||
    ['#VALUE!', 'NAN', 0.1, 0.2],
 | 
			
		||||
];
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user