Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.
<?php

namespace PhpOffice\PhpSpreadsheet\Shared\Trend;

class Trend
{
    const TREND_LINEAR = 'Linear';
    const TREND_LOGARITHMIC = 'Logarithmic';
    const TREND_EXPONENTIAL = 'Exponential';
    const TREND_POWER = 'Power';
    const TREND_POLYNOMIAL_2 = 'Polynomial_2';
    const TREND_POLYNOMIAL_3 = 'Polynomial_3';
    const TREND_POLYNOMIAL_4 = 'Polynomial_4';
    const TREND_POLYNOMIAL_5 = 'Polynomial_5';
    const TREND_POLYNOMIAL_6 = 'Polynomial_6';
    const TREND_BEST_FIT = 'Bestfit';
    const TREND_BEST_FIT_NO_POLY = 'Bestfit_no_Polynomials';

    /**
     * Names of the best-fit Trend analysis methods.
     *
     * @var string[]
     */
    private static $trendTypes = [
        self::TREND_LINEAR,
        self::TREND_LOGARITHMIC,
        self::TREND_EXPONENTIAL,
        self::TREND_POWER,
    ];

    /**
     * Names of the best-fit Trend polynomial orders.
     *
     * @var string[]
     */
    private static $trendTypePolynomialOrders = [
        self::TREND_POLYNOMIAL_2,
        self::TREND_POLYNOMIAL_3,
        self::TREND_POLYNOMIAL_4,
        self::TREND_POLYNOMIAL_5,
        self::TREND_POLYNOMIAL_6,
    ];

    /**
     * Cached results for each method when trying to identify which provides the best fit.
     *
< * @var bestFit[]
> * @var BestFit[]
*/ private static $trendCache = [];
> /** public static function calculate($trendType = self::TREND_BEST_FIT, $yValues = [], $xValues = [], $const = true) > * @param string $trendType { > * @param array $yValues // Calculate number of points in each dataset > * @param array $xValues $nY = count($yValues); > * @param bool $const $nX = count($xValues); > * > * @return mixed // Define X Values if necessary > */
< if ($nX == 0) {
> if ($nX === 0) {
$xValues = range(1, $nY);
< $nX = $nY; < } elseif ($nY != $nX) {
> } elseif ($nY !== $nX) {
// Ensure both arrays of points are the same size trigger_error('Trend(): Number of elements in coordinate arrays do not match.', E_USER_ERROR); } $key = md5($trendType . $const . serialize($yValues) . serialize($xValues)); // Determine which Trend method has been requested switch ($trendType) { // Instantiate and return the class for the requested Trend method case self::TREND_LINEAR: case self::TREND_LOGARITHMIC: case self::TREND_EXPONENTIAL: case self::TREND_POWER: if (!isset(self::$trendCache[$key])) { $className = '\PhpOffice\PhpSpreadsheet\Shared\Trend\\' . $trendType . 'BestFit'; self::$trendCache[$key] = new $className($yValues, $xValues, $const); } return self::$trendCache[$key]; case self::TREND_POLYNOMIAL_2: case self::TREND_POLYNOMIAL_3: case self::TREND_POLYNOMIAL_4: case self::TREND_POLYNOMIAL_5: case self::TREND_POLYNOMIAL_6: if (!isset(self::$trendCache[$key])) {
< $order = substr($trendType, -1); < self::$trendCache[$key] = new PolynomialBestFit($order, $yValues, $xValues, $const);
> $order = (int) substr($trendType, -1); > self::$trendCache[$key] = new PolynomialBestFit($order, $yValues, $xValues);
} return self::$trendCache[$key]; case self::TREND_BEST_FIT: case self::TREND_BEST_FIT_NO_POLY: // If the request is to determine the best fit regression, then we test each Trend line in turn // Start by generating an instance of each available Trend method
> $bestFit = []; foreach (self::$trendTypes as $trendMethod) { > $bestFitValue = [];
$className = '\PhpOffice\PhpSpreadsheet\Shared\Trend\\' . $trendType . 'BestFit';
> //* @phpstan-ignore-next-line
$bestFit[$trendMethod] = new $className($yValues, $xValues, $const);
> //* @phpstan-ignore-next-line
$bestFitValue[$trendMethod] = $bestFit[$trendMethod]->getGoodnessOfFit(); } if ($trendType != self::TREND_BEST_FIT_NO_POLY) { foreach (self::$trendTypePolynomialOrders as $trendMethod) {
< $order = substr($trendMethod, -1); < $bestFit[$trendMethod] = new PolynomialBestFit($order, $yValues, $xValues, $const);
> $order = (int) substr($trendMethod, -1); > $bestFit[$trendMethod] = new PolynomialBestFit($order, $yValues, $xValues);
if ($bestFit[$trendMethod]->getError()) { unset($bestFit[$trendMethod]); } else { $bestFitValue[$trendMethod] = $bestFit[$trendMethod]->getGoodnessOfFit(); } } } // Determine which of our Trend lines is the best fit, and then we return the instance of that Trend class arsort($bestFitValue); $bestFitType = key($bestFitValue); return $bestFit[$bestFitType]; default: return false; } } }