Start splitting some of the basic Statistical functions out into separate classes (#1888)
* Start splitting some of the basic Statistical functions out into separate classes containing just a few similar functions * Splitting some of the basic Statistical functions out into separate classes containing just a few similar functions - MAX(), MAXA(), MIN() and MINA() * Splitting some more of the basic Statistical functions out into separate classes containing just a few similar functions - StandardDeviations and Variances
This commit is contained in:
parent
8721f795fc
commit
2eaf9b53aa
|
|
@ -328,17 +328,17 @@ class Calculation
|
||||||
],
|
],
|
||||||
'AVEDEV' => [
|
'AVEDEV' => [
|
||||||
'category' => Category::CATEGORY_STATISTICAL,
|
'category' => Category::CATEGORY_STATISTICAL,
|
||||||
'functionCall' => [Statistical::class, 'AVEDEV'],
|
'functionCall' => [Statistical\Averages::class, 'AVEDEV'],
|
||||||
'argumentCount' => '1+',
|
'argumentCount' => '1+',
|
||||||
],
|
],
|
||||||
'AVERAGE' => [
|
'AVERAGE' => [
|
||||||
'category' => Category::CATEGORY_STATISTICAL,
|
'category' => Category::CATEGORY_STATISTICAL,
|
||||||
'functionCall' => [Statistical::class, 'AVERAGE'],
|
'functionCall' => [Statistical\Averages::class, 'AVERAGE'],
|
||||||
'argumentCount' => '1+',
|
'argumentCount' => '1+',
|
||||||
],
|
],
|
||||||
'AVERAGEA' => [
|
'AVERAGEA' => [
|
||||||
'category' => Category::CATEGORY_STATISTICAL,
|
'category' => Category::CATEGORY_STATISTICAL,
|
||||||
'functionCall' => [Statistical::class, 'AVERAGEA'],
|
'functionCall' => [Statistical\Averages::class, 'AVERAGEA'],
|
||||||
'argumentCount' => '1+',
|
'argumentCount' => '1+',
|
||||||
],
|
],
|
||||||
'AVERAGEIF' => [
|
'AVERAGEIF' => [
|
||||||
|
|
@ -624,17 +624,17 @@ class Calculation
|
||||||
],
|
],
|
||||||
'COUNT' => [
|
'COUNT' => [
|
||||||
'category' => Category::CATEGORY_STATISTICAL,
|
'category' => Category::CATEGORY_STATISTICAL,
|
||||||
'functionCall' => [Statistical::class, 'COUNT'],
|
'functionCall' => [Statistical\Counts::class, 'COUNT'],
|
||||||
'argumentCount' => '1+',
|
'argumentCount' => '1+',
|
||||||
],
|
],
|
||||||
'COUNTA' => [
|
'COUNTA' => [
|
||||||
'category' => Category::CATEGORY_STATISTICAL,
|
'category' => Category::CATEGORY_STATISTICAL,
|
||||||
'functionCall' => [Statistical::class, 'COUNTA'],
|
'functionCall' => [Statistical\Counts::class, 'COUNTA'],
|
||||||
'argumentCount' => '1+',
|
'argumentCount' => '1+',
|
||||||
],
|
],
|
||||||
'COUNTBLANK' => [
|
'COUNTBLANK' => [
|
||||||
'category' => Category::CATEGORY_STATISTICAL,
|
'category' => Category::CATEGORY_STATISTICAL,
|
||||||
'functionCall' => [Statistical::class, 'COUNTBLANK'],
|
'functionCall' => [Statistical\Counts::class, 'COUNTBLANK'],
|
||||||
'argumentCount' => '1',
|
'argumentCount' => '1',
|
||||||
],
|
],
|
||||||
'COUNTIF' => [
|
'COUNTIF' => [
|
||||||
|
|
@ -1620,12 +1620,12 @@ class Calculation
|
||||||
],
|
],
|
||||||
'MAX' => [
|
'MAX' => [
|
||||||
'category' => Category::CATEGORY_STATISTICAL,
|
'category' => Category::CATEGORY_STATISTICAL,
|
||||||
'functionCall' => [Statistical::class, 'MAX'],
|
'functionCall' => [Statistical\Maximum::class, 'MAX'],
|
||||||
'argumentCount' => '1+',
|
'argumentCount' => '1+',
|
||||||
],
|
],
|
||||||
'MAXA' => [
|
'MAXA' => [
|
||||||
'category' => Category::CATEGORY_STATISTICAL,
|
'category' => Category::CATEGORY_STATISTICAL,
|
||||||
'functionCall' => [Statistical::class, 'MAXA'],
|
'functionCall' => [Statistical\Maximum::class, 'MAXA'],
|
||||||
'argumentCount' => '1+',
|
'argumentCount' => '1+',
|
||||||
],
|
],
|
||||||
'MAXIFS' => [
|
'MAXIFS' => [
|
||||||
|
|
@ -1665,12 +1665,12 @@ class Calculation
|
||||||
],
|
],
|
||||||
'MIN' => [
|
'MIN' => [
|
||||||
'category' => Category::CATEGORY_STATISTICAL,
|
'category' => Category::CATEGORY_STATISTICAL,
|
||||||
'functionCall' => [Statistical::class, 'MIN'],
|
'functionCall' => [Statistical\Minimum::class, 'MIN'],
|
||||||
'argumentCount' => '1+',
|
'argumentCount' => '1+',
|
||||||
],
|
],
|
||||||
'MINA' => [
|
'MINA' => [
|
||||||
'category' => Category::CATEGORY_STATISTICAL,
|
'category' => Category::CATEGORY_STATISTICAL,
|
||||||
'functionCall' => [Statistical::class, 'MINA'],
|
'functionCall' => [Statistical\Minimum::class, 'MINA'],
|
||||||
'argumentCount' => '1+',
|
'argumentCount' => '1+',
|
||||||
],
|
],
|
||||||
'MINIFS' => [
|
'MINIFS' => [
|
||||||
|
|
@ -2263,22 +2263,22 @@ class Calculation
|
||||||
],
|
],
|
||||||
'STDEV' => [
|
'STDEV' => [
|
||||||
'category' => Category::CATEGORY_STATISTICAL,
|
'category' => Category::CATEGORY_STATISTICAL,
|
||||||
'functionCall' => [Statistical::class, 'STDEV'],
|
'functionCall' => [Statistical\StandardDeviations::class, 'STDEV'],
|
||||||
'argumentCount' => '1+',
|
'argumentCount' => '1+',
|
||||||
],
|
],
|
||||||
'STDEV.S' => [
|
'STDEV.S' => [
|
||||||
'category' => Category::CATEGORY_STATISTICAL,
|
'category' => Category::CATEGORY_STATISTICAL,
|
||||||
'functionCall' => [Statistical::class, 'STDEV'],
|
'functionCall' => [Statistical\StandardDeviations::class, 'STDEV'],
|
||||||
'argumentCount' => '1+',
|
'argumentCount' => '1+',
|
||||||
],
|
],
|
||||||
'STDEV.P' => [
|
'STDEV.P' => [
|
||||||
'category' => Category::CATEGORY_STATISTICAL,
|
'category' => Category::CATEGORY_STATISTICAL,
|
||||||
'functionCall' => [Statistical::class, 'STDEVP'],
|
'functionCall' => [Statistical\StandardDeviations::class, 'STDEVP'],
|
||||||
'argumentCount' => '1+',
|
'argumentCount' => '1+',
|
||||||
],
|
],
|
||||||
'STDEVA' => [
|
'STDEVA' => [
|
||||||
'category' => Category::CATEGORY_STATISTICAL,
|
'category' => Category::CATEGORY_STATISTICAL,
|
||||||
'functionCall' => [Statistical::class, 'STDEVA'],
|
'functionCall' => [Statistical\StandardDeviations::class, 'STDEVA'],
|
||||||
'argumentCount' => '1+',
|
'argumentCount' => '1+',
|
||||||
],
|
],
|
||||||
'STDEVP' => [
|
'STDEVP' => [
|
||||||
|
|
@ -2524,32 +2524,32 @@ class Calculation
|
||||||
],
|
],
|
||||||
'VAR' => [
|
'VAR' => [
|
||||||
'category' => Category::CATEGORY_STATISTICAL,
|
'category' => Category::CATEGORY_STATISTICAL,
|
||||||
'functionCall' => [Statistical::class, 'VARFunc'],
|
'functionCall' => [Statistical\Variances::class, 'VAR'],
|
||||||
'argumentCount' => '1+',
|
'argumentCount' => '1+',
|
||||||
],
|
],
|
||||||
'VAR.P' => [
|
'VAR.P' => [
|
||||||
'category' => Category::CATEGORY_STATISTICAL,
|
'category' => Category::CATEGORY_STATISTICAL,
|
||||||
'functionCall' => [Statistical::class, 'VARP'],
|
'functionCall' => [Statistical\Variances::class, 'VARP'],
|
||||||
'argumentCount' => '1+',
|
'argumentCount' => '1+',
|
||||||
],
|
],
|
||||||
'VAR.S' => [
|
'VAR.S' => [
|
||||||
'category' => Category::CATEGORY_STATISTICAL,
|
'category' => Category::CATEGORY_STATISTICAL,
|
||||||
'functionCall' => [Statistical::class, 'VARFunc'],
|
'functionCall' => [Statistical\Variances::class, 'VAR'],
|
||||||
'argumentCount' => '1+',
|
'argumentCount' => '1+',
|
||||||
],
|
],
|
||||||
'VARA' => [
|
'VARA' => [
|
||||||
'category' => Category::CATEGORY_STATISTICAL,
|
'category' => Category::CATEGORY_STATISTICAL,
|
||||||
'functionCall' => [Statistical::class, 'VARA'],
|
'functionCall' => [Statistical\Variances::class, 'VARA'],
|
||||||
'argumentCount' => '1+',
|
'argumentCount' => '1+',
|
||||||
],
|
],
|
||||||
'VARP' => [
|
'VARP' => [
|
||||||
'category' => Category::CATEGORY_STATISTICAL,
|
'category' => Category::CATEGORY_STATISTICAL,
|
||||||
'functionCall' => [Statistical::class, 'VARP'],
|
'functionCall' => [Statistical\Variances::class, 'VARP'],
|
||||||
'argumentCount' => '1+',
|
'argumentCount' => '1+',
|
||||||
],
|
],
|
||||||
'VARPA' => [
|
'VARPA' => [
|
||||||
'category' => Category::CATEGORY_STATISTICAL,
|
'category' => Category::CATEGORY_STATISTICAL,
|
||||||
'functionCall' => [Statistical::class, 'VARPA'],
|
'functionCall' => [Statistical\Variances::class, 'VARPA'],
|
||||||
'argumentCount' => '1+',
|
'argumentCount' => '1+',
|
||||||
],
|
],
|
||||||
'VDB' => [
|
'VDB' => [
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
|
namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
|
||||||
|
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Averages;
|
||||||
|
|
||||||
class DAverage extends DatabaseAbstract
|
class DAverage extends DatabaseAbstract
|
||||||
{
|
{
|
||||||
|
|
@ -38,7 +38,7 @@ class DAverage extends DatabaseAbstract
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Statistical::AVERAGE(
|
return Averages::AVERAGE(
|
||||||
self::getFilteredColumn($database, $field, $criteria)
|
self::getFilteredColumn($database, $field, $criteria)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
|
namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
|
||||||
|
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Counts;
|
||||||
|
|
||||||
class DCount extends DatabaseAbstract
|
class DCount extends DatabaseAbstract
|
||||||
{
|
{
|
||||||
|
|
@ -36,7 +36,7 @@ class DCount extends DatabaseAbstract
|
||||||
{
|
{
|
||||||
$field = self::fieldExtract($database, $field);
|
$field = self::fieldExtract($database, $field);
|
||||||
|
|
||||||
return Statistical::COUNT(
|
return Counts::COUNT(
|
||||||
self::getFilteredColumn($database, $field, $criteria)
|
self::getFilteredColumn($database, $field, $criteria)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
|
namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
|
||||||
|
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Counts;
|
||||||
|
|
||||||
class DCountA extends DatabaseAbstract
|
class DCountA extends DatabaseAbstract
|
||||||
{
|
{
|
||||||
|
|
@ -35,7 +35,7 @@ class DCountA extends DatabaseAbstract
|
||||||
{
|
{
|
||||||
$field = self::fieldExtract($database, $field);
|
$field = self::fieldExtract($database, $field);
|
||||||
|
|
||||||
return Statistical::COUNTA(
|
return Counts::COUNTA(
|
||||||
self::getFilteredColumn($database, $field ?? 0, $criteria)
|
self::getFilteredColumn($database, $field ?? 0, $criteria)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
|
namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
|
||||||
|
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Maximum;
|
||||||
|
|
||||||
class DMax extends DatabaseAbstract
|
class DMax extends DatabaseAbstract
|
||||||
{
|
{
|
||||||
|
|
@ -39,7 +39,7 @@ class DMax extends DatabaseAbstract
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Statistical::MAX(
|
return Maximum::MAX(
|
||||||
self::getFilteredColumn($database, $field, $criteria)
|
self::getFilteredColumn($database, $field, $criteria)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
|
namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
|
||||||
|
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Minimum;
|
||||||
|
|
||||||
class DMin extends DatabaseAbstract
|
class DMin extends DatabaseAbstract
|
||||||
{
|
{
|
||||||
|
|
@ -39,7 +39,7 @@ class DMin extends DatabaseAbstract
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Statistical::MIN(
|
return Minimum::MIN(
|
||||||
self::getFilteredColumn($database, $field, $criteria)
|
self::getFilteredColumn($database, $field, $criteria)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
|
namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
|
||||||
|
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\StandardDeviations;
|
||||||
|
|
||||||
class DStDev extends DatabaseAbstract
|
class DStDev extends DatabaseAbstract
|
||||||
{
|
{
|
||||||
|
|
@ -39,7 +39,7 @@ class DStDev extends DatabaseAbstract
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Statistical::STDEV(
|
return StandardDeviations::STDEV(
|
||||||
self::getFilteredColumn($database, $field, $criteria)
|
self::getFilteredColumn($database, $field, $criteria)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
|
namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
|
||||||
|
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\StandardDeviations;
|
||||||
|
|
||||||
class DStDevP extends DatabaseAbstract
|
class DStDevP extends DatabaseAbstract
|
||||||
{
|
{
|
||||||
|
|
@ -39,7 +39,7 @@ class DStDevP extends DatabaseAbstract
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Statistical::STDEVP(
|
return StandardDeviations::STDEVP(
|
||||||
self::getFilteredColumn($database, $field, $criteria)
|
self::getFilteredColumn($database, $field, $criteria)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
|
namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
|
||||||
|
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Variances;
|
||||||
|
|
||||||
class DVar extends DatabaseAbstract
|
class DVar extends DatabaseAbstract
|
||||||
{
|
{
|
||||||
|
|
@ -39,7 +39,7 @@ class DVar extends DatabaseAbstract
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Statistical::VARFunc(
|
return Variances::VAR(
|
||||||
self::getFilteredColumn($database, $field, $criteria)
|
self::getFilteredColumn($database, $field, $criteria)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
|
namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
|
||||||
|
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Variances;
|
||||||
|
|
||||||
class DVarP extends DatabaseAbstract
|
class DVarP extends DatabaseAbstract
|
||||||
{
|
{
|
||||||
|
|
@ -39,7 +39,7 @@ class DVarP extends DatabaseAbstract
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Statistical::VARP(
|
return Variances::VARP(
|
||||||
self::getFilteredColumn($database, $field, $criteria)
|
self::getFilteredColumn($database, $field, $criteria)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1222,27 +1222,27 @@ class MathTrig
|
||||||
$aArgs = self::filterFormulaArgs($cellReference, $aArgs);
|
$aArgs = self::filterFormulaArgs($cellReference, $aArgs);
|
||||||
switch ($subtotal) {
|
switch ($subtotal) {
|
||||||
case 1:
|
case 1:
|
||||||
return Statistical::AVERAGE($aArgs);
|
return Statistical\Averages::AVERAGE($aArgs);
|
||||||
case 2:
|
case 2:
|
||||||
return Statistical::COUNT($aArgs);
|
return Statistical\Counts::COUNT($aArgs);
|
||||||
case 3:
|
case 3:
|
||||||
return Statistical::COUNTA($aArgs);
|
return Statistical\Counts::COUNTA($aArgs);
|
||||||
case 4:
|
case 4:
|
||||||
return Statistical::MAX($aArgs);
|
return Statistical\Maximum::MAX($aArgs);
|
||||||
case 5:
|
case 5:
|
||||||
return Statistical::MIN($aArgs);
|
return Statistical\Minimum::MIN($aArgs);
|
||||||
case 6:
|
case 6:
|
||||||
return self::PRODUCT($aArgs);
|
return self::PRODUCT($aArgs);
|
||||||
case 7:
|
case 7:
|
||||||
return Statistical::STDEV($aArgs);
|
return Statistical\StandardDeviations::STDEV($aArgs);
|
||||||
case 8:
|
case 8:
|
||||||
return Statistical::STDEVP($aArgs);
|
return Statistical\StandardDeviations::STDEVP($aArgs);
|
||||||
case 9:
|
case 9:
|
||||||
return self::SUM($aArgs);
|
return self::SUM($aArgs);
|
||||||
case 10:
|
case 10:
|
||||||
return Statistical::VARFunc($aArgs);
|
return Statistical\Variances::VAR($aArgs);
|
||||||
case 11:
|
case 11:
|
||||||
return Statistical::VARP($aArgs);
|
return Statistical\Variances::VARP($aArgs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,14 @@
|
||||||
|
|
||||||
namespace PhpOffice\PhpSpreadsheet\Calculation;
|
namespace PhpOffice\PhpSpreadsheet\Calculation;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Averages;
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Conditional;
|
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Conditional;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Counts;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Maximum;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Minimum;
|
||||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Permutations;
|
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Permutations;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\StandardDeviations;
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Variances;
|
||||||
use PhpOffice\PhpSpreadsheet\Shared\Trend\Trend;
|
use PhpOffice\PhpSpreadsheet\Shared\Trend\Trend;
|
||||||
|
|
||||||
class Statistical
|
class Statistical
|
||||||
|
|
@ -520,48 +526,6 @@ class Statistical
|
||||||
return Functions::NULL();
|
return Functions::NULL();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* MS Excel does not count Booleans if passed as cell values, but they are counted if passed as literals.
|
|
||||||
* OpenOffice Calc always counts Booleans.
|
|
||||||
* Gnumeric never counts Booleans.
|
|
||||||
*
|
|
||||||
* @param mixed $arg
|
|
||||||
* @param mixed $k
|
|
||||||
*
|
|
||||||
* @return int|mixed
|
|
||||||
*/
|
|
||||||
private static function testAcceptedBoolean($arg, $k)
|
|
||||||
{
|
|
||||||
if (
|
|
||||||
(is_bool($arg)) &&
|
|
||||||
((!Functions::isCellValue($k) && (Functions::getCompatibilityMode() === Functions::COMPATIBILITY_EXCEL)) ||
|
|
||||||
(Functions::getCompatibilityMode() === Functions::COMPATIBILITY_OPENOFFICE))
|
|
||||||
) {
|
|
||||||
$arg = (int) $arg;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $arg;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param mixed $arg
|
|
||||||
* @param mixed $k
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
private static function isAcceptedCountable($arg, $k)
|
|
||||||
{
|
|
||||||
if (
|
|
||||||
((is_numeric($arg)) && (!is_string($arg))) ||
|
|
||||||
((is_numeric($arg)) && (!Functions::isCellValue($k)) &&
|
|
||||||
(Functions::getCompatibilityMode() !== Functions::COMPATIBILITY_GNUMERIC))
|
|
||||||
) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AVEDEV.
|
* AVEDEV.
|
||||||
*
|
*
|
||||||
|
|
@ -571,45 +535,18 @@ class Statistical
|
||||||
* Excel Function:
|
* Excel Function:
|
||||||
* AVEDEV(value1[,value2[, ...]])
|
* AVEDEV(value1[,value2[, ...]])
|
||||||
*
|
*
|
||||||
|
* @Deprecated 1.17.0
|
||||||
|
*
|
||||||
|
* @see Statistical\Averages::AVEDEV()
|
||||||
|
* Use the AVEDEV() method in the Statistical\Averages class instead
|
||||||
|
*
|
||||||
* @param mixed ...$args Data values
|
* @param mixed ...$args Data values
|
||||||
*
|
*
|
||||||
* @return float|string
|
* @return float|string
|
||||||
*/
|
*/
|
||||||
public static function AVEDEV(...$args)
|
public static function AVEDEV(...$args)
|
||||||
{
|
{
|
||||||
$aArgs = Functions::flattenArrayIndexed($args);
|
return Averages::AVEDEV(...$args);
|
||||||
|
|
||||||
// Return value
|
|
||||||
$returnValue = 0;
|
|
||||||
|
|
||||||
$aMean = self::AVERAGE(...$args);
|
|
||||||
if ($aMean === Functions::DIV0()) {
|
|
||||||
return Functions::NAN();
|
|
||||||
} elseif ($aMean === Functions::VALUE()) {
|
|
||||||
return Functions::VALUE();
|
|
||||||
}
|
|
||||||
|
|
||||||
$aCount = 0;
|
|
||||||
foreach ($aArgs as $k => $arg) {
|
|
||||||
$arg = self::testAcceptedBoolean($arg, $k);
|
|
||||||
// Is it a numeric value?
|
|
||||||
// Strings containing numeric values are only counted if they are string literals (not cell values)
|
|
||||||
// and then only in MS Excel and in Open Office, not in Gnumeric
|
|
||||||
if ((is_string($arg)) && (!is_numeric($arg)) && (!Functions::isCellValue($k))) {
|
|
||||||
return Functions::VALUE();
|
|
||||||
}
|
|
||||||
if (self::isAcceptedCountable($arg, $k)) {
|
|
||||||
$returnValue += abs($arg - $aMean);
|
|
||||||
++$aCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return
|
|
||||||
if ($aCount === 0) {
|
|
||||||
return Functions::DIV0();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $returnValue / $aCount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -620,35 +557,18 @@ class Statistical
|
||||||
* Excel Function:
|
* Excel Function:
|
||||||
* AVERAGE(value1[,value2[, ...]])
|
* AVERAGE(value1[,value2[, ...]])
|
||||||
*
|
*
|
||||||
|
* @Deprecated 1.17.0
|
||||||
|
*
|
||||||
|
* @see Statistical\Averages::AVERAGE()
|
||||||
|
* Use the AVERAGE() method in the Statistical\Averages class instead
|
||||||
|
*
|
||||||
* @param mixed ...$args Data values
|
* @param mixed ...$args Data values
|
||||||
*
|
*
|
||||||
* @return float|string
|
* @return float|string
|
||||||
*/
|
*/
|
||||||
public static function AVERAGE(...$args)
|
public static function AVERAGE(...$args)
|
||||||
{
|
{
|
||||||
$returnValue = $aCount = 0;
|
return Averages::AVERAGE(...$args);
|
||||||
|
|
||||||
// Loop through arguments
|
|
||||||
foreach (Functions::flattenArrayIndexed($args) as $k => $arg) {
|
|
||||||
$arg = self::testAcceptedBoolean($arg, $k);
|
|
||||||
// Is it a numeric value?
|
|
||||||
// Strings containing numeric values are only counted if they are string literals (not cell values)
|
|
||||||
// and then only in MS Excel and in Open Office, not in Gnumeric
|
|
||||||
if ((is_string($arg)) && (!is_numeric($arg)) && (!Functions::isCellValue($k))) {
|
|
||||||
return Functions::VALUE();
|
|
||||||
}
|
|
||||||
if (self::isAcceptedCountable($arg, $k)) {
|
|
||||||
$returnValue += $arg;
|
|
||||||
++$aCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return
|
|
||||||
if ($aCount > 0) {
|
|
||||||
return $returnValue / $aCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Functions::DIV0();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -659,39 +579,18 @@ class Statistical
|
||||||
* Excel Function:
|
* Excel Function:
|
||||||
* AVERAGEA(value1[,value2[, ...]])
|
* AVERAGEA(value1[,value2[, ...]])
|
||||||
*
|
*
|
||||||
|
* @Deprecated 1.17.0
|
||||||
|
*
|
||||||
|
* @see Statistical\Averages::AVERAGEA()
|
||||||
|
* Use the AVERAGEA() method in the Statistical\Averages class instead
|
||||||
|
*
|
||||||
* @param mixed ...$args Data values
|
* @param mixed ...$args Data values
|
||||||
*
|
*
|
||||||
* @return float|string
|
* @return float|string
|
||||||
*/
|
*/
|
||||||
public static function AVERAGEA(...$args)
|
public static function AVERAGEA(...$args)
|
||||||
{
|
{
|
||||||
$returnValue = null;
|
return Averages::AVERAGEA(...$args);
|
||||||
|
|
||||||
$aCount = 0;
|
|
||||||
// Loop through arguments
|
|
||||||
foreach (Functions::flattenArrayIndexed($args) as $k => $arg) {
|
|
||||||
if (
|
|
||||||
(is_bool($arg)) &&
|
|
||||||
(!Functions::isMatrixValue($k))
|
|
||||||
) {
|
|
||||||
} else {
|
|
||||||
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
|
|
||||||
if (is_bool($arg)) {
|
|
||||||
$arg = (int) $arg;
|
|
||||||
} elseif (is_string($arg)) {
|
|
||||||
$arg = 0;
|
|
||||||
}
|
|
||||||
$returnValue += $arg;
|
|
||||||
++$aCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($aCount > 0) {
|
|
||||||
return $returnValue / $aCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Functions::DIV0();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -715,7 +614,7 @@ class Statistical
|
||||||
*/
|
*/
|
||||||
public static function AVERAGEIF($range, $condition, $averageRange = [])
|
public static function AVERAGEIF($range, $condition, $averageRange = [])
|
||||||
{
|
{
|
||||||
return Statistical\Conditional::AVERAGEIF($range, $condition, $averageRange);
|
return Conditional::AVERAGEIF($range, $condition, $averageRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1026,27 +925,18 @@ class Statistical
|
||||||
* Excel Function:
|
* Excel Function:
|
||||||
* COUNT(value1[,value2[, ...]])
|
* COUNT(value1[,value2[, ...]])
|
||||||
*
|
*
|
||||||
|
* @Deprecated 1.17.0
|
||||||
|
*
|
||||||
|
* @see Statistical\Counts::COUNT()
|
||||||
|
* Use the COUNT() method in the Statistical\Counts class instead
|
||||||
|
*
|
||||||
* @param mixed ...$args Data values
|
* @param mixed ...$args Data values
|
||||||
*
|
*
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public static function COUNT(...$args)
|
public static function COUNT(...$args)
|
||||||
{
|
{
|
||||||
$returnValue = 0;
|
return Counts::COUNT(...$args);
|
||||||
|
|
||||||
// Loop through arguments
|
|
||||||
$aArgs = Functions::flattenArrayIndexed($args);
|
|
||||||
foreach ($aArgs as $k => $arg) {
|
|
||||||
$arg = self::testAcceptedBoolean($arg, $k);
|
|
||||||
// Is it a numeric value?
|
|
||||||
// Strings containing numeric values are only counted if they are string literals (not cell values)
|
|
||||||
// and then only in MS Excel and in Open Office, not in Gnumeric
|
|
||||||
if (self::isAcceptedCountable($arg, $k)) {
|
|
||||||
++$returnValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $returnValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1057,24 +947,18 @@ class Statistical
|
||||||
* Excel Function:
|
* Excel Function:
|
||||||
* COUNTA(value1[,value2[, ...]])
|
* COUNTA(value1[,value2[, ...]])
|
||||||
*
|
*
|
||||||
|
* @Deprecated 1.17.0
|
||||||
|
*
|
||||||
|
* @see Statistical\Counts::COUNTA()
|
||||||
|
* Use the COUNTA() method in the Statistical\Counts class instead
|
||||||
|
*
|
||||||
* @param mixed ...$args Data values
|
* @param mixed ...$args Data values
|
||||||
*
|
*
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public static function COUNTA(...$args)
|
public static function COUNTA(...$args)
|
||||||
{
|
{
|
||||||
$returnValue = 0;
|
return Counts::COUNTA(...$args);
|
||||||
|
|
||||||
// Loop through arguments
|
|
||||||
$aArgs = Functions::flattenArrayIndexed($args);
|
|
||||||
foreach ($aArgs as $k => $arg) {
|
|
||||||
// Nulls are counted if literals, but not if cell values
|
|
||||||
if ($arg !== null || (!Functions::isCellValue($k))) {
|
|
||||||
++$returnValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $returnValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1085,24 +969,18 @@ class Statistical
|
||||||
* Excel Function:
|
* Excel Function:
|
||||||
* COUNTBLANK(value1[,value2[, ...]])
|
* COUNTBLANK(value1[,value2[, ...]])
|
||||||
*
|
*
|
||||||
|
* @Deprecated 1.17.0
|
||||||
|
*
|
||||||
|
* @see Statistical\Counts::COUNTBLANK()
|
||||||
|
* Use the COUNTBLANK() method in the Statistical\Counts class instead
|
||||||
|
*
|
||||||
* @param mixed ...$args Data values
|
* @param mixed ...$args Data values
|
||||||
*
|
*
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public static function COUNTBLANK(...$args)
|
public static function COUNTBLANK(...$args)
|
||||||
{
|
{
|
||||||
$returnValue = 0;
|
return Counts::COUNTBLANK(...$args);
|
||||||
|
|
||||||
// Loop through arguments
|
|
||||||
$aArgs = Functions::flattenArray($args);
|
|
||||||
foreach ($aArgs as $arg) {
|
|
||||||
// Is it a blank cell?
|
|
||||||
if (($arg === null) || ((is_string($arg)) && ($arg == ''))) {
|
|
||||||
++$returnValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $returnValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1125,7 +1003,7 @@ class Statistical
|
||||||
*/
|
*/
|
||||||
public static function COUNTIF($range, $condition)
|
public static function COUNTIF($range, $condition)
|
||||||
{
|
{
|
||||||
return Statistical\Conditional::COUNTIF($range, $condition);
|
return Conditional::COUNTIF($range, $condition);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1147,7 +1025,7 @@ class Statistical
|
||||||
*/
|
*/
|
||||||
public static function COUNTIFS(...$args)
|
public static function COUNTIFS(...$args)
|
||||||
{
|
{
|
||||||
return Statistical\Conditional::COUNTIFS(...$args);
|
return Conditional::COUNTIFS(...$args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1325,7 +1203,7 @@ class Statistical
|
||||||
// Return value
|
// Return value
|
||||||
$returnValue = null;
|
$returnValue = null;
|
||||||
|
|
||||||
$aMean = self::AVERAGE($aArgs);
|
$aMean = Averages::AVERAGE($aArgs);
|
||||||
if ($aMean != Functions::DIV0()) {
|
if ($aMean != Functions::DIV0()) {
|
||||||
$aCount = -1;
|
$aCount = -1;
|
||||||
foreach ($aArgs as $k => $arg) {
|
foreach ($aArgs as $k => $arg) {
|
||||||
|
|
@ -1711,8 +1589,8 @@ class Statistical
|
||||||
|
|
||||||
$aMean = MathTrig::PRODUCT($aArgs);
|
$aMean = MathTrig::PRODUCT($aArgs);
|
||||||
if (is_numeric($aMean) && ($aMean > 0)) {
|
if (is_numeric($aMean) && ($aMean > 0)) {
|
||||||
$aCount = self::COUNT($aArgs);
|
$aCount = Counts::COUNT($aArgs);
|
||||||
if (self::MIN($aArgs) > 0) {
|
if (Minimum::MIN($aArgs) > 0) {
|
||||||
return $aMean ** (1 / $aCount);
|
return $aMean ** (1 / $aCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1772,7 +1650,7 @@ class Statistical
|
||||||
|
|
||||||
// Loop through arguments
|
// Loop through arguments
|
||||||
$aArgs = Functions::flattenArray($args);
|
$aArgs = Functions::flattenArray($args);
|
||||||
if (self::MIN($aArgs) < 0) {
|
if (Minimum::MIN($aArgs) < 0) {
|
||||||
return Functions::NAN();
|
return Functions::NAN();
|
||||||
}
|
}
|
||||||
$aCount = 0;
|
$aCount = 0;
|
||||||
|
|
@ -1883,8 +1761,8 @@ class Statistical
|
||||||
public static function KURT(...$args)
|
public static function KURT(...$args)
|
||||||
{
|
{
|
||||||
$aArgs = Functions::flattenArrayIndexed($args);
|
$aArgs = Functions::flattenArrayIndexed($args);
|
||||||
$mean = self::AVERAGE($aArgs);
|
$mean = Averages::AVERAGE($aArgs);
|
||||||
$stdDev = self::STDEV($aArgs);
|
$stdDev = StandardDeviations::STDEV($aArgs);
|
||||||
|
|
||||||
if ($stdDev > 0) {
|
if ($stdDev > 0) {
|
||||||
$count = $summer = 0;
|
$count = $summer = 0;
|
||||||
|
|
@ -1941,7 +1819,7 @@ class Statistical
|
||||||
$mArgs[] = $arg;
|
$mArgs[] = $arg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$count = self::COUNT($mArgs);
|
$count = Counts::COUNT($mArgs);
|
||||||
--$entry;
|
--$entry;
|
||||||
if (($entry < 0) || ($entry >= $count) || ($count == 0)) {
|
if (($entry < 0) || ($entry >= $count) || ($count == 0)) {
|
||||||
return Functions::NAN();
|
return Functions::NAN();
|
||||||
|
|
@ -2184,30 +2062,18 @@ class Statistical
|
||||||
* Excel Function:
|
* Excel Function:
|
||||||
* MAX(value1[,value2[, ...]])
|
* MAX(value1[,value2[, ...]])
|
||||||
*
|
*
|
||||||
|
* @Deprecated 1.17.0
|
||||||
|
*
|
||||||
|
* @see Statistical\Maximum::MAX()
|
||||||
|
* Use the MAX() method in the Statistical\Maximum class instead
|
||||||
|
*
|
||||||
* @param mixed ...$args Data values
|
* @param mixed ...$args Data values
|
||||||
*
|
*
|
||||||
* @return float
|
* @return float
|
||||||
*/
|
*/
|
||||||
public static function MAX(...$args)
|
public static function MAX(...$args)
|
||||||
{
|
{
|
||||||
$returnValue = null;
|
return Maximum::MAX(...$args);
|
||||||
|
|
||||||
// Loop through arguments
|
|
||||||
$aArgs = Functions::flattenArray($args);
|
|
||||||
foreach ($aArgs as $arg) {
|
|
||||||
// Is it a numeric value?
|
|
||||||
if ((is_numeric($arg)) && (!is_string($arg))) {
|
|
||||||
if (($returnValue === null) || ($arg > $returnValue)) {
|
|
||||||
$returnValue = $arg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($returnValue === null) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $returnValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -2218,35 +2084,18 @@ class Statistical
|
||||||
* Excel Function:
|
* Excel Function:
|
||||||
* MAXA(value1[,value2[, ...]])
|
* MAXA(value1[,value2[, ...]])
|
||||||
*
|
*
|
||||||
|
* @Deprecated 1.17.0
|
||||||
|
*
|
||||||
|
* @see Statistical\Maximum::MAXA()
|
||||||
|
* Use the MAXA() method in the Statistical\Maximum class instead
|
||||||
|
*
|
||||||
* @param mixed ...$args Data values
|
* @param mixed ...$args Data values
|
||||||
*
|
*
|
||||||
* @return float
|
* @return float
|
||||||
*/
|
*/
|
||||||
public static function MAXA(...$args)
|
public static function MAXA(...$args)
|
||||||
{
|
{
|
||||||
$returnValue = null;
|
return Maximum::MAXA(...$args);
|
||||||
|
|
||||||
// Loop through arguments
|
|
||||||
$aArgs = Functions::flattenArray($args);
|
|
||||||
foreach ($aArgs as $arg) {
|
|
||||||
// Is it a numeric value?
|
|
||||||
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
|
|
||||||
if (is_bool($arg)) {
|
|
||||||
$arg = (int) $arg;
|
|
||||||
} elseif (is_string($arg)) {
|
|
||||||
$arg = 0;
|
|
||||||
}
|
|
||||||
if (($returnValue === null) || ($arg > $returnValue)) {
|
|
||||||
$returnValue = $arg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($returnValue === null) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $returnValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -2321,30 +2170,18 @@ class Statistical
|
||||||
* Excel Function:
|
* Excel Function:
|
||||||
* MIN(value1[,value2[, ...]])
|
* MIN(value1[,value2[, ...]])
|
||||||
*
|
*
|
||||||
|
* @Deprecated 1.17.0
|
||||||
|
*
|
||||||
|
* @see Statistical\Minimum::MIN()
|
||||||
|
* Use the MIN() method in the Statistical\Minimum class instead
|
||||||
|
*
|
||||||
* @param mixed ...$args Data values
|
* @param mixed ...$args Data values
|
||||||
*
|
*
|
||||||
* @return float
|
* @return float
|
||||||
*/
|
*/
|
||||||
public static function MIN(...$args)
|
public static function MIN(...$args)
|
||||||
{
|
{
|
||||||
$returnValue = null;
|
return Minimum::MIN(...$args);
|
||||||
|
|
||||||
// Loop through arguments
|
|
||||||
$aArgs = Functions::flattenArray($args);
|
|
||||||
foreach ($aArgs as $arg) {
|
|
||||||
// Is it a numeric value?
|
|
||||||
if ((is_numeric($arg)) && (!is_string($arg))) {
|
|
||||||
if (($returnValue === null) || ($arg < $returnValue)) {
|
|
||||||
$returnValue = $arg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($returnValue === null) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $returnValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -2355,35 +2192,18 @@ class Statistical
|
||||||
* Excel Function:
|
* Excel Function:
|
||||||
* MINA(value1[,value2[, ...]])
|
* MINA(value1[,value2[, ...]])
|
||||||
*
|
*
|
||||||
|
* @Deprecated 1.17.0
|
||||||
|
*
|
||||||
|
* @see Statistical\Minimum::MINA()
|
||||||
|
* Use the MINA() method in the Statistical\Minimum class instead
|
||||||
|
*
|
||||||
* @param mixed ...$args Data values
|
* @param mixed ...$args Data values
|
||||||
*
|
*
|
||||||
* @return float
|
* @return float
|
||||||
*/
|
*/
|
||||||
public static function MINA(...$args)
|
public static function MINA(...$args)
|
||||||
{
|
{
|
||||||
$returnValue = null;
|
return Minimum::MINA(...$args);
|
||||||
|
|
||||||
// Loop through arguments
|
|
||||||
$aArgs = Functions::flattenArray($args);
|
|
||||||
foreach ($aArgs as $arg) {
|
|
||||||
// Is it a numeric value?
|
|
||||||
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
|
|
||||||
if (is_bool($arg)) {
|
|
||||||
$arg = (int) $arg;
|
|
||||||
} elseif (is_string($arg)) {
|
|
||||||
$arg = 0;
|
|
||||||
}
|
|
||||||
if (($returnValue === null) || ($arg < $returnValue)) {
|
|
||||||
$returnValue = $arg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($returnValue === null) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $returnValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -2688,7 +2508,7 @@ class Statistical
|
||||||
$mValueCount = count($mArgs);
|
$mValueCount = count($mArgs);
|
||||||
if ($mValueCount > 0) {
|
if ($mValueCount > 0) {
|
||||||
sort($mArgs);
|
sort($mArgs);
|
||||||
$count = self::COUNT($mArgs);
|
$count = Counts::COUNT($mArgs);
|
||||||
$index = $entry * ($count - 1);
|
$index = $entry * ($count - 1);
|
||||||
$iBase = floor($index);
|
$iBase = floor($index);
|
||||||
if ($index == $iBase) {
|
if ($index == $iBase) {
|
||||||
|
|
@ -2775,7 +2595,7 @@ class Statistical
|
||||||
*/
|
*/
|
||||||
public static function PERMUT($numObjs, $numInSet)
|
public static function PERMUT($numObjs, $numInSet)
|
||||||
{
|
{
|
||||||
return Statistical\Permutations::PERMUT($numObjs, $numInSet);
|
return Permutations::PERMUT($numObjs, $numInSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -2930,8 +2750,8 @@ class Statistical
|
||||||
public static function SKEW(...$args)
|
public static function SKEW(...$args)
|
||||||
{
|
{
|
||||||
$aArgs = Functions::flattenArrayIndexed($args);
|
$aArgs = Functions::flattenArrayIndexed($args);
|
||||||
$mean = self::AVERAGE($aArgs);
|
$mean = Averages::AVERAGE($aArgs);
|
||||||
$stdDev = self::STDEV($aArgs);
|
$stdDev = StandardDeviations::STDEV($aArgs);
|
||||||
|
|
||||||
$count = $summer = 0;
|
$count = $summer = 0;
|
||||||
// Loop through arguments
|
// Loop through arguments
|
||||||
|
|
@ -3015,7 +2835,7 @@ class Statistical
|
||||||
$mArgs[] = $arg;
|
$mArgs[] = $arg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$count = self::COUNT($mArgs);
|
$count = Counts::COUNT($mArgs);
|
||||||
--$entry;
|
--$entry;
|
||||||
if (($entry < 0) || ($entry >= $count) || ($count == 0)) {
|
if (($entry < 0) || ($entry >= $count) || ($count == 0)) {
|
||||||
return Functions::NAN();
|
return Functions::NAN();
|
||||||
|
|
@ -3065,45 +2885,18 @@ class Statistical
|
||||||
* Excel Function:
|
* Excel Function:
|
||||||
* STDEV(value1[,value2[, ...]])
|
* STDEV(value1[,value2[, ...]])
|
||||||
*
|
*
|
||||||
|
* @Deprecated 1.17.0
|
||||||
|
*
|
||||||
|
* @see Statistical\StandardDeviations::STDEV()
|
||||||
|
* Use the STDEV() method in the Statistical\StandardDeviations class instead
|
||||||
|
*
|
||||||
* @param mixed ...$args Data values
|
* @param mixed ...$args Data values
|
||||||
*
|
*
|
||||||
* @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 STDEV(...$args)
|
public static function STDEV(...$args)
|
||||||
{
|
{
|
||||||
$aArgs = Functions::flattenArrayIndexed($args);
|
return StandardDeviations::STDEV(...$args);
|
||||||
|
|
||||||
// Return value
|
|
||||||
$returnValue = null;
|
|
||||||
|
|
||||||
$aMean = self::AVERAGE($aArgs);
|
|
||||||
if ($aMean !== null) {
|
|
||||||
$aCount = -1;
|
|
||||||
foreach ($aArgs as $k => $arg) {
|
|
||||||
if (
|
|
||||||
(is_bool($arg)) &&
|
|
||||||
((!Functions::isCellValue($k)) || (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE))
|
|
||||||
) {
|
|
||||||
$arg = (int) $arg;
|
|
||||||
}
|
|
||||||
// Is it a numeric value?
|
|
||||||
if ((is_numeric($arg)) && (!is_string($arg))) {
|
|
||||||
if ($returnValue === null) {
|
|
||||||
$returnValue = ($arg - $aMean) ** 2;
|
|
||||||
} else {
|
|
||||||
$returnValue += ($arg - $aMean) ** 2;
|
|
||||||
}
|
|
||||||
++$aCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return
|
|
||||||
if (($aCount > 0) && ($returnValue >= 0)) {
|
|
||||||
return sqrt($returnValue / $aCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Functions::DIV0();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -3114,48 +2907,18 @@ class Statistical
|
||||||
* Excel Function:
|
* Excel Function:
|
||||||
* STDEVA(value1[,value2[, ...]])
|
* STDEVA(value1[,value2[, ...]])
|
||||||
*
|
*
|
||||||
|
* @Deprecated 1.17.0
|
||||||
|
*
|
||||||
|
* @see Statistical\StandardDeviations::STDEVA()
|
||||||
|
* Use the STDEVA() method in the Statistical\StandardDeviations class instead
|
||||||
|
*
|
||||||
* @param mixed ...$args Data values
|
* @param mixed ...$args Data values
|
||||||
*
|
*
|
||||||
* @return float|string
|
* @return float|string
|
||||||
*/
|
*/
|
||||||
public static function STDEVA(...$args)
|
public static function STDEVA(...$args)
|
||||||
{
|
{
|
||||||
$aArgs = Functions::flattenArrayIndexed($args);
|
return StandardDeviations::STDEVA(...$args);
|
||||||
|
|
||||||
$returnValue = null;
|
|
||||||
|
|
||||||
$aMean = self::AVERAGEA($aArgs);
|
|
||||||
if ($aMean !== null) {
|
|
||||||
$aCount = -1;
|
|
||||||
foreach ($aArgs as $k => $arg) {
|
|
||||||
if (
|
|
||||||
(is_bool($arg)) &&
|
|
||||||
(!Functions::isMatrixValue($k))
|
|
||||||
) {
|
|
||||||
} else {
|
|
||||||
// Is it a numeric value?
|
|
||||||
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) {
|
|
||||||
if (is_bool($arg)) {
|
|
||||||
$arg = (int) $arg;
|
|
||||||
} elseif (is_string($arg)) {
|
|
||||||
$arg = 0;
|
|
||||||
}
|
|
||||||
if ($returnValue === null) {
|
|
||||||
$returnValue = ($arg - $aMean) ** 2;
|
|
||||||
} else {
|
|
||||||
$returnValue += ($arg - $aMean) ** 2;
|
|
||||||
}
|
|
||||||
++$aCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (($aCount > 0) && ($returnValue >= 0)) {
|
|
||||||
return sqrt($returnValue / $aCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Functions::DIV0();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -3166,43 +2929,18 @@ class Statistical
|
||||||
* Excel Function:
|
* Excel Function:
|
||||||
* STDEVP(value1[,value2[, ...]])
|
* STDEVP(value1[,value2[, ...]])
|
||||||
*
|
*
|
||||||
|
* @Deprecated 1.17.0
|
||||||
|
*
|
||||||
|
* @see Statistical\StandardDeviations::STDEVP()
|
||||||
|
* Use the STDEVP() method in the Statistical\StandardDeviations class instead
|
||||||
|
*
|
||||||
* @param mixed ...$args Data values
|
* @param mixed ...$args Data values
|
||||||
*
|
*
|
||||||
* @return float|string
|
* @return float|string
|
||||||
*/
|
*/
|
||||||
public static function STDEVP(...$args)
|
public static function STDEVP(...$args)
|
||||||
{
|
{
|
||||||
$aArgs = Functions::flattenArrayIndexed($args);
|
return StandardDeviations::STDEVP(...$args);
|
||||||
|
|
||||||
$returnValue = null;
|
|
||||||
|
|
||||||
$aMean = self::AVERAGE($aArgs);
|
|
||||||
if ($aMean !== null) {
|
|
||||||
$aCount = 0;
|
|
||||||
foreach ($aArgs as $k => $arg) {
|
|
||||||
if (
|
|
||||||
(is_bool($arg)) &&
|
|
||||||
((!Functions::isCellValue($k)) || (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE))
|
|
||||||
) {
|
|
||||||
$arg = (int) $arg;
|
|
||||||
}
|
|
||||||
// Is it a numeric value?
|
|
||||||
if ((is_numeric($arg)) && (!is_string($arg))) {
|
|
||||||
if ($returnValue === null) {
|
|
||||||
$returnValue = ($arg - $aMean) ** 2;
|
|
||||||
} else {
|
|
||||||
$returnValue += ($arg - $aMean) ** 2;
|
|
||||||
}
|
|
||||||
++$aCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (($aCount > 0) && ($returnValue >= 0)) {
|
|
||||||
return sqrt($returnValue / $aCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Functions::DIV0();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -3213,48 +2951,18 @@ class Statistical
|
||||||
* Excel Function:
|
* Excel Function:
|
||||||
* STDEVPA(value1[,value2[, ...]])
|
* STDEVPA(value1[,value2[, ...]])
|
||||||
*
|
*
|
||||||
|
* @Deprecated 1.17.0
|
||||||
|
*
|
||||||
|
* @see Statistical\StandardDeviations::STDEVPA()
|
||||||
|
* Use the STDEVPA() method in the Statistical\StandardDeviations class instead
|
||||||
|
*
|
||||||
* @param mixed ...$args Data values
|
* @param mixed ...$args Data values
|
||||||
*
|
*
|
||||||
* @return float|string
|
* @return float|string
|
||||||
*/
|
*/
|
||||||
public static function STDEVPA(...$args)
|
public static function STDEVPA(...$args)
|
||||||
{
|
{
|
||||||
$aArgs = Functions::flattenArrayIndexed($args);
|
return StandardDeviations::STDEVPA(...$args);
|
||||||
|
|
||||||
$returnValue = null;
|
|
||||||
|
|
||||||
$aMean = self::AVERAGEA($aArgs);
|
|
||||||
if ($aMean !== null) {
|
|
||||||
$aCount = 0;
|
|
||||||
foreach ($aArgs as $k => $arg) {
|
|
||||||
if (
|
|
||||||
(is_bool($arg)) &&
|
|
||||||
(!Functions::isMatrixValue($k))
|
|
||||||
) {
|
|
||||||
} else {
|
|
||||||
// Is it a numeric value?
|
|
||||||
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) {
|
|
||||||
if (is_bool($arg)) {
|
|
||||||
$arg = (int) $arg;
|
|
||||||
} elseif (is_string($arg)) {
|
|
||||||
$arg = 0;
|
|
||||||
}
|
|
||||||
if ($returnValue === null) {
|
|
||||||
$returnValue = ($arg - $aMean) ** 2;
|
|
||||||
} else {
|
|
||||||
$returnValue += ($arg - $aMean) ** 2;
|
|
||||||
}
|
|
||||||
++$aCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (($aCount > 0) && ($returnValue >= 0)) {
|
|
||||||
return sqrt($returnValue / $aCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Functions::DIV0();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -3472,14 +3180,14 @@ class Statistical
|
||||||
$mArgs[] = $arg;
|
$mArgs[] = $arg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$discard = floor(self::COUNT($mArgs) * $percent / 2);
|
$discard = floor(Counts::COUNT($mArgs) * $percent / 2);
|
||||||
sort($mArgs);
|
sort($mArgs);
|
||||||
for ($i = 0; $i < $discard; ++$i) {
|
for ($i = 0; $i < $discard; ++$i) {
|
||||||
array_pop($mArgs);
|
array_pop($mArgs);
|
||||||
array_shift($mArgs);
|
array_shift($mArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::AVERAGE($mArgs);
|
return Averages::AVERAGE($mArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Functions::VALUE();
|
return Functions::VALUE();
|
||||||
|
|
@ -3493,38 +3201,18 @@ class Statistical
|
||||||
* Excel Function:
|
* Excel Function:
|
||||||
* VAR(value1[,value2[, ...]])
|
* VAR(value1[,value2[, ...]])
|
||||||
*
|
*
|
||||||
|
* @Deprecated 1.17.0
|
||||||
|
*
|
||||||
* @param mixed ...$args Data values
|
* @param mixed ...$args Data values
|
||||||
*
|
*
|
||||||
* @return float|string (string if result is an error)
|
* @return float|string (string if result is an error)
|
||||||
|
*
|
||||||
|
*@see Statistical\Variances::VAR()
|
||||||
|
* Use the VAR() method in the Statistical\Variances class instead
|
||||||
*/
|
*/
|
||||||
public static function VARFunc(...$args)
|
public static function VARFunc(...$args)
|
||||||
{
|
{
|
||||||
$returnValue = Functions::DIV0();
|
return Variances::VAR(...$args);
|
||||||
|
|
||||||
$summerA = $summerB = 0;
|
|
||||||
|
|
||||||
// Loop through arguments
|
|
||||||
$aArgs = Functions::flattenArray($args);
|
|
||||||
$aCount = 0;
|
|
||||||
foreach ($aArgs as $arg) {
|
|
||||||
if (is_bool($arg)) {
|
|
||||||
$arg = (int) $arg;
|
|
||||||
}
|
|
||||||
// Is it a numeric value?
|
|
||||||
if ((is_numeric($arg)) && (!is_string($arg))) {
|
|
||||||
$summerA += ($arg * $arg);
|
|
||||||
$summerB += $arg;
|
|
||||||
++$aCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($aCount > 1) {
|
|
||||||
$summerA *= $aCount;
|
|
||||||
$summerB *= $summerB;
|
|
||||||
$returnValue = ($summerA - $summerB) / ($aCount * ($aCount - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $returnValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -3535,51 +3223,18 @@ class Statistical
|
||||||
* Excel Function:
|
* Excel Function:
|
||||||
* VARA(value1[,value2[, ...]])
|
* VARA(value1[,value2[, ...]])
|
||||||
*
|
*
|
||||||
|
* @Deprecated 1.17.0
|
||||||
|
*
|
||||||
|
* @see Statistical\Variances::VARA()
|
||||||
|
* Use the VARA() method in the Statistical\Variances class instead
|
||||||
|
*
|
||||||
* @param mixed ...$args Data values
|
* @param mixed ...$args Data values
|
||||||
*
|
*
|
||||||
* @return float|string (string if result is an error)
|
* @return float|string (string if result is an error)
|
||||||
*/
|
*/
|
||||||
public static function VARA(...$args)
|
public static function VARA(...$args)
|
||||||
{
|
{
|
||||||
$returnValue = Functions::DIV0();
|
return Variances::VARA(...$args);
|
||||||
|
|
||||||
$summerA = $summerB = 0;
|
|
||||||
|
|
||||||
// Loop through arguments
|
|
||||||
$aArgs = Functions::flattenArrayIndexed($args);
|
|
||||||
$aCount = 0;
|
|
||||||
foreach ($aArgs as $k => $arg) {
|
|
||||||
if (
|
|
||||||
(is_string($arg)) &&
|
|
||||||
(Functions::isValue($k))
|
|
||||||
) {
|
|
||||||
return Functions::VALUE();
|
|
||||||
} elseif (
|
|
||||||
(is_string($arg)) &&
|
|
||||||
(!Functions::isMatrixValue($k))
|
|
||||||
) {
|
|
||||||
} else {
|
|
||||||
// Is it a numeric value?
|
|
||||||
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) {
|
|
||||||
if (is_bool($arg)) {
|
|
||||||
$arg = (int) $arg;
|
|
||||||
} elseif (is_string($arg)) {
|
|
||||||
$arg = 0;
|
|
||||||
}
|
|
||||||
$summerA += ($arg * $arg);
|
|
||||||
$summerB += $arg;
|
|
||||||
++$aCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($aCount > 1) {
|
|
||||||
$summerA *= $aCount;
|
|
||||||
$summerB *= $summerB;
|
|
||||||
$returnValue = ($summerA - $summerB) / ($aCount * ($aCount - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $returnValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -3590,39 +3245,18 @@ class Statistical
|
||||||
* Excel Function:
|
* Excel Function:
|
||||||
* VARP(value1[,value2[, ...]])
|
* VARP(value1[,value2[, ...]])
|
||||||
*
|
*
|
||||||
|
* @Deprecated 1.17.0
|
||||||
|
*
|
||||||
|
* @see Statistical\Variances::VARP()
|
||||||
|
* Use the VARP() method in the Statistical\Variances class instead
|
||||||
|
*
|
||||||
* @param mixed ...$args Data values
|
* @param mixed ...$args Data values
|
||||||
*
|
*
|
||||||
* @return float|string (string if result is an error)
|
* @return float|string (string if result is an error)
|
||||||
*/
|
*/
|
||||||
public static function VARP(...$args)
|
public static function VARP(...$args)
|
||||||
{
|
{
|
||||||
// Return value
|
return Variances::VARP(...$args);
|
||||||
$returnValue = Functions::DIV0();
|
|
||||||
|
|
||||||
$summerA = $summerB = 0;
|
|
||||||
|
|
||||||
// Loop through arguments
|
|
||||||
$aArgs = Functions::flattenArray($args);
|
|
||||||
$aCount = 0;
|
|
||||||
foreach ($aArgs as $arg) {
|
|
||||||
if (is_bool($arg)) {
|
|
||||||
$arg = (int) $arg;
|
|
||||||
}
|
|
||||||
// Is it a numeric value?
|
|
||||||
if ((is_numeric($arg)) && (!is_string($arg))) {
|
|
||||||
$summerA += ($arg * $arg);
|
|
||||||
$summerB += $arg;
|
|
||||||
++$aCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($aCount > 0) {
|
|
||||||
$summerA *= $aCount;
|
|
||||||
$summerB *= $summerB;
|
|
||||||
$returnValue = ($summerA - $summerB) / ($aCount * $aCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $returnValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -3633,51 +3267,18 @@ class Statistical
|
||||||
* Excel Function:
|
* Excel Function:
|
||||||
* VARPA(value1[,value2[, ...]])
|
* VARPA(value1[,value2[, ...]])
|
||||||
*
|
*
|
||||||
|
* @Deprecated 1.17.0
|
||||||
|
*
|
||||||
|
* @see Statistical\Variances::VARPA()
|
||||||
|
* Use the VARPA() method in the Statistical\Variances class instead
|
||||||
|
*
|
||||||
* @param mixed ...$args Data values
|
* @param mixed ...$args Data values
|
||||||
*
|
*
|
||||||
* @return float|string (string if result is an error)
|
* @return float|string (string if result is an error)
|
||||||
*/
|
*/
|
||||||
public static function VARPA(...$args)
|
public static function VARPA(...$args)
|
||||||
{
|
{
|
||||||
$returnValue = Functions::DIV0();
|
return Variances::VARPA(...$args);
|
||||||
|
|
||||||
$summerA = $summerB = 0;
|
|
||||||
|
|
||||||
// Loop through arguments
|
|
||||||
$aArgs = Functions::flattenArrayIndexed($args);
|
|
||||||
$aCount = 0;
|
|
||||||
foreach ($aArgs as $k => $arg) {
|
|
||||||
if (
|
|
||||||
(is_string($arg)) &&
|
|
||||||
(Functions::isValue($k))
|
|
||||||
) {
|
|
||||||
return Functions::VALUE();
|
|
||||||
} elseif (
|
|
||||||
(is_string($arg)) &&
|
|
||||||
(!Functions::isMatrixValue($k))
|
|
||||||
) {
|
|
||||||
} else {
|
|
||||||
// Is it a numeric value?
|
|
||||||
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) {
|
|
||||||
if (is_bool($arg)) {
|
|
||||||
$arg = (int) $arg;
|
|
||||||
} elseif (is_string($arg)) {
|
|
||||||
$arg = 0;
|
|
||||||
}
|
|
||||||
$summerA += ($arg * $arg);
|
|
||||||
$summerB += $arg;
|
|
||||||
++$aCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($aCount > 0) {
|
|
||||||
$summerA *= $aCount;
|
|
||||||
$summerB *= $summerB;
|
|
||||||
$returnValue = ($summerA - $summerB) / ($aCount * $aCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $returnValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -3734,10 +3335,10 @@ class Statistical
|
||||||
$sigma = Functions::flattenSingleValue($sigma);
|
$sigma = Functions::flattenSingleValue($sigma);
|
||||||
|
|
||||||
if ($sigma === null) {
|
if ($sigma === null) {
|
||||||
$sigma = self::STDEV($dataSet);
|
$sigma = StandardDeviations::STDEV($dataSet);
|
||||||
}
|
}
|
||||||
$n = count($dataSet);
|
$n = count($dataSet);
|
||||||
|
|
||||||
return 1 - self::NORMSDIST((self::AVERAGE($dataSet) - $m0) / ($sigma / sqrt($n)));
|
return 1 - self::NORMSDIST((Averages::AVERAGE($dataSet) - $m0) / ($sigma / sqrt($n)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||||
|
|
||||||
|
abstract class AggregateBase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* MS Excel does not count Booleans if passed as cell values, but they are counted if passed as literals.
|
||||||
|
* OpenOffice Calc always counts Booleans.
|
||||||
|
* Gnumeric never counts Booleans.
|
||||||
|
*
|
||||||
|
* @param mixed $arg
|
||||||
|
* @param mixed $k
|
||||||
|
*
|
||||||
|
* @return int|mixed
|
||||||
|
*/
|
||||||
|
protected static function testAcceptedBoolean($arg, $k)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
(is_bool($arg)) &&
|
||||||
|
((!Functions::isCellValue($k) && (Functions::getCompatibilityMode() === Functions::COMPATIBILITY_EXCEL)) ||
|
||||||
|
(Functions::getCompatibilityMode() === Functions::COMPATIBILITY_OPENOFFICE))
|
||||||
|
) {
|
||||||
|
$arg = (int) $arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed $arg
|
||||||
|
* @param mixed $k
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected static function isAcceptedCountable($arg, $k)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
((is_numeric($arg)) && (!is_string($arg))) ||
|
||||||
|
((is_numeric($arg)) && (!Functions::isCellValue($k)) &&
|
||||||
|
(Functions::getCompatibilityMode() !== Functions::COMPATIBILITY_GNUMERIC))
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,137 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||||
|
|
||||||
|
class Averages extends AggregateBase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* AVEDEV.
|
||||||
|
*
|
||||||
|
* Returns the average of the absolute deviations of data points from their mean.
|
||||||
|
* AVEDEV is a measure of the variability in a data set.
|
||||||
|
*
|
||||||
|
* Excel Function:
|
||||||
|
* AVEDEV(value1[,value2[, ...]])
|
||||||
|
*
|
||||||
|
* @param mixed ...$args Data values
|
||||||
|
*
|
||||||
|
* @return float|string (string if result is an error)
|
||||||
|
*/
|
||||||
|
public static function AVEDEV(...$args)
|
||||||
|
{
|
||||||
|
$aArgs = Functions::flattenArrayIndexed($args);
|
||||||
|
|
||||||
|
// Return value
|
||||||
|
$returnValue = 0;
|
||||||
|
|
||||||
|
$aMean = self::AVERAGE(...$args);
|
||||||
|
if ($aMean === Functions::DIV0()) {
|
||||||
|
return Functions::NAN();
|
||||||
|
} elseif ($aMean === Functions::VALUE()) {
|
||||||
|
return Functions::VALUE();
|
||||||
|
}
|
||||||
|
|
||||||
|
$aCount = 0;
|
||||||
|
foreach ($aArgs as $k => $arg) {
|
||||||
|
$arg = self::testAcceptedBoolean($arg, $k);
|
||||||
|
// Is it a numeric value?
|
||||||
|
// Strings containing numeric values are only counted if they are string literals (not cell values)
|
||||||
|
// and then only in MS Excel and in Open Office, not in Gnumeric
|
||||||
|
if ((is_string($arg)) && (!is_numeric($arg)) && (!Functions::isCellValue($k))) {
|
||||||
|
return Functions::VALUE();
|
||||||
|
}
|
||||||
|
if (self::isAcceptedCountable($arg, $k)) {
|
||||||
|
$returnValue += abs($arg - $aMean);
|
||||||
|
++$aCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return
|
||||||
|
if ($aCount === 0) {
|
||||||
|
return Functions::DIV0();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $returnValue / $aCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AVERAGE.
|
||||||
|
*
|
||||||
|
* Returns the average (arithmetic mean) of the arguments
|
||||||
|
*
|
||||||
|
* Excel Function:
|
||||||
|
* AVERAGE(value1[,value2[, ...]])
|
||||||
|
*
|
||||||
|
* @param mixed ...$args Data values
|
||||||
|
*
|
||||||
|
* @return float|string (string if result is an error)
|
||||||
|
*/
|
||||||
|
public static function AVERAGE(...$args)
|
||||||
|
{
|
||||||
|
$returnValue = $aCount = 0;
|
||||||
|
|
||||||
|
// Loop through arguments
|
||||||
|
foreach (Functions::flattenArrayIndexed($args) as $k => $arg) {
|
||||||
|
$arg = self::testAcceptedBoolean($arg, $k);
|
||||||
|
// Is it a numeric value?
|
||||||
|
// Strings containing numeric values are only counted if they are string literals (not cell values)
|
||||||
|
// and then only in MS Excel and in Open Office, not in Gnumeric
|
||||||
|
if ((is_string($arg)) && (!is_numeric($arg)) && (!Functions::isCellValue($k))) {
|
||||||
|
return Functions::VALUE();
|
||||||
|
}
|
||||||
|
if (self::isAcceptedCountable($arg, $k)) {
|
||||||
|
$returnValue += $arg;
|
||||||
|
++$aCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return
|
||||||
|
if ($aCount > 0) {
|
||||||
|
return $returnValue / $aCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Functions::DIV0();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AVERAGEA.
|
||||||
|
*
|
||||||
|
* Returns the average of its arguments, including numbers, text, and logical values
|
||||||
|
*
|
||||||
|
* Excel Function:
|
||||||
|
* AVERAGEA(value1[,value2[, ...]])
|
||||||
|
*
|
||||||
|
* @param mixed ...$args Data values
|
||||||
|
*
|
||||||
|
* @return float|string (string if result is an error)
|
||||||
|
*/
|
||||||
|
public static function AVERAGEA(...$args)
|
||||||
|
{
|
||||||
|
$returnValue = null;
|
||||||
|
|
||||||
|
$aCount = 0;
|
||||||
|
// Loop through arguments
|
||||||
|
foreach (Functions::flattenArrayIndexed($args) as $k => $arg) {
|
||||||
|
if ((is_bool($arg)) && (!Functions::isMatrixValue($k))) {
|
||||||
|
} else {
|
||||||
|
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
|
||||||
|
if (is_bool($arg)) {
|
||||||
|
$arg = (int) $arg;
|
||||||
|
} elseif (is_string($arg)) {
|
||||||
|
$arg = 0;
|
||||||
|
}
|
||||||
|
$returnValue += $arg;
|
||||||
|
++$aCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($aCount > 0) {
|
||||||
|
return $returnValue / $aCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Functions::DIV0();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,95 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||||
|
|
||||||
|
class Counts extends AggregateBase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* COUNT.
|
||||||
|
*
|
||||||
|
* Counts the number of cells that contain numbers within the list of arguments
|
||||||
|
*
|
||||||
|
* Excel Function:
|
||||||
|
* COUNT(value1[,value2[, ...]])
|
||||||
|
*
|
||||||
|
* @param mixed ...$args Data values
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public static function COUNT(...$args)
|
||||||
|
{
|
||||||
|
$returnValue = 0;
|
||||||
|
|
||||||
|
// Loop through arguments
|
||||||
|
$aArgs = Functions::flattenArrayIndexed($args);
|
||||||
|
foreach ($aArgs as $k => $arg) {
|
||||||
|
$arg = self::testAcceptedBoolean($arg, $k);
|
||||||
|
// Is it a numeric value?
|
||||||
|
// Strings containing numeric values are only counted if they are string literals (not cell values)
|
||||||
|
// and then only in MS Excel and in Open Office, not in Gnumeric
|
||||||
|
if (self::isAcceptedCountable($arg, $k)) {
|
||||||
|
++$returnValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* COUNTA.
|
||||||
|
*
|
||||||
|
* Counts the number of cells that are not empty within the list of arguments
|
||||||
|
*
|
||||||
|
* Excel Function:
|
||||||
|
* COUNTA(value1[,value2[, ...]])
|
||||||
|
*
|
||||||
|
* @param mixed ...$args Data values
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public static function COUNTA(...$args)
|
||||||
|
{
|
||||||
|
$returnValue = 0;
|
||||||
|
|
||||||
|
// Loop through arguments
|
||||||
|
$aArgs = Functions::flattenArrayIndexed($args);
|
||||||
|
foreach ($aArgs as $k => $arg) {
|
||||||
|
// Nulls are counted if literals, but not if cell values
|
||||||
|
if ($arg !== null || (!Functions::isCellValue($k))) {
|
||||||
|
++$returnValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* COUNTBLANK.
|
||||||
|
*
|
||||||
|
* Counts the number of empty cells within the list of arguments
|
||||||
|
*
|
||||||
|
* Excel Function:
|
||||||
|
* COUNTBLANK(value1[,value2[, ...]])
|
||||||
|
*
|
||||||
|
* @param mixed ...$args Data values
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public static function COUNTBLANK(...$args)
|
||||||
|
{
|
||||||
|
$returnValue = 0;
|
||||||
|
|
||||||
|
// Loop through arguments
|
||||||
|
$aArgs = Functions::flattenArray($args);
|
||||||
|
foreach ($aArgs as $arg) {
|
||||||
|
// Is it a blank cell?
|
||||||
|
if (($arg === null) || ((is_string($arg)) && ($arg == ''))) {
|
||||||
|
++$returnValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $returnValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||||
|
|
||||||
|
abstract class MaxMinBase
|
||||||
|
{
|
||||||
|
protected static function datatypeAdjustmentAllowStrings($value)
|
||||||
|
{
|
||||||
|
if (is_bool($value)) {
|
||||||
|
return (int) $value;
|
||||||
|
} elseif (is_string($value)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||||
|
|
||||||
|
class Maximum extends MaxMinBase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* MAX.
|
||||||
|
*
|
||||||
|
* MAX returns the value of the element of the values passed that has the highest value,
|
||||||
|
* with negative numbers considered smaller than positive numbers.
|
||||||
|
*
|
||||||
|
* Excel Function:
|
||||||
|
* MAX(value1[,value2[, ...]])
|
||||||
|
*
|
||||||
|
* @param mixed ...$args Data values
|
||||||
|
*
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
public static function MAX(...$args)
|
||||||
|
{
|
||||||
|
$returnValue = null;
|
||||||
|
|
||||||
|
// Loop through arguments
|
||||||
|
$aArgs = Functions::flattenArray($args);
|
||||||
|
foreach ($aArgs as $arg) {
|
||||||
|
// Is it a numeric value?
|
||||||
|
if ((is_numeric($arg)) && (!is_string($arg))) {
|
||||||
|
if (($returnValue === null) || ($arg > $returnValue)) {
|
||||||
|
$returnValue = $arg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($returnValue === null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MAXA.
|
||||||
|
*
|
||||||
|
* Returns the greatest value in a list of arguments, including numbers, text, and logical values
|
||||||
|
*
|
||||||
|
* Excel Function:
|
||||||
|
* MAXA(value1[,value2[, ...]])
|
||||||
|
*
|
||||||
|
* @param mixed ...$args Data values
|
||||||
|
*
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
public static function MAXA(...$args)
|
||||||
|
{
|
||||||
|
$returnValue = null;
|
||||||
|
|
||||||
|
// Loop through arguments
|
||||||
|
$aArgs = Functions::flattenArray($args);
|
||||||
|
foreach ($aArgs as $arg) {
|
||||||
|
// Is it a numeric value?
|
||||||
|
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
|
||||||
|
$arg = self::datatypeAdjustmentAllowStrings($arg);
|
||||||
|
if (($returnValue === null) || ($arg > $returnValue)) {
|
||||||
|
$returnValue = $arg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($returnValue === null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $returnValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||||
|
|
||||||
|
class Minimum extends MaxMinBase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* MIN.
|
||||||
|
*
|
||||||
|
* MIN returns the value of the element of the values passed that has the smallest value,
|
||||||
|
* with negative numbers considered smaller than positive numbers.
|
||||||
|
*
|
||||||
|
* Excel Function:
|
||||||
|
* MIN(value1[,value2[, ...]])
|
||||||
|
*
|
||||||
|
* @param mixed ...$args Data values
|
||||||
|
*
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
public static function MIN(...$args)
|
||||||
|
{
|
||||||
|
$returnValue = null;
|
||||||
|
|
||||||
|
// Loop through arguments
|
||||||
|
$aArgs = Functions::flattenArray($args);
|
||||||
|
foreach ($aArgs as $arg) {
|
||||||
|
// Is it a numeric value?
|
||||||
|
if ((is_numeric($arg)) && (!is_string($arg))) {
|
||||||
|
if (($returnValue === null) || ($arg < $returnValue)) {
|
||||||
|
$returnValue = $arg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($returnValue === null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MINA.
|
||||||
|
*
|
||||||
|
* Returns the smallest value in a list of arguments, including numbers, text, and logical values
|
||||||
|
*
|
||||||
|
* Excel Function:
|
||||||
|
* MINA(value1[,value2[, ...]])
|
||||||
|
*
|
||||||
|
* @param mixed ...$args Data values
|
||||||
|
*
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
public static function MINA(...$args)
|
||||||
|
{
|
||||||
|
$returnValue = null;
|
||||||
|
|
||||||
|
// Loop through arguments
|
||||||
|
$aArgs = Functions::flattenArray($args);
|
||||||
|
foreach ($aArgs as $arg) {
|
||||||
|
// Is it a numeric value?
|
||||||
|
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
|
||||||
|
$arg = self::datatypeAdjustmentAllowStrings($arg);
|
||||||
|
if (($returnValue === null) || ($arg < $returnValue)) {
|
||||||
|
$returnValue = $arg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($returnValue === null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $returnValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,181 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||||
|
|
||||||
|
class StandardDeviations extends VarianceBase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* STDEV.
|
||||||
|
*
|
||||||
|
* Estimates standard deviation based on a sample. The standard deviation is a measure of how
|
||||||
|
* widely values are dispersed from the average value (the mean).
|
||||||
|
*
|
||||||
|
* Excel Function:
|
||||||
|
* STDEV(value1[,value2[, ...]])
|
||||||
|
*
|
||||||
|
* @param mixed ...$args Data values
|
||||||
|
*
|
||||||
|
* @return float|string The result, or a string containing an error
|
||||||
|
*/
|
||||||
|
public static function STDEV(...$args)
|
||||||
|
{
|
||||||
|
$aArgs = Functions::flattenArrayIndexed($args);
|
||||||
|
|
||||||
|
$aMean = Averages::AVERAGE($aArgs);
|
||||||
|
|
||||||
|
if (!is_string($aMean)) {
|
||||||
|
$returnValue = 0.0;
|
||||||
|
$aCount = -1;
|
||||||
|
|
||||||
|
foreach ($aArgs as $k => $arg) {
|
||||||
|
if (
|
||||||
|
(is_bool($arg)) &&
|
||||||
|
((!Functions::isCellValue($k)) || (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE))
|
||||||
|
) {
|
||||||
|
$arg = (int) $arg;
|
||||||
|
}
|
||||||
|
// Is it a numeric value?
|
||||||
|
if ((is_numeric($arg)) && (!is_string($arg))) {
|
||||||
|
$returnValue += ($arg - $aMean) ** 2;
|
||||||
|
++$aCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($aCount > 0) {
|
||||||
|
return sqrt($returnValue / $aCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Functions::DIV0();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* STDEVA.
|
||||||
|
*
|
||||||
|
* Estimates standard deviation based on a sample, including numbers, text, and logical values
|
||||||
|
*
|
||||||
|
* Excel Function:
|
||||||
|
* STDEVA(value1[,value2[, ...]])
|
||||||
|
*
|
||||||
|
* @param mixed ...$args Data values
|
||||||
|
*
|
||||||
|
* @return float|string
|
||||||
|
*/
|
||||||
|
public static function STDEVA(...$args)
|
||||||
|
{
|
||||||
|
$aArgs = Functions::flattenArrayIndexed($args);
|
||||||
|
|
||||||
|
$aMean = Averages::AVERAGEA($aArgs);
|
||||||
|
|
||||||
|
if (!is_string($aMean)) {
|
||||||
|
$returnValue = 0.0;
|
||||||
|
$aCount = -1;
|
||||||
|
|
||||||
|
foreach ($aArgs as $k => $arg) {
|
||||||
|
if ((is_bool($arg)) && (!Functions::isMatrixValue($k))) {
|
||||||
|
} else {
|
||||||
|
// Is it a numeric value?
|
||||||
|
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
|
||||||
|
$arg = self::datatypeAdjustmentAllowStrings($arg);
|
||||||
|
$returnValue += ($arg - $aMean) ** 2;
|
||||||
|
++$aCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($aCount > 0) {
|
||||||
|
return sqrt($returnValue / $aCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Functions::DIV0();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* STDEVP.
|
||||||
|
*
|
||||||
|
* Calculates standard deviation based on the entire population
|
||||||
|
*
|
||||||
|
* Excel Function:
|
||||||
|
* STDEVP(value1[,value2[, ...]])
|
||||||
|
*
|
||||||
|
* @param mixed ...$args Data values
|
||||||
|
*
|
||||||
|
* @return float|string
|
||||||
|
*/
|
||||||
|
public static function STDEVP(...$args)
|
||||||
|
{
|
||||||
|
$aArgs = Functions::flattenArrayIndexed($args);
|
||||||
|
|
||||||
|
$aMean = Averages::AVERAGE($aArgs);
|
||||||
|
|
||||||
|
if (!is_string($aMean)) {
|
||||||
|
$returnValue = 0.0;
|
||||||
|
$aCount = 0;
|
||||||
|
|
||||||
|
foreach ($aArgs as $k => $arg) {
|
||||||
|
if (
|
||||||
|
(is_bool($arg)) &&
|
||||||
|
((!Functions::isCellValue($k)) || (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE))
|
||||||
|
) {
|
||||||
|
$arg = (int) $arg;
|
||||||
|
}
|
||||||
|
// Is it a numeric value?
|
||||||
|
if ((is_numeric($arg)) && (!is_string($arg))) {
|
||||||
|
$returnValue += ($arg - $aMean) ** 2;
|
||||||
|
++$aCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($aCount > 0) {
|
||||||
|
return sqrt($returnValue / $aCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Functions::DIV0();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* STDEVPA.
|
||||||
|
*
|
||||||
|
* Calculates standard deviation based on the entire population, including numbers, text, and logical values
|
||||||
|
*
|
||||||
|
* Excel Function:
|
||||||
|
* STDEVPA(value1[,value2[, ...]])
|
||||||
|
*
|
||||||
|
* @param mixed ...$args Data values
|
||||||
|
*
|
||||||
|
* @return float|string
|
||||||
|
*/
|
||||||
|
public static function STDEVPA(...$args)
|
||||||
|
{
|
||||||
|
$aArgs = Functions::flattenArrayIndexed($args);
|
||||||
|
|
||||||
|
$aMean = Averages::AVERAGEA($aArgs);
|
||||||
|
|
||||||
|
if (!is_string($aMean)) {
|
||||||
|
$returnValue = 0.0;
|
||||||
|
$aCount = 0;
|
||||||
|
|
||||||
|
foreach ($aArgs as $k => $arg) {
|
||||||
|
if ((is_bool($arg)) && (!Functions::isMatrixValue($k))) {
|
||||||
|
} else {
|
||||||
|
// Is it a numeric value?
|
||||||
|
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
|
||||||
|
$arg = self::datatypeAdjustmentAllowStrings($arg);
|
||||||
|
$returnValue += ($arg - $aMean) ** 2;
|
||||||
|
++$aCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($aCount > 0) {
|
||||||
|
return sqrt($returnValue / $aCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Functions::DIV0();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||||
|
|
||||||
|
abstract class VarianceBase
|
||||||
|
{
|
||||||
|
protected static function datatypeAdjustmentAllowStrings($value)
|
||||||
|
{
|
||||||
|
if (is_bool($value)) {
|
||||||
|
return (int) $value;
|
||||||
|
} elseif (is_string($value)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static function datatypeAdjustmentBooleans($value)
|
||||||
|
{
|
||||||
|
if (is_bool($value)) {
|
||||||
|
return (int) $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,183 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||||
|
|
||||||
|
class Variances extends VarianceBase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* VAR.
|
||||||
|
*
|
||||||
|
* Estimates variance based on a sample.
|
||||||
|
*
|
||||||
|
* Excel Function:
|
||||||
|
* VAR(value1[,value2[, ...]])
|
||||||
|
*
|
||||||
|
* @param mixed ...$args Data values
|
||||||
|
*
|
||||||
|
* @return float|string (string if result is an error)
|
||||||
|
*/
|
||||||
|
public static function VAR(...$args)
|
||||||
|
{
|
||||||
|
$returnValue = Functions::DIV0();
|
||||||
|
|
||||||
|
$summerA = $summerB = 0.0;
|
||||||
|
|
||||||
|
// Loop through arguments
|
||||||
|
$aArgs = Functions::flattenArray($args);
|
||||||
|
$aCount = 0;
|
||||||
|
foreach ($aArgs as $arg) {
|
||||||
|
$arg = self::datatypeAdjustmentBooleans($arg);
|
||||||
|
// Is it a numeric value?
|
||||||
|
if ((is_numeric($arg)) && (!is_string($arg))) {
|
||||||
|
$summerA += ($arg * $arg);
|
||||||
|
$summerB += $arg;
|
||||||
|
++$aCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($aCount > 1) {
|
||||||
|
$summerA *= $aCount;
|
||||||
|
$summerB *= $summerB;
|
||||||
|
|
||||||
|
return ($summerA - $summerB) / ($aCount * ($aCount - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VARA.
|
||||||
|
*
|
||||||
|
* Estimates variance based on a sample, including numbers, text, and logical values
|
||||||
|
*
|
||||||
|
* Excel Function:
|
||||||
|
* VARA(value1[,value2[, ...]])
|
||||||
|
*
|
||||||
|
* @param mixed ...$args Data values
|
||||||
|
*
|
||||||
|
* @return float|string (string if result is an error)
|
||||||
|
*/
|
||||||
|
public static function VARA(...$args)
|
||||||
|
{
|
||||||
|
$returnValue = Functions::DIV0();
|
||||||
|
|
||||||
|
$summerA = $summerB = 0.0;
|
||||||
|
|
||||||
|
// Loop through arguments
|
||||||
|
$aArgs = Functions::flattenArrayIndexed($args);
|
||||||
|
$aCount = 0;
|
||||||
|
foreach ($aArgs as $k => $arg) {
|
||||||
|
if ((is_string($arg)) && (Functions::isValue($k))) {
|
||||||
|
return Functions::VALUE();
|
||||||
|
} elseif ((is_string($arg)) && (!Functions::isMatrixValue($k))) {
|
||||||
|
} else {
|
||||||
|
// Is it a numeric value?
|
||||||
|
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) {
|
||||||
|
$arg = self::datatypeAdjustmentAllowStrings($arg);
|
||||||
|
$summerA += ($arg * $arg);
|
||||||
|
$summerB += $arg;
|
||||||
|
++$aCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($aCount > 1) {
|
||||||
|
$summerA *= $aCount;
|
||||||
|
$summerB *= $summerB;
|
||||||
|
|
||||||
|
return ($summerA - $summerB) / ($aCount * ($aCount - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VARP.
|
||||||
|
*
|
||||||
|
* Calculates variance based on the entire population
|
||||||
|
*
|
||||||
|
* Excel Function:
|
||||||
|
* VARP(value1[,value2[, ...]])
|
||||||
|
*
|
||||||
|
* @param mixed ...$args Data values
|
||||||
|
*
|
||||||
|
* @return float|string (string if result is an error)
|
||||||
|
*/
|
||||||
|
public static function VARP(...$args)
|
||||||
|
{
|
||||||
|
// Return value
|
||||||
|
$returnValue = Functions::DIV0();
|
||||||
|
|
||||||
|
$summerA = $summerB = 0.0;
|
||||||
|
|
||||||
|
// Loop through arguments
|
||||||
|
$aArgs = Functions::flattenArray($args);
|
||||||
|
$aCount = 0;
|
||||||
|
foreach ($aArgs as $arg) {
|
||||||
|
$arg = self::datatypeAdjustmentBooleans($arg);
|
||||||
|
// Is it a numeric value?
|
||||||
|
if ((is_numeric($arg)) && (!is_string($arg))) {
|
||||||
|
$summerA += ($arg * $arg);
|
||||||
|
$summerB += $arg;
|
||||||
|
++$aCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($aCount > 0) {
|
||||||
|
$summerA *= $aCount;
|
||||||
|
$summerB *= $summerB;
|
||||||
|
|
||||||
|
return ($summerA - $summerB) / ($aCount * $aCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VARPA.
|
||||||
|
*
|
||||||
|
* Calculates variance based on the entire population, including numbers, text, and logical values
|
||||||
|
*
|
||||||
|
* Excel Function:
|
||||||
|
* VARPA(value1[,value2[, ...]])
|
||||||
|
*
|
||||||
|
* @param mixed ...$args Data values
|
||||||
|
*
|
||||||
|
* @return float|string (string if result is an error)
|
||||||
|
*/
|
||||||
|
public static function VARPA(...$args)
|
||||||
|
{
|
||||||
|
$returnValue = Functions::DIV0();
|
||||||
|
|
||||||
|
$summerA = $summerB = 0.0;
|
||||||
|
|
||||||
|
// Loop through arguments
|
||||||
|
$aArgs = Functions::flattenArrayIndexed($args);
|
||||||
|
$aCount = 0;
|
||||||
|
foreach ($aArgs as $k => $arg) {
|
||||||
|
if ((is_string($arg)) && (Functions::isValue($k))) {
|
||||||
|
return Functions::VALUE();
|
||||||
|
} elseif ((is_string($arg)) && (!Functions::isMatrixValue($k))) {
|
||||||
|
} else {
|
||||||
|
// Is it a numeric value?
|
||||||
|
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) {
|
||||||
|
$arg = self::datatypeAdjustmentAllowStrings($arg);
|
||||||
|
$summerA += ($arg * $arg);
|
||||||
|
$summerB += $arg;
|
||||||
|
++$aCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($aCount > 0) {
|
||||||
|
$summerA *= $aCount;
|
||||||
|
$summerB *= $summerB;
|
||||||
|
|
||||||
|
return ($summerA - $summerB) / ($aCount * $aCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $returnValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -24,7 +24,7 @@ class Tcpdf extends Pdf
|
||||||
*
|
*
|
||||||
* @param string $orientation Page orientation
|
* @param string $orientation Page orientation
|
||||||
* @param string $unit Unit measure
|
* @param string $unit Unit measure
|
||||||
* @param string $paperSize Paper size
|
* @param array|string $paperSize Paper size
|
||||||
*
|
*
|
||||||
* @return \TCPDF implementation
|
* @return \TCPDF implementation
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class StDevATest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @dataProvider providerSTDEVA
|
||||||
|
*
|
||||||
|
* @param mixed $expectedResult
|
||||||
|
* @param mixed $values
|
||||||
|
*/
|
||||||
|
public function testSTDEVA($expectedResult, $values): void
|
||||||
|
{
|
||||||
|
$result = Statistical::STDEVA($values);
|
||||||
|
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function providerSTDEVA()
|
||||||
|
{
|
||||||
|
return require 'tests/data/Calculation/Statistical/STDEVA.php';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class StDevPATest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @dataProvider providerSTDEVPA
|
||||||
|
*
|
||||||
|
* @param mixed $expectedResult
|
||||||
|
* @param mixed $values
|
||||||
|
*/
|
||||||
|
public function testSTDEVPA($expectedResult, $values): void
|
||||||
|
{
|
||||||
|
$result = Statistical::STDEVPA($values);
|
||||||
|
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function providerSTDEVPA()
|
||||||
|
{
|
||||||
|
return require 'tests/data/Calculation/Statistical/STDEVPA.php';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class StDevPTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @dataProvider providerSTDEVP
|
||||||
|
*
|
||||||
|
* @param mixed $expectedResult
|
||||||
|
* @param mixed $values
|
||||||
|
*/
|
||||||
|
public function testSTDEVP($expectedResult, $values): void
|
||||||
|
{
|
||||||
|
$result = Statistical::STDEVP($values);
|
||||||
|
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function providerSTDEVP()
|
||||||
|
{
|
||||||
|
return require 'tests/data/Calculation/Statistical/STDEVP.php';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class StDevTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @dataProvider providerSTDEV
|
||||||
|
*
|
||||||
|
* @param mixed $expectedResult
|
||||||
|
* @param mixed $values
|
||||||
|
*/
|
||||||
|
public function testSTDEV($expectedResult, $values): void
|
||||||
|
{
|
||||||
|
$result = Statistical::STDEV($values);
|
||||||
|
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function providerSTDEV()
|
||||||
|
{
|
||||||
|
return require 'tests/data/Calculation/Statistical/STDEV.php';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class VarATest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @dataProvider providerVARA
|
||||||
|
*
|
||||||
|
* @param mixed $expectedResult
|
||||||
|
* @param mixed $values
|
||||||
|
*/
|
||||||
|
public function testVARA($expectedResult, $values): void
|
||||||
|
{
|
||||||
|
$result = Statistical::VARA($values);
|
||||||
|
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function providerVARA()
|
||||||
|
{
|
||||||
|
return require 'tests/data/Calculation/Statistical/VARA.php';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class VarPATest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @dataProvider providerVARPA
|
||||||
|
*
|
||||||
|
* @param mixed $expectedResult
|
||||||
|
* @param mixed $values
|
||||||
|
*/
|
||||||
|
public function testVARPA($expectedResult, $values): void
|
||||||
|
{
|
||||||
|
$result = Statistical::VARPA($values);
|
||||||
|
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function providerVARPA()
|
||||||
|
{
|
||||||
|
return require 'tests/data/Calculation/Statistical/VARPA.php';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class VarPTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @dataProvider providerVARP
|
||||||
|
*
|
||||||
|
* @param mixed $expectedResult
|
||||||
|
* @param mixed $values
|
||||||
|
*/
|
||||||
|
public function testVARP($expectedResult, $values): void
|
||||||
|
{
|
||||||
|
$result = Statistical::VARP($values);
|
||||||
|
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function providerVARP()
|
||||||
|
{
|
||||||
|
return require 'tests/data/Calculation/Statistical/VARP.php';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
|
||||||
|
|
||||||
|
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class VarTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @dataProvider providerVAR
|
||||||
|
*
|
||||||
|
* @param mixed $expectedResult
|
||||||
|
* @param mixed $values
|
||||||
|
*/
|
||||||
|
public function testVAR($expectedResult, $values): void
|
||||||
|
{
|
||||||
|
$result = Statistical::VARFunc($values);
|
||||||
|
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function providerVAR()
|
||||||
|
{
|
||||||
|
return require 'tests/data/Calculation/Statistical/VAR.php';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
27.463915719843,
|
||||||
|
[1345, 1301, 1368, 1322, 1310, 1370, 1318, 1350, 1303, 1299],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'#DIV/0!',
|
||||||
|
['A', 'B', 'C'],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
27.463915719843,
|
||||||
|
[1345, 1301, 1368, 1322, 1310, 1370, 1318, 1350, 1303, 1299],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'#DIV/0!',
|
||||||
|
[],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
26.0545581424825,
|
||||||
|
[1345, 1301, 1368, 1322, 1310, 1370, 1318, 1350, 1303, 1299],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'#DIV/0!',
|
||||||
|
['A', 'B', 'C'],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
26.0545581424825,
|
||||||
|
[1345, 1301, 1368, 1322, 1310, 1370, 1318, 1350, 1303, 1299],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'#DIV/0!',
|
||||||
|
[],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
754.266666666667,
|
||||||
|
[1345, 1301, 1368, 1322, 1310, 1370, 1318, 1350, 1303, 1299],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
754.266666666667,
|
||||||
|
[1345, 1301, 1368, 1322, 1310, 1370, 1318, 1350, 1303, 1299],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
678.84,
|
||||||
|
[1345, 1301, 1368, 1322, 1310, 1370, 1318, 1350, 1303, 1299],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
678.84,
|
||||||
|
[1345, 1301, 1368, 1322, 1310, 1370, 1318, 1350, 1303, 1299],
|
||||||
|
],
|
||||||
|
];
|
||||||
Loading…
Reference in New Issue