PageRenderTime 67ms CodeModel.GetById 8ms app.highlight 36ms RepoModel.GetById 1ms app.codeStats 2ms

/libs/phpexcel/PHPExcel/Calculation/Functions.php

https://github.com/vykintasv/psiprogresas
PHP | 10505 lines | 6179 code | 1177 blank | 3149 comment | 1740 complexity | 27b4aa5a53e42a0b4ac7064b57ba6c84 MD5 | raw file

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

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