ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
BestFit.php
Go to the documentation of this file.
1 <?php
2 
4 
5 abstract class BestFit
6 {
12  protected $error = false;
13 
19  protected $bestFitType = 'undetermined';
20 
26  protected $valueCount = 0;
27 
33  protected $xValues = [];
34 
40  protected $yValues = [];
41 
47  protected $adjustToZero = false;
48 
54  protected $yBestFitValues = [];
55 
56  protected $goodnessOfFit = 1;
57 
58  protected $stdevOfResiduals = 0;
59 
60  protected $covariance = 0;
61 
62  protected $correlation = 0;
63 
64  protected $SSRegression = 0;
65 
66  protected $SSResiduals = 0;
67 
68  protected $DFResiduals = 0;
69 
70  protected $f = 0;
71 
72  protected $slope = 0;
73 
74  protected $slopeSE = 0;
75 
76  protected $intersect = 0;
77 
78  protected $intersectSE = 0;
79 
80  protected $xOffset = 0;
81 
82  protected $yOffset = 0;
83 
84  public function getError()
85  {
86  return $this->error;
87  }
88 
89  public function getBestFitType()
90  {
91  return $this->bestFitType;
92  }
93 
101  abstract public function getValueOfYForX($xValue);
102 
110  abstract public function getValueOfXForY($yValue);
111 
117  public function getXValues()
118  {
119  return $this->xValues;
120  }
121 
129  abstract public function getEquation($dp = 0);
130 
138  public function getSlope($dp = 0)
139  {
140  if ($dp != 0) {
141  return round($this->slope, $dp);
142  }
143 
144  return $this->slope;
145  }
146 
154  public function getSlopeSE($dp = 0)
155  {
156  if ($dp != 0) {
157  return round($this->slopeSE, $dp);
158  }
159 
160  return $this->slopeSE;
161  }
162 
170  public function getIntersect($dp = 0)
171  {
172  if ($dp != 0) {
173  return round($this->intersect, $dp);
174  }
175 
176  return $this->intersect;
177  }
178 
186  public function getIntersectSE($dp = 0)
187  {
188  if ($dp != 0) {
189  return round($this->intersectSE, $dp);
190  }
191 
192  return $this->intersectSE;
193  }
194 
202  public function getGoodnessOfFit($dp = 0)
203  {
204  if ($dp != 0) {
205  return round($this->goodnessOfFit, $dp);
206  }
207 
208  return $this->goodnessOfFit;
209  }
210 
218  public function getGoodnessOfFitPercent($dp = 0)
219  {
220  if ($dp != 0) {
221  return round($this->goodnessOfFit * 100, $dp);
222  }
223 
224  return $this->goodnessOfFit * 100;
225  }
226 
234  public function getStdevOfResiduals($dp = 0)
235  {
236  if ($dp != 0) {
237  return round($this->stdevOfResiduals, $dp);
238  }
239 
241  }
242 
248  public function getSSRegression($dp = 0)
249  {
250  if ($dp != 0) {
251  return round($this->SSRegression, $dp);
252  }
253 
254  return $this->SSRegression;
255  }
256 
262  public function getSSResiduals($dp = 0)
263  {
264  if ($dp != 0) {
265  return round($this->SSResiduals, $dp);
266  }
267 
268  return $this->SSResiduals;
269  }
270 
276  public function getDFResiduals($dp = 0)
277  {
278  if ($dp != 0) {
279  return round($this->DFResiduals, $dp);
280  }
281 
282  return $this->DFResiduals;
283  }
284 
290  public function getF($dp = 0)
291  {
292  if ($dp != 0) {
293  return round($this->f, $dp);
294  }
295 
296  return $this->f;
297  }
298 
304  public function getCovariance($dp = 0)
305  {
306  if ($dp != 0) {
307  return round($this->covariance, $dp);
308  }
309 
310  return $this->covariance;
311  }
312 
318  public function getCorrelation($dp = 0)
319  {
320  if ($dp != 0) {
321  return round($this->correlation, $dp);
322  }
323 
324  return $this->correlation;
325  }
326 
330  public function getYBestFitValues()
331  {
332  return $this->yBestFitValues;
333  }
334 
335  protected function calculateGoodnessOfFit($sumX, $sumY, $sumX2, $sumY2, $sumXY, $meanX, $meanY, $const): void
336  {
337  $SSres = $SScov = $SScor = $SStot = $SSsex = 0.0;
338  foreach ($this->xValues as $xKey => $xValue) {
339  $bestFitY = $this->yBestFitValues[$xKey] = $this->getValueOfYForX($xValue);
340 
341  $SSres += ($this->yValues[$xKey] - $bestFitY) * ($this->yValues[$xKey] - $bestFitY);
342  if ($const === true) {
343  $SStot += ($this->yValues[$xKey] - $meanY) * ($this->yValues[$xKey] - $meanY);
344  } else {
345  $SStot += $this->yValues[$xKey] * $this->yValues[$xKey];
346  }
347  $SScov += ($this->xValues[$xKey] - $meanX) * ($this->yValues[$xKey] - $meanY);
348  if ($const === true) {
349  $SSsex += ($this->xValues[$xKey] - $meanX) * ($this->xValues[$xKey] - $meanX);
350  } else {
351  $SSsex += $this->xValues[$xKey] * $this->xValues[$xKey];
352  }
353  }
354 
355  $this->SSResiduals = $SSres;
356  $this->DFResiduals = $this->valueCount - 1 - ($const === true ? 1 : 0);
357 
358  if ($this->DFResiduals == 0.0) {
359  $this->stdevOfResiduals = 0.0;
360  } else {
361  $this->stdevOfResiduals = sqrt($SSres / $this->DFResiduals);
362  }
363  if (($SStot == 0.0) || ($SSres == $SStot)) {
364  $this->goodnessOfFit = 1;
365  } else {
366  $this->goodnessOfFit = 1 - ($SSres / $SStot);
367  }
368 
369  $this->SSRegression = $this->goodnessOfFit * $SStot;
370  $this->covariance = $SScov / $this->valueCount;
371  $this->correlation = ($this->valueCount * $sumXY - $sumX * $sumY) / sqrt(($this->valueCount * $sumX2 - $sumX ** 2) * ($this->valueCount * $sumY2 - $sumY ** 2));
372  $this->slopeSE = $this->stdevOfResiduals / sqrt($SSsex);
373  $this->intersectSE = $this->stdevOfResiduals * sqrt(1 / ($this->valueCount - ($sumX * $sumX) / $sumX2));
374  if ($this->SSResiduals != 0.0) {
375  if ($this->DFResiduals == 0.0) {
376  $this->f = 0.0;
377  } else {
378  $this->f = $this->SSRegression / ($this->SSResiduals / $this->DFResiduals);
379  }
380  } else {
381  if ($this->DFResiduals == 0.0) {
382  $this->f = 0.0;
383  } else {
384  $this->f = $this->SSRegression / $this->DFResiduals;
385  }
386  }
387  }
388 
389  private function sumSquares(array $values)
390  {
391  return array_sum(
392  array_map(
393  function ($value) {
394  return $value ** 2;
395  },
396  $values
397  )
398  );
399  }
400 
405  protected function leastSquareFit(array $yValues, array $xValues, bool $const): void
406  {
407  // calculate sums
408  $sumValuesX = array_sum($xValues);
409  $sumValuesY = array_sum($yValues);
410  $meanValueX = $sumValuesX / $this->valueCount;
411  $meanValueY = $sumValuesY / $this->valueCount;
412  $sumSquaresX = $this->sumSquares($xValues);
413  $sumSquaresY = $this->sumSquares($yValues);
414  $mBase = $mDivisor = 0.0;
415  $xy_sum = 0.0;
416  for ($i = 0; $i < $this->valueCount; ++$i) {
417  $xy_sum += $xValues[$i] * $yValues[$i];
418 
419  if ($const === true) {
420  $mBase += ($xValues[$i] - $meanValueX) * ($yValues[$i] - $meanValueY);
421  $mDivisor += ($xValues[$i] - $meanValueX) * ($xValues[$i] - $meanValueX);
422  } else {
423  $mBase += $xValues[$i] * $yValues[$i];
424  $mDivisor += $xValues[$i] * $xValues[$i];
425  }
426  }
427 
428  // calculate slope
429  $this->slope = $mBase / $mDivisor;
430 
431  // calculate intersect
432  $this->intersect = ($const === true) ? $meanValueY - ($this->slope * $meanValueX) : 0.0;
433 
434  $this->calculateGoodnessOfFit($sumValuesX, $sumValuesY, $sumSquaresX, $sumSquaresY, $xy_sum, $meanValueX, $meanValueY, $const);
435  }
436 
443  public function __construct($yValues, $xValues = [])
444  {
445  // Calculate number of points
446  $yValueCount = count($yValues);
447  $xValueCount = count($xValues);
448 
449  // Define X Values if necessary
450  if ($xValueCount === 0) {
451  $xValues = range(1, $yValueCount);
452  } elseif ($yValueCount !== $xValueCount) {
453  // Ensure both arrays of points are the same size
454  $this->error = true;
455  }
456 
457  $this->valueCount = $yValueCount;
458  $this->xValues = $xValues;
459  $this->yValues = $yValues;
460  }
461 }
calculateGoodnessOfFit($sumX, $sumY, $sumX2, $sumY2, $sumXY, $meanX, $meanY, $const)
Definition: BestFit.php:335
getValueOfXForY($yValue)
Return the X-Value for a specified value of Y.
getGoodnessOfFit($dp=0)
Return the goodness of fit for this regression.
Definition: BestFit.php:202
getIntersect($dp=0)
Return the Value of X where it intersects Y = 0.
Definition: BestFit.php:170
getSlope($dp=0)
Return the Slope of the line.
Definition: BestFit.php:138
getXValues()
Return the original set of X-Values.
Definition: BestFit.php:117
getIntersectSE($dp=0)
Return the standard error of the Intersect.
Definition: BestFit.php:186
$values
__construct($yValues, $xValues=[])
Define the regression.
Definition: BestFit.php:443
$i
Definition: disco.tpl.php:19
getEquation($dp=0)
Return the Equation of the best-fit line.
getValueOfYForX($xValue)
Return the Y-Value for a specified value of X.
getStdevOfResiduals($dp=0)
Return the standard deviation of the residuals for this regression.
Definition: BestFit.php:234
leastSquareFit(array $yValues, array $xValues, bool $const)
Definition: BestFit.php:405
getSlopeSE($dp=0)
Return the standard error of the Slope.
Definition: BestFit.php:154
getGoodnessOfFitPercent($dp=0)
Return the goodness of fit for this regression.
Definition: BestFit.php:218