Skip to content
Time Series

time-series-ai999x

Moving averages, exponential smoothing, autocorrelation, ARIMA basics, stationarity tests, change points, forecasting accuracy and Kalman filtering.

77capabilities
14topics
77formulas typeset
8worked examples below
1.0.0version
About this model

What Time Series does

Time Series (time-series-ai999x) is an offline Python package for time series. It covers moving averages, exponential smoothing, autocorrelation, ARIMA basics, stationarity tests, change points, forecasting accuracy and Kalman filtering.

It has 77 capabilities — 77 computational procedures — in 14 topics, the largest being ARMA theory, Exponential smoothing, ARIMA models, Forecast accuracy, Kalman filtering and Trend fitting. Ask a question in words with ask(), or call a capability by name with typed inputs with solve(). Every answer carries its value and unit, the steps that produced it and the formula in LaTeX.

When a question is not determined — a value is missing, an input is out of range, or the request is outside the package — it says so and names what it needs, instead of guessing. It runs on an ordinary CPU without a network connection (Python >=3.10), and the same question always gets the same answer.

Install

pip install time-series-ai999x
hf download AI999X/time-series-ai999x --local-dir time-series-ai999x

What it covers

ARIMA models7AR(1) forecast towards the mean · AR(p) estimation by conditional least squares · AR(p) estimation by Yule-Walker …ARMA theory13h-step forecast error variance of an ARMA model · Invertibility of an MA(2) process · Mean, variance and autocorrelation of an AR(1) process …Autocorrelation6Bartlett standard error of a sample autocorrelation · Box-Pierce test · Ljung-Box test …Change points5CUSUM estimate of a change point · Multiple change points with a penalty (PELT) · Single change point in the mean (least squares) …Classical decomposition4Seasonal indices (additive decomposition) · Seasonal indices (multiplicative decomposition) · Seasonally adjusted series (additive) …Cross-correlation2Lag of the strongest cross-correlation · Sample cross-correlation at lag kExponential smoothing8Best smoothing constant among candidates · Damped-trend Holt method · Exponential smoothing forecast update …Forecast accuracy7Mean absolute error · Mean absolute percentage error · Mean absolute scaled error …Interpolation of missing values2Exponential (log-linear) interpolation · Linear interpolation of a missing valueKalman filtering7Kalman filter for a constant-velocity model · Kalman filter for a random-walk (local level) model · Kalman measurement update (scalar) …Moving averages4Centred moving average · Exponential moving average · Linearly weighted moving average …Stationarity tests3Augmented Dickey-Fuller statistic · Dickey-Fuller unit-root statistic · KPSS stationarity statisticTransformations and growth2Compound average growth rate of a series · Regular and seasonal differencingTrend fitting7Exponential trend fit and forecast · Linear trend fit and forecast · Linear trend with seasonal dummy variables …
Try it

Worked examples

Each question below was put to time-series-ai999x and the answer shown is the one it returned, with the steps it took.

Moving averagesm.ask(…)

Find the 3-period simple moving average of [10, 12, 14, 13, 15].

sma = [12, 13, 14]
last = 14
count = 3
Show the steps
  1. Simple moving average
    \mathrm{SMA}_t = \frac{1}{k}\sum_{i=0}^{k-1} x_{t-i}
    with x = [10, 12, 14, 13, 15], k = 3
    → sma = [12, 13, 14], last = 14, count = 3
Exponential smoothingm.ask(…)

Apply Holt's linear trend method with alpha = 0.5 and beta = 0.3 to [10, 12, 15, 16, 19, 21].

forecast = 22.65328591
level = 20.65533969
trend = 1.997946219
sse = 7.492761855
Show the steps
  1. Holt's linear trend method
    \ell_t=\alpha x_t+(1-\alpha)(\ell_{t-1}+b_{t-1}),\ b_t=\beta(\ell_t-\ell_{t-1})+(1-\beta)b_{t-1},\ \hat x_{n+h}=\ell_n+h\,b_n
    with x = [10, 12, 15, 16, 19, 21], alpha = 0.5, beta = 0.3
    → forecast = 22.65328591, level = 20.65533969, trend = 1.997946219, sse = 7.492761855
Autocorrelationm.ask(…)

Perform the Ljung-Box test with 3 lags on [4, 6, 5, 8, 7, 9, 8, 10, 9, 12, 11, 13].

q = 9.319101598
p_value = 0.0253357685
df = 3
Show the steps
  1. Ljung-Box test
    Q_{LB} = n(n+2)\sum_{k=1}^{h}\frac{r_k^2}{n-k}
    with x = [4, 6, 5, 8, 7, 9, 8, 10, 9, 12, 11, 13], h = 3
    → q = 9.319101598, p_value = 0.0253357685, df = 3
Capability: Ljung-Box test
Forecast accuracym.ask(…)

Find the MAPE for actual values [10, 12, 14, 13] and forecasts [11, 12, 13, 15].

mape = 8.131868132
n = 4
Show the steps
  1. Mean absolute percentage error
    \mathrm{MAPE} = \frac{100}{n}\sum_{t=1}^{n}\left|\frac{y_t - f_t}{y_t}\right|
    with y = [10, 12, 14, 13], f = [11, 12, 13, 15]
    → mape = 8.131868132, n = 4
Kalman filteringm.solve(…)
m.solve("kalman_filter_local_level", x="10.4, 11.1, 10.7, 11.9, 12.3", q=0.5, r=2, m0=10, p0=5)
estimate = 11.62410315
variance = 0.7906396594
gain = 0.3953198297
estimates = [10.29333333, 10.69327731, 10.69614922, 11.18222422, 11.62410315]
log_likelihood = -8.617118062
Show the steps
  1. Kalman filter for a random-walk (local level) model
    P_t^- = P_{t-1}+q,\ K_t = \frac{P_t^-}{P_t^-+r},\ \hat x_t = \hat x_{t-1} + K_t(z_t - \hat x_{t-1})
    with x = [10.4, 11.1, 10.7, 11.9, 12.3], q = 0.5, r = 2, m0 = 10, p0 = 5
    → estimate = 11.62410315, variance = 0.7906396594, gain = 0.3953198297, estimates = [10.29333333, 10.69327731, 10.69614922, 11.18222422, 11.62410315], log_likelihood = -8.617118062
ARIMA modelsm.ask(…)

Forecast 3 steps ahead for an AR(1) process with mean 50, phi = 0.7 and last value 58.

forecast = 52.744
Show the steps
  1. AR(1) forecast towards the mean
    \hat x_{n+h} = \mu + \phi^h(x_n - \mu),\ \operatorname{Var} = \sigma^2\frac{1-\phi^{2h}}{1-\phi^2}
    with x = 58, phi = 0.7, mu = 50, h = 3
    → forecast = 52.744
ARMA theorym.ask(…)

Find the mean and variance of the AR(1) process with constant 2, phi = 0.6 and sigma2 = 4.

mean = 5
variance = 6.25
acf_k = 0.6
acov_k = 3.75
Show the steps
  1. Mean, variance and autocorrelation of an AR(1) process
    \mu = \frac{c}{1-\phi},\ \gamma_0 = \frac{\sigma^2}{1-\phi^2},\ \rho_k = \phi^k
    with phi = 0.6, sigma2 = 4, c = 2
    → mean = 5, variance = 6.25, acf_k = 0.6, acov_k = 3.75
Change pointsm.ask(…)

Find the change point in the mean of [5, 6, 5, 7, 6, 12, 13, 12, 14].

change_index = 5
mean_before = 5.8
mean_after = 12.75
cost = 5.55
reduction = 107.3388889
Show the steps
  1. Single change point in the mean (least squares)
    \hat k = \arg\min_k\Big[\sum_{t\le k}(x_t-\bar x_{1:k})^2 + \sum_{t>k}(x_t-\bar x_{k+1:n})^2\Big]
    with x = [5, 6, 5, 7, 6, 12, 13, 12, 14]
    → change_index = 5, mean_before = 5.8, mean_after = 12.75, cost = 5.55, reduction = 107.3388889
Use it

From Python or the command line

Every snippet was run as shown; the output under it is what it printed.

import time_series_ai999x as m

a = m.ask("Find the 3-period simple moving average of [10, 12, 14, 13, 15].")
print(a.outcome)
print(a.values)
for step in a.steps:
    print(step["name"])
Output
SOLVED
{'sma': [12.0, 13.0, 14.0], 'last': 14.0, 'count': 3}
Simple moving average
Figures

Computed, not drawn by hand

Every value in these figures was computed by the package, each point a run of solve(); in a notebook, plot() and plot_relation() draw a capability's curves the same way.

Seasonal series and three forecasts

\hat x_{n+h} = \ell_n + h b_n + s_{n+h-m(\lfloor (h-1)/m\rfloor+1)}
Seasonal series and three forecastsA quarterly series of 12 values (30, 21, 29, 31, 40, 30, 39, 41, 50, 39, 48, 51) and three forecasts for the next 8 periods, each step computed by the package: Holt–Winters additive and multiplicative (m = 4, α = 0.5, β = 0.3, γ = 0.2) and a linear trend with seasonal effects; 8-step forecasts 67.8788, 68.1074 and 69.875.05101520204060forecasthistoryHolt–Winters additiveHolt–Winters multiplicativetrend + seasonal regressiont — periodx
A quarterly series of 12 values (30, 21, 29, 31, 40, 30, 39, 41, 50, 39, 48, 51) and three forecasts for the next 8 periods, each step computed by the package: Holt–Winters additive and multiplicative (m = 4, α = 0.5, β = 0.3, γ = 0.2) and a linear trend with seasonal effects; 8-step forecasts 67.8788, 68.1074 and 69.875.

AR(1) forecast fan reverting to the mean

\hat x_{n+h} = \mu + \phi^h(x_n - \mu),\ \operatorname{Var} = \sigma^2\frac{1-\phi^{2h}}{1-\phi^2}
AR(1) forecast fan reverting to the meanAR(1) forecasts from the last value x = 58 with φ = 0.7, μ = 50 and innovation variance σ² = 4, 1 to 12 steps ahead, with the 95 % interval the package returns at each step (it widens to [44.6223, 55.5992] at h = 12); marked: h = 3, forecast = 52.744.051045505560mean μ = 5052.74495 % intervalforecastlast valueh — steps aheadforecast
AR(1) forecasts from the last value x = 58 with φ = 0.7, μ = 50 and innovation variance σ² = 4, 1 to 12 steps ahead, with the 95 % interval the package returns at each step (it widens to [44.6223, 55.5992] at h = 12); marked: h = 3, forecast = 52.744.

Autocorrelation function with its significance band

r_k = \frac{\sum_{t=1}^{n-k}(x_t-\bar x)(x_{t+k}-\bar x)}{\sum_{t=1}^{n}(x_t-\bar x)^2}
Autocorrelation function with its significance bandSample autocorrelations of the series 30, 21, 29, 31, 40, 30, 39, 41, 50, 39, 48, 51 at lags 1 to 6 (0.512567, 0.361929, 0.190263, 0.157039, -0.138822, -0.267831) and the 95 % band ±0.565793 … ±0.789621 from Bartlett's standard errors, all returned by the package.246-0.500.595 % band (Bartlett)sample autocorrelationk — lagautocorrelation
Sample autocorrelations of the series 30, 21, 29, 31, 40, 30, 39, 41, 50, 39, 48, 51 at lags 1 to 6 (0.512567, 0.361929, 0.190263, 0.157039, -0.138822, -0.267831) and the 95 % band ±0.565793 … ±0.789621 from Bartlett's standard errors, all returned by the package.

Kalman filter and smoother against noisy observations

P_t^- = P_{t-1}+q,\ K_t = \frac{P_t^-}{P_t^-+r},\ \hat x_t = \hat x_{t-1} + K_t(z_t - \hat x_{t-1})
Kalman filter and smoother against noisy observationsA local-level model (state noise q = 0.5, observation noise r = 2, start m₀ = 10, p₀ = 5) run by the package on 12 observations: the filtered level after each observation and the smoothed level from the backward pass; marked: t = 12, filtered level = 13.8669 (variance 0.780786, gain 0.390393).2.557.51012.5101112131413.8669observationsKalman filtersmoother (backward pass)t — time steplevel
A local-level model (state noise q = 0.5, observation noise r = 2, start m₀ = 10, p₀ = 5) run by the package on 12 observations: the filtered level after each observation and the smoothed level from the backward pass; marked: t = 12, filtered level = 13.8669 (variance 0.780786, gain 0.390393).

Two change points and the segment means

\min_{i<j}\ \mathrm{SS}(1{:}i)+\mathrm{SS}(i{+}1{:}j)+\mathrm{SS}(j{+}1{:}n)
Two change points and the segment meansThe two change points the package finds in x = 5, 6, 5, 12, 13, 12, 20, 21, 19: after observations 3 and 6, splitting the series into segments with means 5.33333, 12.3333, 20 (total squared error 3.33333).02.557.5105101520segment meansdatat — indexx
The two change points the package finds in x = 5, 6, 5, 12, 13, 12, 20, 21, 19: after observations 3 and 6, splitting the series into segments with means 5.33333, 12.3333, 20 (total squared error 3.33333).

Where an AR(2) model is stationary

z^2 - \phi_1 z - \phi_2 = 0,\quad \text{stationary} \iff \max|z_i| < 1
Where an AR(2) model is stationaryWhich AR(2) models x_t = φ₁x_(t−1) + φ₂x_(t−2) + e_t are stationary: the package's verdict at 1025 points of the (φ₁, φ₂) plane — stationary with real roots (120 points), stationary with complex roots, i.e. damped oscillation (223), or not stationary (682); together they trace the stationarity triangle. Marked: φ₁ = 0.5, φ₂ = 0.3, real roots, largest modulus 0.85208.-2-1012-101max |root| 0.8521not stationarystationary, real rootsstationary, complex rootsφ₁φ₂
Which AR(2) models x_t = φ₁x_(t−1) + φ₂x_(t−2) + e_t are stationary: the package's verdict at 1025 points of the (φ₁, φ₂) plane — stationary with real roots (120 points), stationary with complex roots, i.e. damped oscillation (223), or not stationary (682); together they trace the stationarity triangle. Marked: φ₁ = 0.5, φ₂ = 0.3, real roots, largest modulus 0.85208.
Formulas

The mathematics inside

12 of its 77 formulas; every one is in the capability browser below.

Simple moving average
\mathrm{SMA}_t = \frac{1}{k}\sum_{i=0}^{k-1} x_{t-i}
Holt's linear trend method
\ell_t=\alpha x_t+(1-\alpha)(\ell_{t-1}+b_{t-1}),\ b_t=\beta(\ell_t-\ell_{t-1})+(1-\beta)b_{t-1},\ \hat x_{n+h}=\ell_n+h\,b_n
Ljung-Box test
Q_{LB} = n(n+2)\sum_{k=1}^{h}\frac{r_k^2}{n-k}
Mean absolute percentage error
\mathrm{MAPE} = \frac{100}{n}\sum_{t=1}^{n}\left|\frac{y_t - f_t}{y_t}\right|
Kalman filter for a random-walk (local level) model
P_t^- = P_{t-1}+q,\ K_t = \frac{P_t^-}{P_t^-+r},\ \hat x_t = \hat x_{t-1} + K_t(z_t - \hat x_{t-1})
AR(1) forecast towards the mean
\hat x_{n+h} = \mu + \phi^h(x_n - \mu),\ \operatorname{Var} = \sigma^2\frac{1-\phi^{2h}}{1-\phi^2}
Mean, variance and autocorrelation of an AR(1) process
\mu = \frac{c}{1-\phi},\ \gamma_0 = \frac{\sigma^2}{1-\phi^2},\ \rho_k = \phi^k
Single change point in the mean (least squares)
\hat k = \arg\min_k\Big[\sum_{t\le k}(x_t-\bar x_{1:k})^2 + \sum_{t>k}(x_t-\bar x_{k+1:n})^2\Big]
AR(p) estimation by conditional least squares
\min_{c,\phi}\sum_{t=p+1}^{n}\Big(x_t - c - \sum_{j=1}^{p}\phi_j x_{t-j}\Big)^2
h-step forecast error variance of an ARMA model
\operatorname{Var}(e_n(h)) = \sigma^2\sum_{j=0}^{h-1}\psi_j^2
Bartlett standard error of a sample autocorrelation
\mathrm{se}(r_k) = \sqrt{\frac{1 + 2\sum_{j=1}^{k-1} r_j^2}{n}}
CUSUM estimate of a change point
S_k = \sum_{t=1}^{k}(x_t - \bar x),\quad \hat k = \arg\max_k |S_k|
Capabilities

Every capability, with an example

Search by name, formula, input or topic. Each capability opens to show what it takes, what it returns, when it applies, and a question it answered.

77 capabilities

ARIMA models 7

AR(1) forecast towards the meanar1_forecast

The h-step forecast mu + phi^h (x_n - mu) of a stationary AR(1) with mean mu, and (when the innovation variance is given) its forecast error variance and 95 % prediction interval.

\hat x_{n+h} = \mu + \phi^h(x_n - \mu),\ \operatorname{Var} = \sigma^2\frac{1-\phi^{2h}}{1-\phi^2}

Inputs

  • x the last observed value x_n
  • phi AR coefficient, |phi| < 1
  • mu the process mean
  • h forecast horizon (default 1) integer optional
  • sigma2 innovation variance (optional, for the interval) optional

Returns

  • forecast mu + phi^h (x_n - mu)
  • variance sigma^2 (1 - phi^(2h)) / (1 - phi^2)
  • lower lower 95 % limit
  • upper upper 95 % limit

Applies when

  • |phi| < 1
  • known parameters
  • normal innovations for the interval

Example

m.ask("Forecast 3 steps ahead for an AR(1) process with mean 50, phi = 0.7 and last value 58.")
→ forecast = 52.744
AR(p) estimation by conditional least squaresar_least_squares

Fit x_t = c + phi_1 x_{t-1} + ... + phi_p x_{t-p} + e_t by ordinary least squares on t = p+1..n; the innovation variance is the residual sum of squares divided by n - p.

\min_{c,\phi}\sum_{t=p+1}^{n}\Big(x_t - c - \sum_{j=1}^{p}\phi_j x_{t-j}\Big)^2

Inputs

  • x the series, oldest first vector
  • p the AR order p integer

Returns

  • const the constant c
  • phi the coefficients phi_1..phi_p
  • phi1 phi_1
  • sigma2 residual sum of squares / (n - p)

Applies when

  • n - p > p + 2
  • regressors not collinear
  • the first p values are conditioned on

Example

m.ask("Fit an AR(1) model by least squares to [4, 6, 5, 8, 7, 9, 8, 10, 9, 12].")
→ const = 3.5625, phi = [0.6354166666666665], phi1 = 0.635417, sigma2 = 2.51505
AR(p) estimation by Yule-Walkerar_yule_walker

Estimate the coefficients phi_1..phi_p and the innovation variance of an AR(p) model from data by the Yule-Walker equations (sample autocovariances divided by n, mean removed).

\begin{pmatrix}1&r_1&\cdots\\ r_1&1&\cdots\\ \vdots&&\ddots\end{pmatrix}\phi = \begin{pmatrix}r_1\\ \vdots\\ r_p\end{pmatrix}

Inputs

  • x the series, oldest first vector
  • p the AR order p integer

Returns

  • phi the coefficients phi_1..phi_p
  • phi1 phi_1
  • sigma2 the innovation variance c_0 (1 - sum phi_j r_j)

Applies when

  • the series is not constant
  • 1 <= p < n - 1
  • denominator n

Example

m.ask("Estimate an AR(2) model by Yule-Walker for the series [4, 6, 5, 8, 7, 9, 8, 10, 9, 12].")
→ phi = [0.21521751734534134, 0.40165819531144314], phi1 = 0.215218, sigma2 = 3.76766
Forecasts of an AR(p) modelar_forecast

h-step forecasts of x_t = c + phi_1 x_{t-1} + ... + phi_p x_{t-p} + e_t from the last p observations (future shocks set to 0).

\hat x_{n+j} = c + \sum_{i=1}^{p}\phi_i\,\hat x_{n+j-i}

Inputs

  • x the series, oldest first (at least p values) vector
  • phi the coefficients phi_1..phi_p vector
  • c the constant c (default 0) optional
  • h forecast horizon (default 1) integer optional

Returns

  • forecasts the forecasts for steps 1..h
  • forecast the h-step forecast

Applies when

  • phi_1 multiplies the latest observation

Example

m.ask("Forecast 3 steps ahead with the AR(2) model with coefficients [0.5, 0.2] and constant 1 from the series [10, 11, 12].")
→ forecasts = [9.2, 8.0, 6.84], forecast = 6.84
Forecasts of an ARIMA(p,1,0) modelarima_p10_forecast

h-step forecasts of an ARIMA(p,1,0) model without constant: the differences follow a stationary AR(p); forecast differences are accumulated onto the last observation.

(1-\phi_1L-\dots-\phi_pL^p)(1-L)x_t = e_t

Inputs

  • x the series, oldest first (at least p + 2 values) vector
  • phi AR coefficients of the differences vector
  • h forecast horizon (default 1) integer optional

Returns

  • forecasts the forecasts for steps 1..h
  • forecast the h-step forecast

Applies when

  • stationary AR part
  • no constant (no drift)
  • n >= p + 2

Example

m.ask("Forecast 3 steps ahead with an ARIMA(1,1,0) model with coefficients [0.4] for the series [100, 102, 105, 104, 108].")
→ forecasts = [109.6, 110.24, 110.496], forecast = 110.496
Partial autocorrelations from autocorrelationspartial_autocorrelations_from_autocorrelations

The partial autocorrelations phi_11..phi_pp implied by autocorrelations rho_1..rho_p (Durbin-Levinson).

\phi_{kk} = \frac{\rho_k-\sum_{j=1}^{k-1}\phi_{k-1,j}\rho_{k-j}}{1-\sum_{j=1}^{k-1}\phi_{k-1,j}\rho_j}

Inputs

  • rho the autocorrelations rho_1..rho_p vector

Returns

  • pacf partial autocorrelations at lags 1..p
  • last phi_pp

