For God so loved the world, that He gave His only begotten Son, that all who believe in Him should not perish but have everlasting life
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

147 lines
6.1 KiB

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