3 require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/linearBestFitClass.php';
4 require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/logarithmicBestFitClass.php';
5 require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/exponentialBestFitClass.php';
6 require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/powerBestFitClass.php';
7 require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/polynomialBestFitClass.php';
12 * Copyright (c) 2006 - 2015 PHPExcel
14 * This library is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU Lesser General Public
16 * License as published by the Free Software Foundation; either
17 * version 2.1 of the License, or (at your option) any later version.
19 * This library is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Lesser General Public License for more details.
24 * You should have received a copy of the GNU Lesser General Public
25 * License along with this library; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29 * @package PHPExcel_Shared_Trend
30 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel)
31 * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
32 * @version ##VERSION##, ##DATE##
36 const TREND_LINEAR = 'Linear';
37 const TREND_LOGARITHMIC = 'Logarithmic';
38 const TREND_EXPONENTIAL = 'Exponential';
39 const TREND_POWER = 'Power';
40 const TREND_POLYNOMIAL_2 = 'Polynomial_2';
41 const TREND_POLYNOMIAL_3 = 'Polynomial_3';
42 const TREND_POLYNOMIAL_4 = 'Polynomial_4';
43 const TREND_POLYNOMIAL_5 = 'Polynomial_5';
44 const TREND_POLYNOMIAL_6 = 'Polynomial_6';
45 const TREND_BEST_FIT = 'Bestfit';
46 const TREND_BEST_FIT_NO_POLY = 'Bestfit_no_Polynomials';
49 * Names of the best-fit trend analysis methods
53 private static $trendTypes = array(
55 self::TREND_LOGARITHMIC,
56 self::TREND_EXPONENTIAL,
61 * Names of the best-fit trend polynomial orders
65 private static $trendTypePolynomialOrders = array(
66 self::TREND_POLYNOMIAL_2,
67 self::TREND_POLYNOMIAL_3,
68 self::TREND_POLYNOMIAL_4,
69 self::TREND_POLYNOMIAL_5,
70 self::TREND_POLYNOMIAL_6
74 * Cached results for each method when trying to identify which provides the best fit
76 * @var PHPExcel_Best_Fit[]
78 private static $trendCache = array();
81 public static function calculate($trendType = self::TREND_BEST_FIT, $yValues, $xValues = array(), $const = true)
83 // Calculate number of points in each dataset
84 $nY = count($yValues);
85 $nX = count($xValues);
87 // Define X Values if necessary
89 $xValues = range(1, $nY);
91 } elseif ($nY != $nX) {
92 // Ensure both arrays of points are the same size
93 trigger_error("trend(): Number of elements in coordinate arrays do not match.", E_USER_ERROR);
96 $key = md5($trendType.$const.serialize($yValues).serialize($xValues));
97 // Determine which trend method has been requested
99 // Instantiate and return the class for the requested trend method
100 case self::TREND_LINEAR:
101 case self::TREND_LOGARITHMIC:
102 case self::TREND_EXPONENTIAL:
103 case self::TREND_POWER:
104 if (!isset(self::$trendCache[$key])) {
105 $className = 'PHPExcel_'.$trendType.'_Best_Fit';
106 self::$trendCache[$key] = new $className($yValues, $xValues, $const);
108 return self::$trendCache[$key];
109 case self::TREND_POLYNOMIAL_2:
110 case self::TREND_POLYNOMIAL_3:
111 case self::TREND_POLYNOMIAL_4:
112 case self::TREND_POLYNOMIAL_5:
113 case self::TREND_POLYNOMIAL_6:
114 if (!isset(self::$trendCache[$key])) {
115 $order = substr($trendType, -1);
116 self::$trendCache[$key] = new PHPExcel_Polynomial_Best_Fit($order, $yValues, $xValues, $const);
118 return self::$trendCache[$key];
119 case self::TREND_BEST_FIT:
120 case self::TREND_BEST_FIT_NO_POLY:
121 // If the request is to determine the best fit regression, then we test each trend line in turn
122 // Start by generating an instance of each available trend method
123 foreach (self::$trendTypes as $trendMethod) {
124 $className = 'PHPExcel_'.$trendMethod.'BestFit';
125 $bestFit[$trendMethod] = new $className($yValues, $xValues, $const);
126 $bestFitValue[$trendMethod] = $bestFit[$trendMethod]->getGoodnessOfFit();
128 if ($trendType != self::TREND_BEST_FIT_NO_POLY) {
129 foreach (self::$trendTypePolynomialOrders as $trendMethod) {
130 $order = substr($trendMethod, -1);
131 $bestFit[$trendMethod] = new PHPExcel_Polynomial_Best_Fit($order, $yValues, $xValues, $const);
132 if ($bestFit[$trendMethod]->getError()) {
133 unset($bestFit[$trendMethod]);
135 $bestFitValue[$trendMethod] = $bestFit[$trendMethod]->getGoodnessOfFit();
139 // Determine which of our trend lines is the best fit, and then we return the instance of that trend class
140 arsort($bestFitValue);
141 $bestFitType = key($bestFitValue);
142 return $bestFit[$bestFitType];