Applies when

  • the autocorrelations form a positive definite sequence

Example

m.ask("Find the partial autocorrelations from the autocorrelations [0.6, 0.3, 0.1].")
→ pacf = [0.6, -0.09375, -0.06403940886699507], last = -0.0640394
Yule-Walker equations from autocorrelationsyule_walker_from_autocorrelations

Solve the Yule-Walker equations for the AR(p) coefficients given the autocorrelations rho_1..rho_p, and the ratio of the innovation variance to the process variance.

\rho_k = \sum_{j=1}^{p}\phi_j\,\rho_{|k-j|},\ k = 1..p

Inputs

  • rho the autocorrelations rho_1..rho_p vector

Returns

  • phi the AR coefficients phi_1..phi_p
  • phi1 phi_1
  • variance_ratio sigma^2 / gamma_0 = 1 - sum phi_j rho_j

Applies when

  • the autocorrelations form a positive definite sequence

Example

m.ask("Solve the Yule-Walker equations for the autocorrelations [0.6, 0.2].")
→ phi = [0.75, -0.24999999999999994], phi1 = 0.75, variance_ratio = 0.6

ARMA theory 13

h-step forecast error variance of an ARMA modelforecast_error_variance

The variance (and standard deviation) of the h-step-ahead forecast error of a stationary ARMA(p,q) with known parameters: sigma^2 (psi_0^2 + ... + psi_{h-1}^2).

\operatorname{Var}(e_n(h)) = \sigma^2\sum_{j=0}^{h-1}\psi_j^2

Inputs

  • phi AR coefficients ([0] for none) vector
  • theta MA coefficients ([0] for none) vector
  • sigma2 innovation variance sigma^2
  • h forecast horizon integer

Returns

  • variance forecast error variance
  • sd forecast error standard deviation

Applies when

  • stationary AR part
  • known parameters (no estimation error)

Example

m.ask("Find the 3-step forecast error variance of the ARMA(1,1) model with phi = [0.5], theta = [0.3] and sigma2 = 2.")
→ variance = 3.6, sd = 1.89737
Invertibility of an MA(2) processma2_invertibility

Whether x_t = e_t + theta1 e_{t-1} + theta2 e_{t-2} is invertible: the largest modulus of the inverse roots (roots of z^2 + theta1 z + theta2) must be below 1.

z^2 + \theta_1 z + \theta_2 = 0,\quad \text{invertible} \iff \max|z_i| < 1

Inputs

  • theta1 theta_1
  • theta2 theta_2

Returns

  • invertible yes or no
  • max_modulus largest modulus of the inverse roots
  • roots real or complex

Applies when

  • plus-sign MA convention
  • a modulus of exactly 1 counts as not invertible

Example

m.ask("Is the MA(2) process with theta1 = 0.5 and theta2 = 0.3 invertible?")
→ invertible = yes, max_modulus = 0.547723, roots = complex
Mean, variance and autocorrelation of an AR(1) processar1_properties

For a stationary AR(1) x_t = c + phi x_{t-1} + e_t: the mean c/(1 - phi), the variance sigma^2/(1 - phi^2), and the lag-k autocorrelation phi^k and autocovariance.

\mu = \frac{c}{1-\phi},\ \gamma_0 = \frac{\sigma^2}{1-\phi^2},\ \rho_k = \phi^k

Inputs

  • phi AR coefficient, |phi| < 1
  • sigma2 innovation variance sigma^2
  • k the lag k (default 1) integer optional
  • c the constant c (default 0) optional

Returns

  • mean c / (1 - phi)
  • variance sigma^2 / (1 - phi^2)
  • acf_k phi^k
  • acov_k variance x phi^k

Applies when

  • |phi| < 1
  • sigma^2 > 0

Example

m.ask("Find the mean and variance of the AR(1) process with constant 2, phi = 0.6 and sigma2 = 4.")
→ mean = 5, variance = 6.25, acf_k = 0.6, acov_k = 3.75
Pi weights (AR-infinity representation) of an ARMA processpi_weights

The weights pi_1..pi_K of x_t = sum_{j>=1} pi_j x_{t-j} + e_t for an invertible ARMA(p,q).

\pi(L) = 1 - \sum_{j\ge1}\pi_j L^j = \frac{\phi(L)}{\theta(L)}

Inputs

  • phi AR coefficients ([0] for none) vector
  • theta MA coefficients ([0] for none), invertible vector
  • K number of weights (default 10) integer optional

Returns

  • pi pi_1..pi_K
  • pi1 pi_1 = phi_1 + theta_1

Applies when

  • invertible MA part
  • stationary AR part
  • plus-sign MA convention

Example

m.ask("Find the first 5 pi weights of the ARMA(1,1) process with phi = [0.5] and theta = [0.3].")
→ pi = [0.8, -0.24, 0.072, -0.021599999999999998, 0.006479999999999999], pi1 = 0.8
Psi weights (MA-infinity representation) of an ARMA processpsi_weights

The weights psi_1..psi_K of x_t = sum_{j>=0} psi_j e_{t-j} (psi_0 = 1) for a stationary ARMA(p,q); they are also the impulse response.

\psi_j = \theta_j + \sum_{i=1}^{\min(j,p)}\phi_i\,\psi_{j-i},\ \psi_0 = 1

Inputs

  • phi AR coefficients ([0] for none) vector
  • theta MA coefficients ([0] for none) vector
  • K number of weights (default 10) integer optional

Returns

  • psi psi_1..psi_K
  • psi1 psi_1 = phi_1 + theta_1

Applies when

  • stationary AR part
  • plus-sign MA convention

Example

m.ask("Find the first 5 psi weights of the ARMA(1,1) process with phi = [0.5] and theta = [0.3].")
→ psi = [0.8, 0.4, 0.2, 0.1, 0.05], psi1 = 0.8
Stationarity of an AR(2) processar2_stationarity

Whether x_t = phi1 x_{t-1} + phi2 x_{t-2} + e_t is stationary: the largest modulus of the inverse characteristic roots (roots of z^2 - phi1 z - phi2) must be below 1.

z^2 - \phi_1 z - \phi_2 = 0,\quad \text{stationary} \iff \max|z_i| < 1

Inputs

  • phi1 phi_1
  • phi2 phi_2

Returns

  • stationary yes or no
  • max_modulus largest modulus of the inverse roots
  • roots real or complex

Applies when

  • a modulus of exactly 1 (unit root) counts as not stationary

Example

m.ask("Is the AR(2) process with phi1 = 0.5 and phi2 = 0.3 stationary?")
→ stationary = yes, max_modulus = 0.85208, roots = real
Theoretical autocorrelations of an AR(2) processar2_theoretical_acf

The autocorrelations rho_1..rho_K of a stationary AR(2) process from the Yule-Walker recursion rho_1 = phi1/(1 - phi2), rho_k = phi1 rho_{k-1} + phi2 rho_{k-2}.

\rho_1 = \frac{\phi_1}{1-\phi_2},\ \rho_k = \phi_1\rho_{k-1} + \phi_2\rho_{k-2}

Inputs

  • phi1 phi_1
  • phi2 phi_2
  • K number of lags (default 5) integer optional

Returns

  • acf rho_1..rho_K
  • rho1 rho_1

Applies when

  • stationary AR(2)

Example

m.ask("Find the autocorrelations of the AR(2) process with phi1 = 0.5 and phi2 = 0.3.")
→ acf = [0.7142857142857143, 0.6571428571428571, 0.5428571428571428, 0.4685714285714285, 0.39714285714285713], rho1 = 0.714286
Theoretical autocorrelations of an ARMA(1,1) processarma11_theoretical_acf

The autocorrelations rho_1..rho_K of x_t = phi x_{t-1} + e_t + theta e_{t-1}.

\rho_1 = \frac{(1+\phi\theta)(\phi+\theta)}{1+2\phi\theta+\theta^2},\ \rho_k = \phi\,\rho_{k-1}

Inputs

  • phi AR coefficient, |phi| < 1
  • theta MA coefficient (plus-sign convention)
  • K number of lags (default 5) integer optional

Returns

  • acf rho_1..rho_K
  • rho1 rho_1

Applies when

  • |phi| < 1
  • x_t = phi x_{t-1} + e_t + theta e_{t-1}

Example

m.ask("Find the autocorrelations of the ARMA(1,1) process with phi = 0.6 and theta = 0.3.")
→ acf = [0.7324137931034482, 0.4394482758620689, 0.26366896551724134, 0.1582013793103448, 0.09492082758620689], rho1 = 0.732414
Theoretical autocorrelations of an ARMA(p,q) processarma_theoretical_acf

The autocorrelations rho_1..rho_K of a stationary ARMA(p,q) process x_t = sum phi_i x_{t-i} + e_t + sum theta_j e_{t-j}.

\gamma_k - \sum_{i=1}^{p}\phi_i\gamma_{k-i} = \sigma^2\sum_{j=k}^{q}\theta_j\psi_{j-k}

Inputs

  • phi AR coefficients phi_1..phi_p (stationary; [0] for none) vector
  • theta MA coefficients theta_1..theta_q ([0] for none) vector
  • K number of lags (default 5) integer optional

Returns

  • acf rho_1..rho_K
  • rho1 rho_1

Applies when

  • stationary AR part
  • plus-sign MA convention

Example

m.ask("Find the autocorrelations of the ARMA(2,1) process with phi = [0.5, 0.2] and theta = [0.4].")
→ acf = [0.8012048192771084, 0.6006024096385542, 0.46054216867469877, 0.35039156626506024, 0.2673042168674699], rho1 = 0.801205
Theoretical autocorrelations of an MA(q) processma_theoretical_acf

The autocorrelations rho_1..rho_K of x_t = e_t + theta_1 e_{t-1} + ... + theta_q e_{t-q}; they vanish beyond lag q.

\rho_k = \frac{\theta_k + \sum_{j=1}^{q-k}\theta_j\theta_{j+k}}{1+\sum_{j=1}^{q}\theta_j^2}

Inputs

  • theta the MA coefficients theta_1..theta_q (plus-sign convention) vector
  • K number of lags (default q + 1) integer optional

Returns

  • acf rho_1..rho_K
  • rho1 rho_1

Applies when

  • x_t = e_t + sum theta_j e_{t-j} (plus signs)

Example

m.ask("Find the autocorrelations of the MA(2) process with theta = [0.5, 0.3].")
→ acf = [0.48507462686567165, 0.22388059701492535, 0.0], rho1 = 0.485075
Theoretical partial autocorrelations of an ARMA(p,q) processarma_theoretical_pacf

The partial autocorrelations phi_11..phi_KK of a stationary ARMA(p,q) process (Durbin-Levinson on its exact autocorrelations).

\phi_{kk} = \frac{\rho_k-\sum_{j=1}^{k-1}\phi_{k-1,j}\rho_{k-j}}{1-\sum_{j=1}^{k-1}\phi_{k-1,j}\rho_j}

Inputs

  • phi AR coefficients ([0] for none) vector
  • theta MA coefficients ([0] for none) vector
  • K number of lags (default 5) integer optional

Returns

  • pacf phi_11..phi_KK
  • pacf1 phi_11 = rho_1

