[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 3 require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php'; 4 require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/JAMA/Matrix.php'; 5 6 /** 7 * PHPExcel_Polynomial_Best_Fit 8 * 9 * Copyright (c) 2006 - 2015 PHPExcel 10 * 11 * This library is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU Lesser General Public 13 * License as published by the Free Software Foundation; either 14 * version 2.1 of the License, or (at your option) any later version. 15 * 16 * This library is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 * Lesser General Public License for more details. 20 * 21 * You should have received a copy of the GNU Lesser General Public 22 * License along with this library; if not, write to the Free Software 23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 24 * 25 * @category PHPExcel 26 * @package PHPExcel_Shared_Trend 27 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) 28 * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL 29 * @version ##VERSION##, ##DATE## 30 */ 31 class PHPExcel_Polynomial_Best_Fit extends PHPExcel_Best_Fit 32 { 33 /** 34 * Algorithm type to use for best-fit 35 * (Name of this trend class) 36 * 37 * @var string 38 **/ 39 protected $bestFitType = 'polynomial'; 40 41 /** 42 * Polynomial order 43 * 44 * @protected 45 * @var int 46 **/ 47 protected $order = 0; 48 49 50 /** 51 * Return the order of this polynomial 52 * 53 * @return int 54 **/ 55 public function getOrder() 56 { 57 return $this->order; 58 } 59 60 61 /** 62 * Return the Y-Value for a specified value of X 63 * 64 * @param float $xValue X-Value 65 * @return float Y-Value 66 **/ 67 public function getValueOfYForX($xValue) 68 { 69 $retVal = $this->getIntersect(); 70 $slope = $this->getSlope(); 71 foreach ($slope as $key => $value) { 72 if ($value != 0.0) { 73 $retVal += $value * pow($xValue, $key + 1); 74 } 75 } 76 return $retVal; 77 } 78 79 80 /** 81 * Return the X-Value for a specified value of Y 82 * 83 * @param float $yValue Y-Value 84 * @return float X-Value 85 **/ 86 public function getValueOfXForY($yValue) 87 { 88 return ($yValue - $this->getIntersect()) / $this->getSlope(); 89 } 90 91 92 /** 93 * Return the Equation of the best-fit line 94 * 95 * @param int $dp Number of places of decimal precision to display 96 * @return string 97 **/ 98 public function getEquation($dp = 0) 99 { 100 $slope = $this->getSlope($dp); 101 $intersect = $this->getIntersect($dp); 102 103 $equation = 'Y = ' . $intersect; 104 foreach ($slope as $key => $value) { 105 if ($value != 0.0) { 106 $equation .= ' + ' . $value . ' * X'; 107 if ($key > 0) { 108 $equation .= '^' . ($key + 1); 109 } 110 } 111 } 112 return $equation; 113 } 114 115 116 /** 117 * Return the Slope of the line 118 * 119 * @param int $dp Number of places of decimal precision to display 120 * @return string 121 **/ 122 public function getSlope($dp = 0) 123 { 124 if ($dp != 0) { 125 $coefficients = array(); 126 foreach ($this->_slope as $coefficient) { 127 $coefficients[] = round($coefficient, $dp); 128 } 129 return $coefficients; 130 } 131 return $this->_slope; 132 } 133 134 135 public function getCoefficients($dp = 0) 136 { 137 return array_merge(array($this->getIntersect($dp)), $this->getSlope($dp)); 138 } 139 140 141 /** 142 * Execute the regression and calculate the goodness of fit for a set of X and Y data values 143 * 144 * @param int $order Order of Polynomial for this regression 145 * @param float[] $yValues The set of Y-values for this regression 146 * @param float[] $xValues The set of X-values for this regression 147 * @param boolean $const 148 */ 149 private function polynomialRegression($order, $yValues, $xValues, $const) 150 { 151 // calculate sums 152 $x_sum = array_sum($xValues); 153 $y_sum = array_sum($yValues); 154 $xx_sum = $xy_sum = 0; 155 for ($i = 0; $i < $this->valueCount; ++$i) { 156 $xy_sum += $xValues[$i] * $yValues[$i]; 157 $xx_sum += $xValues[$i] * $xValues[$i]; 158 $yy_sum += $yValues[$i] * $yValues[$i]; 159 } 160 /* 161 * This routine uses logic from the PHP port of polyfit version 0.1 162 * written by Michael Bommarito and Paul Meagher 163 * 164 * The function fits a polynomial function of order $order through 165 * a series of x-y data points using least squares. 166 * 167 */ 168 for ($i = 0; $i < $this->valueCount; ++$i) { 169 for ($j = 0; $j <= $order; ++$j) { 170 $A[$i][$j] = pow($xValues[$i], $j); 171 } 172 } 173 for ($i=0; $i < $this->valueCount; ++$i) { 174 $B[$i] = array($yValues[$i]); 175 } 176 $matrixA = new Matrix($A); 177 $matrixB = new Matrix($B); 178 $C = $matrixA->solve($matrixB); 179 180 $coefficients = array(); 181 for ($i = 0; $i < $C->m; ++$i) { 182 $r = $C->get($i, 0); 183 if (abs($r) <= pow(10, -9)) { 184 $r = 0; 185 } 186 $coefficients[] = $r; 187 } 188 189 $this->intersect = array_shift($coefficients); 190 $this->_slope = $coefficients; 191 192 $this->calculateGoodnessOfFit($x_sum, $y_sum, $xx_sum, $yy_sum, $xy_sum); 193 foreach ($this->xValues as $xKey => $xValue) { 194 $this->yBestFitValues[$xKey] = $this->getValueOfYForX($xValue); 195 } 196 } 197 198 199 /** 200 * Define the regression and calculate the goodness of fit for a set of X and Y data values 201 * 202 * @param int $order Order of Polynomial for this regression 203 * @param float[] $yValues The set of Y-values for this regression 204 * @param float[] $xValues The set of X-values for this regression 205 * @param boolean $const 206 */ 207 public function __construct($order, $yValues, $xValues = array(), $const = true) 208 { 209 if (parent::__construct($yValues, $xValues) !== false) { 210 if ($order < $this->valueCount) { 211 $this->bestFitType .= '_'.$order; 212 $this->order = $order; 213 $this->polynomialRegression($order, $yValues, $xValues, $const); 214 if (($this->getGoodnessOfFit() < 0.0) || ($this->getGoodnessOfFit() > 1.0)) { 215 $this->_error = true; 216 } 217 } else { 218 $this->_error = true; 219 } 220 } 221 } 222 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |