[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/phpexcel/PHPExcel/Shared/trend/ -> bestFitClass.php (source)

   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  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1