rustima 0.2.0__tar.gz → 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. rustima-0.3.0/CHANGELOG.md +112 -0
  2. {rustima-0.2.0 → rustima-0.3.0}/Cargo.lock +1 -1
  3. {rustima-0.2.0 → rustima-0.3.0}/Cargo.toml +1 -1
  4. {rustima-0.2.0 → rustima-0.3.0}/PKG-INFO +1 -1
  5. {rustima-0.2.0 → rustima-0.3.0}/benches/bench_fit.rs +0 -3
  6. {rustima-0.2.0 → rustima-0.3.0}/benches/bench_kalman.rs +0 -2
  7. {rustima-0.2.0 → rustima-0.3.0}/examples/high_order_bench.rs +0 -1
  8. {rustima-0.2.0 → rustima-0.3.0}/lbfgsb_c/lbfgsb.c +39 -39
  9. {rustima-0.2.0 → rustima-0.3.0}/lbfgsb_c/lbfgsb.h +12 -2
  10. {rustima-0.2.0 → rustima-0.3.0}/lbfgsb_c/linesearch.c +11 -11
  11. {rustima-0.2.0 → rustima-0.3.0}/lbfgsb_c/linpack.c +5 -5
  12. {rustima-0.2.0 → rustima-0.3.0}/lbfgsb_c/miniCBLAS.c +6 -6
  13. {rustima-0.2.0 → rustima-0.3.0}/lbfgsb_c/print.c +4 -4
  14. {rustima-0.2.0 → rustima-0.3.0}/lbfgsb_c/subalgorithms.c +45 -45
  15. {rustima-0.2.0 → rustima-0.3.0}/pyproject.toml +1 -1
  16. {rustima-0.2.0 → rustima-0.3.0}/python/rustima/__init__.py +2 -2
  17. {rustima-0.2.0 → rustima-0.3.0}/python/rustima/auto.py +27 -102
  18. {rustima-0.2.0 → rustima-0.3.0}/python/rustima/model.py +68 -183
  19. {rustima-0.2.0 → rustima-0.3.0}/python_tests/test_auto.py +7 -1
  20. {rustima-0.2.0 → rustima-0.3.0}/python_tests/test_forecast.py +1 -1
  21. {rustima-0.2.0 → rustima-0.3.0}/python_tests/test_inference.py +27 -29
  22. rustima-0.3.0/python_tests/test_init_correctness.py +112 -0
  23. rustima-0.3.0/python_tests/test_matrix_cells.py +92 -0
  24. {rustima-0.2.0 → rustima-0.3.0}/python_tests/test_profile_trust_region.py +26 -11
  25. rustima-0.3.0/python_tests/test_robustness.py +99 -0
  26. {rustima-0.2.0 → rustima-0.3.0}/python_tests/test_safety_guards.py +3 -1
  27. {rustima-0.2.0 → rustima-0.3.0}/python_tests/test_simple_diff.py +67 -0
  28. {rustima-0.2.0 → rustima-0.3.0}/src/batch.rs +85 -22
  29. {rustima-0.2.0 → rustima-0.3.0}/src/forecast.rs +34 -10
  30. {rustima-0.2.0 → rustima-0.3.0}/src/inference.rs +14 -2
  31. {rustima-0.2.0 → rustima-0.3.0}/src/initialization.rs +64 -40
  32. {rustima-0.2.0 → rustima-0.3.0}/src/kalman.rs +12 -30
  33. {rustima-0.2.0 → rustima-0.3.0}/src/lbfgsb_ffi.rs +0 -5
  34. {rustima-0.2.0 → rustima-0.3.0}/src/lib.rs +126 -102
  35. rustima-0.3.0/src/optimizer/mod.rs +835 -0
  36. rustima-0.3.0/src/optimizer/multistart.rs +726 -0
  37. rustima-0.3.0/src/optimizer/objective.rs +566 -0
  38. rustima-0.3.0/src/optimizer/runners.rs +405 -0
  39. rustima-0.3.0/src/optimizer/tests.rs +689 -0
  40. rustima-0.3.0/src/optimizer/transforms.rs +147 -0
  41. rustima-0.3.0/src/optimizer/trust_region.rs +868 -0
  42. {rustima-0.2.0 → rustima-0.3.0}/src/params.rs +1 -1
  43. {rustima-0.2.0 → rustima-0.3.0}/src/pipeline.rs +0 -1
  44. {rustima-0.2.0 → rustima-0.3.0}/src/score.rs +227 -374
  45. {rustima-0.2.0 → rustima-0.3.0}/src/start_params.rs +60 -335
  46. {rustima-0.2.0 → rustima-0.3.0}/src/state_space.rs +1 -13
  47. {rustima-0.2.0 → rustima-0.3.0}/src/types.rs +37 -3
  48. {rustima-0.2.0 → rustima-0.3.0}/uv.lock +1 -1
  49. rustima-0.2.0/src/optimizer.rs +0 -4070
  50. {rustima-0.2.0 → rustima-0.3.0}/.env.example +0 -0
  51. {rustima-0.2.0 → rustima-0.3.0}/.gitignore +0 -0
  52. {rustima-0.2.0 → rustima-0.3.0}/LICENSE +0 -0
  53. {rustima-0.2.0 → rustima-0.3.0}/README.md +0 -0
  54. {rustima-0.2.0 → rustima-0.3.0}/build.rs +0 -0
  55. {rustima-0.2.0 → rustima-0.3.0}/docs/PERF_DIAGNOSIS.md +0 -0
  56. {rustima-0.2.0 → rustima-0.3.0}/docs/SUPPORTED_COMBINATIONS.md +0 -0
  57. {rustima-0.2.0 → rustima-0.3.0}/docs/api_reference.md +0 -0
  58. {rustima-0.2.0 → rustima-0.3.0}/docs/error_codes.md +0 -0
  59. {rustima-0.2.0 → rustima-0.3.0}/docs/migration_guide.md +0 -0
  60. {rustima-0.2.0 → rustima-0.3.0}/docs/profiled_kalman_gls_plan.md +0 -0
  61. {rustima-0.2.0 → rustima-0.3.0}/docs/statsmodels_compat.md +0 -0
  62. {rustima-0.2.0 → rustima-0.3.0}/docs/ver5_convergence_improvement.md +0 -0
  63. {rustima-0.2.0 → rustima-0.3.0}/examples/bench_comprehensive.py +0 -0
  64. {rustima-0.2.0 → rustima-0.3.0}/examples/bench_vs_statsmodels.py +0 -0
  65. {rustima-0.2.0 → rustima-0.3.0}/examples/sarimax_exog_demo.py +0 -0
  66. {rustima-0.2.0 → rustima-0.3.0}/examples/sarimax_hourly_s24.py +0 -0
  67. {rustima-0.2.0 → rustima-0.3.0}/lbfgsb_c/License.txt +0 -0
  68. {rustima-0.2.0 → rustima-0.3.0}/lbfgsb_c/timer.c +0 -0
  69. {rustima-0.2.0 → rustima-0.3.0}/python_tests/conftest.py +0 -0
  70. {rustima-0.2.0 → rustima-0.3.0}/python_tests/generate_fixtures.py +0 -0
  71. {rustima-0.2.0 → rustima-0.3.0}/python_tests/generate_matrix_fixtures.py +0 -0
  72. {rustima-0.2.0 → rustima-0.3.0}/python_tests/test_batch.py +0 -0
  73. {rustima-0.2.0 → rustima-0.3.0}/python_tests/test_exog.py +0 -0
  74. {rustima-0.2.0 → rustima-0.3.0}/python_tests/test_extend.py +0 -0
  75. {rustima-0.2.0 → rustima-0.3.0}/python_tests/test_fit.py +0 -0
  76. {rustima-0.2.0 → rustima-0.3.0}/python_tests/test_high_order_accuracy.py +0 -0
  77. {rustima-0.2.0 → rustima-0.3.0}/python_tests/test_input_validation.py +0 -0
  78. {rustima-0.2.0 → rustima-0.3.0}/python_tests/test_matrix_tier_a.py +0 -0
  79. {rustima-0.2.0 → rustima-0.3.0}/python_tests/test_multi_order_accuracy.py +0 -0
  80. {rustima-0.2.0 → rustima-0.3.0}/python_tests/test_polars.py +0 -0
  81. {rustima-0.2.0 → rustima-0.3.0}/python_tests/test_prediction_quality.py +0 -0
  82. {rustima-0.2.0 → rustima-0.3.0}/python_tests/test_rolling.py +0 -0
  83. {rustima-0.2.0 → rustima-0.3.0}/python_tests/test_smoke.py +0 -0
  84. {rustima-0.2.0 → rustima-0.3.0}/python_tests/test_trend.py +0 -0
  85. {rustima-0.2.0 → rustima-0.3.0}/python_tests/test_variance_parity.py +0 -0
  86. {rustima-0.2.0 → rustima-0.3.0}/src/css.rs +0 -0
  87. {rustima-0.2.0 → rustima-0.3.0}/src/error.rs +0 -0
  88. {rustima-0.2.0 → rustima-0.3.0}/src/lbfgsb_wrapper.rs +0 -0
  89. {rustima-0.2.0 → rustima-0.3.0}/src/polynomial.rs +0 -0
  90. {rustima-0.2.0 → rustima-0.3.0}/src/test_helpers.rs +0 -0
  91. {rustima-0.2.0 → rustima-0.3.0}/tests/fixtures/.gitkeep +0 -0
  92. {rustima-0.2.0 → rustima-0.3.0}/tests/fixtures/matrix_tier_a.json +0 -0
  93. {rustima-0.2.0 → rustima-0.3.0}/tests/fixtures/matrix_tier_b.json +0 -0
  94. {rustima-0.2.0 → rustima-0.3.0}/tests/fixtures/statsmodels_fit_reference.json +0 -0
  95. {rustima-0.2.0 → rustima-0.3.0}/tests/fixtures/statsmodels_forecast_reference.json +0 -0
  96. {rustima-0.2.0 → rustima-0.3.0}/tests/fixtures/statsmodels_reference.json +0 -0
@@ -0,0 +1,112 @@
1
+ # Changelog
2
+
3
+ All notable changes to rustima are documented here.
4
+ Versions follow `0.MINOR.PATCH`, where breaking changes bump MINOR.
5
+
6
+ ## 0.3.0 — 2026-07-25
7
+
8
+ A diagnosis sweep of the engine (~1,800 adversarial inputs, 9 numerical
9
+ regimes against statsmodels, and a structural audit) found and fixed four
10
+ defects that returned **wrong numbers without raising**. Full report:
11
+ `planner/ver9/DIAGNOSIS_V9.md`.
12
+
13
+ > **Results from 0.2.x are not comparable to 0.3.0.** The log-likelihood,
14
+ > AIC and BIC of every model **without differencing** (`d=0, D=0`) were
15
+ > biased, and `inference="hessian"` standard errors were inflated. If you
16
+ > have published or stored numbers from 0.2.x, re-run them.
17
+
18
+ ### Breaking — corrected numerical results
19
+
20
+ - **Initial state covariance for non-differenced models.** `P₀` for the
21
+ stationary ARMA block used the DARE fixed point (the steady-state
22
+ *filtering* covariance) instead of the unconditional *Lyapunov*
23
+ covariance. For AR(1) this used `σ²` where the correct prior is
24
+ `σ²/(1-φ²)`. The error grows like `1/(1-φ²)` and does not vanish with
25
+ sample size: `Δloglike` ≈ −0.1 at φ=0.5, −62 at φ=0.995, and `ΔAIC`
26
+ +156 for a seasonal SAR=0.99 model. Fixed-parameter log-likelihoods now
27
+ match statsmodels to 1e-10. Models with `d≥1` were always correct.
28
+ - **Standard errors from `inference="hessian"`.** The Hessian was mapped
29
+ from unconstrained to constrained space with the Jacobian instead of its
30
+ inverse, applying the transform twice and inflating AR/MA standard
31
+ errors by up to 6.6×. Now matches statsmodels `cov_params_approx` to
32
+ five decimals. `inference="opg"` was unaffected.
33
+ - **False convergence with trend terms.** A deterministic trend made the
34
+ CSS/Burg start-parameter estimator see near-integration, saturating the
35
+ AR start on the constraint boundary where L-BFGS-B stalls and reports
36
+ `converged=True` with a gradient of order 100 — up to 192 nats below the
37
+ optimum. Start parameters are now detrended, and out-of-box estimates
38
+ fall back to zeros instead of clamping.
39
+ - **Near-cancellation detection.** AR and MA roots were compared against
40
+ the sign-flipped MA polynomial, so genuine cancellation (`θ = −φ`) was
41
+ never detected — the warning and the multi-start restart filter both ran
42
+ on the wrong condition.
43
+ - **Post-estimation ran a differently-initialized filter.** `forecast`,
44
+ `rolling_forecast`, `residuals`, `batch_forecast` and `diagnostics`
45
+ ignored the model's enforcement flags and silently used an approximate
46
+ diffuse initialization, so `res.llf` and `res.resid` / `res.diagnostics()`
47
+ described different models — Ljung-Box tested residuals the likelihood
48
+ never saw.
49
+
50
+ ### Breaking — stricter inputs and API
51
+
52
+ - Masked arrays are rejected by `SARIMAXModel` and `auto_arima` (previously
53
+ the mask was silently dropped and masked entries used as data).
54
+ - `sarimax_inference` validates the parameter-vector length instead of
55
+ returning empty arrays.
56
+ - `SARIMAXResult.param_names` raises if the Rust layout and the Python
57
+ naming disagree, instead of padding with `param_N` and printing values
58
+ under the wrong names.
59
+ - `sarimax_rolling_forecast` refuses configurations whose origin snapshots
60
+ would exceed 2 GiB (previously unbounded — 4.4 GB measured at n=1000,
61
+ s=365, and an allocation failure aborts the process).
62
+ - `sarimax_residuals` returns an additional `prediction_variances` key.
63
+ Code asserting an exact key set must be updated.
64
+ - Rust: the never-supported `SarimaxConfig.measurement_error` field is
65
+ removed.
66
+
67
+ ### Added
68
+
69
+ - `PredictionResult.conf_int(alpha=...)` and `.se_mean` —
70
+ `get_prediction()` now produces intervals across the whole range, not
71
+ only the out-of-sample tail.
72
+ - `sarimax_residuals` returns `prediction_variances` (one-step-ahead
73
+ prediction variance).
74
+ - `sarimax_forecast`, `sarimax_rolling_forecast`, `sarimax_residuals`,
75
+ `sarimax_batch_forecast` and `sarimax_diagnostics` accept
76
+ `enforce_stationarity` / `enforce_invertibility` (appended to the
77
+ signature; positional calls are unaffected).
78
+
79
+ ### Fixed
80
+
81
+ - **Deadlock in forked processes.** Rayon's global pool is not fork-safe:
82
+ any batch or grid call in a `fork()`ed child hung forever with no error
83
+ (reachable through `multiprocessing`'s fork context after a single
84
+ earlier batch call). Parallel entry points now fail fast with a clear
85
+ message, and the optimizer's internal parallel sections fall back to
86
+ sequential execution.
87
+ - Batch workers isolate panics per series, so the documented per-series
88
+ error isolation holds even if a worker panics.
89
+ - The analytical gradient no longer disappears near unit roots: the score
90
+ pass now shares the likelihood pass's `F_t ≤ 0` fallback and
91
+ steady-state adoption guard, keeping the gradient finite wherever the
92
+ log-likelihood is.
93
+ - The analytical score accounts for `∂P₀/∂θ` when the initialization
94
+ depends on the parameters.
95
+
96
+ ### Internal
97
+
98
+ - Single-sourced the trend basis, the flat-parameter count, and
99
+ single-series input validation (the last was duplicated into
100
+ `sarimax_grid_search`, the `auto_arima` hot path). Model flags moved from
101
+ adjacent positional booleans into a named struct.
102
+ - Removed dead code: `auto_arima`'s unused evaluation path, the
103
+ `measurement_error` plumbing, and the redundant Python numerical-Hessian
104
+ implementation.
105
+ - Python test suite 407 → 429, including regression tests for every defect
106
+ above and eight previously uncovered option-matrix combinations. CI is
107
+ green for the first time since 2026-05-23.
108
+
109
+ ## 0.2.0
110
+
111
+ Initial tagged release with the SARIMAX engine, `auto_arima`, batch
112
+ processing and the statsmodels-compatible Python API.
@@ -880,7 +880,7 @@ checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
880
880
 
