See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401] [Versions 401 and 402] [Versions 401 and 403]
1 <?php 2 3 namespace PhpOffice\PhpSpreadsheet\Shared\Trend; 4 5 class Trend 6 { 7 const TREND_LINEAR = 'Linear'; 8 const TREND_LOGARITHMIC = 'Logarithmic'; 9 const TREND_EXPONENTIAL = 'Exponential'; 10 const TREND_POWER = 'Power'; 11 const TREND_POLYNOMIAL_2 = 'Polynomial_2'; 12 const TREND_POLYNOMIAL_3 = 'Polynomial_3'; 13 const TREND_POLYNOMIAL_4 = 'Polynomial_4'; 14 const TREND_POLYNOMIAL_5 = 'Polynomial_5'; 15 const TREND_POLYNOMIAL_6 = 'Polynomial_6'; 16 const TREND_BEST_FIT = 'Bestfit'; 17 const TREND_BEST_FIT_NO_POLY = 'Bestfit_no_Polynomials'; 18 19 /** 20 * Names of the best-fit Trend analysis methods. 21 * 22 * @var string[] 23 */ 24 private static $trendTypes = [ 25 self::TREND_LINEAR, 26 self::TREND_LOGARITHMIC, 27 self::TREND_EXPONENTIAL, 28 self::TREND_POWER, 29 ]; 30 31 /** 32 * Names of the best-fit Trend polynomial orders. 33 * 34 * @var string[] 35 */ 36 private static $trendTypePolynomialOrders = [ 37 self::TREND_POLYNOMIAL_2, 38 self::TREND_POLYNOMIAL_3, 39 self::TREND_POLYNOMIAL_4, 40 self::TREND_POLYNOMIAL_5, 41 self::TREND_POLYNOMIAL_6, 42 ]; 43 44 /** 45 * Cached results for each method when trying to identify which provides the best fit. 46 * 47 * @var BestFit[] 48 */ 49 private static $trendCache = []; 50 51 public static function calculate($trendType = self::TREND_BEST_FIT, $yValues = [], $xValues = [], $const = true) 52 { 53 // Calculate number of points in each dataset 54 $nY = count($yValues); 55 $nX = count($xValues); 56 57 // Define X Values if necessary 58 if ($nX === 0) { 59 $xValues = range(1, $nY); 60 } elseif ($nY !== $nX) { 61 // Ensure both arrays of points are the same size 62 trigger_error('Trend(): Number of elements in coordinate arrays do not match.', E_USER_ERROR); 63 } 64 65 $key = md5($trendType . $const . serialize($yValues) . serialize($xValues)); 66 // Determine which Trend method has been requested 67 switch ($trendType) { 68 // Instantiate and return the class for the requested Trend method 69 case self::TREND_LINEAR: 70 case self::TREND_LOGARITHMIC: 71 case self::TREND_EXPONENTIAL: 72 case self::TREND_POWER: 73 if (!isset(self::$trendCache[$key])) { 74 $className = '\PhpOffice\PhpSpreadsheet\Shared\Trend\\' . $trendType . 'BestFit'; 75 // @phpstan-ignore-next-line 76 self::$trendCache[$key] = new $className($yValues, $xValues, $const); 77 } 78 79 return self::$trendCache[$key]; 80 case self::TREND_POLYNOMIAL_2: 81 case self::TREND_POLYNOMIAL_3: 82 case self::TREND_POLYNOMIAL_4: 83 case self::TREND_POLYNOMIAL_5: 84 case self::TREND_POLYNOMIAL_6: 85 if (!isset(self::$trendCache[$key])) { 86 $order = (int) substr($trendType, -1); 87 self::$trendCache[$key] = new PolynomialBestFit($order, $yValues, $xValues); 88 } 89 90 return self::$trendCache[$key]; 91 case self::TREND_BEST_FIT: 92 case self::TREND_BEST_FIT_NO_POLY: 93 // If the request is to determine the best fit regression, then we test each Trend line in turn 94 // Start by generating an instance of each available Trend method 95 $bestFit = []; 96 $bestFitValue = []; 97 foreach (self::$trendTypes as $trendMethod) { 98 $className = '\PhpOffice\PhpSpreadsheet\Shared\Trend\\' . $trendType . 'BestFit'; 99 $bestFit[$trendMethod] = new $className($yValues, $xValues, $const); 100 $bestFitValue[$trendMethod] = $bestFit[$trendMethod]->getGoodnessOfFit(); 101 } 102 if ($trendType != self::TREND_BEST_FIT_NO_POLY) { 103 foreach (self::$trendTypePolynomialOrders as $trendMethod) { 104 $order = (int) substr($trendMethod, -1); 105 $bestFit[$trendMethod] = new PolynomialBestFit($order, $yValues, $xValues); 106 if ($bestFit[$trendMethod]->getError()) { 107 unset($bestFit[$trendMethod]); 108 } else { 109 $bestFitValue[$trendMethod] = $bestFit[$trendMethod]->getGoodnessOfFit(); 110 } 111 } 112 } 113 // Determine which of our Trend lines is the best fit, and then we return the instance of that Trend class 114 arsort($bestFitValue); 115 $bestFitType = key($bestFitValue); 116 117 return $bestFit[$bestFitType]; 118 default: 119 return false; 120 } 121 } 122 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body