Applies when

  • stationary AR part
  • plus-sign MA convention

Example

m.ask("Find the partial autocorrelations of the ARMA(1,1) process with phi = [0.5] and theta = [0.4].")
→ pacf = [0.6923076923076924, -0.2556818181818184, 0.1010327795240235, -0.04033486904612524, 0.016128951324258605], pacf1 = 0.692308
Theoretical partial autocorrelations of an MA(1) processma1_theoretical_pacf

The partial autocorrelations phi_11..phi_KK of x_t = e_t + theta e_{t-1} (they decay, never cut off).

\phi_{kk} = -\frac{(-\theta)^k(1-\theta^2)}{1-\theta^{2(k+1)}}

Inputs

  • theta MA coefficient, |theta| != 1
  • K number of lags (default 5) integer optional

Returns

  • pacf phi_11..phi_KK
  • pacf1 phi_11 = theta/(1 + theta^2)

Applies when

  • |theta| != 1
  • plus-sign MA convention

Example

m.ask("Find the partial autocorrelations of the MA(1) process with theta = 0.6.")
→ pacf = [0.441176470588, -0.241675617615, 0.140601566406, -0.0834485816626, 0.0498749669471], pacf1 = 0.441176
Variance and lag-1 autocovariance of an ARMA(p,q) processarma_variance

The process variance gamma_0 and lag-1 autocovariance gamma_1 of a stationary ARMA(p,q) process with innovation variance sigma^2.

\gamma_0 = \sigma^2\sum_{j\ge0}\psi_j^2

Inputs

  • phi AR coefficients ([0] for none) vector
  • theta MA coefficients ([0] for none) vector
  • sigma2 innovation (white-noise) variance sigma^2

Returns

  • gamma0 the variance of the process
  • gamma1 the lag-1 autocovariance

Applies when

  • stationary AR part
  • sigma^2 > 0

Example

m.ask("Find the variance of the ARMA(1,1) process with phi = [0.5], theta = [0.4] and sigma2 = 2.")
→ gamma0 = 4.16, gamma1 = 2.88

Autocorrelation 6

Bartlett standard error of a sample autocorrelationbartlett_standard_error

Bartlett's standard error of r_k under the hypothesis that the autocorrelations beyond lag k - 1 are zero, and the 95 % band half-width used in correlograms.

\mathrm{se}(r_k) = \sqrt{\frac{1 + 2\sum_{j=1}^{k-1} r_j^2}{n}}

Inputs

  • x the series, oldest first vector
  • k the lag k integer

Returns

  • se Bartlett standard error of r_k
  • half_width_95 1.959964 x se
  • acf the sample autocorrelation r_k

Applies when

  • 1 <= k <= n - 1
  • autocorrelations with denominator n

Example

m.ask("Find the Bartlett standard error of the lag 3 autocorrelation of [4, 6, 5, 8, 7, 9, 8, 10, 9, 12].")
→ se = 0.41446, half_width_95 = 0.812326, acf = -0.0410853
Box-Pierce testbox_pierce_test

The Box-Pierce test portmanteau statistic for no autocorrelation up to lag h and its chi-square p-value (h - model_df degrees of freedom; autocorrelations with denominator n).

Q_{BP} = n\sum_{k=1}^{h} r_k^2

Inputs

  • x the series (or residuals), oldest first vector
  • h the number of lags h integer
  • model_df parameters of a fitted ARMA model subtracted from the degrees of freedom (default 0) integer optional

Returns

  • q the test statistic
  • p_value upper-tail chi-square probability, df = h - model_df
  • df degrees of freedom h - model_df

Applies when

  • 1 <= h <= n - 1
  • model_df < h (default 0: raw series)

Example

m.ask("Perform the Box-Pierce test with 3 lags on [4, 6, 5, 8, 7, 9, 8, 10, 9, 12, 11, 13].")
→ q = 6.9439, p_value = 0.0737077, df = 3
Ljung-Box testljung_box_test

The Ljung-Box test portmanteau statistic for no autocorrelation up to lag h and its chi-square p-value (h - model_df degrees of freedom; autocorrelations with denominator n).

Q_{LB} = n(n+2)\sum_{k=1}^{h}\frac{r_k^2}{n-k}

Inputs

  • x the series (or residuals), oldest first vector
  • h the number of lags h integer
  • model_df parameters of a fitted ARMA model subtracted from the degrees of freedom (default 0) integer optional

Returns

  • q the test statistic
  • p_value upper-tail chi-square probability, df = h - model_df
  • df degrees of freedom h - model_df

Applies when

  • 1 <= h <= n - 1
  • model_df < h (default 0: raw series)

Example

m.ask("Perform the Ljung-Box test with 3 lags on [4, 6, 5, 8, 7, 9, 8, 10, 9, 12, 11, 13].")
→ q = 9.3191, p_value = 0.0253358, df = 3
Sample autocorrelation at lag ksample_autocorrelation

The sample autocorrelation r_k of a series (and r_1..r_k), with autocovariances divided by n and taken about the sample mean.

r_k = \frac{\sum_{t=1}^{n-k}(x_t-\bar x)(x_{t+k}-\bar x)}{\sum_{t=1}^{n}(x_t-\bar x)^2}

Inputs

  • x the series, oldest first vector
  • k the lag k (1 <= k <= n - 1) integer

Returns

  • acf the sample autocorrelation r_k
  • acf_list r_1, ..., r_k

Applies when

  • the series is not constant
  • 1 <= k <= n - 1
  • denominator n (not n - k)

Example

m.ask("Find the lag 1 autocorrelation of [4, 6, 5, 8, 7, 9, 8, 10].")
→ acf = 0.272186, acf_list = [0.2721861471861472]
Sample autocovariance at lag ksample_autocovariance

The sample autocovariance c_k of a series, divided by n and taken about the sample mean.

c_k = \frac1n\sum_{t=1}^{n-k}(x_t-\bar x)(x_{t+k}-\bar x)

Inputs

  • x the series, oldest first vector
  • k the lag k (0 <= k <= n - 1) integer

Returns

  • acov the sample autocovariance c_k
  • gamma0 c_0, the variance divided by n

Applies when

  • 0 <= k <= n - 1
  • denominator n (not n - k)

Example

m.ask("Find the lag 2 autocovariance of [4, 6, 5, 8, 7, 9, 8, 10].")
→ acov = 1.60547, gamma0 = 3.60938
Sample partial autocorrelation at lag ksample_partial_autocorrelation

The sample partial autocorrelation phi_kk of a series (and phi_11..phi_kk) by the Durbin-Levinson recursion on the sample autocorrelations (denominator n).

\phi_{kk} = \frac{r_k - \sum_{j=1}^{k-1}\phi_{k-1,j}\,r_{k-j}}{1-\sum_{j=1}^{k-1}\phi_{k-1,j}\,r_j}

Inputs

  • x the series, oldest first vector
  • k the lag k (1 <= k < n/2) integer

Returns

  • pacf the partial autocorrelation at lag k
  • pacf_list partial autocorrelations at lags 1..k

Applies when

  • the series is not constant
  • 1 <= k < n/2
  • autocovariances divided by n

Example

m.ask("Find the partial autocorrelation at lag 2 of [4, 6, 5, 8, 7, 9, 8, 10, 9, 12].")
→ pacf = 0.401658, pacf_list = [0.3596899224806201, 0.40165819531144314]

Change points 5

CUSUM estimate of a change pointcusum_change_point

The change point estimated by the cumulative sum of deviations from the overall mean, S_k = sum_{t<=k}(x_t - xbar): the k with the largest |S_k|.

S_k = \sum_{t=1}^{k}(x_t - \bar x),\quad \hat k = \arg\max_k |S_k|

Inputs

  • x the series, oldest first vector

Returns

  • change_index k with the largest |S_k| (first segment x_1..x_k)
  • max_cusum max |S_k|
  • mean_before mean of x_1..x_k
  • mean_after mean of x_{k+1}..x_n

Applies when

  • k = 1..n-1
  • ties: the smallest k

Example

m.ask("Estimate the change point with CUSUM for [5, 6, 5, 7, 6, 12, 13, 12, 14].")
→ change_index = 5, max_cusum = 15.4444, mean_before = 5.8, mean_after = 12.75
Multiple change points with a penalty (PELT)penalised_change_points

The segmentation minimising the within-segment sum of squares plus a penalty per change point (optimal partitioning, as found by PELT): the number and positions of the changes in the mean.

\min_{K,\tau}\sum_{i=0}^{K}\mathrm{SS}(\tau_i{+}1{:}\tau_{i+1}) + \beta K

Inputs

  • x the series, oldest first vector
  • penalty penalty per change point (> 0)

Returns

  • n_changes number of change points
  • change_indices ends of all segments but the last
  • cost within-segment sum of squares of the chosen segmentation

Applies when

  • penalty > 0
  • segments of any length >= 1
  • ties: the earlier last change

Example

m.ask("Find the change points with PELT and penalty 10 in [5, 6, 5, 12, 13, 12, 20, 21, 19, 20].")
→ n_changes = 2, change_indices = [3, 6], cost = 3.33333
Single change point in the mean (least squares)change_point_mean_shift

The single change point that minimises the total within-segment sum of squares (a shift in the mean), with the means before and after.

\hat k = \arg\min_k\Big[\sum_{t\le k}(x_t-\bar x_{1:k})^2 + \sum_{t>k}(x_t-\bar x_{k+1:n})^2\Big]

Inputs

  • x the series, oldest first vector
  • min_size minimum segment length (default 2) integer optional

Returns

  • change_index k: the first segment is x_1..x_k
  • mean_before mean of x_1..x_k
  • mean_after mean of x_{k+1}..x_n
  • cost total within-segment sum of squares
  • reduction sum of squares removed by the split

Applies when

  • each segment has at least min_size values
  • ties: the smallest k

Example

m.ask("Find the change point in the mean of [5, 6, 5, 7, 6, 12, 13, 12, 14].")
→ change_index = 5, mean_before = 5.8, mean_after = 12.75, cost = 5.55, reduction = 107.339
Tabular CUSUM control charttabular_cusum

The upper and lower tabular CUSUM statistics for a target mean mu0 with allowance k, and the first time either exceeds the decision interval h.

C_t^+ = \max(0,\,C_{t-1}^+ + x_t - \mu_0 - k),\quad C_t^- = \max(0,\,C_{t-1}^- + \mu_0 - k - x_t)

Inputs

  • x the observations, oldest first vector
  • mu0 target (in-control) mean
  • k allowance (reference value) k >= 0
  • h decision interval h > 0

Returns

  • c_plus final upper CUSUM C+_n
  • c_minus final lower CUSUM C-_n
  • alarm_index first t with C+_t > h or C-_t > h (0 if none)
  • side upper, lower, both or none

Applies when

  • C+_0 = C-_0 = 0
  • an alarm needs a value strictly above h

Example

m.ask("Run a tabular CUSUM with target 10, allowance 0.5 and decision interval 4 on [10.2, 9.8, 10.5, 11.2, 11.8, 12.1, 11.9].")
→ c_plus = 5, c_minus = 0, alarm_index = 7, side = upper
Two change points in the mean (optimal segmentation)two_change_points

