trendClass.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. <?php
  2. /**
  3. * PHPExcel
  4. *
  5. * Copyright (c) 2006 - 2014 PHPExcel
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. *
  21. * @category PHPExcel
  22. * @package PHPExcel_Shared_Trend
  23. * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
  24. * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
  25. * @version 1.8.0, 2014-03-02
  26. */
  27. require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/linearBestFitClass.php';
  28. require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/logarithmicBestFitClass.php';
  29. require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/exponentialBestFitClass.php';
  30. require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/powerBestFitClass.php';
  31. require_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/polynomialBestFitClass.php';
  32. /**
  33. * PHPExcel_trendClass
  34. *
  35. * @category PHPExcel
  36. * @package PHPExcel_Shared_Trend
  37. * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
  38. */
  39. class trendClass
  40. {
  41. const TREND_LINEAR = 'Linear';
  42. const TREND_LOGARITHMIC = 'Logarithmic';
  43. const TREND_EXPONENTIAL = 'Exponential';
  44. const TREND_POWER = 'Power';
  45. const TREND_POLYNOMIAL_2 = 'Polynomial_2';
  46. const TREND_POLYNOMIAL_3 = 'Polynomial_3';
  47. const TREND_POLYNOMIAL_4 = 'Polynomial_4';
  48. const TREND_POLYNOMIAL_5 = 'Polynomial_5';
  49. const TREND_POLYNOMIAL_6 = 'Polynomial_6';
  50. const TREND_BEST_FIT = 'Bestfit';
  51. const TREND_BEST_FIT_NO_POLY = 'Bestfit_no_Polynomials';
  52. /**
  53. * Names of the best-fit trend analysis methods
  54. *
  55. * @var string[]
  56. **/
  57. private static $_trendTypes = array( self::TREND_LINEAR,
  58. self::TREND_LOGARITHMIC,
  59. self::TREND_EXPONENTIAL,
  60. self::TREND_POWER
  61. );
  62. /**
  63. * Names of the best-fit trend polynomial orders
  64. *
  65. * @var string[]
  66. **/
  67. private static $_trendTypePolyOrders = array( self::TREND_POLYNOMIAL_2,
  68. self::TREND_POLYNOMIAL_3,
  69. self::TREND_POLYNOMIAL_4,
  70. self::TREND_POLYNOMIAL_5,
  71. self::TREND_POLYNOMIAL_6
  72. );
  73. /**
  74. * Cached results for each method when trying to identify which provides the best fit
  75. *
  76. * @var PHPExcel_Best_Fit[]
  77. **/
  78. private static $_trendCache = array();
  79. public static function calculate($trendType=self::TREND_BEST_FIT, $yValues, $xValues=array(), $const=True) {
  80. // Calculate number of points in each dataset
  81. $nY = count($yValues);
  82. $nX = count($xValues);
  83. // Define X Values if necessary
  84. if ($nX == 0) {
  85. $xValues = range(1,$nY);
  86. $nX = $nY;
  87. } elseif ($nY != $nX) {
  88. // Ensure both arrays of points are the same size
  89. trigger_error("trend(): Number of elements in coordinate arrays do not match.", E_USER_ERROR);
  90. }
  91. $key = md5($trendType.$const.serialize($yValues).serialize($xValues));
  92. // Determine which trend method has been requested
  93. switch ($trendType) {
  94. // Instantiate and return the class for the requested trend method
  95. case self::TREND_LINEAR :
  96. case self::TREND_LOGARITHMIC :
  97. case self::TREND_EXPONENTIAL :
  98. case self::TREND_POWER :
  99. if (!isset(self::$_trendCache[$key])) {
  100. $className = 'PHPExcel_'.$trendType.'_Best_Fit';
  101. self::$_trendCache[$key] = new $className($yValues,$xValues,$const);
  102. }
  103. return self::$_trendCache[$key];
  104. break;
  105. case self::TREND_POLYNOMIAL_2 :
  106. case self::TREND_POLYNOMIAL_3 :
  107. case self::TREND_POLYNOMIAL_4 :
  108. case self::TREND_POLYNOMIAL_5 :
  109. case self::TREND_POLYNOMIAL_6 :
  110. if (!isset(self::$_trendCache[$key])) {
  111. $order = substr($trendType,-1);
  112. self::$_trendCache[$key] = new PHPExcel_Polynomial_Best_Fit($order,$yValues,$xValues,$const);
  113. }
  114. return self::$_trendCache[$key];
  115. break;
  116. case self::TREND_BEST_FIT :
  117. case self::TREND_BEST_FIT_NO_POLY :
  118. // If the request is to determine the best fit regression, then we test each trend line in turn
  119. // Start by generating an instance of each available trend method
  120. foreach(self::$_trendTypes as $trendMethod) {
  121. $className = 'PHPExcel_'.$trendMethod.'BestFit';
  122. $bestFit[$trendMethod] = new $className($yValues,$xValues,$const);
  123. $bestFitValue[$trendMethod] = $bestFit[$trendMethod]->getGoodnessOfFit();
  124. }
  125. if ($trendType != self::TREND_BEST_FIT_NO_POLY) {
  126. foreach(self::$_trendTypePolyOrders as $trendMethod) {
  127. $order = substr($trendMethod,-1);
  128. $bestFit[$trendMethod] = new PHPExcel_Polynomial_Best_Fit($order,$yValues,$xValues,$const);
  129. if ($bestFit[$trendMethod]->getError()) {
  130. unset($bestFit[$trendMethod]);
  131. } else {
  132. $bestFitValue[$trendMethod] = $bestFit[$trendMethod]->getGoodnessOfFit();
  133. }
  134. }
  135. }
  136. // Determine which of our trend lines is the best fit, and then we return the instance of that trend class
  137. arsort($bestFitValue);
  138. $bestFitType = key($bestFitValue);
  139. return $bestFit[$bestFitType];
  140. break;
  141. default :
  142. return false;
  143. }
  144. } // function calculate()
  145. } // class trendClass