PageRenderTime 63ms CodeModel.GetById 6ms app.highlight 34ms RepoModel.GetById 1ms app.codeStats 2ms

/add-ons/PHPExcel/PHPExcel/Calculation/Functions.php

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

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