[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * PHPExcel_Best_Fit 5 * 6 * Copyright (c) 2006 - 2015 PHPExcel 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 * 22 * @category PHPExcel 23 * @package PHPExcel_Shared_Trend 24 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) 25 * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL 26 * @version ##VERSION##, ##DATE## 27 */ 28 class PHPExcel_Best_Fit 29 { 30 /** 31 * Indicator flag for a calculation error 32 * 33 * @var boolean 34 **/ 35 protected $error = false; 36 37 /** 38 * Algorithm type to use for best-fit 39 * 40 * @var string 41 **/ 42 protected $bestFitType = 'undetermined'; 43 44 /** 45 * Number of entries in the sets of x- and y-value arrays 46 * 47 * @var int 48 **/ 49 protected $valueCount = 0; 50 51 /** 52 * X-value dataseries of values 53 * 54 * @var float[] 55 **/ 56 protected $xValues = array(); 57 58 /** 59 * Y-value dataseries of values 60 * 61 * @var float[] 62 **/ 63 protected $yValues = array(); 64 65 /** 66 * Flag indicating whether values should be adjusted to Y=0 67 * 68 * @var boolean 69 **/ 70 protected $adjustToZero = false; 71 72 /** 73 * Y-value series of best-fit values 74 * 75 * @var float[] 76 **/ 77 protected $yBestFitValues = array(); 78 79 protected $goodnessOfFit = 1; 80 81 protected $stdevOfResiduals = 0; 82 83 protected $covariance = 0; 84 85 protected $correlation = 0; 86 87 protected $SSRegression = 0; 88 89 protected $SSResiduals = 0; 90 91 protected $DFResiduals = 0; 92 93 protected $f = 0; 94 95 protected $slope = 0; 96 97 protected $slopeSE = 0; 98 99 protected $intersect = 0; 100 101 protected $intersectSE = 0; 102 103 protected $xOffset = 0; 104 105 protected $yOffset = 0; 106 107 108 public function getError() 109 { 110 return $this->error; 111 } 112 113 114 public function getBestFitType() 115 { 116 return $this->bestFitType; 117 } 118 119 /** 120 * Return the Y-Value for a specified value of X 121 * 122 * @param float $xValue X-Value 123 * @return float Y-Value 124 */ 125 public function getValueOfYForX($xValue) 126 { 127 return false; 128 } 129 130 /** 131 * Return the X-Value for a specified value of Y 132 * 133 * @param float $yValue Y-Value 134 * @return float X-Value 135 */ 136 public function getValueOfXForY($yValue) 137 { 138 return false; 139 } 140 141 /** 142 * Return the original set of X-Values 143 * 144 * @return float[] X-Values 145 */ 146 public function getXValues() 147 { 148 return $this->xValues; 149 } 150 151 /** 152 * Return the Equation of the best-fit line 153 * 154 * @param int $dp Number of places of decimal precision to display 155 * @return string 156 */ 157 public function getEquation($dp = 0) 158 { 159 return false; 160 } 161 162 /** 163 * Return the Slope of the line 164 * 165 * @param int $dp Number of places of decimal precision to display 166 * @return string 167 */ 168 public function getSlope($dp = 0) 169 { 170 if ($dp != 0) { 171 return round($this->slope, $dp); 172 } 173 return $this->slope; 174 } 175 176 /** 177 * Return the standard error of the Slope 178 * 179 * @param int $dp Number of places of decimal precision to display 180 * @return string 181 */ 182 public function getSlopeSE($dp = 0) 183 { 184 if ($dp != 0) { 185 return round($this->slopeSE, $dp); 186 } 187 return $this->slopeSE; 188 } 189 190 /** 191 * Return the Value of X where it intersects Y = 0 192 * 193 * @param int $dp Number of places of decimal precision to display 194 * @return string 195 */ 196 public function getIntersect($dp = 0) 197 { 198 if ($dp != 0) { 199 return round($this->intersect, $dp); 200 } 201 return $this->intersect; 202 } 203 204 /** 205 * Return the standard error of the Intersect 206 * 207 * @param int $dp Number of places of decimal precision to display 208 * @return string 209 */ 210 public function getIntersectSE($dp = 0) 211 { 212 if ($dp != 0) { 213 return round($this->intersectSE, $dp); 214 } 215 return $this->intersectSE; 216 } 217 218 /** 219 * Return the goodness of fit for this regression 220 * 221 * @param int $dp Number of places of decimal precision to return 222 * @return float 223 */ 224 public function getGoodnessOfFit($dp = 0) 225 { 226 if ($dp != 0) { 227 return round($this->goodnessOfFit, $dp); 228 } 229 return $this->goodnessOfFit; 230 } 231 232 public function getGoodnessOfFitPercent($dp = 0) 233 { 234 if ($dp != 0) { 235 return round($this->goodnessOfFit * 100, $dp); 236 } 237 return $this->goodnessOfFit * 100; 238 } 239 240 /** 241 * Return the standard deviation of the residuals for this regression 242 * 243 * @param int $dp Number of places of decimal precision to return 244 * @return float 245 */ 246 public function getStdevOfResiduals($dp = 0) 247 { 248 if ($dp != 0) { 249 return round($this->stdevOfResiduals, $dp); 250 } 251 return $this->stdevOfResiduals; 252 } 253 254 public function getSSRegression($dp = 0) 255 { 256 if ($dp != 0) { 257 return round($this->SSRegression, $dp); 258 } 259 return $this->SSRegression; 260 } 261 262 public function getSSResiduals($dp = 0) 263 { 264 if ($dp != 0) { 265 return round($this->SSResiduals, $dp); 266 } 267 return $this->SSResiduals; 268 } 269 270 public function getDFResiduals($dp = 0) 271 { 272 if ($dp != 0) { 273 return round($this->DFResiduals, $dp); 274 } 275 return $this->DFResiduals; 276 } 277 278 public function getF($dp = 0) 279 { 280 if ($dp != 0) { 281 return round($this->f, $dp); 282 } 283 return $this->f; 284 } 285 286 public function getCovariance($dp = 0) 287 { 288 if ($dp != 0) { 289 return round($this->covariance, $dp); 290 } 291 return $this->covariance; 292 } 293 294 public function getCorrelation($dp = 0) 295 { 296 if ($dp != 0) { 297 return round($this->correlation, $dp); 298 } 299 return $this->correlation; 300 } 301 302 public function getYBestFitValues() 303 { 304 return $this->yBestFitValues; 305 } 306 307 protected function calculateGoodnessOfFit($sumX, $sumY, $sumX2, $sumY2, $sumXY, $meanX, $meanY, $const) 308 { 309 $SSres = $SScov = $SScor = $SStot = $SSsex = 0.0; 310 foreach ($this->xValues as $xKey => $xValue) { 311 $bestFitY = $this->yBestFitValues[$xKey] = $this->getValueOfYForX($xValue); 312 313 $SSres += ($this->yValues[$xKey] - $bestFitY) * ($this->yValues[$xKey] - $bestFitY); 314 if ($const) { 315 $SStot += ($this->yValues[$xKey] - $meanY) * ($this->yValues[$xKey] - $meanY); 316 } else { 317 $SStot += $this->yValues[$xKey] * $this->yValues[$xKey]; 318 } 319 $SScov += ($this->xValues[$xKey] - $meanX) * ($this->yValues[$xKey] - $meanY); 320 if ($const) { 321 $SSsex += ($this->xValues[$xKey] - $meanX) * ($this->xValues[$xKey] - $meanX); 322 } else { 323 $SSsex += $this->xValues[$xKey] * $this->xValues[$xKey]; 324 } 325 } 326 327 $this->SSResiduals = $SSres; 328 $this->DFResiduals = $this->valueCount - 1 - $const; 329 330 if ($this->DFResiduals == 0.0) { 331 $this->stdevOfResiduals = 0.0; 332 } else { 333 $this->stdevOfResiduals = sqrt($SSres / $this->DFResiduals); 334 } 335 if (($SStot == 0.0) || ($SSres == $SStot)) { 336 $this->goodnessOfFit = 1; 337 } else { 338 $this->goodnessOfFit = 1 - ($SSres / $SStot); 339 } 340 341 $this->SSRegression = $this->goodnessOfFit * $SStot; 342 $this->covariance = $SScov / $this->valueCount; 343 $this->correlation = ($this->valueCount * $sumXY - $sumX * $sumY) / sqrt(($this->valueCount * $sumX2 - pow($sumX, 2)) * ($this->valueCount * $sumY2 - pow($sumY, 2))); 344 $this->slopeSE = $this->stdevOfResiduals / sqrt($SSsex); 345 $this->intersectSE = $this->stdevOfResiduals * sqrt(1 / ($this->valueCount - ($sumX * $sumX) / $sumX2)); 346 if ($this->SSResiduals != 0.0) { 347 if ($this->DFResiduals == 0.0) { 348 $this->f = 0.0; 349 } else { 350 $this->f = $this->SSRegression / ($this->SSResiduals / $this->DFResiduals); 351 } 352 } else { 353 if ($this->DFResiduals == 0.0) { 354 $this->f = 0.0; 355 } else { 356 $this->f = $this->SSRegression / $this->DFResiduals; 357 } 358 } 359 } 360 361 protected function leastSquareFit($yValues, $xValues, $const) 362 { 363 // calculate sums 364 $x_sum = array_sum($xValues); 365 $y_sum = array_sum($yValues); 366 $meanX = $x_sum / $this->valueCount; 367 $meanY = $y_sum / $this->valueCount; 368 $mBase = $mDivisor = $xx_sum = $xy_sum = $yy_sum = 0.0; 369 for ($i = 0; $i < $this->valueCount; ++$i) { 370 $xy_sum += $xValues[$i] * $yValues[$i]; 371 $xx_sum += $xValues[$i] * $xValues[$i]; 372 $yy_sum += $yValues[$i] * $yValues[$i]; 373 374 if ($const) { 375 $mBase += ($xValues[$i] - $meanX) * ($yValues[$i] - $meanY); 376 $mDivisor += ($xValues[$i] - $meanX) * ($xValues[$i] - $meanX); 377 } else { 378 $mBase += $xValues[$i] * $yValues[$i]; 379 $mDivisor += $xValues[$i] * $xValues[$i]; 380 } 381 } 382 383 // calculate slope 384 // $this->slope = (($this->valueCount * $xy_sum) - ($x_sum * $y_sum)) / (($this->valueCount * $xx_sum) - ($x_sum * $x_sum)); 385 $this->slope = $mBase / $mDivisor; 386 387 // calculate intersect 388 // $this->intersect = ($y_sum - ($this->slope * $x_sum)) / $this->valueCount; 389 if ($const) { 390 $this->intersect = $meanY - ($this->slope * $meanX); 391 } else { 392 $this->intersect = 0; 393 } 394 395 $this->calculateGoodnessOfFit($x_sum, $y_sum, $xx_sum, $yy_sum, $xy_sum, $meanX, $meanY, $const); 396 } 397 398 /** 399 * Define the regression 400 * 401 * @param float[] $yValues The set of Y-values for this regression 402 * @param float[] $xValues The set of X-values for this regression 403 * @param boolean $const 404 */ 405 public function __construct($yValues, $xValues = array(), $const = true) 406 { 407 // Calculate number of points 408 $nY = count($yValues); 409 $nX = count($xValues); 410 411 // Define X Values if necessary 412 if ($nX == 0) { 413 $xValues = range(1, $nY); 414 $nX = $nY; 415 } elseif ($nY != $nX) { 416 // Ensure both arrays of points are the same size 417 $this->error = true; 418 return false; 419 } 420 421 $this->valueCount = $nY; 422 $this->xValues = $xValues; 423 $this->yValues = $yValues; 424 } 425 }
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 |