* * @since 1.0.0 */ public static function getForecastInteval(float $forecast, float $standardDeviation, float $interval = 1.96) : array { return [$forecast - $interval * $standardDeviation, $forecast + $interval * $standardDeviation]; } /** * Simple seasonal forecast. * * @param array $history History * @param int $periods Number of periods to forecast * @param int $seasonality Seasonality * * @return array * * @since 1.0.0 */ public static function simpleSeasonalForecast(array $history, int $periods, int $seasonality = 1) : array { $size = \count($history); $avg = \array_sum($history) / $size; $variance = 0; foreach ($history as $sale) { $variance += \pow($sale - $avg, 2); } $variance /= $size; $stdDeviation = \sqrt($variance); // Calculate the seasonal index for each period $seasonalIndex = []; for ($i = 0; $i < $seasonality; ++$i) { $seasonalIndex[$i] = 0; $count = 0; for ($j = $i; $j < $size; $j += $seasonality) { $seasonalIndex[$i] += $history[$j]; ++$count; } if ($count > 0) { $seasonalIndex[$i] /= $count; $seasonalIndex[$i] /= $avg; } } // Forecast the next periods $forecast = []; for ($i = 1; $i <= $periods; ++$i) { $seasonalMultiplier = $seasonalIndex[($i - 1) % $seasonality]; $forecast[] = $avg * $seasonalMultiplier + ($stdDeviation * $i); } return $forecast; } }