trendClass.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. <?php
  2. require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/linearBestFitClass.php';
  3. require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/logarithmicBestFitClass.php';
  4. require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/exponentialBestFitClass.php';
  5. require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/powerBestFitClass.php';
  6. require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/polynomialBestFitClass.php';
  7. class trendClass
  8. {
  9. const TREND_LINEAR = 'Linear';
  10. const TREND_LOGARITHMIC = 'Logarithmic';
  11. const TREND_EXPONENTIAL = 'Exponential';
  12. const TREND_POWER = 'Power';
  13. const TREND_POLYNOMIAL_2 = 'Polynomial_2';
  14. const TREND_POLYNOMIAL_3 = 'Polynomial_3';
  15. const TREND_POLYNOMIAL_4 = 'Polynomial_4';
  16. const TREND_POLYNOMIAL_5 = 'Polynomial_5';
  17. const TREND_POLYNOMIAL_6 = 'Polynomial_6';
  18. const TREND_BEST_FIT = 'Bestfit';
  19. const TREND_BEST_FIT_NO_POLY = 'Bestfit_no_Polynomials';
  20. private static $_trendTypes = array( self::TREND_LINEAR,
  21. self::TREND_LOGARITHMIC,
  22. self::TREND_EXPONENTIAL,
  23. self::TREND_POWER
  24. );
  25. private static $_trendTypePolyOrders = array( self::TREND_POLYNOMIAL_2,
  26. self::TREND_POLYNOMIAL_3,
  27. self::TREND_POLYNOMIAL_4,
  28. self::TREND_POLYNOMIAL_5,
  29. self::TREND_POLYNOMIAL_6
  30. );
  31. private static $_trendCache = array();
  32. public static function calculate($trendType=self::TREND_BEST_FIT, $yValues, $xValues=array(), $const=True) {
  33. // Calculate number of points in each dataset
  34. $nY = count($yValues);
  35. $nX = count($xValues);
  36. // Define X Values if necessary
  37. if ($nX == 0) {
  38. $xValues = range(1,$nY);
  39. $nX = $nY;
  40. } elseif ($nY != $nX) {
  41. // Ensure both arrays of points are the same size
  42. trigger_error("trend(): Number of elements in coordinate arrays do not match.", E_USER_ERROR);
  43. }
  44. $key = md5($trendType.$const.serialize($yValues).serialize($xValues));
  45. // Determine which trend method has been requested
  46. switch ($trendType) {
  47. // Instantiate and return the class for the requested trend method
  48. case self::TREND_LINEAR :
  49. case self::TREND_LOGARITHMIC :
  50. case self::TREND_EXPONENTIAL :
  51. case self::TREND_POWER :
  52. if (!isset(self::$_trendCache[$key])) {
  53. $className = 'PHPExcel_'.$trendType.'_Best_Fit';
  54. self::$_trendCache[$key] = new $className($yValues,$xValues,$const);
  55. }
  56. return self::$_trendCache[$key];
  57. break;
  58. case self::TREND_POLYNOMIAL_2 :
  59. case self::TREND_POLYNOMIAL_3 :
  60. case self::TREND_POLYNOMIAL_4 :
  61. case self::TREND_POLYNOMIAL_5 :
  62. case self::TREND_POLYNOMIAL_6 :
  63. if (!isset(self::$_trendCache[$key])) {
  64. $order = substr($trendType,-1);
  65. self::$_trendCache[$key] = new PHPExcel_Polynomial_Best_Fit($order,$yValues,$xValues,$const);
  66. }
  67. return self::$_trendCache[$key];
  68. break;
  69. case self::TREND_BEST_FIT :
  70. case self::TREND_BEST_FIT_NO_POLY :
  71. // If the request is to determine the best fit regression, then we test each trend line in turn
  72. // Start by generating an instance of each available trend method
  73. foreach(self::$_trendTypes as $trendMethod) {
  74. $className = 'PHPExcel_'.$trendMethod.'BestFit';
  75. $bestFit[$trendMethod] = new $className($yValues,$xValues,$const);
  76. $bestFitValue[$trendMethod] = $bestFit[$trendMethod]->getGoodnessOfFit();
  77. }
  78. if ($trendType != self::TREND_BEST_FIT_NO_POLY) {
  79. foreach(self::$_trendTypePolyOrders as $trendMethod) {
  80. $order = substr($trendMethod,-1);
  81. $bestFit[$trendMethod] = new PHPExcel_Polynomial_Best_Fit($order,$yValues,$xValues,$const);
  82. if ($bestFit[$trendMethod]->getError()) {
  83. unset($bestFit[$trendMethod]);
  84. } else {
  85. $bestFitValue[$trendMethod] = $bestFit[$trendMethod]->getGoodnessOfFit();
  86. }
  87. }
  88. }
  89. // Determine which of our trend lines is the best fit, and then we return the instance of that trend class
  90. arsort($bestFitValue);
  91. $bestFitType = key($bestFitValue);
  92. return $bestFit[$bestFitType];
  93. break;
  94. default :
  95. return false;
  96. }
  97. } // function calculate()
  98. } // class trendClass