Extract Poisson distribution into its own class (#1953)

This commit is contained in:
Mark Baker 2021-03-26 09:08:23 +01:00 committed by GitHub
parent f51c19c125
commit c380b25d3c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 138 additions and 88 deletions

View File

@ -1963,12 +1963,12 @@ class Calculation
], ],
'POISSON' => [ 'POISSON' => [
'category' => Category::CATEGORY_STATISTICAL, 'category' => Category::CATEGORY_STATISTICAL,
'functionCall' => [Statistical::class, 'POISSON'], 'functionCall' => [Statistical\Distributions\Poisson::class, 'distribution'],
'argumentCount' => '3', 'argumentCount' => '3',
], ],
'POISSON.DIST' => [ 'POISSON.DIST' => [
'category' => Category::CATEGORY_STATISTICAL, 'category' => Category::CATEGORY_STATISTICAL,
'functionCall' => [Statistical::class, 'POISSON'], 'functionCall' => [Statistical\Distributions\Poisson::class, 'distribution'],
'argumentCount' => '3', 'argumentCount' => '3',
], ],
'POWER' => [ 'POWER' => [

View File

@ -22,7 +22,7 @@ class Days360
* PHP DateTime object, or a standard date string * PHP DateTime object, or a standard date string
* @param mixed $endDate Excel date serial value (float), PHP date timestamp (integer), * @param mixed $endDate Excel date serial value (float), PHP date timestamp (integer),
* PHP DateTime object, or a standard date string * PHP DateTime object, or a standard date string
* @param bool $method US or European Method * @param mixed (bool) $method US or European Method
* FALSE or omitted: U.S. (NASD) method. If the starting date is * FALSE or omitted: U.S. (NASD) method. If the starting date is
* the last day of a month, it becomes equal to the 30th of the * the last day of a month, it becomes equal to the 30th of the
* same month. If the ending date is the last day of a month and * same month. If the ending date is the last day of a month and

View File

@ -16,9 +16,9 @@ class Complex
* Excel Function: * Excel Function:
* COMPLEX(realNumber,imaginary[,suffix]) * COMPLEX(realNumber,imaginary[,suffix])
* *
* @param float $realNumber the real coefficient of the complex number * @param mixed (float) $realNumber the real coefficient of the complex number
* @param float $imaginary the imaginary coefficient of the complex number * @param mixed (float) $imaginary the imaginary coefficient of the complex number
* @param string $suffix The suffix for the imaginary component of the complex number. * @param mixed (string) $suffix The suffix for the imaginary component of the complex number.
* If omitted, the suffix is assumed to be "i". * If omitted, the suffix is assumed to be "i".
* *
* @return string * @return string

View File

@ -42,15 +42,15 @@ class Financial
* @param mixed $settlement The security's settlement date. * @param mixed $settlement The security's settlement date.
* The security settlement date is the date after the issue date * The security settlement date is the date after the issue date
* when the security is traded to the buyer. * when the security is traded to the buyer.
* @param float $rate the security's annual coupon rate * @param mixed (float) $rate the security's annual coupon rate
* @param float $par The security's par value. * @param mixed (float) $par The security's par value.
* If you omit par, ACCRINT uses $1,000. * If you omit par, ACCRINT uses $1,000.
* @param int $frequency the number of coupon payments per year. * @param mixed (int) $frequency the number of coupon payments per year.
* Valid frequency values are: * Valid frequency values are:
* 1 Annual * 1 Annual
* 2 Semi-Annual * 2 Semi-Annual
* 4 Quarterly * 4 Quarterly
* @param int $basis The type of day count to use. * @param mixed (int) $basis The type of day count to use.
* 0 or omitted US (NASD) 30/360 * 0 or omitted US (NASD) 30/360
* 1 Actual/actual * 1 Actual/actual
* 2 Actual/360 * 2 Actual/360
@ -98,10 +98,10 @@ class Financial
* *
* @param mixed $issue The security's issue date * @param mixed $issue The security's issue date
* @param mixed $settlement The security's settlement (or maturity) date * @param mixed $settlement The security's settlement (or maturity) date
* @param float $rate The security's annual coupon rate * @param mixed (float) $rate The security's annual coupon rate
* @param float $par The security's par value. * @param mixed (float) $par The security's par value.
* If you omit par, ACCRINT uses $1,000. * If you omit par, ACCRINT uses $1,000.
* @param int $basis The type of day count to use. * @param mixed (int) $basis The type of day count to use.
* 0 or omitted US (NASD) 30/360 * 0 or omitted US (NASD) 30/360
* 1 Actual/actual * 1 Actual/actual
* 2 Actual/360 * 2 Actual/360
@ -890,11 +890,11 @@ class Financial
* Excel Function: * Excel Function:
* IRR(values[,guess]) * IRR(values[,guess])
* *
* @param float[] $values An array or a reference to cells that contain numbers for which you want * @param mixed (float[]) $values An array or a reference to cells that contain numbers for which you want
* to calculate the internal rate of return. * to calculate the internal rate of return.
* Values must contain at least one positive value and one negative value to * Values must contain at least one positive value and one negative value to
* calculate the internal rate of return. * calculate the internal rate of return.
* @param float $guess A number that you guess is close to the result of IRR * @param mixed (float) $guess A number that you guess is close to the result of IRR
* *
* @return float|string * @return float|string
*/ */
@ -1000,11 +1000,11 @@ class Financial
* Excel Function: * Excel Function:
* MIRR(values,finance_rate, reinvestment_rate) * MIRR(values,finance_rate, reinvestment_rate)
* *
* @param float[] $values An array or a reference to cells that contain a series of payments and * @param mixed (float[]) $values An array or a reference to cells that contain a series of payments and
* income occurring at regular intervals. * income occurring at regular intervals.
* Payments are negative value, income is positive values. * Payments are negative value, income is positive values.
* @param float $finance_rate The interest rate you pay on the money used in the cash flows * @param mixed (float) $finance_rate The interest rate you pay on the money used in the cash flows
* @param float $reinvestment_rate The interest rate you receive on the cash flows as you reinvest them * @param mixed (float) $reinvestment_rate The interest rate you receive on the cash flows as you reinvest them
* *
* @return float|string Result, or a string containing an error * @return float|string Result, or a string containing an error
*/ */
@ -1371,20 +1371,20 @@ class Financial
* Excel Function: * Excel Function:
* RATE(nper,pmt,pv[,fv[,type[,guess]]]) * RATE(nper,pmt,pv[,fv[,type[,guess]]])
* *
* @param float $nper The total number of payment periods in an annuity * @param mixed (float) $nper The total number of payment periods in an annuity
* @param float $pmt The payment made each period and cannot change over the life * @param mixed (float) $pmt The payment made each period and cannot change over the life
* of the annuity. * of the annuity.
* Typically, pmt includes principal and interest but no other * Typically, pmt includes principal and interest but no other
* fees or taxes. * fees or taxes.
* @param float $pv The present value - the total amount that a series of future * @param mixed (float) $pv The present value - the total amount that a series of future
* payments is worth now * payments is worth now
* @param float $fv The future value, or a cash balance you want to attain after * @param mixed (float) $fv The future value, or a cash balance you want to attain after
* the last payment is made. If fv is omitted, it is assumed * the last payment is made. If fv is omitted, it is assumed
* to be 0 (the future value of a loan, for example, is 0). * to be 0 (the future value of a loan, for example, is 0).
* @param int $type A number 0 or 1 and indicates when payments are due: * @param mixed (int) $type A number 0 or 1 and indicates when payments are due:
* 0 or omitted At the end of the period. * 0 or omitted At the end of the period.
* 1 At the beginning of the period. * 1 At the beginning of the period.
* @param float $guess Your guess for what the rate will be. * @param mixed (float) $guess Your guess for what the rate will be.
* If you omit guess, it is assumed to be 10 percent. * If you omit guess, it is assumed to be 10 percent.
* *
* @return float|string * @return float|string
@ -1443,9 +1443,9 @@ class Financial
* The security settlement date is the date after the issue date when the security is traded to the buyer. * The security settlement date is the date after the issue date when the security is traded to the buyer.
* @param mixed $maturity The security's maturity date. * @param mixed $maturity The security's maturity date.
* The maturity date is the date when the security expires. * The maturity date is the date when the security expires.
* @param int $investment The amount invested in the security * @param mixed (int) $investment The amount invested in the security
* @param int $discount The security's discount rate * @param mixed (int) $discount The security's discount rate
* @param int $basis The type of day count to use. * @param mixed (int) $basis The type of day count to use.
* 0 or omitted US (NASD) 30/360 * 0 or omitted US (NASD) 30/360
* 1 Actual/actual * 1 Actual/actual
* 2 Actual/360 * 2 Actual/360

View File

@ -137,9 +137,9 @@ class Depreciation
* *
* Returns the straight-line depreciation of an asset for one period * Returns the straight-line depreciation of an asset for one period
* *
* @param mixed $cost Initial cost of the asset * @param mixed (float) $cost Initial cost of the asset
* @param mixed $salvage Value at the end of the depreciation * @param mixed (float) $salvage Value at the end of the depreciation
* @param mixed $life Number of periods over which the asset is depreciated * @param mixed (float) $life Number of periods over which the asset is depreciated
* *
* @return float|string Result, or a string containing an error * @return float|string Result, or a string containing an error
*/ */
@ -169,10 +169,10 @@ class Depreciation
* *
* Returns the sum-of-years' digits depreciation of an asset for a specified period. * Returns the sum-of-years' digits depreciation of an asset for a specified period.
* *
* @param mixed $cost Initial cost of the asset * @param mixed (float) $cost Initial cost of the asset
* @param mixed $salvage Value at the end of the depreciation * @param mixed (float) $salvage Value at the end of the depreciation
* @param mixed $life Number of periods over which the asset is depreciated * @param mixed (float) $life Number of periods over which the asset is depreciated
* @param mixed $period Period * @param mixed (float) $period Period
* *
* @return float|string Result, or a string containing an error * @return float|string Result, or a string containing an error
*/ */

View File

@ -576,7 +576,7 @@ class Functions
/** /**
* Convert a multi-dimensional array to a simple 1-dimensional array. * Convert a multi-dimensional array to a simple 1-dimensional array.
* *
* @param array $array Array to be flattened * @param mixed (array) $array Array to be flattened
* *
* @return array Flattened array * @return array Flattened array
*/ */
@ -609,7 +609,7 @@ class Functions
/** /**
* Convert a multi-dimensional array to a simple 1-dimensional array, but retain an element of indexing. * Convert a multi-dimensional array to a simple 1-dimensional array, but retain an element of indexing.
* *
* @param array $array Array to be flattened * @param mixed (array) $array Array to be flattened
* *
* @return array Flattened array * @return array Flattened array
*/ */

View File

@ -148,8 +148,8 @@ class LookupRef
* Excel Function: * Excel Function:
* =HYPERLINK(linkURL,displayName) * =HYPERLINK(linkURL,displayName)
* *
* @param string $linkURL Value to check, is also the value returned when no error * @param mixed (string) $linkURL Value to check, is also the value returned when no error
* @param string $displayName Value to return when testValue is an error condition * @param mixed (string) $displayName Value to return when testValue is an error condition
* @param Cell $pCell The cell to set the hyperlink in * @param Cell $pCell The cell to set the hyperlink in
* *
* @return mixed The value of $displayName (or $linkURL if $displayName was blank) * @return mixed The value of $displayName (or $linkURL if $displayName was blank)

View File

@ -9,7 +9,7 @@ class Matrix
/** /**
* TRANSPOSE. * TRANSPOSE.
* *
* @param array $matrixData A matrix of values * @param mixed (array) $matrixData A matrix of values
* *
* @return array * @return array
*/ */

View File

@ -251,10 +251,10 @@ class Statistical
* experiment. For example, BINOMDIST can calculate the probability that two of the next three * experiment. For example, BINOMDIST can calculate the probability that two of the next three
* babies born are male. * babies born are male.
* *
* @param float $value Number of successes in trials * @param mixed (float) $value Number of successes in trials
* @param float $trials Number of trials * @param mixed (float) $trials Number of trials
* @param float $probability Probability of success on each trial * @param mixed (float) $probability Probability of success on each trial
* @param bool $cumulative * @param mixed (bool) $cumulative
* *
* @return float|string * @return float|string
*/ */
@ -1502,9 +1502,9 @@ class Statistical
* distribution, except that the number of successes is fixed, and the number of trials is * distribution, except that the number of successes is fixed, and the number of trials is
* variable. Like the binomial, trials are assumed to be independent. * variable. Like the binomial, trials are assumed to be independent.
* *
* @param float $failures Number of Failures * @param mixed (float) $failures Number of Failures
* @param float $successes Threshold number of Successes * @param mixed (float) $successes Threshold number of Successes
* @param float $probability Probability of success on each trial * @param mixed (float) $probability Probability of success on each trial
* *
* @return float|string The result, or a string containing an error * @return float|string The result, or a string containing an error
*/ */
@ -1539,10 +1539,10 @@ class Statistical
* function has a very wide range of applications in statistics, including hypothesis * function has a very wide range of applications in statistics, including hypothesis
* testing. * testing.
* *
* @param float $value * @param mixed (float) $value
* @param float $mean Mean Value * @param mixed (float) $mean Mean Value
* @param float $stdDev Standard Deviation * @param mixed (float) $stdDev Standard Deviation
* @param bool $cumulative * @param mixed (bool) $cumulative
* *
* @return float|string The result, or a string containing an error * @return float|string The result, or a string containing an error
*/ */
@ -1573,9 +1573,9 @@ class Statistical
* *
* Returns the inverse of the normal cumulative distribution for the specified mean and standard deviation. * Returns the inverse of the normal cumulative distribution for the specified mean and standard deviation.
* *
* @param float $probability * @param mixed (float) $probability
* @param float $mean Mean Value * @param mixed (float) $mean Mean Value
* @param float $stdDev Standard Deviation * @param mixed (float) $stdDev Standard Deviation
* *
* @return float|string The result, or a string containing an error * @return float|string The result, or a string containing an error
*/ */
@ -1606,7 +1606,7 @@ class Statistical
* a mean of 0 (zero) and a standard deviation of one. Use this function in place of a * a mean of 0 (zero) and a standard deviation of one. Use this function in place of a
* table of standard normal curve areas. * table of standard normal curve areas.
* *
* @param float $value * @param mixed (float) $value
* *
* @return float|string The result, or a string containing an error * @return float|string The result, or a string containing an error
*/ */
@ -1627,8 +1627,8 @@ class Statistical
* a mean of 0 (zero) and a standard deviation of one. Use this function in place of a * a mean of 0 (zero) and a standard deviation of one. Use this function in place of a
* table of standard normal curve areas. * table of standard normal curve areas.
* *
* @param float $value * @param mixed (float) $value
* @param bool $cumulative * @param mixed (bool) $cumulative
* *
* @return float|string The result, or a string containing an error * @return float|string The result, or a string containing an error
*/ */
@ -1648,7 +1648,7 @@ class Statistical
* *
* Returns the inverse of the standard normal cumulative distribution * Returns the inverse of the standard normal cumulative distribution
* *
* @param float $value * @param mixed (float) $value
* *
* @return float|string The result, or a string containing an error * @return float|string The result, or a string containing an error
*/ */
@ -1714,9 +1714,9 @@ class Statistical
* rather than floored (as MS Excel), so value 3 for a value set of 1, 2, 3, 4 will return * rather than floored (as MS Excel), so value 3 for a value set of 1, 2, 3, 4 will return
* 0.667 rather than 0.666 * 0.667 rather than 0.666
* *
* @param float[] $valueSet An array of, or a reference to, a list of numbers * @param mixed (float[]) $valueSet An array of, or a reference to, a list of numbers
* @param int $value the number whose rank you want to find * @param mixed (int) $value the number whose rank you want to find
* @param int $significance the number of significant digits for the returned percentage value * @param mixed (int) $significance the number of significant digits for the returned percentage value
* *
* @return float|string (string if result is an error) * @return float|string (string if result is an error)
*/ */
@ -1787,37 +1787,20 @@ class Statistical
* is predicting the number of events over a specific time, such as the number of * is predicting the number of events over a specific time, such as the number of
* cars arriving at a toll plaza in 1 minute. * cars arriving at a toll plaza in 1 minute.
* *
* @param float $value * @Deprecated 1.18.0
* @param float $mean Mean Value *
* @param bool $cumulative * @see Statistical\Distributions\Poisson::distribution()
* Use the distribution() method in the Statistical\Distributions\Poisson class instead
*
* @param mixed (float) $value
* @param mixed (float) $mean Mean Value
* @param mixed (bool) $cumulative
* *
* @return float|string The result, or a string containing an error * @return float|string The result, or a string containing an error
*/ */
public static function POISSON($value, $mean, $cumulative) public static function POISSON($value, $mean, $cumulative)
{ {
$value = Functions::flattenSingleValue($value); return Statistical\Distributions\Poisson::distribution($value, $mean, $cumulative);
$mean = Functions::flattenSingleValue($mean);
if ((is_numeric($value)) && (is_numeric($mean))) {
if (($value < 0) || ($mean <= 0)) {
return Functions::NAN();
}
if ((is_numeric($cumulative)) || (is_bool($cumulative))) {
if ($cumulative) {
$summer = 0;
$floor = floor($value);
for ($i = 0; $i <= $floor; ++$i) {
$summer += $mean ** $i / MathTrig::FACT($i);
}
return exp(0 - $mean) * $summer;
}
return (exp(0 - $mean) * $mean ** $value) / MathTrig::FACT($value);
}
}
return Functions::VALUE();
} }
/** /**

View File

@ -0,0 +1,55 @@
<?php
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions;
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
class Poisson
{
use BaseValidations;
/**
* POISSON.
*
* Returns the Poisson distribution. A common application of the Poisson distribution
* is predicting the number of events over a specific time, such as the number of
* cars arriving at a toll plaza in 1 minute.
*
* @param mixed (float) $value
* @param mixed (float) $mean Mean Value
* @param mixed (bool) $cumulative
*
* @return float|string The result, or a string containing an error
*/
public static function distribution($value, $mean, $cumulative)
{
$value = Functions::flattenSingleValue($value);
$mean = Functions::flattenSingleValue($mean);
try {
$value = self::validateFloat($value);
$mean = self::validateFloat($mean);
$cumulative = self::validateBool($cumulative);
} catch (Exception $e) {
return $e->getMessage();
}
if (($value < 0) || ($mean < 0)) {
return Functions::NAN();
}
if ($cumulative) {
$summer = 0;
$floor = floor($value);
for ($i = 0; $i <= $floor; ++$i) {
$summer += $mean ** $i / MathTrig::FACT($i);
}
return exp(0 - $mean) * $summer;
}
return (exp(0 - $mean) * $mean ** $value) / MathTrig::FACT($value);
}
}

View File

@ -18,11 +18,23 @@ return [
35, 40, true, 35, 40, true,
], ],
[ [
'#NUM!', '#VALUE!',
35, -40, true, 'Nan', 40, true,
], ],
[ [
'#VALUE!', '#VALUE!',
35, 'Nan', true, 35, 'Nan', true,
], ],
[
'#VALUE!',
35, 40, 'Nan',
],
'Value < 0' => [
'#NUM!',
-35, 40, true,
],
'Mean < 0' => [
'#NUM!',
35, -40, true,
],
]; ];