The two change points that minimise the total within-segment sum of squares (three mean levels), found by exhaustive dynamic search.

\min_{i<j}\ \mathrm{SS}(1{:}i)+\mathrm{SS}(i{+}1{:}j)+\mathrm{SS}(j{+}1{:}n)

Inputs

  • x the series, oldest first vector
  • min_size minimum segment length (default 2) integer optional

Returns

  • change_1 end of the first segment
  • change_2 end of the second segment
  • means the three segment means
  • cost total within-segment sum of squares

Applies when

  • each segment has at least min_size values
  • ties: the smallest first, then second index

Example

m.ask("Find two change points in the mean of [5, 6, 5, 12, 13, 12, 20, 21, 19].")
→ change_1 = 3, change_2 = 6, means = [5.333333333333333, 12.333333333333334, 20.0], cost = 3.33333

Classical decomposition 4

Seasonal indices (additive decomposition)seasonal_indices_additive

Seasonal indices of classical additive decomposition: detrend by the centred moving average, average each season, normalise the indices to sum to 0.

S_i = \bar d_i - \tfrac1m\sum_j \bar d_j,\quad d_t = x_t-\mathrm{CMA}_t

Inputs

  • x the series, oldest first (at least two full seasons) vector
  • m season length integer

Returns

  • indices the m seasonal indices, starting with the season of x_1
  • first the index of the first observation's season