881
881
  [[package]]
882
882
  name = "rustima"
883
- version = "0.2.0"
883
+ version = "0.3.0"
884
884
  dependencies = [
885
885
  "anyhow",
886
886
  "approx",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "rustima"
3
- version = "0.2.0"
3
+ version = "0.3.0"
4
4
  edition = "2021"
5
5
  rust-version = "1.83"
6
6
  description = "High-performance SARIMAX engine with PyO3 bindings"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rustima
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Intended Audience :: Science/Research
6
6
  Classifier: Intended Audience :: Developers
@@ -26,7 +26,6 @@ fn bench_fit_ar1(c: &mut Criterion) {
26
26
  enforce_invertibility: true,
27
27
  concentrate_scale: true,
28
28
  simple_differencing: false,
29
- measurement_error: false,
30
29
  };
31
30
 
32
31
  c.bench_function("fit_ar1_n500", |b| {
@@ -44,7 +43,6 @@ fn bench_fit_arima111(c: &mut Criterion) {
44
43
  enforce_invertibility: true,
45
44
  concentrate_scale: true,
46
45
  simple_differencing: false,
47
- measurement_error: false,
48
46
  };
49
47
 
50
48
  c.bench_function("fit_arima111_n500", |b| {
@@ -66,7 +64,6 @@ fn bench_fit_sarima_111_111_12(c: &mut Criterion) {
66
64
  enforce_invertibility: false,
67
65
  concentrate_scale: true,
68
66
  simple_differencing: false,
69
- measurement_error: false,
70
67
  };
71
68
 
72
69
  c.bench_function("fit_sarima111_111_12_n500", |b| {
@@ -30,7 +30,6 @@ fn bench_kalman_ar1(c: &mut Criterion) {
30
30
  enforce_invertibility: false,
31
31
  concentrate_scale: true,
32
32
  simple_differencing: false,
33
- measurement_error: false,
34
33
  };
35
34
  let params = SarimaxParams {
36
35
  trend_coeffs: vec![],
@@ -60,7 +59,6 @@ fn bench_kalman_arima111(c: &mut Criterion) {
60
59
  enforce_invertibility: false,
61
60
  concentrate_scale: true,
62
61
  simple_differencing: false,
63
- measurement_error: false,
64
62
  };
65
63
  let params = SarimaxParams {
66
64
  trend_coeffs: vec![],
@@ -28,7 +28,6 @@ fn run_test(label: &str, order: SarimaxOrder, n: usize) {
28
28
  enforce_invertibility: true,
29
29
  concentrate_scale: true,
30
30
  simple_differencing: false,
31
- measurement_error: false,
32
31
  };
33
32
 
34
33
  let start = Instant::now();
@@ -60,7 +60,7 @@ static integer c__1 = 1;
60
60
 
61
61
 
62
62
  /* Local variables */
63
- _Thread_local static integer ld, lr, lt, lz, lwa, lwn, lss, lxp, lws, lwt, lsy, lwy,
63
+ static _Thread_local integer ld, lr, lt, lz, lwa, lwn, lss, lxp, lws, lwt, lsy, lwy,
64
64
  lsnd;
65
65
 
66
66
  /* -jlm-jn */
@@ -343,45 +343,45 @@ static double c_b7 = 0.;
343
343
  fileType o__1=NULL;
344
344
 
345
345
  /* Local variables */
346
- _Thread_local static integer i__, k;
347
- _Thread_local static double gd, dr, rr, dtd;
348
- _Thread_local static integer col;
349
- _Thread_local static double tol;
350
- _Thread_local static logical wrk;
351
- _Thread_local static double stp, cpu1, cpu2;
352
- _Thread_local static integer head;
353
- _Thread_local static double fold;
354
- _Thread_local static integer nact;
355
- _Thread_local static double ddum;
356
- _Thread_local static integer info, nseg;
357
- _Thread_local static double time;
358
- _Thread_local static integer nfgv, ifun, iter;
359
- _Thread_local static integer wordTemp;
360
- _Thread_local static integer *word;
346
+ static _Thread_local integer i__, k;
347
+ static _Thread_local double gd, dr, rr, dtd;
348
+ static _Thread_local integer col;
349
+ static _Thread_local double tol;
350
+ static _Thread_local logical wrk;
351
+ static _Thread_local double stp, cpu1, cpu2;
352
+ static _Thread_local integer head;
353
+ static _Thread_local double fold;
354
+ static _Thread_local integer nact;
355
+ static _Thread_local double ddum;
356
+ static _Thread_local integer info, nseg;
357
+ static _Thread_local double time;
358
+ static _Thread_local integer nfgv, ifun, iter;
359
+ static _Thread_local integer wordTemp;
360
+ static _Thread_local integer *word;
361
361
  word = &wordTemp;
362
- _Thread_local static double time1, time2;
363
- _Thread_local static integer iback;
364
- _Thread_local static double gdold;
365
- _Thread_local static integer nfree;
366
- _Thread_local static logical boxed;
367
- _Thread_local static integer itail;
368
- _Thread_local static double theta;
369
- _Thread_local static double dnorm;
370
- _Thread_local static integer nskip, iword;
371
- _Thread_local static double xstep, stpmx;
372
- _Thread_local static integer ileave;
373
- _Thread_local static double cachyt;
374
- _Thread_local static integer itfile;
375
- _Thread_local static double epsmch;
376
- _Thread_local static logical updatd;
377
- _Thread_local static double sbtime;
378
- _Thread_local static logical prjctd;
379
- _Thread_local static integer iupdat;
380
- _Thread_local static double sbgnrm;
381
- _Thread_local static logical cnstnd;
382
- _Thread_local static integer nenter;
383
- _Thread_local static double lnscht;
384
- _Thread_local static integer nintol;
362
+ static _Thread_local double time1, time2;
363
+ static _Thread_local integer iback;
364
+ static _Thread_local double gdold;
365
+ static _Thread_local integer nfree;
366
+ static _Thread_local logical boxed;
367
+ static _Thread_local integer itail;
368
+ static _Thread_local double theta;
369
+ static _Thread_local double dnorm;
370
+ static _Thread_local integer nskip, iword;
371
+ static _Thread_local double xstep, stpmx;
372
+ static _Thread_local integer ileave;
373
+ static _Thread_local double cachyt;
374
+ static _Thread_local integer itfile;
375
+ static _Thread_local double epsmch;
376
+ static _Thread_local logical updatd;
377
+ static _Thread_local double sbtime;
378
+ static _Thread_local logical prjctd;
379
+ static _Thread_local integer iupdat;
380
+ static _Thread_local double sbgnrm;
381
+ static _Thread_local logical cnstnd;
382
+ static _Thread_local integer nenter;
383
+ static _Thread_local double lnscht;
384
+ static _Thread_local integer nintol;
385
385
 
386
386
  /* -jlm-jn */
387
387
  /* ************ */
@@ -5,10 +5,20 @@
5
5
  #ifndef lbfgsb_h
6
6
  #define lbfgsb_h
7
7
 
8
- /* MSVC's C mode has no C11 _Thread_local keyword map to its equivalent
9
- * so Windows wheel builds compile. gcc/clang paths are unaffected. */
8
+ /* Portable thread-local shim. The C11 _Thread_local keyword is missing on:
9
+ * - MSVC C mode -> __declspec(thread)
10
+ * - gcc < 4.9 (manylinux2014 aarch64
11
+ * cross toolchain is gcc 4.8; it even
12
+ * accepts -std=c11 without the keyword) -> GNU __thread
13
+ * - any pre-C11 mode -> GNU __thread
14
+ * Modern clang/gcc with C11 keep the native keyword. */
10
15
  #if defined(_MSC_VER) && !defined(__clang__)
11
16
  #define _Thread_local __declspec(thread)
17
+ #elif defined(__GNUC__) && !defined(__clang__) && \
18
+ (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 9))
19
+ #define _Thread_local __thread
20
+ #elif !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 201112L)
21
+ #define _Thread_local __thread
12
22
  #endif
13
23
 
14
24
 
@@ -43,18 +43,18 @@ static integer c__1 = 1;
43
43
 
44
44
 
45
45
  /* Table of constant values */
46
- _Thread_local static double c_b14 = FTOL;
47
- _Thread_local static double c_b15 = GTOL;
48
- _Thread_local static double c_b16 = XTOL;
49
- _Thread_local static double c_b17 = STEPMIN;
46
+ static _Thread_local double c_b14 = FTOL;
47
+ static _Thread_local double c_b15 = GTOL;
48
+ static _Thread_local double c_b16 = XTOL;
49
+ static _Thread_local double c_b17 = STEPMIN;
50
50
  /* System generated locals */
51
51
  integer i__1;
52
52
  double d__1;
53
53
 
54
54
 
55
55
  /* Local variables */
56
- _Thread_local static integer i__;
57
- _Thread_local static double a1, a2;
56
+ static _Thread_local integer i__;
57
+ static _Thread_local double a1, a2;
58
58
 
59
59
  /* Parameter adjustments */
60
60
  --z__;
@@ -170,10 +170,10 @@ int dcsrch(double *f, double *g, double *stp,
170
170
 
171
171
 
172
172
  /* Local variables */
173
- _Thread_local static double fm, gm, fx, fy, gx, gy, fxm, fym, gxm, gym, stx, sty;
174
- _Thread_local static integer stage;
175
- _Thread_local static double finit, ginit, width, ftest, gtest, stmin, stmax, width1;
176
- _Thread_local static logical brackt;
173
+ static _Thread_local double fm, gm, fx, fy, gx, gy, fxm, fym, gxm, gym, stx, sty;
174
+ static _Thread_local integer stage;
175
+ static _Thread_local double finit, ginit, width, ftest, gtest, stmin, stmax, width1;
176
+ static _Thread_local logical brackt;
177
177
 
178
178
  /*
179
179
  **********
@@ -496,7 +496,7 @@ L1000:
496
496
  double sqrt(double);
497
497
 
498
498
  /* Local variables */
499
- _Thread_local static double p, q, r__, s, sgnd, stpc, stpf, stpq, gamma, theta;
499
+ static _Thread_local double p, q, r__, s, sgnd, stpc, stpf, stpq, gamma, theta;
500
500
 
501
501
  /*
502
502
  **********
@@ -18,9 +18,9 @@ int dpofa(double *a, integer *lda, integer *n, integer *
18
18
  double sqrt(double);
19
19
 
20
20
  /* Local variables */
21
- _Thread_local static integer j, k;
22
- _Thread_local static double s, t;
23
- _Thread_local static integer jm1;
21
+ static _Thread_local integer j, k;
22
+ static _Thread_local double s, t;
23
+ static _Thread_local integer jm1;
24
24
 
25
25
  /*
26
26
  dpofa factors a double precision symmetric positive definite
@@ -115,8 +115,8 @@ int dtrsl(double *t, integer *ldt, integer *n,
115
115
  integer t_dim1, t_offset, i__1, i__2;
116
116
 
117
117
  /* Local variables */
118
- _Thread_local static integer j, jj, case__;
119
- _Thread_local static double temp;
118
+ static _Thread_local integer j, jj, case__;
119
+ static _Thread_local double temp;
120
120
  /*
121
121
  extern double ddot(integer *, double *, integer *, double *,
122
122
  integer *);
@@ -52,7 +52,7 @@
52
52
  integer i__1;
53
53
 
54
54
  /* Local variables */
55
- _Thread_local static integer i, m, ix, iy, mp1;
55
+ static _Thread_local integer i, m, ix, iy, mp1;
56
56
 
57
57
 
58
58
  /* constant times a vector plus a vector.
@@ -139,7 +139,7 @@ L40:
139
139
  integer i__1;
140
140
 
141
141
  /* Local variables */
142
- _Thread_local static integer i, m, ix, iy, mp1;
142
+ static _Thread_local integer i, m, ix, iy, mp1;
143
143
 
144
144
 
145
145
  /* copies a vector, x, to a vector, y.
@@ -226,9 +226,9 @@ double ddotRef(integer *n, double *dx, integer *incx, double *dy,
226
226
  double ret_val;
227
227
 
228
228
  /* Local variables */
229
- _Thread_local static integer i, m;
230
- _Thread_local static double dtemp;
231
- _Thread_local static integer ix, iy, mp1;
229
+ static _Thread_local integer i, m;
230
+ static _Thread_local double dtemp;
231
+ static _Thread_local integer ix, iy, mp1;
232
232
 
233
233
 
234
234
  /* forms the dot product of two vectors.
@@ -314,7 +314,7 @@ L60:
314
314
  integer i__1, i__2;
315
315
 
316
316
  /* Local variables */
317
- _Thread_local static integer i, m, nincx, mp1;
317
+ static _Thread_local integer i, m, nincx, mp1;
318
318
 
319
319
 
320
320
  /* scales a vector by a constant.
@@ -30,7 +30,7 @@ int prn1lb(integer *n, integer *m, double *l,
30
30
  integer i__1;
31
31
 
32
32
  /* Local variables */
33
- _Thread_local static integer i__;
33
+ static _Thread_local integer i__;
34
34
 
35
35
  /* Parameter adjustments */
36
36
  --x;
@@ -103,7 +103,7 @@ int prn1lb(integer *n, integer *m, double *l,
103
103
  integer i__1;
104
104
 
105
105
  /* Local variables */
106
- _Thread_local static integer i__, imod;
106
+ static _Thread_local integer i__, imod;
107
107
 
108
108
  /* Parameter adjustments */
109
109
  --g;
@@ -186,7 +186,7 @@ int prn3lb(integer *n, double *x, double *f, integer *
186
186
  integer i__1;
187
187
 
188
188
  /* Local variables */
189
- _Thread_local static integer i__;
189
+ static _Thread_local integer i__;
190
190
  /* Parameter adjustments */
191
191
  --x;
192
192
 
@@ -304,7 +304,7 @@ int errclb(integer *n, integer *m, double *factr,
304
304
  integer i__1;
305
305
 
306
306
  /* Local variables */
307
- _Thread_local static integer i__;
307
+ static _Thread_local integer i__;
308
308
 
309
309
  /* Parameter adjustments */
310
310
  --nbd;
@@ -12,7 +12,7 @@ static integer c__11 = 11;
12
12
  integer i__1;
13
13
 
14
14
  /* Local variables */
15
- _Thread_local static integer i__, nbdd;
15
+ static _Thread_local integer i__, nbdd;
16
16
 
17
17
 
18
18
  /* ************ */
@@ -127,8 +127,8 @@ static integer c__11 = 11;
127
127
  double sqrt(double);
128
128
 
129
129
  /* Local variables */
130
- _Thread_local static integer i__, k, i2;
131
- _Thread_local static double sum;
130
+ static _Thread_local integer i__, k, i2;
131
+ static _Thread_local double sum;
132
132
 
133
133
  /* ************ */
134
134
 
@@ -275,28 +275,28 @@ static integer c__11 = 11;
275
275
 
276
276
 
277
277
  /* Local variables */
278
- _Thread_local static integer i__, j;
279
- _Thread_local static double f1, f2, dt, tj, tl, tu, tj0;
280
- _Thread_local static integer ibp;
281
- _Thread_local static double dtm;
278
+ static _Thread_local integer i__, j;
279
+ static _Thread_local double f1, f2, dt, tj, tl, tu, tj0;
280
+ static _Thread_local integer ibp;
281
+ static _Thread_local double dtm;
282
282
  extern /* Subroutine */ int bmv(integer *, double *, double *,
283
283
  integer *, double *, double *, integer *);
284
- _Thread_local static double wmc, wmp, wmw;
285
- _Thread_local static integer col2;
286
- _Thread_local static double dibp;
287
- _Thread_local static integer iter;
288
- _Thread_local static double zibp, tsum, dibp2;
289
- _Thread_local static logical bnded;
290
- _Thread_local static double neggi;
291
- _Thread_local static integer nfree;
292
- _Thread_local static double bkmin;
293
- _Thread_local static integer nleft;
294
- _Thread_local static double f2_org__;
295
- _Thread_local static integer nbreak, ibkmin;
284
+ static _Thread_local double wmc, wmp, wmw;
285
+ static _Thread_local integer col2;
286
+ static _Thread_local double dibp;
287
+ static _Thread_local integer iter;
288
+ static _Thread_local double zibp, tsum, dibp2;
289
+ static _Thread_local logical bnded;
290
+ static _Thread_local double neggi;
291
+ static _Thread_local integer nfree;
292
+ static _Thread_local double bkmin;
293
+ static _Thread_local integer nleft;
294
+ static _Thread_local double f2_org__;
295
+ static _Thread_local integer nbreak, ibkmin;
296
296
  extern /* Subroutine */ int hpsolb(integer *, double *, integer *,
297
297
  integer *);
298
- _Thread_local static integer pointr;
299
- _Thread_local static logical xlower, xupper;
298
+ static _Thread_local integer pointr;
299
+ static _Thread_local logical xlower, xupper;
300
300
 
301
301
  /* ************ */
302
302
 
@@ -828,11 +828,11 @@ L999:
828
828
  wt_dim1, wt_offset, i__1, i__2;
829
829
 
830
830
  /* Local variables */
831
- _Thread_local static integer i__, j, k;
832
- _Thread_local static double a1, a2;
831
+ static _Thread_local integer i__, j, k;
832
+ static _Thread_local double a1, a2;
833
833
  extern /* Subroutine */ int bmv(integer *, double *, double *,
834
834
  integer *, double *, double *, integer *);
835
- _Thread_local static integer pointr;
835
+ static _Thread_local integer pointr;
836
836
 
837
837
  /* ************ */
838
838
 
@@ -928,10 +928,10 @@ L999:
928
928
  wy_dim1, wy_offset, sy_dim1, sy_offset, i__1, i__2, i__3;
929
929
 
930
930
  /* Local variables */
931
- _Thread_local static integer i__, k, k1, m2, is, js, iy, jy, is1, js1, col2, dend, pend;
932
- _Thread_local static integer upcl;
933
- _Thread_local static double temp1, temp2, temp3, temp4;
934
- _Thread_local static integer ipntr, jpntr, dbegin, pbegin;
931
+ static _Thread_local integer i__, k, k1, m2, is, js, iy, jy, is1, js1, col2, dend, pend;
932
+ static _Thread_local integer upcl;
933
+ static _Thread_local double temp1, temp2, temp3, temp4;
934
+ static _Thread_local integer ipntr, jpntr, dbegin, pbegin;
935
935
 
936
936
  /* ************ */
937
937
 
@@ -1310,8 +1310,8 @@ L999:
1310
1310
  i__2, i__3;
1311
1311
 
1312
1312
  /* Local variables */
1313
- _Thread_local static integer i__, j, k, k1;
1314
- _Thread_local static double ddum;
1313
+ static _Thread_local integer i__, j, k, k1;
1314
+ static _Thread_local double ddum;
1315
1315
 
1316
1316
  /* ************ */
1317
1317
 
@@ -1399,7 +1399,7 @@ L999:
1399
1399
  integer i__1;
1400
1400
 
1401
1401
  /* Local variables */
1402
- _Thread_local static integer i__, k, iact;
1402
+ static _Thread_local integer i__, k, iact;
1403
1403
 
1404
1404
 
1405
1405
  /* ************ */
@@ -1517,9 +1517,9 @@ L999:
1517
1517
  integer i__1;
1518
1518
 
1519
1519
  /* Local variables */
1520
- _Thread_local static integer i__, j, k;
1521
- _Thread_local static double out, ddum;
1522
- _Thread_local static integer indxin, indxou;
1520
+ static _Thread_local integer i__, j, k;
1521
+ static _Thread_local double out, ddum;
1522
+ static _Thread_local integer indxin, indxou;
1523
1523
 
1524
1524
  /* ************ */
1525
1525
 
@@ -1639,8 +1639,8 @@ L30:
1639
1639
  ss_dim1, ss_offset, i__1, i__2;
1640
1640
 
1641
1641
  /* Local variables */
1642
- _Thread_local static integer j;
1643
- _Thread_local static integer pointr;
1642
+ static _Thread_local integer j;
1643
+ static _Thread_local integer pointr;
1644
1644
 
1645
1645
  /* ************ */
1646
1646
 
@@ -1746,8 +1746,8 @@ L30:
1746
1746
  double d__1, d__2;
1747
1747
 
1748
1748
  /* Local variables */
1749
- _Thread_local static integer i__;
1750
- _Thread_local static double gi;
1749
+ static _Thread_local integer i__;
1750
+ static _Thread_local double gi;
1751
1751
 
1752
1752
  /* ************ */
1753
1753
 
@@ -1827,13 +1827,13 @@ L30:
1827
1827
  double d__1, d__2;
1828
1828
 
1829
1829
  /* Local variables */
1830
- _Thread_local static integer i__, j, k, m2;
1831
- _Thread_local static double dk;
1832
- _Thread_local static integer js, jy;
1833
- _Thread_local static double xk;
1834
- _Thread_local static integer ibd, col2;
1835
- _Thread_local static double dd_p__, temp1, temp2, alpha;
1836
- _Thread_local static integer pointr;
1830
+ static _Thread_local integer i__, j, k, m2;
1831
+ static _Thread_local double dk;
1832
+ static _Thread_local integer js, jy;
1833
+ static _Thread_local double xk;
1834
+ static _Thread_local integer ibd, col2;
1835
+ static _Thread_local double dd_p__, temp1, temp2, alpha;
1836
+ static _Thread_local integer pointr;
1837
1837
 
1838
1838
  /* ********************************************************************** */
1839
1839
 
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "rustima"
7
- version = "0.2.0"
7
+ version = "0.3.0"
8
8
  requires-python = ">=3.10"
9
9
  description = "High-performance SARIMAX (Seasonal ARIMA with eXogenous regressors) engine in Rust with statsmodels-compatible Python API"
10
10
  readme = "README.md"
@@ -14,15 +14,15 @@ import os as _os
14
14
  if "RAYON_NUM_THREADS" not in _os.environ:
15
15
  import sys as _sys
16
16
  if _sys.platform == "darwin":
17
+ import subprocess as _sp
17
18
  try:
18
- import subprocess as _sp
19
19
  _n = _sp.check_output(
20
20
  ["sysctl", "-n", "hw.perflevel0.physicalcpu"],
21
21
  stderr=_sp.DEVNULL, timeout=2,
22
22
  ).decode().strip()
23
23
  if _n.isdigit() and int(_n) > 0:
24
24
  _os.environ["RAYON_NUM_THREADS"] = _n
25
- except Exception:
25
+ except (OSError, _sp.SubprocessError, UnicodeDecodeError):
26
26
  pass
27
27
 
28
28
  # Native extension module — maturin places the .so here automatically.