Skip to main content

High-performance SARIMAX (Seasonal ARIMA with eXogenous regressors) engine in Rust with statsmodels-compatible Python API

Project description

rustima

Rust Python License: GPL v3

Korean / 한국어

A high-performance SARIMAX (Seasonal ARIMA with eXogenous regressors) engine written in Rust with Python bindings via PyO3. It provides a statsmodels-compatible high-level API, native-compiled speed, numerical accuracy on par with statsmodels, and Rayon-based job-level parallel batch processing for large-scale time series workloads.

Motivation

Python's statsmodels.tsa.SARIMAX is the de facto standard for SARIMA modeling, but its pure-Python + NumPy implementation has structural bottlenecks:

Bottleneck Root Cause Impact
Slow Kalman filter loop Python for loop over matrix ops Seconds to tens of seconds on long series or high-order models
MLE optimization overhead Python call stack on every iteration Accumulated latency over hundreds of iterations
No real parallelism GIL prevents multi-threaded batch fitting Cannot simultaneously fit thousands of series
Memory fragmentation Python object overhead per allocation Unnecessary heap pressure on large state spaces

rustima replaces these bottlenecks with native Rust:

  • Kalman filter: Rust for + nalgebra dense matrix ops (zero interpreter overhead)
  • Optimization: L-BFGS-B (default), L-BFGS, Nelder-Mead run entirely in Rust with analytical score vector (sparse tangent-linear Kalman + steady-state optimization)
  • Batch parallelism: Rayon work-stealing thread pool that assigns one full fit/forecast job per series
  • Grid search parallelization: sarimax_grid_search assigns one ARIMA order combination per worker via Rayon
  • auto_arima: Hyndman-Khandakar stepwise + Rayon parallel grid search for automatic order selection
  • Memory: Stack allocation + contiguous column-major layout for cache-friendliness
  • Python interop: PyO3 + numpy bindings — import rustima

What is SARIMAX? (For Beginners)

If you've never used SARIMAX before, here's a 30-second primer:

SARIMAX = S + ARIMA + X

  • AR (AutoRegressive) — predict today's value from the past few days
  • I (Integrated / differencing) — subtract today from yesterday to make a trending series stationary
  • MA (Moving Average) — use past forecast errors to improve today's prediction
  • S (Seasonal) — a repeating pattern (weekly=7, monthly=12, hourly=24)
  • X (eXogenous) — extra columns that help explain y (e.g. temperature, price, promotions)

You describe the model with two tuples:

Tuple Meaning Example
order=(p, d, q) Non-seasonal (AR, diff, MA) (1, 1, 1) = 1 lag AR, 1 diff, 1 lag MA
seasonal_order=(P, D, Q, s) Seasonal part + period (1, 0, 1, 12) = monthly seasonality

Quick rules of thumb:

  • Has trend? → d=1
  • Has yearly pattern in monthly data? → s=12
  • Not sure about orders? → Use auto_arima() and it picks for you

Recommended learning path:

  1. Try auto_arima() on your series first (it picks orders automatically)
  2. Read Forecasting: Principles and Practice, Ch. 9 (free textbook) for theory
  3. Come back to tune order/seasonal_order manually

Supported Models

SARIMA(p, d, q)(P, D, Q, s) + trend + exogenous regressors
Parameter Description Range
p AR order (autoregressive) 0–20
d Differencing order 0–3
q MA order (moving average) 0–20
P Seasonal AR order 0–4
D Seasonal differencing order 0–1
Q Seasonal MA order 0–4
s Seasonal period (e.g. 12=monthly, 7=daily, 24=hourly) 2–365
trend Trend component ('n', 'c', 't', 'ct')
exog Exogenous regressors n_obs × n_exog matrix

Installation

Prerequisites

Because rustima ships Rust source, you must build it locally (there is no pre-built wheel on PyPI yet). You need:

Tool Minimum Why Install
Rust 1.83+ Compiles the engine curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Python 3.10+ Hosts the extension python.org or pyenv
uv latest Fast Python package/env manager curl -LsSf https://astral.sh/uv/install.sh | sh
maturin 1.7+ Rust ↔ Python bridge (auto-installed by uv sync --extra dev)