Applies when

  • n >= 2m
  • trend: centred moving average of length m (2 x m for even m)
  • index i belongs to the season of observation i (the list starts at the first observation's season)

Example

m.ask("Find the additive seasonal indices of the quarterly series [30, 21, 29, 31, 40, 30, 39, 41, 50, 39, 48, 51].")
→ indices = [6.484375, -6.453125, 0.171875, -0.203125], first = 6.48438
Seasonal indices (multiplicative decomposition)seasonal_indices_multiplicative

Seasonal indices of classical multiplicative decomposition: detrend by the centred moving average, average each season, normalise the indices to average 1.

S_i = \bar r_i \Big/ \tfrac1m\sum_j \bar r_j,\quad r_t = x_t/\mathrm{CMA}_t

Inputs

  • x the series, oldest first (at least two full seasons) vector
  • m season length integer

Returns

  • indices the m seasonal indices, starting with the season of x_1
  • first the index of the first observation's season

Applies when

  • n >= 2m
  • trend: centred moving average of length m (2 x m for even m)
  • index i belongs to the season of observation i (the list starts at the first observation's season)
  • positive data

Example

m.ask("Find the multiplicative seasonal indices of the quarterly series [30, 21, 29, 31, 40, 30, 39, 41, 50, 39, 48, 51].")
→ indices = [1.1675854591936505, 0.8390338031104935, 1.002044887955251, 0.9913358497406046], first = 1.16759
Seasonally adjusted series (additive)seasonally_adjusted_additive

The seasonally adjusted series of classical additive decomposition: each value minus its seasonal index.

x_t^{\mathrm{SA}} = x_t - S_{t}

Inputs

  • x the series, oldest first (at least two full seasons) vector
  • m season length integer

Returns

  • adjusted the seasonally adjusted series
  • last the latest adjusted value

Applies when

  • n >= 2m
  • trend: centred moving average of length m (2 x m for even m)
  • index i belongs to the season of observation i (the list starts at the first observation's season)

Example

m.ask("Seasonally adjust the quarterly series [30, 21, 29, 31, 40, 30, 39, 41, 50, 39, 48, 51] using additive decomposition.")
→ adjusted = [23.515625, 27.453125, 28.828125, 31.203125, 33.515625, 36.453125, 38.828125, 41.203125, 43.515625, 45.453125, 47.828125, 51.203125], last = 51.2031
Seasonally adjusted series (multiplicative)seasonally_adjusted_multiplicative

The seasonally adjusted series of classical multiplicative decomposition: each value divided by its seasonal index.

x_t^{\mathrm{SA}} = x_t / S_{t}

Inputs

  • x the series, oldest first (at least two full seasons) vector
  • m season length integer

Returns

  • adjusted the seasonally adjusted series
  • last the latest adjusted value

Applies when

  • n >= 2m
  • trend: centred moving average of length m (2 x m for even m)
  • index i belongs to the season of observation i (the list starts at the first observation's season)
  • positive data

Example

m.ask("Seasonally adjust the quarterly series [30, 21, 29, 31, 40, 30, 39, 41, 50, 39, 48, 51] using multiplicative decomposition.")
→ adjusted = [25.694050712757576, 25.02878897387461, 28.940819267265272, 31.27093608902728, 34.25873428367677, 35.755412819820876, 38.9204121180464, 41.35833482742318, 42.82341785459596, 46.48203666576713, 47.902045683749414, 51.445733565819076], last = 51.4457

Cross-correlation 2

Lag of the strongest cross-correlationcross_correlation_best_lag

The lag k in -K..K with the largest |r_xy(k)|, r_xy(k) = corr(x_{t+k}, y_t): a positive k means y leads x by k periods.

k^* = \arg\max_{|k|\le K}|r_{xy}(k)|

Inputs

  • x the first series vector
  • y the second series (same length) vector
  • K the largest lag searched integer

Returns

  • lag the lag with the largest absolute cross-correlation
  • ccf r_xy at that lag

Applies when

  • equal lengths
  • K <= n - 1
  • ties: the smallest |k|, then the positive k

Example

m.ask("At which lag up to 3 is the cross-correlation strongest between x = [1, 3, 2, 5, 4, 6, 5, 8] and y = [3, 2, 5, 4, 6, 5, 8, 7]?")
→ lag = 1, ccf = 0.713657
Sample cross-correlation at lag kcross_correlation_at_lag

The sample cross-correlation r_xy(k) = corr(x_{t+k}, y_t) of two equally long series (y leads x by k).

r_{xy}(k) = \frac{\frac1n\sum_{t=1}^{n-k}(x_{t+k}-\bar x)(y_t-\bar y)}{s_x s_y}

Inputs

  • x the first series vector
  • y the second series (same length) vector
  • k the lag k >= 0 integer

Returns

  • ccf the cross-correlation r_xy(k)

Applies when

  • equal lengths
  • 0 <= k <= n - 1
  • denominator n, standard deviations with divisor n

Example

m.ask("Compute the cross-correlation at lag 1 between x = [1, 3, 2, 5, 4, 6] and y = [2, 1, 4, 3, 6, 5].")
→ ccf = 0.642857

Exponential smoothing 8

Best smoothing constant among candidatesses_best_alpha

Among candidate smoothing constants, the one whose simple exponential smoothing (l_0 = x_1) gives the smallest sum of squared one-step errors, with that SSE and its forecast.

\alpha^* = \arg\min_{\alpha\in A}\sum_t (x_t - \ell_{t-1}(\alpha))^2

Inputs

  • x the series, oldest first vector
  • alphas candidate smoothing constants, each in (0, 1] vector

Returns

  • alpha the best smoothing constant
  • sse its sum of squared one-step errors
  • forecast its forecast of the next period

Applies when

  • l_0 = x_1
  • ties: the first candidate listed

Example

m.ask("Which smoothing constant among [0.1, 0.3, 0.5] gives the smallest SSE for simple exponential smoothing of [20, 22, 21, 24, 23, 26]?")
→ alpha = 0.5, sse = 23.8125, forecast = 24.375
Damped-trend Holt methodholt_damped_trend

Holt's method with a damped trend (damping parameter phi): the h-step forecast is l_n + (phi + phi^2 + ... + phi^h) b_n. Initial states l_0 = x_1, b_0 = x_2 - x_1 unless stated.

\hat x_{n+h} = \ell_n + (\phi+\phi^2+\dots+\phi^h)\,b_n

Inputs

  • x the series, oldest first vector
  • alpha level smoothing constant, 0 < alpha <= 1
  • beta trend smoothing constant, 0 < beta <= 1 (b_t = beta (l_t - l_{t-1}) + (1 - beta) b_{t-1})
  • phi damping parameter, 0 < phi <= 1
  • l0 initial level l_0 (default x_1) optional
  • b0 initial trend b_0 (default x_2 - x_1) optional
  • h forecast horizon in periods (default 1) integer optional

Returns

  • forecast the h-step-ahead forecast
  • level the final level l_n
  • trend the final trend b_n
  • sse sum of squared one-step errors

Applies when

  • 0 < alpha, beta, phi <= 1
  • l_0 = x_1, b_0 = x_2 - x_1 unless stated

Example

m.ask("Apply Holt's damped trend method with alpha = 0.5, beta = 0.3 and phi = 0.9 to [10, 12, 15, 16, 19, 21].")
→ forecast = 21.6649, level = 20.1927, trend = 1.63569, sse = 13.0169
Exponential smoothing forecast updateexponential_smoothing_update

The next forecast by simple exponential smoothing from the previous forecast, the actual value and the smoothing constant: F_new = F + alpha (A - F).

F_{t+1} = F_t + \alpha\,(A_t - F_t)

Inputs

  • F the previous forecast
  • A the actual value of that period
  • alpha smoothing constant, 0 < alpha <= 1

Returns

  • forecast the new forecast
  • error the forecast error A - F

Applies when

  • 0 < alpha <= 1

Example

m.ask("With exponential smoothing, the previous forecast was 100, the actual value was 110 and alpha = 0.2. What is the new forecast?")
→ forecast = 102, error = 10
Holt's linear trend methodholt_linear_trend

Holt's linear (double) exponential smoothing: level and trend updated each period, h-step forecast l_n + h b_n. Initial states l_0 = x_1 and b_0 = x_2 - x_1 (before the first observation) unless stated.

\ell_t=\alpha x_t+(1-\alpha)(\ell_{t-1}+b_{t-1}),\ b_t=\beta(\ell_t-\ell_{t-1})+(1-\beta)b_{t-1},\ \hat x_{n+h}=\ell_n+h\,b_n

Inputs

  • x the series, oldest first vector
  • alpha level smoothing constant, 0 < alpha <= 1
  • beta trend smoothing constant, 0 < beta <= 1 (b_t = beta (l_t - l_{t-1}) + (1 - beta) b_{t-1})
  • l0 initial level l_0 (default x_1) optional
  • b0 initial trend b_0 (default x_2 - x_1) optional
  • h forecast horizon in periods (default 1) integer optional

Returns

  • forecast the h-step-ahead forecast
  • level the final level l_n
  • trend the final trend b_n
  • sse sum of squared one-step errors

Applies when

  • 0 < alpha, beta <= 1
  • l_0 = x_1, b_0 = x_2 - x_1 unless stated
  • trend form: beta multiplies (l_t - l_{t-1}) (the error-correction beta* of many texts)

Example

m.ask("Apply Holt's linear trend method with alpha = 0.5 and beta = 0.3 to [10, 12, 15, 16, 19, 21].")
→ forecast = 22.6533, level = 20.6553, trend = 1.99795, sse = 7.49276
Holt-Winters additive methodholt_winters_additive

Holt-Winters exponential smoothing with additive trend and additive seasonality: the h-step forecast, final level and trend, and the sum of squared one-step errors. initialization: l_0 = mean of the first season, b_0 = (mean of season 2 - mean of season 1)/m, s_j = x_j - l_0 (additive) or x_j / l_0 (multiplicative) for the first m observations.

\hat x_{n+h} = \ell_n + h b_n + s_{n+h-m(\lfloor (h-1)/m\rfloor+1)}

Inputs

  • x the series, oldest first (at least two full seasons) vector
  • m season length integer
  • alpha level smoothing constant
  • beta trend smoothing constant
  • gamma seasonal smoothing constant
  • h forecast horizon in periods (default 1) integer optional

Returns

  • forecast the h-step-ahead forecast
  • level final level l_n
  • trend final trend b_n
  • sse sum of squared one-step errors

Applies when

  • n >= 2m
  • 0 < alpha, beta, gamma <= 1
  • initialization: l_0 = mean of the first season, b_0 = (mean of season 2 - mean of season 1)/m, s_j = x_j - l_0 (additive) or x_j / l_0 (multiplicative) for the first m observations

Example

m.ask("Apply the additive Holt-Winters method with m = 4, alpha = 0.5, beta = 0.3 and gamma = 0.2 to [30, 21, 29, 31, 40, 30, 39, 41, 50, 39, 48, 51].")
→ forecast = 56.1588, level = 49.5983, trend = 2.04838, sse = 146.553
Holt-Winters multiplicative methodholt_winters_multiplicative

Holt-Winters exponential smoothing with additive trend and multiplicative seasonality: the h-step forecast, final level and trend, and the sum of squared one-step errors. initialization: l_0 = mean of the first season, b_0 = (mean of season 2 - mean of season 1)/m, s_j = x_j - l_0 (additive) or x_j / l_0 (multiplicative) for the first m observations.

\hat x_{n+h} = (\ell_n + h b_n)\, s_{n+h-m(\lfloor (h-1)/m\rfloor+1)}

Inputs

  • x the series, oldest first (at least two full seasons) vector
  • m season length integer
  • alpha level smoothing constant
  • beta trend smoothing constant
  • gamma seasonal smoothing constant
  • h forecast horizon in periods (default 1) integer optional

Returns

  • forecast the h-step-ahead forecast
  • level final level l_n
  • trend final trend b_n
  • sse sum of squared one-step errors

Applies when

  • n >= 2m
  • 0 < alpha, beta, gamma <= 1
  • initialization: l_0 = mean of the first season, b_0 = (mean of season 2 - mean of season 1)/m, s_j = x_j - l_0 (additive) or x_j / l_0 (multiplicative) for the first m observations
  • positive data

Example

m.ask("Apply the multiplicative Holt-Winters method with m = 4, alpha = 0.5, beta = 0.3 and gamma = 0.2 to [30, 21, 29, 31, 40, 30, 39, 41, 50, 39, 48, 51].")
→ forecast = 58.6565, level = 49.6462, trend = 1.85098, sse = 219.27
One update of Holt's methodholt_update

Update Holt's level and trend with one new observation and forecast h periods ahead.

\ell_t=\alpha y_t+(1-\alpha)(\ell_{t-1}+b_{t-1}),\ b_t=\beta(\ell_t-\ell_{t-1})+(1-\beta)b_{t-1}

Inputs

  • l previous level
  • b previous trend
  • y the new observation
  • alpha level smoothing constant
  • beta trend smoothing constant
  • h forecast horizon (default 1) integer optional

Returns

  • level new level
  • trend new trend
  • forecast level + h trend

Applies when

  • 0 < alpha, beta <= 1
  • b_t = beta (l_t - l_{t-1}) + (1 - beta) b_{t-1}

Example

m.ask("Update Holt's method with previous level 50, previous trend 2, new observation 55, alpha = 0.3 and beta = 0.1.")
→ level = 52.9, trend = 2.09, forecast = 54.99
Simple exponential smoothingsimple_exponential_smoothing

Simple exponential smoothing with smoothing constant alpha: the forecast of the next period and the sum of squared one-step errors. The initial level l_0 is the first observation unless stated.

\ell_t = \alpha x_t + (1-\alpha)\,\ell_{t-1},\qquad \hat x_{n+1} = \ell_n

Inputs

  • x the series, oldest first vector
  • alpha the smoothing constant, 0 < alpha <= 1
  • l0 the initial level l_0 before the first observation (default: x_1) optional

Returns

  • forecast the forecast of the next period (the final level l_n)
  • sse sum of squared one-step errors, e_t = x_t - l_{t-1}

Applies when

  • 0 < alpha <= 1
  • l_0 = x_1 unless an initial level is stated

Example

m.ask("Apply simple exponential smoothing with alpha = 0.3 to [20, 22, 21, 24, 23].")
→ forecast = 22.0928, sse = 16.598

Forecast accuracy 7

Mean absolute errormean_absolute_error

The mean absolute error of forecasts against actual values.

\mathrm{MAE} = \frac1n\sum_{t=1}^{n}|y_t - f_t|

Inputs

  • y the actual values vector
  • f the forecasts (same length) vector

Returns

  • mae Mean absolute error
  • n number of forecasts

Applies when

  • equal lengths
  • errors e_t = actual - forecast

Example

m.ask("Find the MAE for actual values [10, 12, 14, 13] and forecasts [11, 12, 13, 15].")
→ mae = 1, n = 4
Mean absolute percentage errormean_absolute_percentage_error

The mean absolute percentage error (in percent) of forecasts against actual values.

\mathrm{MAPE} = \frac{100}{n}\sum_{t=1}^{n}\left|\frac{y_t - f_t}{y_t}\right|

Inputs

  • y the actual values vector
  • f the forecasts (same length) vector

Returns

  • mape Mean absolute percentage error
  • n number of forecasts

Applies when

  • equal lengths
  • errors e_t = actual - forecast
  • no actual value is 0
  • the result is in percent

Example

m.ask("Find the MAPE for actual values [10, 12, 14, 13] and forecasts [11, 12, 13, 15].")
→ mape = 8.13187, n = 4
Mean absolute scaled errormean_absolute_scaled_error

MASE: the forecasts' mean absolute error divided by the in-sample mean absolute error of the (seasonal) naive forecast on the training data.

\mathrm{MASE} = \frac{\frac1h\sum|y_t - f_t|}{\frac{1}{T-m}\sum_{t=m+1}^{T}|y_t - y_{t-m}|}

Inputs

  • y_train the training (in-sample) data vector
  • y the actual values vector
  • f the forecasts (same length as y) vector
  • sp seasonal period of the naive benchmark (default 1) integer optional

Returns

  • mase the mean absolute scaled error
  • mae the forecasts' MAE
  • scale in-sample MAE of the lag-sp naive forecast

Applies when

  • the training data are longer than sp and not constant at lag sp

Example

m.ask("Find the MASE for training data [10, 12, 11, 14, 13], actual values [15, 14, 16] and forecasts [14, 15, 15].")
→ mase = 0.571429, mae = 1, scale = 1.75
Mean forecast error (bias)mean_forecast_error

The mean forecast error (bias): positive when the forecasts are too low on average.

\mathrm{ME} = \frac1n\sum_{t=1}^{n}(y_t - f_t)

Inputs

  • y the actual values vector
  • f the forecasts (same length) vector

Returns

  • mean_error Mean forecast error (bias)
  • n number of forecasts

Applies when

  • equal lengths
  • errors e_t = actual - forecast

Example

m.ask("Find the mean forecast error for actual values [10, 12, 14, 13] and forecasts [11, 12, 13, 15].")
→ mean_error = -0.5, n = 4
Mean squared errormean_squared_error

The mean squared error of forecasts against actual values.

\mathrm{MSE} = \frac1n\sum_{t=1}^{n}(y_t - f_t)^2

Inputs

  • y the actual values vector
  • f the forecasts (same length) vector

Returns

  • mse Mean squared error
  • n number of forecasts

Applies when

  • equal lengths
  • errors e_t = actual - forecast

Example

m.ask("Find the MSE for actual values [10, 12, 14, 13] and forecasts [11, 12, 13, 15].")
→ mse = 1.5, n = 4
Root mean squared errorroot_mean_squared_error

The root mean squared error of forecasts against actual values.

\mathrm{RMSE} = \sqrt{\frac1n\sum_{t=1}^{n}(y_t - f_t)^2}

Inputs

  • y the actual values vector
  • f the forecasts (same length) vector

Returns

  • rmse Root mean squared error
  • n number of forecasts

Applies when

  • equal lengths
  • errors e_t = actual - forecast

Example

m.ask("Find the RMSE for actual values [10, 12, 14, 13] and forecasts [11, 12, 13, 15].")
→ rmse = 1.22474, n = 4
Symmetric mean absolute percentage errorsymmetric_mape

The symmetric MAPE in percent: 100/n sum 2|y - f| / (|y| + |f|).

\mathrm{sMAPE} = \frac{100}{n}\sum_{t=1}^{n}\frac{2|y_t - f_t|}{|y_t| + |f_t|}

Inputs

  • y the actual values vector
  • f the forecasts (same length) vector

Returns

  • smape Symmetric mean absolute percentage error
  • n number of forecasts

Applies when

  • equal lengths
  • errors e_t = actual - forecast
  • no pair with actual and forecast both 0
  • the result is in percent (range 0 to 200)

Example

m.ask("Find the sMAPE for actual values [10, 12, 14, 13] and forecasts [11, 12, 13, 15].")
→ smape = 7.80423, n = 4

Interpolation of missing values 2

Exponential (log-linear) interpolationexponential_interpolation

Fill a missing value at time t0 assuming constant growth between the neighbouring observations (linear interpolation of the logarithms).

\hat y(t_0) = y_i\left(\frac{y_{i+1}}{y_i}\right)^{\frac{t_0-t_i}{t_{i+1}-t_i}}

Inputs

  • t the times (strictly increasing) vector
  • y the values at those times vector
  • t0 the time of the missing value

Returns

  • value the interpolated value at t0

Applies when

  • positive values
  • times strictly increasing
  • t0 within the observed times

Example

m.ask("Exponentially interpolate the value at t = 2.5 from times [1, 2, 3, 4] and values [100, 120, 150, 170].")
→ value = 134.164
Linear interpolation of a missing valuelinear_interpolation

Fill a missing value at time t0 by the straight line between the neighbouring observations.

\hat y(t_0) = y_i + \frac{t_0 - t_i}{t_{i+1}-t_i}(y_{i+1}-y_i)

Inputs

  • t the times (strictly increasing) vector
  • y the values at those times vector
  • t0 the time of the missing value

Returns

  • value the interpolated value at t0

Applies when

  • times strictly increasing
  • t0 within the observed times (no extrapolation)

Example

m.ask("Linearly interpolate the value at t = 2.5 from times [1, 2, 3, 4] and values [10, 14, 13, 18].")
→ value = 13.5

Kalman filtering 7

Kalman filter for a constant-velocity modelkalman_filter_constant_velocity

Track position and velocity from noisy position measurements with the constant-velocity Kalman filter (discrete white-noise acceleration with variance q, time step dt): final state and covariance.

F=\begin{pmatrix}1&\Delta t\\0&1\end{pmatrix},\ Q = q\begin{pmatrix}\Delta t^4/4&\Delta t^3/2\\ \Delta t^3/2&\Delta t^2\end{pmatrix}

Inputs

  • x the measured positions, oldest first vector
  • dt time step
  • q acceleration (process) noise variance
  • r position measurement noise variance
  • p0 initial position estimate
  • v0 initial velocity estimate
  • var0 initial variance of position and of velocity (uncorrelated)

Returns

  • position final position estimate
  • velocity final velocity estimate
  • p11 final position variance
  • p12 final position-velocity covariance
  • p22 final velocity variance

Applies when

  • F = [[1, dt], [0, 1]], H = [1, 0]
  • Q = q [[dt^4/4, dt^3/2], [dt^3/2, dt^2]]
  • predict then update at every measurement

Example

m.ask("Run a constant-velocity Kalman filter with time step 1, process variance 0.1, measurement variance 1, initial position 0, initial velocity 1 and initial variance 10 for the positions [1.1, 1.9, 3.2, 4.0, 4.8].")
→ position = 4.89695, velocity = 0.938562, p11 = 0.61539, p12 = 0.24431, p22 = 0.224491
Kalman filter for a random-walk (local level) modelkalman_filter_local_level

Filter a sequence of measurements with the scalar Kalman filter for x_t = x_{t-1} + w_t, z_t = x_t + v_t (predict, then update, at every step): the final estimate, variance, gain, all filtered estimates and the Gaussian log-likelihood of the one-step prediction errors.

P_t^- = P_{t-1}+q,\ K_t = \frac{P_t^-}{P_t^-+r},\ \hat x_t = \hat x_{t-1} + K_t(z_t - \hat x_{t-1})

Inputs

  • x the measurements, oldest first vector
  • q process noise variance
  • r measurement noise variance
  • m0 initial state estimate
  • p0 initial variance

Returns

  • estimate final filtered estimate
  • variance final variance
  • gain final gain
  • estimates filtered estimates for every measurement
  • log_likelihood sum of log N(v_t; 0, S_t)

Applies when

  • q >= 0, r > 0, p0 >= 0
  • the initial estimate is the state before the first measurement

Example

m.ask("Run a Kalman filter with process variance = 0.5, measurement variance = 2, initial estimate = 10 and initial variance = 5 for the measurements [10.4, 11.1, 10.7, 11.9, 12.3].")
→ estimate = 11.6241, variance = 0.79064, gain = 0.39532, estimates = [10.293333333333333, 10.693277310924369, 10.696149217809866, 11.182224215246636, 11.624103148133084], log_likelihood = -8.61712
Kalman measurement update (scalar)kalman_update

Combine a prior estimate (mean, variance) with a measurement (value, noise variance): the posterior mean and variance and the Kalman gain.

K = \frac{P}{P+R},\ \hat x^+ = \hat x + K(z - \hat x),\ P^+ = (1-K)P

Inputs

  • m prior mean
  • p prior variance (> 0)
  • z the measurement
  • r measurement noise variance (> 0)

Returns

  • mean posterior mean
  • variance posterior variance
  • gain Kalman gain p/(p+r)

Applies when

  • p > 0, r > 0
  • the measurement observes the state directly (H = 1)

Example

m.ask("Do a Kalman update with prior mean = 10, prior variance = 4, measurement = 12 and measurement variance = 1.")
→ mean = 11.6, variance = 0.8, gain = 0.8
One Kalman filter step (random-walk model)kalman_step

One predict-and-update step of the scalar Kalman filter for a random-walk state x_t = x_{t-1} + w_t observed as z_t = x_t + v_t.

P^- = P + Q,\ K = \frac{P^-}{P^-+R},\ \hat x = \hat x^- + K(z - \hat x^-),\ P = (1-K)P^-

Inputs

  • m previous estimate
  • p previous estimate variance
  • z the new measurement
  • q process noise variance
  • r measurement noise variance

Returns

  • mean updated estimate
  • variance updated variance
  • gain Kalman gain
  • prior_variance predicted variance p + q

Applies when

  • p, q >= 0, r > 0
  • F = H = 1

Example

m.ask("Do one Kalman filter step with previous estimate = 10, previous variance = 4, process variance = 1, measurement = 12 and measurement variance = 2.")
→ mean = 11.4286, variance = 1.42857, gain = 0.714286, prior_variance = 5
Rauch-Tung-Striebel smoother (random-walk model)rts_smoother_local_level

Smoothed state estimates of the random-walk (local level) model: the Kalman filter forward, then the Rauch-Tung-Striebel recursion backward.

\hat x_{t|n} = \hat x_{t} + C_t(\hat x_{t+1|n} - \hat x_t),\ C_t = \frac{P_t}{P_t+q}

Inputs

  • x the measurements, oldest first vector
  • q process noise variance
  • r measurement noise variance
  • m0 initial state estimate
  • p0 initial variance

Returns

  • smoothed smoothed estimates for every time
  • first smoothed estimate at time 1
  • first_variance its variance

Applies when

  • q > 0, r > 0, p0 >= 0

Example

m.ask("Apply the RTS smoother with process variance = 0.5, measurement variance = 2, initial estimate = 10 and initial variance = 5 for the measurements [10.4, 11.1, 10.7, 11.9, 12.3].")
→ smoothed = [10.83039127959001, 11.013479215813877, 11.174936955991214, 11.455128935166355, 11.624103148133084], first = 10.8304, first_variance = 0.694975
Steady-state Kalman gain (random-walk model)kalman_steady_state_gain

The limiting Kalman gain and variances of the random-walk (local level) model with process variance q and measurement variance r (the solution of the scalar Riccati equation).

P^- = \frac{q + \sqrt{q^2 + 4qr}}{2},\quad K = \frac{P^-}{P^- + r}

Inputs

  • q process noise variance (> 0)
  • r measurement noise variance (> 0)

Returns

  • gain steady-state gain
  • prior_variance steady-state predicted variance P-
  • posterior_variance steady-state filtered variance

Applies when

  • q > 0, r > 0

Example

m.ask("Find the steady-state Kalman gain with process variance 1 and measurement variance 4.")
→ gain = 0.390388, prior_variance = 2.56155, posterior_variance = 1.56155
Steady-state Kalman gains of a constant-velocity modelkalman_steady_state_constant_velocity

The limiting position and velocity gains (and predicted position variance) of the constant-velocity Kalman filter with discrete white-noise acceleration q, time step dt and measurement variance r.

P = F\big(P - PH^\top(HPH^\top+R)^{-1}HP\big)F^\top + Q

Inputs

  • dt time step
  • q acceleration noise variance (> 0)
  • r measurement noise variance (> 0)

Returns

  • k_position steady-state position gain
  • k_velocity steady-state velocity gain
  • prior_p11 steady-state predicted position variance

Applies when

  • dt, q, r > 0
  • Q = q [[dt^4/4, dt^3/2], [dt^3/2, dt^2]]

Example

m.ask("Find the steady-state Kalman gains of a constant-velocity model with time step 1, process variance 0.1 and measurement variance 1.")
→ k_position = 0.546211, k_velocity = 0.213023, prior_p11 = 1.20367

Moving averages 4

Centred moving averagecentred_moving_average

The centred moving average of length k: a symmetric k-term mean for odd k, the 2 x k moving average (half weights at both ends) for even k, as used in classical decomposition.

\mathrm{CMA}_t = \frac{1}{k}\Big(\tfrac12 x_{t-h} + \sum_{i=-h+1}^{h-1} x_{t+i} + \tfrac12 x_{t+h}\Big)

Inputs

  • x the series, oldest first vector
  • k the length of the moving average integer

Returns

  • cma the centred moving averages, from time first_index on
  • first_index the time t (1-based) of the first centred value (k//2 + 1)
  • first the first centred moving average

Applies when

  • k >= 2
  • odd k: k <= n; even k: k + 1 <= n

Example

m.ask("Find the 4-period centred moving average of [12, 15, 14, 18, 20, 19, 23, 25].")
→ cma = [15.75, 17.25, 18.875, 20.875], first_index = 3, first = 15.75
Exponential moving averageexponential_moving_average

The exponential moving average with span k (alpha = 2/(k+1)), started at the first value.

\mathrm{EMA}_t = \alpha x_t + (1-\alpha)\,\mathrm{EMA}_{t-1},\quad \alpha = \frac{2}{k+1}

Inputs

  • x the series, oldest first vector
  • k the span (number of periods) integer

Returns

  • ema the exponential moving average at every time (EMA_1 = x_1)
  • last the latest exponential moving average
  • alpha the weight 2/(k+1)

Applies when

  • k >= 1
  • EMA_1 = x_1 (no averaging of a start-up window)

Example

m.ask("Find the 3-period exponential moving average of [10, 12, 14, 13, 15].")
→ ema = [10.0, 11.0, 12.5, 12.75, 13.875], last = 13.875, alpha = 0.5
Linearly weighted moving averagelinearly_weighted_moving_average

The k-period linearly weighted moving average: weights 1, 2, ..., k from the oldest to the newest value of each window.

\mathrm{WMA}_t = \frac{\sum_{i=0}^{k-1} (k-i)\,x_{t-i}}{k(k+1)/2}

Inputs

  • x the series, oldest first vector
  • k the window length integer

Returns

  • lwma the weighted moving averages, one per complete window
  • last the latest weighted moving average (forecast of the next period)

Applies when

  • 1 <= k <= n
  • the newest value of a window has weight k, the oldest weight 1

Example

m.ask("Find the 3-period linearly weighted moving average of [10, 12, 14, 13, 15].")
→ lwma = [12.666666666666666, 13.166666666666666, 14.166666666666666], last = 14.1667
Simple moving averagesimple_moving_average

The k-period simple (trailing) moving average of a series; its last value is the moving-average forecast of the next period.

\mathrm{SMA}_t = \frac{1}{k}\sum_{i=0}^{k-1} x_{t-i}

Inputs

  • x the series, oldest first vector
  • k the window length (number of periods) integer

Returns

  • sma the moving averages, one per complete window (the first covers x_1..x_k)
  • last the latest moving average (forecast of the next period)
  • count number of moving averages (n - k + 1)

Applies when

  • 1 <= k <= n

Example

m.ask("Find the 3-period simple moving average of [10, 12, 14, 13, 15].")
→ sma = [12.0, 13.0, 14.0], last = 14, count = 3

Stationarity tests 3

Augmented Dickey-Fuller statisticaugmented_dickey_fuller_test

The augmented Dickey-Fuller tau statistic with p lagged differences: the t-ratio of gamma in Delta x_t = gamma x_{t-1} + sum_j delta_j Delta x_{t-j} (+ constant, + trend) + e_t. The statistic only.

\Delta x_t = \alpha + \gamma x_{t-1} + \sum_{j=1}^{p}\delta_j\Delta x_{t-j} + e_t

Inputs

  • x the series, oldest first vector
  • p number of lagged differences integer
  • regression deterministic terms: c = constant (default), ct = constant and trend, n = none choice optional

Returns

  • tau the ADF statistic
  • gamma the coefficient of x_{t-1}
  • se its standard error
  • nobs observations in the regression (n - 1 - p)

Applies when

  • p <= n/2 - (deterministic terms) - 1
  • default deterministic terms: a constant
  • the lag length is given, not selected

Example

m.ask("Compute the augmented Dickey-Fuller statistic with 2 lags and a constant for [10.2, 10.8, 10.5, 11.3, 11.0, 11.9, 11.6, 12.4, 12.0, 12.9, 12.5, 13.4].")
→ tau = -1.18653, gamma = -0.0390526, se = 0.0329132, nobs = 9
Dickey-Fuller unit-root statisticdickey_fuller_test

The Dickey-Fuller tau statistic: the t-ratio of gamma in the regression Delta x_t = gamma x_{t-1} (+ constant, + trend) + e_t. The statistic only: compare it with Dickey-Fuller critical values.

\Delta x_t = \alpha + \gamma x_{t-1} + e_t,\quad \tau = \hat\gamma/\mathrm{se}(\hat\gamma)

Inputs

  • x the series, oldest first vector
  • regression deterministic terms: c = constant (default), ct = constant and trend, n = none choice optional

Returns

  • tau the Dickey-Fuller statistic gamma/se
  • gamma the coefficient of x_{t-1}
  • se its standard error
  • nobs observations in the regression (n - 1)

Applies when

  • the series is not constant
  • default deterministic terms: a constant
  • no lagged differences (see augmented_dickey_fuller_test)

Example

m.ask("Compute the Dickey-Fuller statistic with a constant for [10.2, 10.8, 10.5, 11.3, 11.0, 11.9, 11.6, 12.4, 12.0, 12.9].")
→ tau = -0.927858, gamma = -0.269585, se = 0.290546, nobs = 9
KPSS stationarity statistickpss_test

The KPSS statistic for level (c) or trend (ct) stationarity with a Bartlett-kernel long-run variance using a given number of lags. The statistic only: compare it with KPSS critical values.

\mathrm{KPSS} = \frac{n^{-2}\sum_{t=1}^{n} S_t^2}{\hat\sigma^2_{LR}},\ \hat\sigma^2_{LR} = \frac1n\Big(\sum e_t^2 + 2\sum_{i=1}^{L}\big(1-\tfrac{i}{L+1}\big)\sum_t e_te_{t-i}\Big)

Inputs

  • x the series, oldest first vector
  • nlags Bartlett lags in the long-run variance integer
  • regression c = level stationarity (default), ct = trend stationarity choice optional

Returns

  • kpss the KPSS statistic
  • long_run_variance Bartlett long-run variance of the residuals

Applies when

  • 0 <= lags < n
  • residuals from the mean (c) or a linear trend t = 1..n (ct)

Example

m.ask("Compute the KPSS statistic for level stationarity with 2 lags for [10.2, 10.8, 10.5, 11.3, 11.0, 11.9, 11.6, 12.4].")
→ kpss = 0.401275, long_run_variance = 0.811354

Transformations and growth 2

Compound average growth rate of a seriescompound_average_growth_rate

The compound (geometric) average growth rate per period of a positive series (CAGR when the periods are years), and the total growth from the first to the last value.

g = \left(\frac{x_n}{x_1}\right)^{1/(n-1)} - 1

Inputs

  • x the series, oldest first (positive values) vector

Returns

  • rate compound average growth rate per period, as a fraction
  • rate_percent the same rate in percent
  • total_growth total growth x_n/x_1 - 1, as a fraction
  • periods number of periods n - 1

Applies when

  • all values positive
  • equally spaced periods

Example

m.ask("Find the compound average growth rate of [100, 110, 125, 133, 150].")
→ rate = 0.106682, rate_percent = 10.6682, total_growth = 0.5, periods = 4
Regular and seasonal differencingdifferencing

Difference a series d times (and seasonally D times at lag s): the series that an ARIMA(p, d, q) or seasonal ARIMA model works on.

\nabla^d \nabla_s^D x_t = (1-L)^d (1-L^s)^D x_t

Inputs

  • x the series, oldest first vector
  • d number of regular (lag-1) differences, 0..3 (default 1) integer optional
  • D number of seasonal differences, 0..2 (default 0) integer optional
  • s seasonal lag (needed when D > 0) integer optional

Returns

  • differenced the differenced series
  • last its latest value
  • length its length n - d - D s

Applies when

  • d + D >= 1
  • the series is longer than d + D s

Example

m.ask("Find the second differences of [3, 5, 9, 15, 23, 33].")
→ differenced = [2.0, 2.0, 2.0, 2.0], last = 2, length = 4

Trend fitting 7

Exponential trend fit and forecastexponential_trend_forecast

Fit x_t = a e^(b t) (t = 1..n) by least squares on ln x_t, the growth rate per period e^b - 1, and the forecast of period n + h.

\ln x_t = \ln a + b\,t,\quad \hat x_{n+h} = a\,e^{b(n+h)}

Inputs

  • x the series, oldest first (positive) vector
  • h periods ahead (default 1) integer optional

Returns

  • a the scale a
  • b the exponent rate b
  • growth_rate e^b - 1 per period
  • forecast a e^(b (n + h))

Applies when

  • positive values
  • least squares on the logarithms (not on the values)

Example

m.ask("Fit an exponential trend to [100, 112, 124, 140, 155] and forecast 1 period ahead.")
→ a = 89.6495, b = 0.109965, growth_rate = 0.116239, forecast = 173.417
Linear trend fit and forecastlinear_trend_forecast

Fit the least-squares trend line x_t = a + b t (t = 1..n) and forecast period n + h.

\hat x_t = a + b\,t,\quad \hat x_{n+h} = a + b(n+h)

Inputs

  • x the series, oldest first vector
  • h periods ahead to forecast (default 1) integer optional

Returns

  • slope trend per period b
  • intercept a (the trend value at t = 0)
  • forecast a + b (n + h)
  • r_squared coefficient of determination

Applies when

  • t = 1..n
  • the series is not constant

Example

m.ask("Fit a linear trend to [12, 15, 17, 20, 22, 25] and forecast 2 periods ahead.")
→ slope = 2.54286, intercept = 9.6, forecast = 29.9429, r_squared = 0.996979
Linear trend with seasonal dummy variablestrend_seasonal_regression

Fit x_t = a + b t + (effect of t's season) by least squares with seasonal dummies (the first season is the baseline, effect 0; the series starts in season 1) and forecast period n + h.

x_t = a + b\,t + \sum_{j=2}^{m}\gamma_j D_{j,t} + e_t

Inputs

  • x the series, oldest first, starting in season 1 vector
  • m season length integer
  • h periods ahead (default 1) integer optional

Returns

  • forecast the fitted value at t = n + h
  • intercept a
  • slope b per period
  • season_effects the m seasonal effects (season 1 = 0)

Applies when

  • n >= m + 3
  • x_1 is in season 1
  • season 1 is the baseline

Example

m.ask("Fit a linear trend with seasonal dummies to the quarterly series [30, 21, 29, 31, 40, 30, 39, 41, 50, 39, 48, 51] and forecast 1 period ahead.")
→ forecast = 59.25, intercept = 27.9688, slope = 2.40625, season_effects = [0.0, -12.406249999999996, -6.145833333333333, -6.218749999999999]
Mann-Kendall trend testmann_kendall_test

The Mann-Kendall statistic S, its variance (with the tie correction), the continuity-corrected normal score z and the two-sided p-value for a monotonic trend.

S=\sum_{i<j}\operatorname{sgn}(x_j-x_i),\ \operatorname{Var}S=\frac{n(n-1)(2n+5)-\sum t(t-1)(2t+5)}{18}

Inputs

  • x the series, oldest first vector

Returns

  • s S = sum_{i<j} sign(x_j - x_i)
  • var_s variance of S with tie correction
  • z (S - sign S) / sqrt(var S)
  • p_value two-sided normal p-value

Applies when

  • n >= 4
  • ties corrected in the variance
  • continuity correction of 1 in z

Example

m.ask("Perform the Mann-Kendall trend test on [12, 14, 13, 17, 16, 19, 25, 21, 24].")
→ s = 28, var_s = 92, z = 2.81494, p_value = 0.00487856
Quadratic trend fit and forecastquadratic_trend_forecast

Fit x_t = b0 + b1 t + b2 t^2 (t = 1..n) by least squares and forecast period n + h.

\hat x_t = b_0 + b_1 t + b_2 t^2

Inputs

  • x the series, oldest first vector
  • h periods ahead (default 1) integer optional

Returns

  • b0 constant
  • b1 coefficient of t
  • b2 coefficient of t^2
  • forecast the trend value at t = n + h

Applies when

  • t = 1..n
  • n >= 4

Example

m.ask("Fit a quadratic trend to [3, 5, 9, 15, 22, 32] and forecast 1 period ahead.")
→ b0 = 2.8, b1 = -0.728571, b2 = 0.928571, forecast = 43.2
Random-walk-with-drift (drift method) forecastdrift_forecast

The drift method: the average change per period (x_n - x_1)/(n - 1) and the forecast x_n + h x drift.

\hat x_{n+h} = x_n + h\,\frac{x_n - x_1}{n-1}

Inputs

  • x the series, oldest first vector
  • h periods ahead (default 1) integer optional

Returns

  • drift average change per period
  • forecast x_n + h drift

Applies when

  • n >= 2

Example

m.ask("Forecast 3 periods ahead with the drift method for [100, 104, 103, 109, 112].")
→ drift = 3, forecast = 121
Sen's slope (Theil-Sen trend)sens_slope

Sen's robust trend slope (median of all pairwise slopes, t = 1..n) and the intercept median(x) - slope median(t).

\hat\beta = \operatorname{median}_{i<j}\frac{x_j - x_i}{j - i}

Inputs

  • x the series, oldest first vector

Returns

  • slope median of (x_j - x_i)/(j - i), i < j
  • intercept median(x) - slope (n+1)/2

Applies when

  • t = 1..n

Example

m.ask("Find Sen's slope of [12, 14, 13, 17, 16, 19, 25].")
→ slope = 1.66667, intercept = 9.33333
Questions

Frequently asked

What does time-series-ai999x do?

Time Series answers questions in time series: moving averages, exponential smoothing, autocorrelation, ARIMA basics, stationarity tests, change points, forecasting accuracy and Kalman filtering. Each answer gives the value with its unit, the steps and the formula in LaTeX.

How do I install time-series-ai999x?

With pip: pip install time-series-ai999x. The same files are on Hugging Face (hf download AI999X/time-series-ai999x --local-dir time-series-ai999x) and GitHub.

Does it run offline?

Yes. It is a Python package that runs on an ordinary CPU without a network connection (Python >=3.10); no GPU and no API key are needed.

How many capabilities does time-series-ai999x have?

77 capabilities in 14 topics, including ARMA theory, Exponential smoothing, ARIMA models, Forecast accuracy, Kalman filtering.

Which field and tasks does it cover?

Field: Mathematics & Statistics. Tasks: Question Answering, Token Classification, Text Classification, Time Series Forecasting, Sentence Similarity, Feature Extraction.

What does an answer look like?

Asked "Find the 3-period simple moving average of [10, 12, 14, 13, 15].", it answers: sma = [12.0, 13.0, 14.0], last = 14, count = 3.

What happens when a question cannot be answered?

It says so and names what is missing or out of range, instead of guessing a number.

More from AI999X

Explore every model.