PageRenderTime 63ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/branches/v1.7.2/Classes/PHPExcel/Calculation/Functions.php

#
PHP | 11480 lines | 6870 code | 1305 blank | 3305 comment | 2002 complexity | 02619cf6f0e9b2a50f9d61189a94a5ae MD5 | raw file
Possible License(s): AGPL-1.0, LGPL-2.0, LGPL-2.1, GPL-3.0, LGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. * PHPExcel
  4. *
  5. * Copyright (c) 2006 - 2010 PHPExcel
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. *
  21. * @category PHPExcel
  22. * @package PHPExcel_Calculation
  23. * @copyright Copyright (c) 2006 - 2010 PHPExcel (http://www.codeplex.com/PHPExcel)
  24. * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  25. * @version ##VERSION##, ##DATE##
  26. */
  27. /** EPS */
  28. define('EPS', 2.22e-16);
  29. /** MAX_VALUE */
  30. define('MAX_VALUE', 1.2e308);
  31. /** LOG_GAMMA_X_MAX_VALUE */
  32. define('LOG_GAMMA_X_MAX_VALUE', 2.55e305);
  33. /** SQRT2PI */
  34. define('SQRT2PI', 2.5066282746310005024157652848110452530069867406099);
  35. /** 2 / PI */
  36. define('M_2DIVPI', 0.63661977236758134307553505349006);
  37. /** XMININ */
  38. define('XMININ', 2.23e-308);
  39. /** MAX_ITERATIONS */
  40. define('MAX_ITERATIONS', 256);
  41. /** FINANCIAL_MAX_ITERATIONS */
  42. define('FINANCIAL_MAX_ITERATIONS', 128);
  43. /** PRECISION */
  44. define('PRECISION', 8.88E-016);
  45. /** FINANCIAL_PRECISION */
  46. define('FINANCIAL_PRECISION', 1.0e-08);
  47. /** EULER */
  48. define('EULER', 2.71828182845904523536);
  49. $savedPrecision = ini_get('precision');
  50. if ($savedPrecision < 16) {
  51. ini_set('precision',16);
  52. }
  53. /** PHPExcel root directory */
  54. if (!defined('PHPEXCEL_ROOT')) {
  55. /**
  56. * @ignore
  57. */
  58. define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');
  59. }
  60. /** PHPExcel_Cell */
  61. require_once PHPEXCEL_ROOT . 'PHPExcel/Cell.php';
  62. /** PHPExcel_Calculation */
  63. require_once PHPEXCEL_ROOT . 'PHPExcel/Calculation.php';
  64. /** PHPExcel_Cell_DataType */
  65. require_once PHPEXCEL_ROOT . 'PHPExcel/Cell/DataType.php';
  66. /** PHPExcel_Style_NumberFormat */
  67. require_once PHPEXCEL_ROOT . 'PHPExcel/Style/NumberFormat.php';
  68. /** PHPExcel_Shared_Date */
  69. require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/Date.php';
  70. /** Matrix */
  71. require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/JAMA/Matrix.php';
  72. require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/trendClass.php';
  73. /**
  74. * PHPExcel_Calculation_Functions
  75. *
  76. * @category PHPExcel
  77. * @package PHPExcel_Calculation
  78. * @copyright Copyright (c) 2006 - 2010 PHPExcel (http://www.codeplex.com/PHPExcel)
  79. */
  80. class PHPExcel_Calculation_Functions {
  81. /** constants */
  82. const COMPATIBILITY_EXCEL = 'Excel';
  83. const COMPATIBILITY_GNUMERIC = 'Gnumeric';
  84. const COMPATIBILITY_OPENOFFICE = 'OpenOfficeCalc';
  85. const RETURNDATE_PHP_NUMERIC = 'P';
  86. const RETURNDATE_PHP_OBJECT = 'O';
  87. const RETURNDATE_EXCEL = 'E';
  88. /**
  89. * Compatibility mode to use for error checking and responses
  90. *
  91. * @access private
  92. * @var string
  93. */
  94. private static $compatibilityMode = self::COMPATIBILITY_EXCEL;
  95. /**
  96. * Data Type to use when returning date values
  97. *
  98. * @access private
  99. * @var integer
  100. */
  101. private static $ReturnDateType = self::RETURNDATE_EXCEL;
  102. /**
  103. * List of error codes
  104. *
  105. * @access private
  106. * @var array
  107. */
  108. private static $_errorCodes = array( 'null' => '#NULL!',
  109. 'divisionbyzero' => '#DIV/0!',
  110. 'value' => '#VALUE!',
  111. 'reference' => '#REF!',
  112. 'name' => '#NAME?',
  113. 'num' => '#NUM!',
  114. 'na' => '#N/A',
  115. 'gettingdata' => '#GETTING_DATA'
  116. );
  117. /**
  118. * Set the Compatibility Mode
  119. *
  120. * @access public
  121. * @category Function Configuration
  122. * @param string $compatibilityMode Compatibility Mode
  123. * Permitted values are:
  124. * PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL 'Excel'
  125. * PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC 'Gnumeric'
  126. * PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE 'OpenOfficeCalc'
  127. * @return boolean (Success or Failure)
  128. */
  129. public static function setCompatibilityMode($compatibilityMode) {
  130. if (($compatibilityMode == self::COMPATIBILITY_EXCEL) ||
  131. ($compatibilityMode == self::COMPATIBILITY_GNUMERIC) ||
  132. ($compatibilityMode == self::COMPATIBILITY_OPENOFFICE)) {
  133. self::$compatibilityMode = $compatibilityMode;
  134. return True;
  135. }
  136. return False;
  137. } // function setCompatibilityMode()
  138. /**
  139. * Return the current Compatibility Mode
  140. *
  141. * @access public
  142. * @category Function Configuration
  143. * @return string Compatibility Mode
  144. * Possible Return values are:
  145. * PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL 'Excel'
  146. * PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC 'Gnumeric'
  147. * PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE 'OpenOfficeCalc'
  148. */
  149. public static function getCompatibilityMode() {
  150. return self::$compatibilityMode;
  151. } // function getCompatibilityMode()
  152. /**
  153. * Set the Return Date Format used by functions that return a date/time (Excel, PHP Serialized Numeric or PHP Object)
  154. *
  155. * @access public
  156. * @category Function Configuration
  157. * @param string $returnDateType Return Date Format
  158. * Permitted values are:
  159. * PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC 'P'
  160. * PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT 'O'
  161. * PHPExcel_Calculation_Functions::RETURNDATE_EXCEL 'E'
  162. * @return boolean Success or failure
  163. */
  164. public static function setReturnDateType($returnDateType) {
  165. if (($returnDateType == self::RETURNDATE_PHP_NUMERIC) ||
  166. ($returnDateType == self::RETURNDATE_PHP_OBJECT) ||
  167. ($returnDateType == self::RETURNDATE_EXCEL)) {
  168. self::$ReturnDateType = $returnDateType;
  169. return True;
  170. }
  171. return False;
  172. } // function setReturnDateType()
  173. /**
  174. * Return the current Return Date Format for functions that return a date/time (Excel, PHP Serialized Numeric or PHP Object)
  175. *
  176. * @access public
  177. * @category Function Configuration
  178. * @return string Return Date Format
  179. * Possible Return values are:
  180. * PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC 'P'
  181. * PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT 'O'
  182. * PHPExcel_Calculation_Functions::RETURNDATE_EXCEL 'E'
  183. */
  184. public static function getReturnDateType() {
  185. return self::$ReturnDateType;
  186. } // function getReturnDateType()
  187. /**
  188. * DUMMY
  189. *
  190. * @access public
  191. * @category Error Returns
  192. * @return string #Not Yet Implemented
  193. */
  194. public static function DUMMY() {
  195. return '#Not Yet Implemented';
  196. } // function DUMMY()
  197. /**
  198. * NA
  199. *
  200. * @access public
  201. * @category Error Returns
  202. * @return string #N/A!
  203. */
  204. public static function NA() {
  205. return self::$_errorCodes['na'];
  206. } // function NA()
  207. /**
  208. * NAN
  209. *
  210. * @access public
  211. * @category Error Returns
  212. * @return string #NUM!
  213. */
  214. public static function NaN() {
  215. return self::$_errorCodes['num'];
  216. } // function NAN()
  217. /**
  218. * NAME
  219. *
  220. * @access public
  221. * @category Error Returns
  222. * @return string #NAME!
  223. */
  224. public static function NAME() {
  225. return self::$_errorCodes['name'];
  226. } // function NAME()
  227. /**
  228. * REF
  229. *
  230. * @access public
  231. * @category Error Returns
  232. * @return string #REF!
  233. */
  234. public static function REF() {
  235. return self::$_errorCodes['reference'];
  236. } // function REF()
  237. /**
  238. * VALUE
  239. *
  240. * @access public
  241. * @category Error Returns
  242. * @return string #VALUE!
  243. */
  244. public static function VALUE() {
  245. return self::$_errorCodes['value'];
  246. } // function VALUE()
  247. private static function isMatrixValue($idx) {
  248. return ((substr_count($idx,'.') <= 1) || (preg_match('/\.[A-Z]/',$idx) > 0));
  249. }
  250. private static function isValue($idx) {
  251. return (substr_count($idx,'.') == 0);
  252. }
  253. private static function isCellValue($idx) {
  254. return (substr_count($idx,'.') > 1);
  255. }
  256. /**
  257. * LOGICAL_AND
  258. *
  259. * Returns boolean TRUE if all its arguments are TRUE; returns FALSE if one or more argument is FALSE.
  260. *
  261. * Excel Function:
  262. * =AND(logical1[,logical2[, ...]])
  263. *
  264. * The arguments must evaluate to logical values such as TRUE or FALSE, or the arguments must be arrays
  265. * or references that contain logical values.
  266. *
  267. * Boolean arguments are treated as True or False as appropriate
  268. * Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False
  269. * If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string holds
  270. * the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value
  271. *
  272. * @access public
  273. * @category Logical Functions
  274. * @param mixed $arg,... Data values
  275. * @return boolean The logical AND of the arguments.
  276. */
  277. public static function LOGICAL_AND() {
  278. // Return value
  279. $returnValue = True;
  280. // Loop through the arguments
  281. $aArgs = self::flattenArray(func_get_args());
  282. $argCount = 0;
  283. foreach ($aArgs as $arg) {
  284. // Is it a boolean value?
  285. if (is_bool($arg)) {
  286. $returnValue = $returnValue && $arg;
  287. } elseif ((is_numeric($arg)) && (!is_string($arg))) {
  288. $returnValue = $returnValue && ($arg != 0);
  289. } elseif (is_string($arg)) {
  290. $arg = strtoupper($arg);
  291. if ($arg == 'TRUE') {
  292. $arg = 1;
  293. } elseif ($arg == 'FALSE') {
  294. $arg = 0;
  295. } else {
  296. return self::$_errorCodes['value'];
  297. }
  298. $returnValue = $returnValue && ($arg != 0);
  299. }
  300. ++$argCount;
  301. }
  302. // Return
  303. if ($argCount == 0) {
  304. return self::$_errorCodes['value'];
  305. }
  306. return $returnValue;
  307. } // function LOGICAL_AND()
  308. /**
  309. * LOGICAL_OR
  310. *
  311. * Returns boolean TRUE if any argument is TRUE; returns FALSE if all arguments are FALSE.
  312. *
  313. * Excel Function:
  314. * =OR(logical1[,logical2[, ...]])
  315. *
  316. * The arguments must evaluate to logical values such as TRUE or FALSE, or the arguments must be arrays
  317. * or references that contain logical values.
  318. *
  319. * Boolean arguments are treated as True or False as appropriate
  320. * Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False
  321. * If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string holds
  322. * the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value
  323. *
  324. * @access public
  325. * @category Logical Functions
  326. * @param mixed $arg,... Data values
  327. * @return boolean The logical OR of the arguments.
  328. */
  329. public static function LOGICAL_OR() {
  330. // Return value
  331. $returnValue = False;
  332. // Loop through the arguments
  333. $aArgs = self::flattenArray(func_get_args());
  334. $argCount = 0;
  335. foreach ($aArgs as $arg) {
  336. // Is it a boolean value?
  337. if (is_bool($arg)) {
  338. $returnValue = $returnValue || $arg;
  339. } elseif ((is_numeric($arg)) && (!is_string($arg))) {
  340. $returnValue = $returnValue || ($arg != 0);
  341. } elseif (is_string($arg)) {
  342. $arg = strtoupper($arg);
  343. if ($arg == 'TRUE') {
  344. $arg = 1;
  345. } elseif ($arg == 'FALSE') {
  346. $arg = 0;
  347. } else {
  348. return self::$_errorCodes['value'];
  349. }
  350. $returnValue = $returnValue || ($arg != 0);
  351. }
  352. ++$argCount;
  353. }
  354. // Return
  355. if ($argCount == 0) {
  356. return self::$_errorCodes['value'];
  357. }
  358. return $returnValue;
  359. } // function LOGICAL_OR()
  360. /**
  361. * LOGICAL_FALSE
  362. *
  363. * Returns the boolean FALSE.
  364. *
  365. * Excel Function:
  366. * =FALSE()
  367. *
  368. * @access public
  369. * @category Logical Functions
  370. * @return boolean False
  371. */
  372. public static function LOGICAL_FALSE() {
  373. return False;
  374. } // function LOGICAL_FALSE()
  375. /**
  376. * LOGICAL_TRUE
  377. *
  378. * Returns the boolean TRUE.
  379. *
  380. * Excel Function:
  381. * =TRUE()
  382. *
  383. * @access public
  384. * @category Logical Functions
  385. * @return boolean True
  386. */
  387. public static function LOGICAL_TRUE() {
  388. return True;
  389. } // function LOGICAL_TRUE()
  390. /**
  391. * LOGICAL_NOT
  392. *
  393. * Returns the boolean inverse of the argument.
  394. *
  395. * Excel Function:
  396. * =NOT(logical)
  397. *
  398. * The argument must evaluate to a logical value such as TRUE or FALSE
  399. *
  400. * Boolean arguments are treated as True or False as appropriate
  401. * Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False
  402. * If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string holds
  403. * the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value
  404. *
  405. * @access public
  406. * @category Logical Functions
  407. * @param mixed $logical A value or expression that can be evaluated to TRUE or FALSE
  408. * @return boolean The boolean inverse of the argument.
  409. */
  410. public static function LOGICAL_NOT($logical) {
  411. $logical = self::flattenSingleValue($logical);
  412. if (is_string($logical)) {
  413. $logical = strtoupper($logical);
  414. if ($logical == 'TRUE') {
  415. return False;
  416. } elseif ($logical == 'FALSE') {
  417. return True;
  418. } else {
  419. return self::$_errorCodes['value'];
  420. }
  421. }
  422. return !$logical;
  423. } // function LOGICAL_NOT()
  424. /**
  425. * STATEMENT_IF
  426. *
  427. * Returns one value if a condition you specify evaluates to TRUE and another value if it evaluates to FALSE.
  428. *
  429. * Excel Function:
  430. * =IF(condition[,returnIfTrue[,returnIfFalse]])
  431. *
  432. * Condition is any value or expression that can be evaluated to TRUE or FALSE.
  433. * For example, A10=100 is a logical expression; if the value in cell A10 is equal to 100,
  434. * the expression evaluates to TRUE. Otherwise, the expression evaluates to FALSE.
  435. * This argument can use any comparison calculation operator.
  436. * ReturnIfTrue is the value that is returned if condition evaluates to TRUE.
  437. * For example, if this argument is the text string "Within budget" and the condition argument evaluates to TRUE,
  438. * then the IF function returns the text "Within budget"
  439. * If condition is TRUE and ReturnIfTrue is blank, this argument returns 0 (zero). To display the word TRUE, use
  440. * the logical value TRUE for this argument.
  441. * ReturnIfTrue can be another formula.
  442. * ReturnIfFalse is the value that is returned if condition evaluates to FALSE.
  443. * For example, if this argument is the text string "Over budget" and the condition argument evaluates to FALSE,
  444. * then the IF function returns the text "Over budget".
  445. * If condition is FALSE and ReturnIfFalse is omitted, then the logical value FALSE is returned.
  446. * If condition is FALSE and ReturnIfFalse is blank, then the value 0 (zero) is returned.
  447. * ReturnIfFalse can be another formula.
  448. *
  449. * @access public
  450. * @category Logical Functions
  451. * @param mixed $condition Condition to evaluate
  452. * @param mixed $returnIfTrue Value to return when condition is true
  453. * @param mixed $returnIfFalse Optional value to return when condition is false
  454. * @return mixed The value of returnIfTrue or returnIfFalse determined by condition
  455. */
  456. public static function STATEMENT_IF($condition = true, $returnIfTrue = 0, $returnIfFalse = False) {
  457. $condition = (is_null($condition)) ? True : (boolean) self::flattenSingleValue($condition);
  458. $returnIfTrue = (is_null($returnIfTrue)) ? 0 : self::flattenSingleValue($returnIfTrue);
  459. $returnIfFalse = (is_null($returnIfFalse)) ? False : self::flattenSingleValue($returnIfFalse);
  460. return ($condition ? $returnIfTrue : $returnIfFalse);
  461. } // function STATEMENT_IF()
  462. /**
  463. * STATEMENT_IFERROR
  464. *
  465. * Excel Function:
  466. * =IFERROR(testValue,errorpart)
  467. *
  468. * @access public
  469. * @category Logical Functions
  470. * @param mixed $testValue Value to check, is also the value returned when no error
  471. * @param mixed $errorpart Value to return when testValue is an error condition
  472. * @return mixed The value of errorpart or testValue determined by error condition
  473. */
  474. public static function STATEMENT_IFERROR($testValue = '', $errorpart = '') {
  475. $testValue = (is_null($testValue)) ? '' : self::flattenSingleValue($testValue);
  476. $errorpart = (is_null($errorpart)) ? '' : self::flattenSingleValue($errorpart);
  477. return self::STATEMENT_IF(self::IS_ERROR($testValue), $errorpart, $testValue);
  478. } // function STATEMENT_IFERROR()
  479. /**
  480. * ATAN2
  481. *
  482. * This function calculates the arc tangent of the two variables x and y. It is similar to
  483. * calculating the arc tangent of y ÷ x, except that the signs of both arguments are used
  484. * to determine the quadrant of the result.
  485. * The arctangent is the angle from the x-axis to a line containing the origin (0, 0) and a
  486. * point with coordinates (xCoordinate, yCoordinate). The angle is given in radians between
  487. * -pi and pi, excluding -pi.
  488. *
  489. * Note that the Excel ATAN2() function accepts its arguments in the reverse order to the standard
  490. * PHP atan2() function, so we need to reverse them here before calling the PHP atan() function.
  491. *
  492. * Excel Function:
  493. * ATAN2(xCoordinate,yCoordinate)
  494. *
  495. * @access public
  496. * @category Mathematical and Trigonometric Functions
  497. * @param float $xCoordinate The x-coordinate of the point.
  498. * @param float $yCoordinate The y-coordinate of the point.
  499. * @return float The inverse tangent of the specified x- and y-coordinates.
  500. */
  501. public static function REVERSE_ATAN2($xCoordinate, $yCoordinate) {
  502. $xCoordinate = (float) self::flattenSingleValue($xCoordinate);
  503. $yCoordinate = (float) self::flattenSingleValue($yCoordinate);
  504. if (($xCoordinate == 0) && ($yCoordinate == 0)) {
  505. return self::$_errorCodes['divisionbyzero'];
  506. }
  507. return atan2($yCoordinate, $xCoordinate);
  508. } // function REVERSE_ATAN2()
  509. /**
  510. * LOG_BASE
  511. *
  512. * Returns the logarithm of a number to a specified base. The default base is 10.
  513. *
  514. * Excel Function:
  515. * LOG(number[,base])
  516. *
  517. * @access public
  518. * @category Mathematical and Trigonometric Functions
  519. * @param float $value The positive real number for which you want the logarithm
  520. * @param float $base The base of the logarithm. If base is omitted, it is assumed to be 10.
  521. * @return float
  522. */
  523. public static function LOG_BASE($number, $base=10) {
  524. $number = self::flattenSingleValue($number);
  525. $base = (is_null($base)) ? 10 : (float) self::flattenSingleValue($base);
  526. return log($number, $base);
  527. } // function LOG_BASE()
  528. /**
  529. * SUM
  530. *
  531. * SUM computes the sum of all the values and cells referenced in the argument list.
  532. *
  533. * Excel Function:
  534. * SUM(value1[,value2[, ...]])
  535. *
  536. * @access public
  537. * @category Mathematical and Trigonometric Functions
  538. * @param mixed $arg,... Data values
  539. * @return float
  540. */
  541. public static function SUM() {
  542. // Return value
  543. $returnValue = 0;
  544. // Loop through the arguments
  545. $aArgs = self::flattenArray(func_get_args());
  546. foreach ($aArgs as $arg) {
  547. // Is it a numeric value?
  548. if ((is_numeric($arg)) && (!is_string($arg))) {
  549. $returnValue += $arg;
  550. }
  551. }
  552. // Return
  553. return $returnValue;
  554. } // function SUM()
  555. /**
  556. * SUMSQ
  557. *
  558. * SUMSQ returns the sum of the squares of the arguments
  559. *
  560. * Excel Function:
  561. * SUMSQ(value1[,value2[, ...]])
  562. *
  563. * @access public
  564. * @category Mathematical and Trigonometric Functions
  565. * @param mixed $arg,... Data values
  566. * @return float
  567. */
  568. public static function SUMSQ() {
  569. // Return value
  570. $returnValue = 0;
  571. // Loop through arguments
  572. $aArgs = self::flattenArray(func_get_args());
  573. foreach ($aArgs as $arg) {
  574. // Is it a numeric value?
  575. if ((is_numeric($arg)) && (!is_string($arg))) {
  576. $returnValue += ($arg * $arg);
  577. }
  578. }
  579. // Return
  580. return $returnValue;
  581. } // function SUMSQ()
  582. /**
  583. * PRODUCT
  584. *
  585. * PRODUCT returns the product of all the values and cells referenced in the argument list.
  586. *
  587. * Excel Function:
  588. * PRODUCT(value1[,value2[, ...]])
  589. *
  590. * @access public
  591. * @category Mathematical and Trigonometric Functions
  592. * @param mixed $arg,... Data values
  593. * @return float
  594. */
  595. public static function PRODUCT() {
  596. // Return value
  597. $returnValue = null;
  598. // Loop through arguments
  599. $aArgs = self::flattenArray(func_get_args());
  600. foreach ($aArgs as $arg) {
  601. // Is it a numeric value?
  602. if ((is_numeric($arg)) && (!is_string($arg))) {
  603. if (is_null($returnValue)) {
  604. $returnValue = $arg;
  605. } else {
  606. $returnValue *= $arg;
  607. }
  608. }
  609. }
  610. // Return
  611. if (is_null($returnValue)) {
  612. return 0;
  613. }
  614. return $returnValue;
  615. } // function PRODUCT()
  616. /**
  617. * QUOTIENT
  618. *
  619. * QUOTIENT function returns the integer portion of a division. Numerator is the divided number
  620. * and denominator is the divisor.
  621. *
  622. * Excel Function:
  623. * QUOTIENT(value1[,value2[, ...]])
  624. *
  625. * @access public
  626. * @category Mathematical and Trigonometric Functions
  627. * @param mixed $arg,... Data values
  628. * @return float
  629. */
  630. public static function QUOTIENT() {
  631. // Return value
  632. $returnValue = null;
  633. // Loop through arguments
  634. $aArgs = self::flattenArray(func_get_args());
  635. foreach ($aArgs as $arg) {
  636. // Is it a numeric value?
  637. if ((is_numeric($arg)) && (!is_string($arg))) {
  638. if (is_null($returnValue)) {
  639. $returnValue = ($arg == 0) ? 0 : $arg;
  640. } else {
  641. if (($returnValue == 0) || ($arg == 0)) {
  642. $returnValue = 0;
  643. } else {
  644. $returnValue /= $arg;
  645. }
  646. }
  647. }
  648. }
  649. // Return
  650. return intval($returnValue);
  651. } // function QUOTIENT()
  652. /**
  653. * MIN
  654. *
  655. * MIN returns the value of the element of the values passed that has the smallest value,
  656. * with negative numbers considered smaller than positive numbers.
  657. *
  658. * Excel Function:
  659. * MIN(value1[,value2[, ...]])
  660. *
  661. * @access public
  662. * @category Statistical Functions
  663. * @param mixed $arg,... Data values
  664. * @return float
  665. */
  666. public static function MIN() {
  667. // Return value
  668. $returnValue = null;
  669. // Loop through arguments
  670. $aArgs = self::flattenArray(func_get_args());
  671. foreach ($aArgs as $arg) {
  672. // Is it a numeric value?
  673. if ((is_numeric($arg)) && (!is_string($arg))) {
  674. if ((is_null($returnValue)) || ($arg < $returnValue)) {
  675. $returnValue = $arg;
  676. }
  677. }
  678. }
  679. // Return
  680. if(is_null($returnValue)) {
  681. return 0;
  682. }
  683. return $returnValue;
  684. } // function MIN()
  685. /**
  686. * MINA
  687. *
  688. * Returns the smallest value in a list of arguments, including numbers, text, and logical values
  689. *
  690. * Excel Function:
  691. * MINA(value1[,value2[, ...]])
  692. *
  693. * @access public
  694. * @category Statistical Functions
  695. * @param mixed $arg,... Data values
  696. * @return float
  697. */
  698. public static function MINA() {
  699. // Return value
  700. $returnValue = null;
  701. // Loop through arguments
  702. $aArgs = self::flattenArray(func_get_args());
  703. foreach ($aArgs as $arg) {
  704. // Is it a numeric value?
  705. if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
  706. if (is_bool($arg)) {
  707. $arg = (integer) $arg;
  708. } elseif (is_string($arg)) {
  709. $arg = 0;
  710. }
  711. if ((is_null($returnValue)) || ($arg < $returnValue)) {
  712. $returnValue = $arg;
  713. }
  714. }
  715. }
  716. // Return
  717. if(is_null($returnValue)) {
  718. return 0;
  719. }
  720. return $returnValue;
  721. } // function MINA()
  722. /**
  723. * SMALL
  724. *
  725. * Returns the nth smallest value in a data set. You can use this function to
  726. * select a value based on its relative standing.
  727. *
  728. * Excel Function:
  729. * SMALL(value1[,value2[, ...]],entry)
  730. *
  731. * @access public
  732. * @category Statistical Functions
  733. * @param mixed $arg,... Data values
  734. * @param int $entry Position (ordered from the smallest) in the array or range of data to return
  735. * @return float
  736. */
  737. public static function SMALL() {
  738. $aArgs = self::flattenArray(func_get_args());
  739. // Calculate
  740. $entry = array_pop($aArgs);
  741. if ((is_numeric($entry)) && (!is_string($entry))) {
  742. $mArgs = array();
  743. foreach ($aArgs as $arg) {
  744. // Is it a numeric value?
  745. if ((is_numeric($arg)) && (!is_string($arg))) {
  746. $mArgs[] = $arg;
  747. }
  748. }
  749. $count = self::COUNT($mArgs);
  750. $entry = floor(--$entry);
  751. if (($entry < 0) || ($entry >= $count) || ($count == 0)) {
  752. return self::$_errorCodes['num'];
  753. }
  754. sort($mArgs);
  755. return $mArgs[$entry];
  756. }
  757. return self::$_errorCodes['value'];
  758. } // function SMALL()
  759. /**
  760. * MAX
  761. *
  762. * MAX returns the value of the element of the values passed that has the highest value,
  763. * with negative numbers considered smaller than positive numbers.
  764. *
  765. * Excel Function:
  766. * MAX(value1[,value2[, ...]])
  767. *
  768. * @access public
  769. * @category Statistical Functions
  770. * @param mixed $arg,... Data values
  771. * @return float
  772. */
  773. public static function MAX() {
  774. // Return value
  775. $returnValue = null;
  776. // Loop through arguments
  777. $aArgs = self::flattenArray(func_get_args());
  778. foreach ($aArgs as $arg) {
  779. // Is it a numeric value?
  780. if ((is_numeric($arg)) && (!is_string($arg))) {
  781. if ((is_null($returnValue)) || ($arg > $returnValue)) {
  782. $returnValue = $arg;
  783. }
  784. }
  785. }
  786. // Return
  787. if(is_null($returnValue)) {
  788. return 0;
  789. }
  790. return $returnValue;
  791. } // function MAX()
  792. /**
  793. * MAXA
  794. *
  795. * Returns the greatest value in a list of arguments, including numbers, text, and logical values
  796. *
  797. * Excel Function:
  798. * MAXA(value1[,value2[, ...]])
  799. *
  800. * @access public
  801. * @category Statistical Functions
  802. * @param mixed $arg,... Data values
  803. * @return float
  804. */
  805. public static function MAXA() {
  806. // Return value
  807. $returnValue = null;
  808. // Loop through arguments
  809. $aArgs = self::flattenArray(func_get_args());
  810. foreach ($aArgs as $arg) {
  811. // Is it a numeric value?
  812. if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
  813. if (is_bool($arg)) {
  814. $arg = (integer) $arg;
  815. } elseif (is_string($arg)) {
  816. $arg = 0;
  817. }
  818. if ((is_null($returnValue)) || ($arg > $returnValue)) {
  819. $returnValue = $arg;
  820. }
  821. }
  822. }
  823. // Return
  824. if(is_null($returnValue)) {
  825. return 0;
  826. }
  827. return $returnValue;
  828. } // function MAXA()
  829. /**
  830. * LARGE
  831. *
  832. * Returns the nth largest value in a data set. You can use this function to
  833. * select a value based on its relative standing.
  834. *
  835. * Excel Function:
  836. * LARGE(value1[,value2[, ...]],entry)
  837. *
  838. * @access public
  839. * @category Statistical Functions
  840. * @param mixed $arg,... Data values
  841. * @param int $entry Position (ordered from the largest) in the array or range of data to return
  842. * @return float
  843. *
  844. */
  845. public static function LARGE() {
  846. $aArgs = self::flattenArray(func_get_args());
  847. // Calculate
  848. $entry = floor(array_pop($aArgs));
  849. if ((is_numeric($entry)) && (!is_string($entry))) {
  850. $mArgs = array();
  851. foreach ($aArgs as $arg) {
  852. // Is it a numeric value?
  853. if ((is_numeric($arg)) && (!is_string($arg))) {
  854. $mArgs[] = $arg;
  855. }
  856. }
  857. $count = self::COUNT($mArgs);
  858. $entry = floor(--$entry);
  859. if (($entry < 0) || ($entry >= $count) || ($count == 0)) {
  860. return self::$_errorCodes['num'];
  861. }
  862. rsort($mArgs);
  863. return $mArgs[$entry];
  864. }
  865. return self::$_errorCodes['value'];
  866. } // function LARGE()
  867. /**
  868. * PERCENTILE
  869. *
  870. * Returns the nth percentile of values in a range..
  871. *
  872. * Excel Function:
  873. * PERCENTILE(value1[,value2[, ...]],entry)
  874. *
  875. * @access public
  876. * @category Statistical Functions
  877. * @param mixed $arg,... Data values
  878. * @param float $entry Percentile value in the range 0..1, inclusive.
  879. * @return float
  880. */
  881. public static function PERCENTILE() {
  882. $aArgs = self::flattenArray(func_get_args());
  883. // Calculate
  884. $entry = array_pop($aArgs);
  885. if ((is_numeric($entry)) && (!is_string($entry))) {
  886. if (($entry < 0) || ($entry > 1)) {
  887. return self::$_errorCodes['num'];
  888. }
  889. $mArgs = array();
  890. foreach ($aArgs as $arg) {
  891. // Is it a numeric value?
  892. if ((is_numeric($arg)) && (!is_string($arg))) {
  893. $mArgs[] = $arg;
  894. }
  895. }
  896. $mValueCount = count($mArgs);
  897. if ($mValueCount > 0) {
  898. sort($mArgs);
  899. $count = self::COUNT($mArgs);
  900. $index = $entry * ($count-1);
  901. $iBase = floor($index);
  902. if ($index == $iBase) {
  903. return $mArgs[$index];
  904. } else {
  905. $iNext = $iBase + 1;
  906. $iProportion = $index - $iBase;
  907. return $mArgs[$iBase] + (($mArgs[$iNext] - $mArgs[$iBase]) * $iProportion) ;
  908. }
  909. }
  910. }
  911. return self::$_errorCodes['value'];
  912. } // function PERCENTILE()
  913. /**
  914. * QUARTILE
  915. *
  916. * Returns the quartile of a data set.
  917. *
  918. * Excel Function:
  919. * QUARTILE(value1[,value2[, ...]],entry)
  920. *
  921. * @access public
  922. * @category Statistical Functions
  923. * @param mixed $arg,... Data values
  924. * @param int $entry Quartile value in the range 1..3, inclusive.
  925. * @return float
  926. */
  927. public static function QUARTILE() {
  928. $aArgs = self::flattenArray(func_get_args());
  929. // Calculate
  930. $entry = floor(array_pop($aArgs));
  931. if ((is_numeric($entry)) && (!is_string($entry))) {
  932. $entry /= 4;
  933. if (($entry < 0) || ($entry > 1)) {
  934. return self::$_errorCodes['num'];
  935. }
  936. return self::PERCENTILE($aArgs,$entry);
  937. }
  938. return self::$_errorCodes['value'];
  939. } // function QUARTILE()
  940. /**
  941. * COUNT
  942. *
  943. * Counts the number of cells that contain numbers within the list of arguments
  944. *
  945. * Excel Function:
  946. * COUNT(value1[,value2[, ...]])
  947. *
  948. * @access public
  949. * @category Statistical Functions
  950. * @param mixed $arg,... Data values
  951. * @return int
  952. */
  953. public static function COUNT() {
  954. // Return value
  955. $returnValue = 0;
  956. // Loop through arguments
  957. $aArgs = self::flattenArrayIndexed(func_get_args());
  958. foreach ($aArgs as $k => $arg) {
  959. if ((is_bool($arg)) &&
  960. ((!self::isCellValue($k)) || (self::$compatibilityMode == self::COMPATIBILITY_OPENOFFICE))) {
  961. $arg = (integer) $arg;
  962. }
  963. // Is it a numeric value?
  964. if ((is_numeric($arg)) && (!is_string($arg))) {
  965. ++$returnValue;
  966. }
  967. }
  968. // Return
  969. return $returnValue;
  970. } // function COUNT()
  971. /**
  972. * COUNTBLANK
  973. *
  974. * Counts the number of empty cells within the list of arguments
  975. *
  976. * Excel Function:
  977. * COUNTBLANK(value1[,value2[, ...]])
  978. *
  979. * @access public
  980. * @category Statistical Functions
  981. * @param mixed $arg,... Data values
  982. * @return int
  983. */
  984. public static function COUNTBLANK() {
  985. // Return value
  986. $returnValue = 0;
  987. // Loop through arguments
  988. $aArgs = self::flattenArray(func_get_args());
  989. foreach ($aArgs as $arg) {
  990. // Is it a blank cell?
  991. if ((is_null($arg)) || ((is_string($arg)) && ($arg == ''))) {
  992. ++$returnValue;
  993. }
  994. }
  995. // Return
  996. return $returnValue;
  997. } // function COUNTBLANK()
  998. /**
  999. * COUNTA
  1000. *
  1001. * Counts the number of cells that are not empty within the list of arguments
  1002. *
  1003. * Excel Function:
  1004. * COUNTA(value1[,value2[, ...]])
  1005. *
  1006. * @access public
  1007. * @category Statistical Functions
  1008. * @param mixed $arg,... Data values
  1009. * @return int
  1010. */
  1011. public static function COUNTA() {
  1012. // Return value
  1013. $returnValue = 0;
  1014. // Loop through arguments
  1015. $aArgs = self::flattenArray(func_get_args());
  1016. foreach ($aArgs as $arg) {
  1017. // Is it a numeric, boolean or string value?
  1018. if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
  1019. ++$returnValue;
  1020. }
  1021. }
  1022. // Return
  1023. return $returnValue;
  1024. } // function COUNTA()
  1025. /**
  1026. * COUNTIF
  1027. *
  1028. * Counts the number of cells that contain numbers within the list of arguments
  1029. *
  1030. * Excel Function:
  1031. * COUNTIF(value1[,value2[, ...]],condition)
  1032. *
  1033. * @access public
  1034. * @category Statistical Functions
  1035. * @param mixed $arg,... Data values
  1036. * @param string $condition The criteria that defines which cells will be counted.
  1037. * @return int
  1038. */
  1039. public static function COUNTIF($aArgs,$condition) {
  1040. // Return value
  1041. $returnValue = 0;
  1042. $aArgs = self::flattenArray($aArgs);
  1043. $condition = self::flattenSingleValue($condition);
  1044. if (!in_array($condition{0},array('>', '<', '='))) {
  1045. if (!is_numeric($condition)) { $condition = PHPExcel_Calculation::_wrapResult(strtoupper($condition)); }
  1046. $condition = '='.$condition;
  1047. } else {
  1048. preg_match('/([<>=]+)(.*)/',$condition,$matches);
  1049. list(,$operator,$operand) = $matches;
  1050. if (!is_numeric($operand)) { $operand = PHPExcel_Calculation::_wrapResult(strtoupper($operand)); }
  1051. $condition = $operator.$operand;
  1052. }
  1053. // Loop through arguments
  1054. foreach ($aArgs as $arg) {
  1055. if (!is_numeric($arg)) { $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); }
  1056. $testCondition = '='.$arg.$condition;
  1057. if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) {
  1058. // Is it a value within our criteria
  1059. ++$returnValue;
  1060. }
  1061. }
  1062. // Return
  1063. return $returnValue;
  1064. } // function COUNTIF()
  1065. /**
  1066. * SUMIF
  1067. *
  1068. * Counts the number of cells that contain numbers within the list of arguments
  1069. *
  1070. * Excel Function:
  1071. * SUMIF(value1[,value2[, ...]],condition)
  1072. *
  1073. * @access public
  1074. * @category Mathematical and Trigonometric Functions
  1075. * @param mixed $arg,... Data values
  1076. * @param string $condition The criteria that defines which cells will be summed.
  1077. * @return float
  1078. */
  1079. public static function SUMIF($aArgs,$condition,$sumArgs = array()) {
  1080. // Return value
  1081. $returnValue = 0;
  1082. $aArgs = self::flattenArray($aArgs);
  1083. $sumArgs = self::flattenArray($sumArgs);
  1084. if (count($sumArgs) == 0) {
  1085. $sumArgs = $aArgs;
  1086. }
  1087. if (!in_array($condition{0},array('>', '<', '='))) {
  1088. if (!is_numeric($condition)) { $condition = PHPExcel_Calculation::_wrapResult(strtoupper($condition)); }
  1089. $condition = '='.$condition;
  1090. } else {
  1091. preg_match('/([<>=]+)(.*)/',$condition,$matches);
  1092. list(,$operator,$operand) = $matches;
  1093. if (!is_numeric($operand)) { $operand = PHPExcel_Calculation::_wrapResult(strtoupper($operand)); }
  1094. $condition = $operator.$operand;
  1095. }
  1096. // Loop through arguments
  1097. foreach ($aArgs as $key => $arg) {
  1098. if (!is_numeric($arg)) { $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); }
  1099. $testCondition = '='.$arg.$condition;
  1100. if (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) {
  1101. // Is it a value within our criteria
  1102. $returnValue += $sumArgs[$key];
  1103. }
  1104. }
  1105. // Return
  1106. return $returnValue;
  1107. } // function SUMIF()
  1108. /**
  1109. * AVERAGE
  1110. *
  1111. * Returns the average (arithmetic mean) of the arguments
  1112. *
  1113. * Excel Function:
  1114. * AVERAGE(value1[,value2[, ...]])
  1115. *
  1116. * @access public
  1117. * @category Statistical Functions
  1118. * @param mixed $arg,... Data values
  1119. * @return float
  1120. */
  1121. public static function AVERAGE() {
  1122. $aArgs = self::flattenArrayIndexed(func_get_args());
  1123. $returnValue = $aCount = 0;
  1124. // Loop through arguments
  1125. foreach ($aArgs as $k => $arg) {
  1126. if ((is_bool($arg)) &&
  1127. ((!self::isCellValue($k)) || (self::$compatibilityMode == self::COMPATIBILITY_OPENOFFICE))) {
  1128. $arg = (integer) $arg;
  1129. }
  1130. // Is it a numeric value?
  1131. if ((is_numeric($arg)) && (!is_string($arg))) {
  1132. if (is_null($returnValue)) {
  1133. $returnValue = $arg;
  1134. } else {
  1135. $returnValue += $arg;
  1136. }
  1137. ++$aCount;
  1138. }
  1139. }
  1140. // Return
  1141. if ($aCount > 0) {
  1142. return $returnValue / $aCount;
  1143. } else {
  1144. return self::$_errorCodes['divisionbyzero'];
  1145. }
  1146. } // function AVERAGE()
  1147. /**
  1148. * AVERAGEA
  1149. *
  1150. * Returns the average of its arguments, including numbers, text, and logical values
  1151. *
  1152. * Excel Function:
  1153. * AVERAGEA(value1[,value2[, ...]])
  1154. *
  1155. * @access public
  1156. * @category Statistical Functions
  1157. * @param mixed $arg,... Data values
  1158. * @return float
  1159. */
  1160. public static function AVERAGEA() {
  1161. // Return value
  1162. $returnValue = null;
  1163. // Loop through arguments
  1164. $aArgs = self::flattenArrayIndexed(func_get_args());
  1165. $aCount = 0;
  1166. foreach ($aArgs as $k => $arg) {
  1167. if ((is_bool($arg)) &&
  1168. (!self::isMatrixValue($k))) {
  1169. } else {
  1170. if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
  1171. if (is_bool($arg)) {
  1172. $arg = (integer) $arg;
  1173. } elseif (is_string($arg)) {
  1174. $arg = 0;
  1175. }
  1176. if (is_null($returnValue)) {
  1177. $returnValue = $arg;
  1178. } else {
  1179. $returnValue += $arg;
  1180. }
  1181. ++$aCount;
  1182. }
  1183. }
  1184. }
  1185. // Return
  1186. if ($aCount > 0) {
  1187. return $returnValue / $aCount;
  1188. } else {
  1189. return self::$_errorCodes['divisionbyzero'];
  1190. }
  1191. } // function AVERAGEA()
  1192. /**
  1193. * MEDIAN
  1194. *
  1195. * Returns the median of the given numbers. The median is the number in the middle of a set of numbers.
  1196. *
  1197. * Excel Function:
  1198. * MEDIAN(value1[,value2[, ...]])
  1199. *
  1200. * @access public
  1201. * @category Statistical Functions
  1202. * @param mixed $arg,... Data values
  1203. * @return float
  1204. */
  1205. public static function MEDIAN() {
  1206. // Return value
  1207. $returnValue = self::$_errorCodes['num'];
  1208. $mArgs = array();
  1209. // Loop through arguments
  1210. $aArgs = self::flattenArray(func_get_args());
  1211. foreach ($aArgs as $arg) {
  1212. // Is it a numeric value?
  1213. if ((is_numeric($arg)) && (!is_string($arg))) {
  1214. $mArgs[] = $arg;
  1215. }
  1216. }
  1217. $mValueCount = count($mArgs);
  1218. if ($mValueCount > 0) {
  1219. sort($mArgs,SORT_NUMERIC);
  1220. $mValueCount = $mValueCount / 2;
  1221. if ($mValueCount == floor($mValueCount)) {
  1222. $returnValue = ($mArgs[$mValueCount--] + $mArgs[$mValueCount]) / 2;
  1223. } else {
  1224. $mValueCount == floor($mValueCount);
  1225. $returnValue = $mArgs[$mValueCount];
  1226. }
  1227. }
  1228. // Return
  1229. return $returnValue;
  1230. } // function MEDIAN()
  1231. //
  1232. // Special variant of array_count_values that isn't limited to strings and integers,
  1233. // but can work with floating point numbers as values
  1234. //
  1235. private static function _modeCalc($data) {
  1236. $frequencyArray = array();
  1237. foreach($data as $datum) {
  1238. $found = False;
  1239. foreach($frequencyArray as $key => $value) {
  1240. if ((string) $value['value'] == (string) $datum) {
  1241. ++$frequencyArray[$key]['frequency'];
  1242. $found = True;
  1243. break;
  1244. }
  1245. }
  1246. if (!$found) {
  1247. $frequencyArray[] = array('value' => $datum,
  1248. 'frequency' => 1 );
  1249. }
  1250. }
  1251. foreach($frequencyArray as $key => $value) {
  1252. $frequencyList[$key] = $value['frequency'];
  1253. $valueList[$key] = $value['value'];
  1254. }
  1255. array_multisort($frequencyList, SORT_DESC, $valueList, SORT_ASC, SORT_NUMERIC, $frequencyArray);
  1256. if ($frequencyArray[0]['frequency'] == 1) {
  1257. return self::NA();
  1258. }
  1259. return $frequencyArray[0]['value'];
  1260. } // function _modeCalc()
  1261. /**
  1262. * MODE
  1263. *
  1264. * Returns the most frequently occurring, or repetitive, value in an array or range of data
  1265. *
  1266. * Excel Function:
  1267. * MODE(value1[,value2[, ...]])
  1268. *
  1269. * @access public
  1270. * @category Statistical Functions
  1271. * @param mixed $arg,... Data values
  1272. * @return float
  1273. */
  1274. public static function MODE() {
  1275. // Return value
  1276. $returnValue = self::NA();
  1277. // Loop through arguments
  1278. $aArgs = self::flattenArray(func_get_args());
  1279. $mArgs = array();
  1280. foreach ($aArgs as $arg) {
  1281. // Is it a numeric value?
  1282. if ((is_numeric($arg)) && (!is_string($arg))) {
  1283. $mArgs[] = $arg;
  1284. }
  1285. }
  1286. if (count($mArgs) > 0) {
  1287. return self::_modeCalc($mArgs);
  1288. }
  1289. // Return
  1290. return $returnValue;
  1291. } // function MODE()
  1292. /**
  1293. * DEVSQ
  1294. *
  1295. * Returns the sum of squares of deviations of data points from their sample mean.
  1296. *
  1297. * Excel Function:
  1298. * DEVSQ(value1[,value2[, ...]])
  1299. *
  1300. * @access public
  1301. * @category Statistical Functions
  1302. * @param mixed $arg,... Data values
  1303. * @return float
  1304. */
  1305. public static function DEVSQ() {
  1306. $aArgs = self::flattenArrayIndexed(func_get_args());
  1307. // Return value
  1308. $returnValue = null;
  1309. $aMean = self::AVERAGE($aArgs);
  1310. if ($aMean != self::$_errorCodes['divisionbyzero']) {
  1311. $aCount = -1;
  1312. foreach ($aArgs as $k => $arg) {
  1313. // Is it a numeric value?
  1314. if ((is_bool($arg)) &&
  1315. ((!self::isCellValue($k)) || (self::$compatibilityMode == self::COMPATIBILITY_OPENOFFICE))) {
  1316. $arg = (integer) $arg;
  1317. }
  1318. if ((is_numeric($arg)) && (!is_string($arg))) {
  1319. if (is_null($returnValue)) {
  1320. $returnValue = pow(($arg - $aMean),2);
  1321. } else {
  1322. $returnValue += pow(($arg - $aMean),2);
  1323. }
  1324. ++$aCount;
  1325. }
  1326. }
  1327. // Return
  1328. if (is_null($returnValue)) {
  1329. return self::$_errorCodes['num'];
  1330. } else {
  1331. return $returnValue;
  1332. }
  1333. }
  1334. return self::NA();
  1335. } // function DEVSQ()
  1336. /**
  1337. * AVEDEV
  1338. *
  1339. * Returns the average of the absolute deviations of data points from their mean.
  1340. * AVEDEV is a measure of the variability in a data set.
  1341. *
  1342. * Excel Function:
  1343. * AVEDEV(value1[,value2[, ...]])
  1344. *
  1345. * @access public
  1346. * @category Statistical Functions
  1347. * @param mixed $arg,... Data values
  1348. * @return float
  1349. */
  1350. public static function AVEDEV() {
  1351. $aArgs = self::flattenArrayIndexed(func_get_args());
  1352. // Return value
  1353. $returnValue = null;
  1354. $aMean = self::AVERAGE($aArgs);
  1355. if ($aMean != self::$_errorCodes['divisionbyzero']) {
  1356. $aCount = 0;
  1357. foreach ($aArgs as $k => $arg) {
  1358. if ((is_bool($arg)) &&
  1359. ((!self::isCellValue($k)) || (self::$compatibilityMode == self::COMPATIBILITY_OPENOFFICE))) {
  1360. $arg = (integer) $arg;
  1361. }
  1362. // Is it a numeric value?
  1363. if ((is_numeric($arg)) && (!is_string($arg))) {
  1364. if (is_null($returnValue)) {
  1365. $returnValue = abs($arg - $aMean);
  1366. } else {
  1367. $returnValue += abs($arg - $aMean);
  1368. }
  1369. ++$aCount;
  1370. }
  1371. }
  1372. // Return
  1373. if ($aCount == 0) {
  1374. return self::$_errorCodes['divisionbyzero'];
  1375. }
  1376. return $returnValue / $aCount;
  1377. }
  1378. return self::$_errorCodes['num'];
  1379. } // function AVEDEV()
  1380. /**
  1381. * GEOMEAN
  1382. *
  1383. * Returns the geometric mean of an array or range of positive data. For example, you
  1384. * can use GEOMEAN to calculate average growth rate given compound interest with
  1385. * variable rates.
  1386. *
  1387. * Excel Function:
  1388. * GEOMEAN(value1[,value2[, ...]])
  1389. *
  1390. * @access public
  1391. * @category Statistical Functions
  1392. * @param mixed $arg,... Data values
  1393. * @return float
  1394. */
  1395. public static function GEOMEAN() {
  1396. $aArgs = self::flattenArray(func_get_args());
  1397. $aMean = self::PRODUCT($aArgs);
  1398. if (is_numeric($aMean) && ($aMean > 0)) {
  1399. $aCount = self::COUNT($aArgs) ;
  1400. if (self::MIN($aArgs) > 0) {
  1401. return pow($aMean, (1 / $aCount));
  1402. }
  1403. }
  1404. return self::$_errorCodes['num'];
  1405. } // GEOMEAN()
  1406. /**
  1407. * HARMEAN
  1408. *
  1409. * Returns the harmonic mean of a data set. The harmonic mean is the reciprocal of the
  1410. * arithmetic mean of reciprocals.
  1411. *
  1412. * Excel Function:
  1413. * HARMEAN(value1[,value2[, ...]])
  1414. *
  1415. * @access public
  1416. * @category Statistical Functions
  1417. * @param mixed $arg,... Data values
  1418. * @return float
  1419. */
  1420. public static function HARMEAN() {
  1421. // Return value
  1422. $returnValue = self::NA();
  1423. // Loop through arguments
  1424. $aArgs = self::flattenArray(func_get_args());
  1425. if (self::MIN($aArgs) < 0) {
  1426. return self::$_errorCodes['num'];
  1427. }
  1428. $aCount = 0;
  1429. foreach ($aArgs as $arg) {
  1430. // Is it a numeric value?
  1431. if ((is_numeric($arg)) && (!is_string($arg))) {
  1432. if ($arg <= 0) {
  1433. return self::$_errorCodes['num'];
  1434. }
  1435. if (is_null($returnValue)) {
  1436. $returnValue = (1 / $arg);
  1437. } else {
  1438. $returnValue += (1 / $arg);
  1439. }
  1440. ++$aCount;
  1441. }
  1442. }
  1443. // Return
  1444. if ($aCount > 0) {
  1445. return 1 / ($returnValue / $aCount);
  1446. } else {
  1447. return $returnValue;
  1448. }
  1449. } // function HARMEAN()
  1450. /**
  1451. * TRIMMEAN
  1452. *
  1453. * Returns the mean of the interior of a data set. TRIMMEAN calculates the mean
  1454. * taken by excluding a percentage of data points from the top and bottom tails
  1455. * of a data set.
  1456. *
  1457. * Excel Function:
  1458. * TRIMEAN(value1[,value2[, ...]],$discard)
  1459. *
  1460. * @access public
  1461. * @category Statistical Functions
  1462. * @param mixed $arg,... Data values
  1463. * @param float $discard Percentage to discard
  1464. * @return float
  1465. */
  1466. public static function TRIMMEAN() {
  1467. $aArgs = self::flattenArray(func_get_args());
  1468. // Calculate
  1469. $percent = array_pop($aArgs);
  1470. if ((is_numeric($percent)) && (!is_string($percent))) {
  1471. if (($percent < 0) || ($percent > 1)) {
  1472. return self::$_errorCodes['num'];
  1473. }
  1474. $mArgs = array();
  1475. foreach ($aArgs as $arg) {
  1476. // Is it a numeric value?
  1477. if ((is_numeric($arg)) && (!is_string($arg))) {
  1478. $mArgs[] = $arg;
  1479. }
  1480. }
  1481. $discard = floor(self::COUNT($mArgs) * $percent / 2);
  1482. sort($mArgs);
  1483. for ($i=0; $i < $discard; ++$i) {
  1484. array_pop($mArgs);
  1485. array_shift($mArgs);
  1486. }
  1487. return self::AVERAGE($mArgs);
  1488. }
  1489. return self::$_errorCodes['value'];
  1490. } // function TRIMMEAN()
  1491. /**
  1492. * STDEV
  1493. *
  1494. * Estimates standard deviation based on a sample. The standard deviation is a measure of how
  1495. * widely values are dispersed from the average value (the mean).
  1496. *
  1497. * Excel Function:
  1498. * STDEV(value1[,value2[, ...]])
  1499. *
  1500. * @access public
  1501. * @category Statistical Functions
  1502. * @param mixed $arg,... Data values
  1503. * @return float
  1504. */
  1505. public static function STDEV() {
  1506. $aArgs = self::flattenArrayIndexed(func_get_args());
  1507. // Return value
  1508. $returnValue = null;
  1509. $aMean = self::AVERAGE($aArgs);
  1510. if (!is_null($aMean)) {
  1511. $aCount = -1;
  1512. foreach ($aArgs as $k => $arg) {
  1513. if ((is_bool($arg)) &&
  1514. ((!self::isCellValue($k)) || (self::$compatibilityMode == self::COMPATIBILITY_OPENOFFICE))) {
  1515. $arg = (integer) $arg;
  1516. }
  1517. // Is it a numeric value?
  1518. if ((is_numeric($arg)) && (!is_string($arg))) {
  1519. if (is_null($returnValue)) {
  1520. $returnValue = pow(($arg - $aMean),2);
  1521. } else {
  1522. $returnValue += pow(($arg - $aMean),2);
  1523. }
  1524. ++$aCount;
  1525. }
  1526. }
  1527. // Return
  1528. if (($aCount > 0) && ($returnValue > 0)) {
  1529. return sqrt($returnValue / $aCount);
  1530. }
  1531. }
  1532. return self::$_errorCodes['divisionbyzero'];
  1533. } // function STDEV()
  1534. /**
  1535. * STDEVA
  1536. *
  1537. * Estimates standard deviation based on a sample, including numbers, text, and logical values
  1538. *
  1539. * Excel Function:
  1540. * STDEVA(value1[,value2[, ...]])
  1541. *
  1542. * @access public
  1543. * @category Statistical Functions
  1544. * @param mixed $arg,... Data values
  1545. * @return float
  1546. */
  1547. public static function STDEVA() {
  1548. $aArgs = self::flattenArrayIndexed(func_get_args());
  1549. // Return value
  1550. $returnValue = null;
  1551. $aMean = self::AVERAGEA($aArgs);
  1552. if (!is_null($aMean)) {
  1553. $aCount = -1;
  1554. foreach ($aArgs as $k => $arg) {
  1555. if ((is_bool($arg)) &&
  1556. (!self::isMatrixValue($k))) {
  1557. } else {
  1558. // Is it a numeric value?
  1559. if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) {
  1560. if (is_bool($arg)) {
  1561. $arg = (integer) $arg;
  1562. } elseif (is_string($arg)) {
  1563. $arg = 0;
  1564. }
  1565. if (is_null($returnValue)) {
  1566. $returnValue = pow(($arg - $aMean),2);
  1567. } else {
  1568. $returnValue += pow(($arg - $aMean),2);
  1569. }
  1570. ++$aCount;
  1571. }
  1572. }
  1573. }
  1574. // Return
  1575. if (($aCount > 0) && ($returnValue > 0)) {
  1576. return sqrt($returnValue / $aCount);
  1577. }
  1578. }
  1579. return self::$_errorCodes['divisionbyzero'];
  1580. } // function STDEVA()
  1581. /**
  1582. * STDEVP
  1583. *
  1584. * Calculates standard deviation based on the entire population
  1585. *
  1586. * Excel Function:
  1587. * STDEVP(value1[,value2[, ...]])
  1588. *
  1589. * @access public
  1590. * @category Statistical Functions
  1591. * @param mixed $arg,... Data values
  1592. * @return float
  1593. */
  1594. public static function STDEVP() {
  1595. $aArgs = self::flattenArrayIndexed(func_get_args());
  1596. // Return value
  1597. $returnValue = null;
  1598. $aMean = self::AVERAGE($aArgs);
  1599. if (!is_null($aMean)) {
  1600. $aCount = 0;
  1601. foreach ($aArgs as $k => $arg) {
  1602. if ((is_bool($arg)) &&
  1603. ((!self::isCellValue($k)) || (self::$compatibilityMode == self::COMPATIBILITY_OPENOFFICE))) {
  1604. $arg = (integer) $arg;
  1605. }
  1606. // Is it a numeric value?
  1607. if ((is_numeric($arg)) && (!is_string($arg))) {
  1608. if (is_null($returnValue)) {
  1609. $returnValue = pow(($arg - $aMean),2);
  1610. } else {
  1611. $returnValue += pow(($arg - $aMean),2);
  1612. }
  1613. ++$aCount;
  1614. }
  1615. }
  1616. // Return
  1617. if (($aCount > 0) && ($returnValue > 0)) {
  1618. return sqrt($returnValue / $aCount);
  1619. }
  1620. }
  1621. return self::$_errorCodes['divisionbyzero'];
  1622. } // function STDEVP()
  1623. /**
  1624. * STDEVPA
  1625. *
  1626. * Calculates standard deviation based on the entire population, including numbers, text, and logical values
  1627. *
  1628. * Excel Function:
  1629. * STDEVPA(value1[,value2[, ...]])
  1630. *
  1631. * @access public
  1632. * @category Statistical Functions
  1633. * @param mixed $arg,... Data values
  1634. * @return float
  1635. */
  1636. public static function STDEVPA() {
  1637. $aArgs = self::flattenArrayIndexed(func_get_args());
  1638. // Return value
  1639. $returnValue = null;
  1640. $aMean = self::AVERAGEA($aArgs);
  1641. if (!is_null($aMean)) {
  1642. $aCount = 0;
  1643. foreach ($aArgs as $k => $arg) {
  1644. if ((is_bool($arg)) &&
  1645. (!self::isMatrixValue($k))) {
  1646. } else {
  1647. // Is it a numeric value?
  1648. if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) {
  1649. if (is_bool($arg)) {
  1650. $arg = (integer) $arg;
  1651. } elseif (is_string($arg)) {
  1652. $arg = 0;
  1653. }
  1654. if (is_null($returnValue)) {
  1655. $returnValue = pow(($arg - $aMean),2);
  1656. } else {
  1657. $returnValue += pow(($arg - $aMean),2);
  1658. }
  1659. ++$aCount;
  1660. }
  1661. }
  1662. }
  1663. // Return
  1664. if (($aCount > 0) && ($returnValue > 0)) {
  1665. return sqrt($returnValue / $aCount);
  1666. }
  1667. }
  1668. return self::$_errorCodes['divisionbyzero'];
  1669. } // function STDEVPA()
  1670. /**
  1671. * VARFunc
  1672. *
  1673. * Estimates variance based on a sample.
  1674. *
  1675. * Excel Function:
  1676. * VAR(value1[,value2[, ...]])
  1677. *
  1678. * @access public
  1679. * @category Statistical Functions
  1680. * @param mixed $arg,... Data values
  1681. * @return float
  1682. */
  1683. public static function VARFunc() {
  1684. // Return value
  1685. $returnValue = self::$_errorCodes['divisionbyzero'];
  1686. $summerA = $summerB = 0;
  1687. // Loop through arguments
  1688. $aArgs = self::flattenArray(func_get_args());
  1689. $aCount = 0;
  1690. foreach ($aArgs as $arg) {
  1691. if (is_bool($arg)) { $arg = (integer) $arg; }
  1692. // Is it a numeric value?
  1693. if ((is_numeric($arg)) && (!is_string($arg))) {
  1694. $summerA += ($arg * $arg);
  1695. $summerB += $arg;
  1696. ++$aCount;
  1697. }
  1698. }
  1699. // Return
  1700. if ($aCount > 1) {
  1701. $summerA *= $aCount;
  1702. $summerB *= $summerB;
  1703. $returnValue = ($summerA - $summerB) / ($aCount * ($aCount - 1));
  1704. }
  1705. return $returnValue;
  1706. } // function VARFunc()
  1707. /**
  1708. * VARA
  1709. *
  1710. * Estimates variance based on a sample, including numbers, text, and logical values
  1711. *
  1712. * Excel Function:
  1713. * VARA(value1[,value2[, ...]])
  1714. *
  1715. * @access public
  1716. * @category Statistical Functions
  1717. * @param mixed $a…

Large files files are truncated, but you can click here to view the full file