Windows users: install Microsoft C++ Build Tools first (needed by Rust's MSVC toolchain).

Option A — Development mode (recommended for most users)

Best for: testing, Jupyter notebooks, running examples. Fast rebuilds on code changes.

git clone https://github.com/<your-org>/rustima.git
cd rustima/        # the repo has an inner `rustima/` package directory

# 1) Create virtualenv + install Python deps (numpy, polars, pytest, etc.)
uv sync --extra dev

# 2) Compile Rust engine in release mode and link it in-place
uv run maturin develop --release

After this you can run:

uv run python -c "import rustima; print(rustima.version())"

Option B — Build a redistributable wheel

Best for: deploying to another machine, CI, production.

cd rustima/
uv sync --extra dev
CARGO_TARGET_DIR=target_wheel uv run maturin build --release --out /tmp/wheels
uv pip install --force-reinstall /tmp/wheels/rustima-*.whl

Copy the .whl from /tmp/wheels/ to the target machine and pip install it there (must have the same OS + Python version).

Verifying the install

import rustima
import numpy as np

print(rustima.version())                              # "0.1.0"
y = np.random.randn(100).cumsum()
r = rustima.sarimax_fit(y, order=(1, 1, 1), seasonal=(0, 0, 0, 0))
print(f"converged={r['converged']}, AIC={r['aic']:.2f}")

If this prints without error you're good to go. See Troubleshooting at the bottom if it fails.

Using inside Jupyter Notebook

cd rustima/
uv sync --extra dev
uv run maturin develop --release

# Register the venv as a Jupyter kernel (run once)
uv run python -m ipykernel install --user --name rustima --display-name "rustima"

# Launch Jupyter
uv run jupyter notebook

In the notebook, select the kernel "rustima" from the top-right corner, then:

import rustima
from rustima import SARIMAXModel, auto_arima

Which API Should I Use?

rustima exposes two layers. Pick one based on what you're doing:

You want to... Use Why
Replace statsmodels.SARIMAX with a faster drop-in SARIMAXModel (high-level) Same class/method names, same output format, statsmodels-style .summary()
Let the library pick the order for you auto_arima() (high-level) Automatic (p,d,q)(P,D,Q,s) search, like pmdarima
Fit thousands of series in parallel rustima.sarimax_batch_fit (low-level) Skips Python object overhead, releases GIL
Try many orders on one series rustima.sarimax_grid_search (low-level) Rayon-parallel over order combinations
Inspect raw log-likelihood / residuals for research rustima.sarimax_loglike / sarimax_residuals Direct access to Kalman filter output

Rule of thumb: Start with SARIMAXModel or auto_arima. Drop to the low-level API only when you need to fit many series/orders at once.

Your First Forecast (5-minute walkthrough)

A complete end-to-end example. Copy-paste into a Python file or notebook.

import numpy as np
from rustima import SARIMAXModel, auto_arima

# ── 1. Simulate monthly sales data with trend + yearly seasonality ─────────
rng = np.random.default_rng(42)
n = 120  # 10 years of monthly data
trend = 0.5 * np.arange(n)                           # linear upward trend
season = 10 * np.sin(2 * np.pi * np.arange(n) / 12)  # yearly cycle (s=12)
noise = rng.normal(0, 1.0, n)
y = trend + season + noise

# ── 2. Let auto_arima pick the orders for you ─────────────────────────────
auto_result = auto_arima(y, s=12, trace=True)  # trace=True prints each try
print(auto_result.search_summary())
# >>> Best: SARIMA(0,1,1)(0,1,1)[12]  AIC=345.67  (evaluated 23 models)

# ── 3. Inspect the chosen model ───────────────────────────────────────────
model = auto_result.result              # a SARIMAXResult
print(model.summary())                  # statsmodels-style parameter table
print(f"AIC={model.aic:.2f}  BIC={model.bic:.2f}")

# ── 4. Forecast the next 12 months with 95% confidence intervals ──────────
forecast = model.forecast(steps=12, alpha=0.05)
df = forecast.to_dataframe()            # Polars DataFrame
print(df)
# shape (12, 5): step | mean | variance | ci_lower | ci_upper

# ── 5. Check residuals (should look like random noise) ────────────────────
diag = model.diagnostics()
print(f"Ljung-Box p-value: {diag['ljung_box_pvalue'][0]:.3f}  (>0.05 = good)")

What to look at in the output:

  • converged=True → optimization succeeded
  • Low AIC / BIC → better model fit (relative to other orders)
  • Ljung-Box p > 0.05 → residuals look like white noise (good)
  • ci_lower / ci_upper → uncertainty band; wider = less confident

Quick Start

Low-Level API (rustima)

import numpy as np
import rustima

y = np.random.randn(200).cumsum()

# 1. Fit model
result = rustima.sarimax_fit(y, order=(1, 1, 1), seasonal=(0, 0, 0, 0))
print(f"Converged: {result['converged']}, AIC: {result['aic']:.2f}")

# 2. 10-step ahead forecast
fc = rustima.sarimax_forecast(
    y, order=(1, 1, 1), seasonal=(0, 0, 0, 0),
    params=np.array(result["params"]), steps=10
)
print(f"Forecast: {fc['mean'][:5]}")

# 3. Residual diagnostics
res = rustima.sarimax_residuals(
    y, order=(1, 1, 1), seasonal=(0, 0, 0, 0),
    params=np.array(result["params"])
)

High-Level API (SARIMAXModel — statsmodels compatible)

from rustima import SARIMAXModel

model = SARIMAXModel(y, order=(1, 1, 1), seasonal_order=(0, 0, 0, 0), trend="c")
result = model.fit()

# Parameter summary (fast, no inference stats)
print(result.summary())

# With Hessian-based inference (std err, z, p-value, CI)
print(result.summary(inference="hessian"))

# Side-by-side Hessian vs statsmodels inference
print(result.summary(inference="both"))

# Parameter table as Polars DataFrame
pt = result.params_table(inference="hessian")
print(pt)  # shape: (k, 7) — name, coef, std_err, z, p_value, ci_lower, ci_upper

print(f"AIC: {result.aic:.2f}, BIC: {result.bic:.2f}, HQIC: {result.hqic:.2f}")

# Forecast with confidence intervals + Polars DataFrame
fcast = result.forecast(steps=10, alpha=0.05)
print(fcast.predicted_mean)
df = fcast.to_dataframe()  # Polars: step, mean, variance, ci_lower, ci_upper
ci = fcast.conf_int()          # (10, 2) array [lower, upper]
ci_90 = fcast.conf_int(0.10)   # recalculate with different alpha

# In-sample prediction
pred = result.get_prediction(start=0, end=210)
pred_df = pred.to_dataframe()  # Polars: index, predicted_mean

# Standardized residuals
residuals = result.resid

# Residual diagnostics (Ljung-Box, Jarque-Bera, heteroskedasticity)
diag = result.diagnostics()

auto_arima — Automatic Order Selection

from rustima import auto_arima

# Stepwise (Hyndman-Khandakar, default)
res = auto_arima(y, max_p=5, max_q=5, s=12, stepwise=True, trace=True)
print(res.summary())           # Full statsmodels-style summary with inference
print(res.search_summary())    # Short 3-line summary (order, IC, model count)
print(res.result.forecast(steps=12).to_dataframe())

# Grid Search (Rayon parallel — one fit job per order combination)
res = auto_arima(y, max_p=3, max_q=3, s=7, stepwise=False, criterion="bic")
print(res.summary())

# Search history (Polars DataFrame)
print(res.history_dataframe())

auto_arima key parameters:

Parameter Default Description
max_p, max_q 5 Max AR/MA order
max_P, max_Q 2 Max seasonal AR/MA order
s 0 Seasonal period (0=non-seasonal)
d, D None Differencing order (None=auto-detect)
trend "n" Trend: 'n', 'c', 't', 'ct'
criterion "aic" Information criterion: "aic", "bic", "hqic"
stepwise True False → exhaustive grid search (Rayon parallel)
trace False True → print each model evaluation result

Trend Support

# Constant (intercept)
model = SARIMAXModel(y, order=(1, 1, 1), seasonal_order=(0, 0, 0, 0), trend="c")
# Linear trend (drift)
model = SARIMAXModel(y, order=(1, 1, 1), seasonal_order=(0, 0, 0, 0), trend="t")
# Constant + linear (intercept + drift)
model = SARIMAXModel(y, order=(1, 1, 1), seasonal_order=(0, 0, 0, 0), trend="ct")

result = model.fit()
print(result.param_names)  # ['intercept', 'drift', 'ar.L1', 'ma.L1'] (trend='ct')

Exogenous Regressors

import numpy as np

X_train = np.column_stack([np.arange(200), np.random.randn(200)])  # (200, 2)
X_future = np.column_stack([np.arange(200, 210), np.random.randn(10)])  # (10, 2)

model = SARIMAXModel(y, order=(1, 0, 1), seasonal_order=(0, 0, 0, 0), exog=X_train)
result = model.fit()
fcast = result.forecast(steps=10, exog=X_future)

Profiled Kalman-GLS Trust-Region for weakly identified exog coefficients. When the exog block is weakly identified (flat likelihood in the β direction), the default optimizer can leave β in a poor basin. The profile-trust-region method (academic name: Profiled Kalman-GLS Trust-Region, equivalently innovations-form profile likelihood with trust-region BFGS) removes β from the nonlinear optimizer and solves it exactly via innovation-space GLS at each likelihood evaluation. The optimizer only sees [trend | AR | MA | sAR | sMA | sigma2]. On exogenous SARIMAX cases it tends to reproduce R stats::arima(method="CSS-ML") β estimates in sign and magnitude:

result = model.fit(method="profile-trust-region", maxiter=200)

If n_exog == 0 the method falls back to the regular trust-region path. When simple_differencing=True, the same differencing operator is now applied to both endog and every exog column so that the regression Δy_t = (Δx_t) β + ARMA noise is solved on a consistent pre-differenced dataset. See rustima/docs/profiled_kalman_gls_plan.md for the algorithm, parameter-level comparison against statsmodels and R, and init-scheme caveats.

Batched Kalman filter inside PTR. Each profiled-likelihood evaluation runs the Kalman filter on y and once per exogenous column x_j at the same ψ; the state-space matrices, predicted covariance, gain, and innovation variance are bit-identical across these passes. rustima's kalman_filter_batched shares the O(k²) covariance recursion once and runs only the cheap O(k) mean recursion per series. For r=2 exog the per-evaluation Kalman cost drops from (1+r) = 3 full passes to 1 full pass plus three cheap mean updates — about a 2× per-PTR-fit speedup. Implementation: rustima/src/kalman.rs::kalman_filter_batched, called from ProfiledSarimaxObjective::profile_beta_and_loglike.

Parallel stepwise neighborhood search. auto_arima(stepwise=True) evaluates the 8–10 candidates around the current best in a single Rayon-parallel rustima.sarimax_grid_search call rather than one-by-one. On a 12-core machine the inner trust-region BFGS routines run concurrently, so each Hyndman-Khandakar step finishes in roughly the time of the slowest neighbour rather than the sum of all neighbours.

Automatic CPU pinning on Apple Silicon (macOS). On import, rustima/python/rustima/__init__.py detects the P-core count via sysctl hw.perflevel0.physicalcpu and exports RAYON_NUM_THREADS=<P-core count> before the native extension loads. This avoids E-cores becoming the per-step critical path on heterogeneous chips (M-series), yielding a 20–35% wall-time reduction on compute-heavy SARIMAX fits. The behaviour is a no-op on Linux/Windows and on macOS systems where the user has already set RAYON_NUM_THREADS themselves.

Batch Parallel Processing

# Fit 100 series with job-level Rayon parallelism
series_list = [np.random.randn(200) for _ in range(100)]

results = rustima.sarimax_batch_fit(
    series_list, order=(1, 0, 0), seasonal=(0, 0, 0, 0)
)

for i, r in enumerate(results):
    print(f"Series {i}: converged={r['converged']}, AIC={r['aic']:.2f}")

# Batch forecast with per-series parameters
params_list = [np.array(r["params"]) for r in results]
forecasts = rustima.sarimax_batch_forecast(
    series_list, order=(1, 0, 0), seasonal=(0, 0, 0, 0),
    params_list=params_list, steps=10, alpha=0.05,
)

Grid Search Parallel Processing

# Fit multiple ARIMA orders via Rayon in one call
results = rustima.sarimax_grid_search(
    y,
    order_list=[(0,1,0), (1,1,0), (1,1,1), (2,1,1)],
    seasonal_list=[(0,0,0,0)] * 4,
    trend="c",
)
for r in results:
    if "error" not in r:
        print(f"{r['order']}: AIC={r['aic']:.3f}")

Architecture

System Overview

graph TB
    subgraph Python["Python Layer"]
        USER["User Code"]
        MODEL["SARIMAXModel<br/><i>python/rustima/model.py</i>"]
        AUTO["auto_arima<br/><i>python/rustima/auto.py</i>"]
        USER --> MODEL
        USER --> AUTO
    end

    subgraph PyO3["PyO3 Bindings — lib.rs"]
        FIT["sarimax_fit()"]
        LL["sarimax_loglike()"]
        FC["sarimax_forecast()"]
        RES["sarimax_residuals()"]
        BF["sarimax_batch_fit()"]
        BFC["sarimax_batch_forecast()"]
        BLL["sarimax_batch_loglike()"]
        GS["sarimax_grid_search()"]
        INF["sarimax_inference()"]
        DIAG["sarimax_diagnostics()"]
    end

    MODEL --> FIT
    MODEL --> FC
    MODEL --> RES
    MODEL --> INF
    MODEL --> DIAG
    AUTO --> GS
    AUTO --> FIT
    USER --> BF
    USER --> BFC
    USER --> BLL

    subgraph Rust["Rust Engine"]
        OPT["optimizer.rs<br/>L-BFGS-B + L-BFGS + Nelder-Mead"]
        KAL["kalman.rs<br/>Kalman filter / log-likelihood"]
        FCAST["forecast.rs<br/>h-step prediction + residuals"]
        BATCH["batch.rs<br/>Rayon par_iter()"]
        SS["state_space.rs<br/>Harvey representation T, Z, R, Q"]
        INIT["initialization.rs<br/>Approximate diffuse init"]
        SP["start_params.rs<br/>Hannan-Rissanen + CSS"]
        POLY["polynomial.rs<br/>AR/MA polynomial expansion"]
        PAR["params.rs<br/>Monahan transform"]
        SCR["score.rs<br/>Analytical gradient"]
        INFER["inference.rs<br/>Hessian / OPG"]
    end

    FIT --> OPT
    LL --> KAL
    FC --> FCAST
    RES --> FCAST
    BF --> BATCH
    BFC --> BATCH
    BLL --> BATCH
    GS --> BATCH
    INF --> INFER

    BATCH --> OPT
    BATCH --> FCAST
    OPT --> KAL
    OPT --> SP
    OPT --> SCR
    FCAST --> KAL
    KAL --> SS
    KAL --> INIT
    SS --> POLY
    SS --> PAR
    OPT --> PAR
    SCR --> KAL
    INFER --> KAL

    style Python fill:#3776ab,color:#fff
    style PyO3 fill:#f7a41d,color:#000
    style Rust fill:#dea584,color:#000

Model Fitting Flow

sequenceDiagram
    participant P as Python
    participant L as lib.rs (PyO3)
    participant O as optimizer.rs
    participant S as start_params.rs
    participant K as kalman.rs
    participant SS as state_space.rs
    participant PR as params.rs
    participant SC as score.rs

    P->>L: sarimax_fit(y, order, seasonal, trend)
    L->>L: Build SarimaxConfig (incl. trend)
    L->>O: fit(endog, config, method, maxiter)

    O->>S: compute_start_params(endog, config)
    S->>S: Differencing → Hannan-Rissanen / Burg+CSS
    S-->>O: initial θ₀

    O->>PR: untransform_params(θ₀)
    PR-->>O: unconstrained x₀

    loop L-BFGS-B iteration (default max 200)
        O->>PR: transform_params(x_k)
        PR-->>O: constrained θ_k
        O->>SS: StateSpace::new(config, θ_k, y)
        SS->>SS: Build T, Z, R, Q matrices + state_intercept(c_t)
        SS-->>O: state_space
        O->>K: kalman_loglike(y, ss, init)
        K->>K: Predict → Observe → Update loop
        K-->>O: loglike, scale
        O->>SC: score(y, ss, init, config, params)
        SC-->>O: analytical gradient
        O->>O: cost = -loglike
        Note over O: Convergence check (pgtol / factr)
    end

    alt L-BFGS-B fails
        O->>O: Nelder-Mead fallback (max 500 iter)
    end

    O->>PR: transform_params(x_final)
    PR-->>O: θ_final
    O->>O: AIC = -2·ll + 2·k<br/>BIC = -2·ll + k·ln(n)
    O-->>L: FitResult
    L-->>P: dict

Forecast Flow

sequenceDiagram
    participant P as Python
    participant L as lib.rs
    participant F as forecast.rs
    participant K as kalman.rs
    participant SS as state_space.rs

    P->>L: sarimax_forecast(y, order, seasonal, params, steps, alpha, trend)
    L->>F: forecast_pipeline(endog, config, params, steps, alpha)

    F->>SS: StateSpace::new(config, params, endog)
    SS-->>F: state_space (T, Z, R, Q)

    F->>K: kalman_filter(endog, ss, init)
    K->>K: Full Kalman filter over time series
    K-->>F: KalmanFilterOutput (filtered_state, filtered_cov, scale)

    F->>F: forecast(ss, filter_output, steps, alpha)

    loop h = 1 to steps
        F->>F: ŷ_h = Z' · â_h
        F->>F: Var_h = Z' · P̂_h · Z · σ²
        F->>F: CI_h = ŷ_h ± z(α/2) · √Var_h
        F->>F: â_{h+1} = T · â_h + c_{n+h}  (trend state_intercept)
        F->>F: P̂_{h+1} = T · P̂_h · T' + R·Q·R'
    end

    F-->>L: ForecastResult (mean, variance, ci_lower, ci_upper)
    L-->>P: dict

Batch & Grid Search Parallel Processing Flow

sequenceDiagram
    participant P as Python
    participant L as lib.rs
    participant B as batch.rs
    participant R as Rayon ThreadPool

    P->>L: sarimax_batch_fit(series_list, order, seasonal)
    L->>L: Convert Vec<Vec<f64>> (GIL held)
    L->>B: batch_fit(series, config, method, maxiter)

    B->>R: series.par_iter()

    par [Rayon parallel execution]
        R->>R: Thread 0: optimizer::fit(series[0])
        R->>R: Thread 1: optimizer::fit(series[1])
        R->>R: Thread N: optimizer::fit(series[N])
    end

    R-->>B: Vec<Result<FitResult>>
    B-->>L: results
    L-->>P: List[dict]

    Note over P,R: grid_search: same data + different order combos in parallel

    P->>L: sarimax_grid_search(y, order_list, seasonal_list)
    L->>B: grid_search_fit(endog, configs)
    B->>R: configs.par_iter()

    par [Rayon parallel — order combinations]
        R->>R: Thread 0: fit(endog, config[0])
        R->>R: Thread 1: fit(endog, config[1])
        R->>R: Thread N: fit(endog, config[N])
    end

    R-->>B: Vec<Result<FitResult>>
    B-->>L: results (with order keys)
    L-->>P: List[dict]

Python API Reference

Low-Level Functions (rustima)

rustima.sarimax_loglike

Computes log-likelihood at given parameters.

ll = rustima.sarimax_loglike(
    y,
    order=(1, 1, 1),           # (p, d, q)
    seasonal=(1, 1, 1, 12),    # (P, D, Q, s)
    params=np.array([0.5, 0.3, 0.2, -0.4]),  # [ar, ma, sar, sma]
    concentrate_scale=True,    # concentrate sigma2 in likelihood
    trend="c",                 # trend: "n", "c", "t", "ct"
)

rustima.sarimax_fit

Fits model via MLE.

result = rustima.sarimax_fit(
    y,
    order=(1, 0, 1),
    seasonal=(0, 0, 0, 0),
    enforce_stationarity=True,   # AR stationarity constraint
    enforce_invertibility=True,  # MA invertibility constraint
    method="lbfgsb",             # "lbfgsb" | "lbfgsb-multi" | "lbfgs" | "bfgs"
                                 # | "trust-region" | "profile-trust-region"
                                 # | "nelder-mead"
    maxiter=500,
    trend="c",
)

Return dict:

Key Type Description
params list[float] Estimated parameters [trend..., exog..., ar..., ma..., sar..., sma...]
loglike float Final log-likelihood
scale float Estimated variance (sigma2)
aic float AIC
bic float BIC
n_obs int Number of observations
n_params int Number of estimated parameters (incl. sigma2)
n_iter int Optimizer iterations (L-BFGS, NM) or function evaluations (L-BFGS-B)
converged bool True convergence, not just maxiter reached
method str Optimization method used

rustima.sarimax_forecast

Performs h-step ahead forecast with confidence intervals.

fc = rustima.sarimax_forecast(
    y,
    order=(1, 0, 0),
    seasonal=(0, 0, 0, 0),
    params=np.array([0.65]),
    steps=10,
    alpha=0.05,        # 95% confidence interval
    exog=X_train,      # past exog if model uses exog
    future_exog=X_future,
    trend="c",
)

print(fc["mean"])       # point forecast (list[float])
print(fc["ci_lower"])   # lower bound
print(fc["ci_upper"])   # upper bound
print(fc["variance"])   # forecast variance

rustima.sarimax_residuals

Computes residuals and standardized residuals.

res = rustima.sarimax_residuals(
    y,
    order=(1, 0, 1),
    seasonal=(0, 0, 0, 0),
    params=np.array([0.5, 0.3]),
    trend="c",
)

print(res["residuals"])                # innovations v_t
print(res["standardized_residuals"])   # v_t / sqrt(F_t * sigma2)

rustima.sarimax_batch_fit

Fits N series in parallel using a Rayon thread pool, with one complete fit job per series.

results = rustima.sarimax_batch_fit(
    series_list,
    order=(1, 0, 0),
    seasonal=(0, 0, 0, 0),
    enforce_stationarity=True,
    method="lbfgsb",
    maxiter=500,
    trend="c",
)
# Returns: list[dict] — same keys as sarimax_fit
# Failed series: {"error": "...", "converged": false}

rustima.sarimax_batch_forecast

Forecasts N series (each with different params) in parallel, with one complete forecast job per series.

params_list = [np.array(r["params"]) for r in results]

forecasts = rustima.sarimax_batch_forecast(
    series_list,
    order=(1, 0, 0),
    seasonal=(0, 0, 0, 0),
    params_list=params_list,
    steps=10,
    alpha=0.05,
)
# Returns: list[dict] with mean, variance, ci_lower, ci_upper

rustima.sarimax_grid_search

Fits a single series with multiple ARIMA order combinations in parallel via Rayon, with one complete fit job per configuration.

results = rustima.sarimax_grid_search(
    y,
    order_list=[(1,0,0), (1,0,1), (2,0,0)],
    seasonal_list=[(0,0,0,0)] * 3,
    enforce_stationarity=True,
    enforce_invertibility=True,
    trend="c",
    method="lbfgsb",
    maxiter=500,
)
# Returns: list[dict] — same keys as sarimax_fit + "order", "seasonal_order"

rustima.sarimax_inference

Computes Hessian or OPG-based inference statistics on fitted parameters.

inf = rustima.sarimax_inference(
    y, order=(1,0,1), seasonal=(0,0,0,0),
    params=np.array([0.5, 0.3]),
    method="hessian",   # "hessian" | "opg"
    alpha=0.05,
    trend="c",
)
print(inf["std_err"])   # standard errors
print(inf["z_stat"])    # z statistics
print(inf["p_value"])   # two-sided p-values
print(inf["ci_lower"])  # CI lower bound
print(inf["ci_upper"])  # CI upper bound

rustima.sarimax_diagnostics

Performs residual diagnostic tests.

diag = rustima.sarimax_diagnostics(
    y, order=(1,0,1), seasonal=(0,0,0,0),
    params=np.array([0.5, 0.3]),
    trend="c",
)
print(diag["ljung_box_stat"])     # Ljung-Box Q statistic
print(diag["ljung_box_pvalue"])   # Ljung-Box p-value
print(diag["jarque_bera_stat"])   # Jarque-Bera normality
print(diag["het_stat"])           # Heteroskedasticity test

High-Level Classes (rustima)

statsmodels-compatible Python wrapper using the Rust engine.

SARIMAXModel

from rustima import SARIMAXModel

model = SARIMAXModel(
    endog=y,                        # time series data
    order=(1, 1, 1),                # ARIMA(p, d, q)
    seasonal_order=(1, 0, 0, 12),   # (P, D, Q, s)
    exog=X,                         # optional: exogenous regressors
    trend="c",                      # trend: 'n', 'c', 't', 'ct'
    enforce_stationarity=True,
    enforce_invertibility=True,
)

SARIMAXResult

Returned by model.fit().

result = model.fit(method="lbfgsb", maxiter=500)

# Attributes
result.params          # np.ndarray — estimated parameters
result.param_names     # list[str] — e.g. ['intercept', 'ar.L1', 'ma.L1']
result.llf             # float — log-likelihood
result.aic             # float — AIC
result.bic             # float — BIC
result.hqic            # float — HQIC (Hannan-Quinn)
result.scale           # float — sigma2
result.nobs            # int — number of observations
result.converged       # bool — convergence status
result.method          # str — optimization method
result.resid           # np.ndarray — standardized residuals (lazy computed)

# Methods
result.forecast(steps=10, alpha=0.05)     # → ForecastResult
result.forecast(steps=10, exog=X_future)  # with future exog
result.get_forecast(steps=10, alpha=0.05) # alias (statsmodels compat)
result.get_prediction(start=0, end=210)   # → PredictionResult (in-sample + OOS)
result.summary()                          # → str (default: parameter table)
result.summary(inference="hessian")       # → str (std err / z / p / CI)
result.summary(inference="statsmodels")   # → str (statsmodels inference values)
result.summary(inference="both")          # → str (side-by-side comparison)
result.params_table(inference="hessian")  # → Polars DataFrame
result.diagnostics()                      # → dict (Ljung-Box, Jarque-Bera, het)

# Machine-friendly parameter summary dict
ps = result.parameter_summary(alpha=0.05, inference="hessian")

Parameter vector layout:

[trend(kt) | exog(k) | ar(p) | ma(q) | sar(P) | sma(Q)]

Parameter name convention (consistent with statsmodels):

Component Name
Constant (trend='c') intercept
Linear trend (trend='t') drift
Constant + linear (trend='ct') intercept, drift
Exogenous regressors x1, x2, ..., xk
AR ar.L1, ar.L2, ..., ar.Lp
MA ma.L1, ma.L2, ..., ma.Lq
Seasonal AR ar.S.L{s}, ar.S.L{2s}, ..., ar.S.L{Ps}
Seasonal MA ma.S.L{s}, ma.S.L{2s}, ..., ma.S.L{Qs}
Variance sigma2 (only when concentrate_scale=False)

ForecastResult

fcast = result.forecast(steps=10)

fcast.predicted_mean   # np.ndarray — point forecasts
fcast.variance         # np.ndarray — forecast variance
fcast.ci_lower         # np.ndarray — CI lower bound
fcast.ci_upper         # np.ndarray — CI upper bound

fcast.conf_int()       # np.ndarray (steps, 2) — [lower, upper]
fcast.conf_int(0.10)   # recalculate with different alpha
fcast.to_dataframe()   # Polars DataFrame (step, mean, variance, ci_lower, ci_upper)

PredictionResult

pred = result.get_prediction(start=0, end=210)

pred.predicted_mean    # np.ndarray — predictions (in-sample + OOS)
pred.to_dataframe()    # Polars DataFrame (index, predicted_mean)

AutoARIMAResult

from rustima import auto_arima

res = auto_arima(y, max_p=5, max_q=5, s=12)

res.result             # SARIMAXResult — best model fit result
res.order              # tuple (p, d, q) — best order
res.seasonal_order     # tuple (P, D, Q, s)
res.best_ic            # float — best information criterion value
res.criterion          # str — criterion used ("aic", "bic", "hqic")
res.history            # list[dict] — search history
res.summary()          # str — full statsmodels-style summary with inference
res.search_summary()   # str — short 3-line search summary
res.history_dataframe()  # Polars DataFrame — search history table

Core Algorithms

1. State-Space Representation (state_space.rs)

Converts SARIMA(p,d,q)(P,D,Q,s) to the Harvey (1989) representation.

State equation:

alpha_{t+1} = T * alpha_t + c_t + R * eta_t,    eta_t ~ N(0, Q)
y_t         = Z' * alpha_t + d_t + eps_t,        eps_t ~ N(0, H), H=0

State vector alpha dimension: k_states = k_states_diff + k_order, where

  • k_states_diff = d + s*D (differencing states)
  • k_order = max(p + s*P, q + s*Q + 1) (ARMA companion matrix dimension)

2. Kalman Filter (kalman.rs)

Standard Harvey-form Kalman filter for log-likelihood evaluation.

For each t = 0, ..., n-1:
  1. Innovation:           v_t = y_t - Z' * a_{t|t-1} - d_t
  2. Innovation variance:  F_t = Z' * P_{t|t-1} * Z
  3. Kalman gain:          K_t = P_{t|t-1} * Z / F_t
  4. State update:         a_{t|t} = a_{t|t-1} + K_t * v_t
  5. Covariance update:    P_{t|t} = (I - K*Z') * P * (I - K*Z')'  [Joseph form]
  6. Prediction:           a_{t+1|t} = T * a_{t|t} + c_t
  7. Covariance prediction: P_{t+1|t} = T * P_{t|t} * T' + R*Q*R'

Concentrated log-likelihood (concentrate_scale=true, default):

σ²_hat = (1/n_eff) * Σ(v_t² / F_t)
loglike = -n_eff/2 * ln(2π) - n_eff/2 * ln(σ²_hat) - n_eff/2 - 0.5 * Σ ln(F_t)

3. Analytical Score Vector (score.rs)

Computes ∂loglike/∂θ via tangent-linear Kalman filter (Koopman & Shephard, 1992; Harvey, 1989) in a single forward pass, avoiding the O(n_params + 1) cost of numerical differentiation. To our knowledge, this is the first Rust implementation of the analytical exact score for state-space models.

Performance optimizations:

  • Sparse T: Exploits companion matrix T sparsity to reduce O(k³) → O(nnz×k) (~23x speedup at k=27)
  • Steady-state detection: Once P converges, freezes dP/dz/dF and updates only da/dv, skipping O(k³×np) ops for all subsequent timesteps

4. Parameter Transform (params.rs)

Optimization in unconstrained space, evaluation in constrained space.

Stationarity constraint (AR) — Monahan (1984) / Jones (1980):

Unconstrained → PACF:  r_k = x_k / sqrt(1 + x_k²)
PACF → AR coefficients: Levinson-Durbin recursion

5. Optimizer (optimizer.rs)

Minimizes negative log-likelihood.

Strategy:

  1. Starting values: Hannan-Rissanen (seasonal) or CSS-based estimation (start_params.rs)
  2. L-BFGS-B (default): Bounded + analytical gradient, pgtol=1e-5, factr=1e7
  3. L-BFGS-B multi-start: 3 perturbed restarts for robustness
  4. L-BFGS: MoreThuente line search, grad_tol=1e-8, cost_tol=1e-12
  5. Nelder-Mead fallback: Auto-switch on L-BFGS failure, 5% scale simplex
  6. Information criteria: AIC = -2·ll + 2·k, BIC = -2·ll + k·ln(n), HQIC = -2·ll + 2·k·ln(ln(n))

6. Forecast (forecast.rs)

h-step ahead prediction from the Kalman filter's final state.

For each forecast step h = 1, ..., steps:
  ŷ_h = Z' · â_h                   (point forecast)
  F_h = Z' · P̂_h · Z · σ²          (forecast variance)
  CI_h = ŷ_h ± z_{α/2} · √F_h      (confidence interval)
  â_{h+1} = T · â_h + c_{n+h}       (state propagation + trend)
  P̂_{h+1} = T · P̂_h · T' + R·Q·R'  (covariance propagation)

7. Batch & Grid Search Parallelism (batch.rs)

Uses Rayon par_iter() for work-stealing parallelism at the independent-job level.

Batch processing (same order + different series):

  • All series share the same SarimaxConfig (Clone, Send + Sync)
  • Each worker independently runs one full StateSpace::new()fit() / forecast_pipeline() pipeline for one series
  • Failed series do not affect others (Vec<Result<T>>)

Grid search (same series + different orders):

  • grid_search_fit(endog, configs) — parallel over order combinations via configs.par_iter(), one full fit per config

Benchmarks

All benchmarks run on macOS 15.1 (Apple Silicon arm64), Python 3.14, rustima 0.1.0 vs statsmodels 0.14.6.

Accuracy vs statsmodels

Both engines fitted with enforce_stationarity=True, enforce_invertibility=True, concentrate_scale=True, trend='n' on identical data.

Model n k Max |Δparam| |Δloglike| |ΔAIC|
AR(1) 200 1 0.000124 0.0000 0.0000
AR(2) 300 2 0.001902 0.0007 0.0013
MA(1) 200 1 0.003862 0.0015 0.0031
ARMA(1,1) 300 2 0.004170 0.0048 0.0096
ARIMA(1,1,1) 300 2 0.026525 0.0011 0.0022
ARIMA(2,1,1) 400 3 0.833380 0.4884 0.9768
SARIMA(1,0,0)(1,0,0,4) 200 2 0.002865 0.0014 0.0028
SARIMA(0,1,1)(0,1,1,12) 300 2 0.054174 1.1886 2.3771
SARIMA(1,1,1)(1,1,1,12) 300 4 0.006335 0.0012 0.0025

Parameter accuracy within 0.006 and log-likelihood difference within 0.005 for most models.

High-Order Models — Accuracy vs statsmodels

16 models from non-seasonal ARIMA(4–5) to hourly (s=24) high-order SARIMA. rs_worse_by shows how much lower the rustima log-likelihood is versus statsmodels; negative (★) means rustima found a better optimum.

Model k_states rs_worse_by Result
ARIMA(4,1,1) 5 +0.002 Pass
ARIMA(4,1,4) 6 -2.07 Pass ★
ARIMA(3,1,3) 5 +0.004 Pass
ARIMA(5,1,1) 6 ~0 Pass
ARIMA(1,1,5) 7 ~0 Pass
SARIMA(3,1,2)(2,1,1,4) 16 +0.86 Pass
SARIMA(2,1,1)(2,1,1,4) 15 +2.40 Pass
SARIMA(2,1,2)(1,1,1,7) 18 +0.003 Pass
SARIMA(3,1,1)(1,1,1,7) 18 +0.04 Pass
SARIMA(4,1,1)(2,1,1,12) 41 +0.07 Pass
SARIMA(4,1,4)(2,1,2,12) 42 +5.90 Pass
SARIMA(2,1,2)(2,1,1,12) 39 -2.46 Pass ★
SARIMA(3,1,1)(2,1,1,12) 40 +0.05 Pass
SARIMA(2,1,1)(2,1,1,24) 75 +1.35 Pass
SARIMA(2,1,2)(1,1,1,24) 52 +1.01 Pass
SARIMA(1,1,1)(2,1,1,24) 74 +0.32 Pass

16/16 pass. ★ models: statsmodels issued ConvergenceWarning and failed to converge, while rustima found a better solution.


Speed — Single Fit

Best-of-5 wall clock time (lower is better):

Model rustima statsmodels Speedup
AR(1) n=200 0.0 ms 2.9 ms 66.8x
ARMA(1,1) n=300 0.1 ms 6.1 ms 41.6x
ARIMA(1,1,1) n=300 0.4 ms 7.6 ms 17.9x
ARIMA(2,1,2) n=400 1.5 ms 31.4 ms 20.4x
SARIMA(1,1,1)(1,1,1,12) n=300 122.6 ms 928.7 ms 7.6x
SARIMA(1,0,0)(1,0,0,7) n=365 0.5 ms 19.9 ms 38.0x
SARIMA(1,1,1)(1,1,1,24) n=2160 2547.8 ms 7364.5 ms 2.9x

Average 27.9x, max 66.8x. Non-seasonal models: 17–67x faster; high-order seasonal SARIMA: 2.9–7.6x faster.

Speed — Batch Fit (Rayon Parallel)

AR(1) n=200/series:

Batch Size rustima statsmodels Speedup
10 series 0.2 ms 32.2 ms 165.7x
50 series 0.7 ms 157.3 ms 232.4x
100 series 1.2 ms 312.2 ms 269.8x

Speed — Grid Search Parallel vs Sequential

Scenario Parallel (ms) Sequential (ms) Speedup
n=200, 9 combos 1.2 1.8 1.53x
n=500, 9 combos 2.0 4.3 2.16x
n=500, 25 combos 0.9 4.3 4.59x
n=2000, 9 combos 2.5 11.2 4.53x

Speed — auto_arima

Scenario n Mode Time Models AIC
Daily s=7 (2yr) 730 stepwise 5.68s 23 1099.16
Daily s=7 (2yr) 730 grid (parallel) 4.52s 81 1099.16
Hourly s=24 (90d) 2160 stepwise 19.21s 17 3222.21
Hourly s=24 (90d) 2160 grid (parallel) 2.59s 16 3222.21
Hourly s=24 (30d) 720 stepwise 20.04s 17 1099.85
Hourly s=24 (30d) 720 grid (parallel) 1.66s 16 1246.49

Grid search with Rayon parallelization is up to 12x faster than stepwise on hourly (s=24) data.


Project Structure

rustima/
├── Cargo.toml                      # Rust dependencies and build config
├── pyproject.toml                   # Python package config (maturin)
├── build.rs                         # cc build script (compiles lbfgsb_c/)
│
├── src/                             # Rust engine (19 modules, ~11,960 LOC)
│   ├── lib.rs                       # PyO3 module entry point (11 Python functions)
│   ├── types.rs                     # SarimaxOrder, SarimaxConfig, Trend, FitResult
│   ├── error.rs                     # SarimaxError (thiserror-based)
│   ├── params.rs                    # Parameter struct + Monahan/Jones transform
│   ├── polynomial.rs                # AR/MA polynomial expansion (polymul, reduced_ar/ma)
│   ├── state_space.rs               # Harvey state-space T, Z, R, Q, c_t construction
│   ├── initialization.rs            # Approximate diffuse / DARE initialization
│   ├── kalman.rs                    # Kalman filter (loglike + full filter)
│   ├── score.rs                     # Analytical gradient (sparse tangent-linear + steady-state)
│   ├── css.rs                       # Conditional sum-of-squares log-likelihood
│   ├── inference.rs                 # Numerical Hessian / OPG inference
│   ├── start_params.rs              # Hannan-Rissanen + CSS initial parameter estimation
│   ├── optimizer.rs                 # L-BFGS-B + L-BFGS + Nelder-Mead MLE
│   ├── forecast.rs                  # h-step prediction + residuals + z_score
│   ├── batch.rs                     # Rayon-based batch/grid search parallel processing
│   ├── pipeline.rs                  # Shared helpers (kalman_eval, kalman_filter_full)
│   ├── lbfgsb_ffi.rs                # L-BFGS-B C FFI bindings (unsafe extern)
│   ├── lbfgsb_wrapper.rs            # Safe Rust wrapper around L-BFGS-B C solver
│   └── test_helpers.rs              # Shared test utilities (cfg(test) only)
│
├── python/
│   └── rustima/                     # Python package (native ext + high-level API)
│       ├── __init__.py              # Package exports (low-level + high-level API)
│       ├── model.py                 # SARIMAXModel, SARIMAXResult, ForecastResult, PredictionResult
│       ├── auto.py                  # auto_arima, AutoARIMAResult
│       └── rustima.*.so             # Compiled Rust extension (built by maturin)
│
├── python_tests/                    # Python integration tests (371 tests, 16 modules)
│   ├── conftest.py                  # pytest fixtures
│   ├── generate_fixtures.py         # statsmodels reference data generator
│   └── test_*.py                    # test_fit, test_forecast, test_batch, test_exog, etc.
│
├── lbfgsb_c/                        # L-BFGS-B C source (compiled via cc build-dep)
│   ├── lbfgsb.c                     # Main L-BFGS-B solver
│   ├── lbfgsb.h                     # Header
│   ├── linesearch.c                 # Line search subroutine
│   ├── linpack.c                    # LINPACK routines
│   └── miniCBLAS.c                  # Minimal CBLAS routines
│
├── tests/fixtures/                  # statsmodels reference data (JSON)
│
└── benches/                         # Criterion benchmarks
    ├── bench_kalman.rs              # Kalman loglike performance
    └── bench_fit.rs                 # Single/batch fit performance

Dependencies

Rust (Cargo.toml)

Crate Version Purpose
nalgebra 0.34 Dynamic matrix/vector operations (DMatrix, DVector)
argmin 0.11 L-BFGS, Nelder-Mead optimization framework
argmin-math 0.5 nalgebra integration for argmin
anyhow 1 Error context propagation
statrs 0.18 Statistical distributions
rayon 1.10 Data parallelism (work-stealing thread pool)
pyo3 0.28 Python C-API bindings
numpy 0.28 NumPy array zero-copy interop
thiserror 2 Error type macros
serde / serde_json 1 Test fixture serialization
cc 1 C compiler driver (build-dep, compiles lbfgsb_c/)

Note: L-BFGS-B is not a crate dependency — it is compiled from vendored C source (lbfgsb_c/) via cc and called through a safe Rust FFI wrapper (lbfgsb_ffi.rs + lbfgsb_wrapper.rs).

Python (pyproject.toml)

Package Purpose
numpy >= 1.24 Array operations (runtime)
polars >= 1.0 DataFrame output (runtime)
ipykernel >= 7.2 Jupyter notebook integration (runtime)
pytest >= 7.0 Test framework (dev)
statsmodels >= 0.14 Reference result generation (dev)
scipy >= 1.10 Statistical utilities (dev)
pandas >= 2.0 Benchmark comparison utilities (dev)
matplotlib >= 3.7 Visualization for benchmarks/reports (dev)
maturin >= 1.7 Rust → Python wheel build (dev)

Development

# Rust unit tests (155 tests)
cargo test --all-targets

# Python integration tests (371 tests, wheel build required first)
uv run maturin develop --release
uv run python -m pytest python_tests/ -v

# Run a single Python test
uv run python -m pytest python_tests/test_fit.py::test_arima_111_fit -v

# Run a single Rust test
cargo test test_name

# Benchmarks
cargo bench

# Regenerate statsmodels reference fixtures
uv run python python_tests/generate_fixtures.py

Test Summary

Category Tests Coverage
Rust unit tests 155 types, params, polynomial, state_space, initialization, kalman, score, css, inference, start_params, optimizer, forecast, batch
Python smoke 14 import, version, basic API checks
Python fit 13 fitting, AIC/BIC, convergence, start_params, Nelder-Mead
Python forecast 9 forecast mean, CI, residuals vs statsmodels
Python input validation 64 param length, seasonal D/s, bounds, exog, NaN/Inf
Python batch 6 batch fit/forecast, parallel perf, error isolation
Python exog 14 exogenous regressors, future_exog, batch exog
Python multi-order accuracy 27 multi-order cross-validation vs statsmodels
Python high-order accuracy 20 ARIMA(4–5), SARIMA(4,1,4)(2,1,2,12), s=24
Python inference 70 Rust Hessian/OPG inference, statsmodels parity
Python trend 16 trend='n','c','t','ct' fit/forecast/residuals/summary
Python Polars 14 to_dataframe(), params_table(), PredictionResult, HQIC
Python auto_arima 19 stepwise, grid, history, criterion, summary
Python safety guards 44 edge case safety, bounds checking
Python simple differencing 22 simple_differencing=True path
Python matrix tier A 12 state-space matrix construction validation
Python prediction quality 7 in-sample/out-of-sample prediction accuracy
Total 526 155 Rust + 371 Python

Troubleshooting & FAQ

Install / Build problems

error: linker 'cc' not found / failed to run custom build command for 'rustima' You don't have a C compiler. On macOS run xcode-select --install; on Ubuntu sudo apt install build-essential; on Windows install MSVC Build Tools.

ModuleNotFoundError: No module named 'rustima' after maturin develop The Rust extension was built but Python can't find it. Check you are running Python inside the same venv:

uv run python -c "import sys; print(sys.executable)"
# Should point to .venv/bin/python inside the rustima/ folder

If you're in Jupyter, make sure you selected the "rustima" kernel (see Installation).

Jupyter notebook says rustima is missing even though uv run python works Your notebook kernel is pointing to a different Python. Re-register it:

uv run python -m ipykernel install --user --name rustima --display-name "rustima"

Then restart the kernel and pick "rustima" from the kernel menu.

error: can't find Rust compiler Install Rust: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh, then source ~/.cargo/env.

Modeling questions

My model didn't converge (converged=False). What now?

  1. If the model has exogenous regressors, try method="profile-trust-region" — it eliminates β from the nonlinear search by Kalman-GLS profiling and often matches R stats::arima β estimates more closely.
  2. Try method="nelder-mead" (slower but more robust)
  3. Increase maxiter=1000
  4. Reduce the orders — high p, q, P, Q often fail to identify
  5. Check your data has no NaN/Inf: np.isfinite(y).all() should be True

auto_arima takes forever on my hourly data (s=24) Use stepwise=False to switch to the Rayon-parallel grid search. On hourly data it's often 10x faster than stepwise (see benchmarks).

My forecast looks like a flat line Usually means d=0 on a trending series, or the model decided the best prediction is the mean. Try setting d=1 manually, or add trend='c' / trend='t'.

Results are slightly different from statsmodels Expected. rustima uses L-BFGS-B with analytical gradients (statsmodels uses L-BFGS with numerical gradients). Differences within |ΔAIC| < 2 are normal. See the accuracy benchmarks above.

How do I know which order / seasonal_order to use?

  1. Easy path: just call auto_arima(y, s=<period>) and use what it picks
  2. Theory path: ACF/PACF plots + unit-root tests — see FPP3 Ch. 9

When should I use simple_differencing=True? Only when you want to match R's default behavior or reproduce results with R-style AIC/BIC on a pre-differenced series. Default (False) matches statsmodels. When True, the same differencing operator is applied to both endog and every exog column (so the regression Δy_t = (Δx_t) β + noise is fitted on a consistently pre-differenced dataset). LL/AIC on this path uses n = n_obs − d − s·D effective observations.

Why does my exog SARIMAX LL differ from statsmodels on the simple_differencing=True path? Under matched enforce_stationarity=False, enforce_invertibility=False, rustima's Kalman log-likelihood at the same parameter vector is bit- identical to statsmodels. Under enforce=True, the two engines initialize the stationary state covariance with different schemes, which accumulates a likelihood-scale offset over n. Parameter estimates remain close. For like-for-like LL comparisons across engines on exogenous models, prefer the exact path (simple_differencing=False) where this divergence does not appear.

Performance

Why is the first fit slow but subsequent ones fast? Python imports, Rust JIT-friendly compilation of specialized monomorphizations, and Rayon thread-pool warmup. Warm up once before benchmarking.

Debug build is slower than statsmodels! Always build with --release. Without it, Rust runs with no optimizations and is ~10× slower than a release build.

Limitations

  • Seasonal differencing D > 1 not supported (only D = 0 or 1)
  • Maximum forecast steps: 10,000; alpha must be in (0, 1)
  • State dimension capped at 1,024 (bounds memory and compute blow-up on extreme orders, but does not eliminate OOM risk in the absolute sense)
  • auto_arima automatic differencing detection uses ADF test (scipy) or variance-reduction heuristic

License

GPL-3.0-or-later. See LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rustima-0.2.0.tar.gz (969.2 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

rustima-0.2.0-cp314-cp314-win_amd64.whl (777.0 kB view details)

Uploaded CPython 3.14Windows x86-64

rustima-0.2.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (948.9 kB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ x86-64

rustima-0.2.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (890.8 kB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ ARM64

rustima-0.2.0-cp314-cp314-macosx_11_0_arm64.whl (831.6 kB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

rustima-0.2.0-cp314-cp314-macosx_10_12_x86_64.whl (887.0 kB view details)

Uploaded CPython 3.14macOS 10.12+ x86-64

rustima-0.2.0-cp313-cp313-win_amd64.whl (776.3 kB view details)

Uploaded CPython 3.13Windows x86-64

rustima-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (949.1 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

rustima-0.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (891.2 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ ARM64

rustima-0.2.0-cp313-cp313-macosx_11_0_arm64.whl (831.0 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

rustima-0.2.0-cp313-cp313-macosx_10_12_x86_64.whl (887.1 kB view details)

Uploaded CPython 3.13macOS 10.12+ x86-64

rustima-0.2.0-cp312-cp312-win_amd64.whl (776.8 kB view details)

Uploaded CPython 3.12Windows x86-64

rustima-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (949.6 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

rustima-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (891.7 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64

rustima-0.2.0-cp312-cp312-macosx_11_0_arm64.whl (831.6 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

rustima-0.2.0-cp312-cp312-macosx_10_12_x86_64.whl (889.1 kB view details)

Uploaded CPython 3.12macOS 10.12+ x86-64

rustima-0.2.0-cp311-cp311-win_amd64.whl (780.5 kB view details)

Uploaded CPython 3.11Windows x86-64

rustima-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (952.3 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

rustima-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (894.2 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ ARM64

rustima-0.2.0-cp311-cp311-macosx_11_0_arm64.whl (833.9 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

rustima-0.2.0-cp311-cp311-macosx_10_12_x86_64.whl (891.1 kB view details)

Uploaded CPython 3.11macOS 10.12+ x86-64

rustima-0.2.0-cp310-cp310-win_amd64.whl (780.5 kB view details)

Uploaded CPython 3.10Windows x86-64

rustima-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (952.2 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

rustima-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (894.1 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ ARM64

rustima-0.2.0-cp310-cp310-macosx_11_0_arm64.whl (834.0 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

rustima-0.2.0-cp310-cp310-macosx_10_12_x86_64.whl (893.1 kB view details)

Uploaded CPython 3.10macOS 10.12+ x86-64

File details

Details for the file rustima-0.2.0.tar.gz.

File metadata

  • Download URL: rustima-0.2.0.tar.gz
  • Upload date:
  • Size: 969.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for rustima-0.2.0.tar.gz
Algorithm Hash digest
SHA256 d913ffaaa47275629f84a73a1fe5adf9dd0c2b37a5706fd37e06262a2527d1e1
MD5 60754e12284ab4e18bcef2b2ed139d04
BLAKE2b-256 a8aa0b0a3391f2d846069c80f571de408da2d829f66a333492dff15b4738050e

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustima-0.2.0.tar.gz:

Publisher: release.yml on zongseung/Rust-python-arima

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustima-0.2.0-cp314-cp314-win_amd64.whl.

File metadata

  • Download URL: rustima-0.2.0-cp314-cp314-win_amd64.whl
  • Upload date:
  • Size: 777.0 kB
  • Tags: CPython 3.14, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for rustima-0.2.0-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 b49fdcff53e41bd353c6563f5bd0467656a2452d6d0bd1a166d34baaec1cfd38
MD5 a95602df82760259dc662b2b5ec18525
BLAKE2b-256 13db688f3ed17ce6bca22aed1cda563690313cbcf61e12193600bfb0e930166d

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustima-0.2.0-cp314-cp314-win_amd64.whl:

Publisher: release.yml on zongseung/Rust-python-arima

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustima-0.2.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rustima-0.2.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 199aed32405857c2a1e9e2ec3cd8281e3a22011d1923ca786d1b528b510ce562
MD5 75e1e94b1161d3b169b286c475c43a01
BLAKE2b-256 4b1cc5cb0b4b5e4b3cf62b8a922f674bc27425ac2c57e81e58b15b58a057c4b0

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustima-0.2.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on zongseung/Rust-python-arima

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustima-0.2.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for rustima-0.2.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 9c6e6c1deda5378c1b43b8585960cee9f20c0faa0db10ae9dc93b4607474847a
MD5 406528d92beb005afa23eae790d70471
BLAKE2b-256 b21cd521dbe3c0f51e7dbf0f120343d39b24fb363f64150c33875b4d6b4efe74

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustima-0.2.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on zongseung/Rust-python-arima

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustima-0.2.0-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rustima-0.2.0-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 43e7b49d5966cb7fba44e0dceee781190dcab926765ffbbbbf255e17239546a8
MD5 efc4a6ebe68d69decdba81bf24d8f056
BLAKE2b-256 a247d93ddde2fec6abd915c26a10da445695e2e5eb47f321ef04b8528036a10f

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustima-0.2.0-cp314-cp314-macosx_11_0_arm64.whl:

Publisher: release.yml on zongseung/Rust-python-arima

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustima-0.2.0-cp314-cp314-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for rustima-0.2.0-cp314-cp314-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 e5d45a543eb318d2442fcaaf97213b6edc86ab5be82007ae09ccaf637e76babf
MD5 a045d04345e9145fd5565ace14e0ecf4
BLAKE2b-256 f0088f004b1401ac47ee362b7cda52fc77eb806fee19239e63a60955c35e3828

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustima-0.2.0-cp314-cp314-macosx_10_12_x86_64.whl:

Publisher: release.yml on zongseung/Rust-python-arima

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustima-0.2.0-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: rustima-0.2.0-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 776.3 kB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for rustima-0.2.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 0954772c62c3a5eabdba0162a00755167f808ce9d046533095748c17e760afc8
MD5 ab498137965a166ecca4e000b625664c
BLAKE2b-256 661d0b44c1b4b439818561d716963d86867cede8d2a382f94e47425541519e74

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustima-0.2.0-cp313-cp313-win_amd64.whl:

Publisher: release.yml on zongseung/Rust-python-arima

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustima-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rustima-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 b4f2f79cc7961b014b06cf3ea1d01411902417d823c795f9f8770f917684f41e
MD5 c1bc47517663d7cc7de926f5b6d62891
BLAKE2b-256 f91cb42ccf960178ed526032f84ccea42465bdcea32d901c77a052ff92ca70bf

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustima-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on zongseung/Rust-python-arima

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustima-0.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for rustima-0.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 bf48984b9ca22b3b61dcb111db22e2fa41dfd7a5947f64eeaa27641da3162a6f
MD5 1b1d61e234e86b36a4ec6e29a36d2e79
BLAKE2b-256 0f1d2d43a4bca9f3be985f46800bd79170d51d6c8a654d499a7dca07aad6acb8

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustima-0.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on zongseung/Rust-python-arima

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustima-0.2.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rustima-0.2.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 1890cacfabe69c7f9b3954d85e6938bbe84cfafbf23fc5a6251efb121d3f5fc7
MD5 9b00c687cbf5f87825facd04a202c64f
BLAKE2b-256 a429c762a8ac31e40eb06fcc6e52566be19edf56c5f3e4cb9cb231abea227971

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustima-0.2.0-cp313-cp313-macosx_11_0_arm64.whl:

Publisher: release.yml on zongseung/Rust-python-arima

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustima-0.2.0-cp313-cp313-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for rustima-0.2.0-cp313-cp313-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 16f61abe1e4a92756e4a3800b80f1c1d9118e092835e25482866fb55594c76a2
MD5 02ff736da23c901d3602f1fde22c49e5
BLAKE2b-256 d83bd74e21b09c27776a24ac8af31c07f20a31599fb153099f52ca71f74c99b2

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustima-0.2.0-cp313-cp313-macosx_10_12_x86_64.whl:

Publisher: release.yml on zongseung/Rust-python-arima

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustima-0.2.0-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: rustima-0.2.0-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 776.8 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for rustima-0.2.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 f0ddec03704052197a912e11262a2123329d461d82df3a421037f77cde9e6170
MD5 a4c4d8e4e904f53fa422cb4563c2db28
BLAKE2b-256 3c55d4bf5e80a8e89a9b0578cf25a22039ede358dbd852c203a4fca4cf06201f

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustima-0.2.0-cp312-cp312-win_amd64.whl:

Publisher: release.yml on zongseung/Rust-python-arima

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustima-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rustima-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 27beb4f93716216609aec223f7dfdd3dc7103d9dc08036809d6fc205766b6c68
MD5 516685fc5ff362e87a555690752275a2
BLAKE2b-256 b4f35e9fe805bf9eca7ee8ab5ff489e14407a269705802762cecb3dcbb94d39c

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustima-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on zongseung/Rust-python-arima

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustima-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for rustima-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 fd83adad1563b9414d2891aabb714412b49de3419db58e4378e56dc6d5cce031
MD5 8dd7b472e699e137a97d212576a922d2
BLAKE2b-256 10c6f0049e02e23098a8bf08a36c1d0041f630ec8294be14c8c10fe32f2bf9d8

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustima-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on zongseung/Rust-python-arima

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustima-0.2.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rustima-0.2.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a0440756cade8f1cb8ff4720600b106a218159ddc5dbca98b9ad2a9b5016f739
MD5 74124329d16bf54317e4463a69234fe8
BLAKE2b-256 e5ad8948f05881cb7b58dcfcdafab63be9f8981638d428d4db821152580050d3

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustima-0.2.0-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: release.yml on zongseung/Rust-python-arima

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustima-0.2.0-cp312-cp312-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for rustima-0.2.0-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 17e2c982505bfc31bc1b38968d68aecc10412967f9e08f96f6f86f3b6c0a8908
MD5 20271ca3569edf251d03ea9d6445d62d
BLAKE2b-256 2c461e90b428d734ac83d8cefb15bfb94caf83b04b5f3ec0785b38e1217adfad

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustima-0.2.0-cp312-cp312-macosx_10_12_x86_64.whl:

Publisher: release.yml on zongseung/Rust-python-arima

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustima-0.2.0-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: rustima-0.2.0-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 780.5 kB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for rustima-0.2.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 e9a1f91d5e63e98eb548a5874b040dd0650b7d8614e46e9a9af0f0bc0a8d4ec0
MD5 89055d3ef7913b0db5c88a62321f5c6e
BLAKE2b-256 e433e4724897e43bc226eb020855103575fbd7ccb6003ff6d269048200d0c701

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustima-0.2.0-cp311-cp311-win_amd64.whl:

Publisher: release.yml on zongseung/Rust-python-arima

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustima-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rustima-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 2ee684ad345e392ba6d340e2febb6a425169e5c6fe9b01aba2b21538b8133647
MD5 5cf2d03e199809589f015c4eba9c83a6
BLAKE2b-256 109939932937e91d8aff035c9406b3336cf9382f3770f044d76acd12e4969ac1

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustima-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on zongseung/Rust-python-arima

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustima-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for rustima-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 8c983f680131d08e170c41fde0972934122d6bdd5a42be31ffad77aaebb63563
MD5 1a38a937baf6a665ff86bd5e4561bee9
BLAKE2b-256 de36b0bf2cc4d6591d3d5ae7f3080c67b9a8e8157566623e487548a0a55ea3bb

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustima-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on zongseung/Rust-python-arima

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustima-0.2.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rustima-0.2.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a40b06d43cbe993ac0445824d34f7c323b01c1d91f0823ecf50f7443effbe756
MD5 964d3b53c80b037adbca4dfc782bc8d2
BLAKE2b-256 b3817127a6fa5f6aa8c5540d6515b15e0a302caee5b56a4d193edef4646e370b

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustima-0.2.0-cp311-cp311-macosx_11_0_arm64.whl:

Publisher: release.yml on zongseung/Rust-python-arima

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustima-0.2.0-cp311-cp311-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for rustima-0.2.0-cp311-cp311-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 7d62d9785c28e974b794ae8daded681d5ce993fd42e780e4a25f550febd5b0f3
MD5 d511a84e5b8c325f97b04b2e33f00579
BLAKE2b-256 a88bad61e8cf548ad1c53b81047192fe0c6f75b2cbb5159b639ff68c720a0e76

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustima-0.2.0-cp311-cp311-macosx_10_12_x86_64.whl:

Publisher: release.yml on zongseung/Rust-python-arima

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustima-0.2.0-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: rustima-0.2.0-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 780.5 kB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for rustima-0.2.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 0b80d82ceaa6be5658d7e870cb49fa002e11f7998fc78a7726a2e3f2bffa3a0f
MD5 0551c63db43b7bea03f4212284a2582f
BLAKE2b-256 636f922b0d146efdbb5d87cea61d74e4537e541830cb508ed9b87a474f43fbc4

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustima-0.2.0-cp310-cp310-win_amd64.whl:

Publisher: release.yml on zongseung/Rust-python-arima

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustima-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rustima-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 a6b8171e1950c28f11a71dddb81041dd9ca083213842546dafa240da1ac0d221
MD5 d76da07cd62108430734567a38b0b08f
BLAKE2b-256 255fb8b867199576c4084092abb22182840e8fa9b6b78be5b336a89679855da0

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustima-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on zongseung/Rust-python-arima

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustima-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for rustima-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 8bd948fdd4f844acec3b7b229e918975db14436053f6bcda18207d26cbd83f34
MD5 c086d6d83fee65b32caef16c694a3d4f
BLAKE2b-256 756ce24e7135242439344711947fa2ba8971550944a4793f916b906355684119

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustima-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on zongseung/Rust-python-arima

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustima-0.2.0-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rustima-0.2.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 0e9920c6eee8b7ab4b2a3384964a7c1b7fbf3c30cb560e3ed60664b8f9dc604f
MD5 fe9bad40c951aa448405f627afeb2b09
BLAKE2b-256 16de198c8ca7dbb14eed4f823ba8e04c11cc134754cbf9b32ec7bad311b10c8b

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustima-0.2.0-cp310-cp310-macosx_11_0_arm64.whl:

Publisher: release.yml on zongseung/Rust-python-arima

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rustima-0.2.0-cp310-cp310-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for rustima-0.2.0-cp310-cp310-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 81a33414611db76ff4e9d2129cd82ea72e75c0bd27175957e4ac51da904dd297
MD5 eab406a6e526ceec4a842223d2c5c4a8
BLAKE2b-256 459c6911bf3d79ffedc6bca51912bdf0e759fc0b4db71a2cbc433fd583541e97

See more details on using hashes here.

Provenance

The following attestation bundles were made for rustima-0.2.0-cp310-cp310-macosx_10_12_x86_64.whl:

Publisher: release.yml on zongseung/Rust-python-arima

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page