Releases: QuantClimate/Impulso
Release list
v0.1.3
Fix
- A VAR embedded with
build_in_modeland a latent series no longer sets a redundant initial value onB, so the host PyMC model can be cloned again:Model.copy(),pm.doandpm.observework (#369). The initial value is still set when a latent own-lag prior mean lies outside the stationary region, the default of 1 included, and such a model stays unclonable; thebuild_in_modeldocstring and ADR-0016 say so.
What's Changed
🐛 Bug Fixes
- fix: leave the host model clonable when the latent start is the prior mean by @thomaspinder in #369
📖 Documentation
- docs: housekeeping for the support link, badges and tutorial kernel paths by @thomaspinder in #366
🧩 Other
- docs: load the Cloudflare Web Analytics beacon by @thomaspinder in #367
Full Changelog: v0.1.2...v0.1.3
v0.1.2
Fix
adf_test,kpss_testandintegration_orderno longer emit statsmodels 0.15'sFutureWarningaboutresult_object(#364). statsmodels 0.14.6 and later remain supported.
The dependency updates below change the development lock file only; the published dependency ranges are unchanged.
What's Changed
🐛 Bug Fixes
- fix: stop leaking statsmodels 0.15's result_object FutureWarning by @thomaspinder in #364
🧩 Other
- build(deps): Bump the python group across 1 directory with 5 updates by @dependabot[bot] in #311
- build(deps-dev): Bump the linters group across 1 directory with 3 updates by @dependabot[bot] in #358
Full Changelog: v0.1.1...v0.1.2
v0.1.1
Impulso has moved
- Repository: QuantClimate/Impulso. Old
thomaspinder/Impulsolinks and git remotes redirect. - Documentation: impulso.quantclimate.com. Old
thomaspinder.github.io/Impulso/links redirect to the same page.
No API or behaviour changes. This release updates the package metadata, so PyPI's Homepage, Repository and Documentation links point at the new locations. The only source change is the issue link in LongRunRestriction's error message.
What's Changed
📖 Documentation
- docs: drop the Experimental note from the README by @thomaspinder in #360
Full Changelog: v0.1.0...v0.1.1
v0.1.0
Highlights
Impulso 0.1.0 makes a VAR embeddable in a PyMC model you already own, alongside the standalone VAR.fit workflow.
VAR.build_in_model: registers a VAR into the active PyMC model and returns handles to its variables.fitandprior_predictivenow go through the same code path. Namespacing works through a nested namedpm.Model.- Symbolic data: the observed block can be a PyTensor tensor, e.g.
pm.Data. Its likelihood is then apm.Potential. - Latent endogenous series:
latent_namesgenerates unobserved series inside the model from standard-normal innovations (non-centred). The observed likelihood is conditional on the innovations, and a stationarity constraint on the latent block keeps sampling stable. MinnesotaPrior(own_lag_mean=...): the textbook per-variable own-lag mean. Use 0 for stationary series.FittedVAR.from_posterior: validated construction of aFittedVARfrom a posterior you produced elsewhere.VARspecs round-trip throughmodel_dumpandmodel_validate, in python and JSON mode.
The design and its evidence are recorded in ADR-0016.
Upgrading from 0.0.14
There are no breaking changes to released APIs. The breaking changes of this development cycle (Minnesota cross-lag scaling in ADR-0015, the required sigma argument to Prior.build_priors, ErrorDistribution.logp, and rejection of constant endogenous columns) shipped in 0.0.14.
Known limits:
- Latent series support Gaussian errors only.
- A
ConjugateVolatilitysubclass (e.g.PandemicBreak) does not round-trip throughmodel_dump. - The latent stationarity constraint's
eigis untested on the JAX backend.
What's Changed
🚀 Features
- feat: accept a symbolic observed endog in build_in_model by @thomaspinder in #342
- feat: generate latent series non-centred in build_in_model by @thomaspinder in #344
- feat: latent own-lag mean, stationary init and stationarity constraint by @thomaspinder in #346
- feat: reject embedded-path options build_in_model can't support by @thomaspinder in #348
🐛 Bug Fixes
- fix: name the actual source in endog_scales validation errors by @thomaspinder in #340
- fix: make VAR specs round-trip through model_dump/model_validate by @thomaspinder in #354
💥 Breaking Changes
- feat!: move the own-lag prior mean onto MinnesotaPrior by @thomaspinder in #352
📖 Documentation
- docs: add ADR-0016 for the embeddable VAR path by @thomaspinder in #349
- docs: remove internal issue references from docstrings and comments by @thomaspinder in #355
Full Changelog: v0.0.14...v0.1.0
v0.0.14
What's Changed
🚀 Features
- feat: make ar1_residual_sd public by @thomaspinder in #315
- feat: add FittedVAR.from_posterior by @thomaspinder in #317
- feat: route VAR.fit and ConjugateVAR.fit through from_posterior by @thomaspinder in #319
- feat: add VAR.build_in_model by @thomaspinder in #329
- feat: add intercept_equations to build_in_model by @thomaspinder in #331
- feat: add per-variable innovation-scale priors to Constant by @thomaspinder in #323
🐛 Bug Fixes
- fix(docs): re-tone theme accent to oxblood and fix dark-mode notebook cells by @thomaspinder in #302
💥 Breaking Changes
- feat!: add ErrorDistribution.logp by @thomaspinder in #321
- feat!: scale MinnesotaPrior cross-lags by sigma_i/sigma_j by @thomaspinder in #325
- feat!: reject constant endogenous columns by @thomaspinder in #327
🧩 Other
- docs: adopt qc-core plotting style by @thomaspinder in #295
- fix(deps): align ArviZ floors with Matplotlib 3.11 by @thomaspinder in #297
- docs(context): audit the glossary against code, then compress it by @thomaspinder in #298
- fix(typing): make SVDynamics members read-only; unblock linter bumps by @thomaspinder in #299
- build(deps): Bump the python group across 1 directory with 13 updates by @dependabot[bot] in #300
- build(deps-dev): Bump the linters group with 3 updates by @dependabot[bot] in #301
- build(deps-dev): Bump the linters group with 3 updates by @dependabot[bot] in #305
- build(deps-dev): Bump ipywidgets from 8.1.8 to 8.1.9 in the python group by @dependabot[bot] in #306
- build(deps-dev): Bump the linters group with 3 updates by @dependabot[bot] in #307
- build(deps-dev): Bump the linters group with 3 updates by @dependabot[bot] in #310
Full Changelog: v0.0.13...v0.0.14
v0.0.13
What's Changed
🧩 Other
- fix(sampling): reject interrupted NaN-padded posteriors; fit proxy-svar SV cell to the CI budget by @thomaspinder in #285
- refactor(identification): declare last_diagnostics as the scheme seam's diagnostics capability by @thomaspinder in #286
- refactor(scenario): one forecast-side solve engine; propagate() owns the lag recursion by @thomaspinder in #288
- refactor(identification): one module per scheme by @thomaspinder in #290
- refactor(posterior): one owner for the posterior schema by @thomaspinder in #291
- refactor(results): deepen the result base; plotting consumes the result interface by @thomaspinder in #292
- test: guard the FittedVAR->IdentifiedVAR field carry; drop the MCMC fit from the dispatch test by @thomaspinder in #293
Full Changelog: v0.0.12...v0.0.13
v0.0.12
What's Changed
🧩 Other
- docs/titghten proxy svar by @thomaspinder in #278
- fix: support ArviZ 1 DataTree results by @juanitorduz in #277
New Contributors
- @juanitorduz made their first contribution in #277
Full Changelog: v0.0.11...v0.0.12
v0.0.11
New tutorial: Checking a VAR Before You Trust It
A full model-checking walkthrough on real U.S. monetary policy data (1965–2007): stationarity and cointegration pretests (adf_test, kpss_test, integration_order, johansen_test), prior predictive checks, MCMC diagnostics in ArviZ (divergences, rank-normalised R-hat, bulk/tail ESS, trace, rank, and energy plots — including a real slow-mixing failure and its low-rank mass-matrix fix), and posterior predictive checks with quantile coverage. Fully cited, and rendered as part of the docs.
Bug fix
FittedVAR.posterior_predictive with named DataFrame indexes. Data built via VARData.from_df from a DataFrame whose index carries a name (e.g. "date") crashed with CoordinateValidationError: xarray adopted the index name as the coordinate's dimension, clashing with the explicit time dim. The time coordinate is now pinned with the explicit-dimension form, matching identified.py. Regression test included.
v0.0.10
Dependency floors
pandas>=3.0 → >=2.3.3. The pandas 3.0 requirement was never needed — pandas is a pure I/O boundary in Impulso, and every numeric path crosses via .to_numpy(dtype=np.float64). Installing Impulso no longer forces a pandas major-version upgrade. Verified against pandas 2.3.3 across the full fast and MCMC suites.
matplotlib>=3.7 → >=3.9. This is a tightening, and consumer-visible. matplotlib 3.7 and 3.8 are built against the NumPy 1.x C ABI and cannot import under numpy>=2.0, which Impulso already required — so that combination never actually worked. If you are pinned to matplotlib 3.7 or 3.8, this release will no longer resolve for you.
CI
New lowest-direct-deps job resolves every declared dependency to its minimum and runs the test suite there, on Python 3.11. Previously the lockfile pinned current versions, so the floors in pyproject.toml were declared but never exercised — the matplotlib problem above is what that job found on its first run.
Full changelog: v0.0.9...v0.0.10
v0.0.9
Structural identification, forecast diagnostics and stationarity testing land together in this release, alongside several fixes to inference that was previously silently wrong.
Before you upgrade
Three fixes change numbers you may already have published. None of them raise an error — the old results simply looked fine.
| If you… | …then | What to do |
|---|---|---|
use a custom Cholesky(ordering=...) |
your IRFs, FEVDs and historical decompositions were mislabelled — rows came back in ordering order while being reported as data order (#208) | re-run; identity orderings are byte-identical and unaffected |
fit with exog on the NUTS path |
the B_exog prior was pinned at Normal(0, 1) regardless of regressor scale, crushing coefficients on small-scale regressors — a true coefficient of 50 on a N(0, 0.01²) regressor recovered ≈1 (#237) |
re-fit; the prior now scales as exog_prior_scale · σᵢ / sd(xⱼ), default 100 |
| forecast with multivariate stochastic volatility | every forecast standard deviation sat at exp(-mu_i/2) times the correct scale — the in-sample fit was unaffected, so nothing looked wrong (#241) |
re-run; affects density, conditional and scenario forecasts. AR(1) log-vol dynamics were never affected |
Three further changes reject input that used to be accepted silently: duplicate or overlapping variable names (#206), StudentT.prior_alpha ≤ 1 (#211), and ConjugateVolatility adapters declaring no hyperparameters (#233).
Highlights
-
ZeroSignRestriction— combined zero-and-sign identification via the Arias–Rubio-Ramírez–Waggoner recursive null-space construction (#218). -
LongRunRestriction— Blanchard–Quah identification on cumulative long-run effects (#183). -
FittedVAR.granger_causality()— reports the posterior of the coefficient norm as a magnitude, not a test statistic, so a small effect stays distinguishable from an imprecise one.toda_yamamoto()covers the lag-augmented procedure when integration orders are uncertain (#226). -
Predictive checks —
VAR.prior_predictive()andFittedVAR.posterior_predictive()(#230). -
Stationarity diagnostics —
adf_test,kpss_test,johansen_test,integration_order, behind a new extra (#197):pip install "impulso[diagnostics]==0.0.9" -
Student-t observation errors (#168) and model evidence / Bayes factors on conjugate fits (#160).
Impulso is pre-v0.1 and the public API is still moving; breaking changes ship in minor releases with the rationale recorded in docs/adr/.
What's Changed
🚀 Features
- feat(sv): align SVForecastResult index to calendar dates by @thomaspinder in #158
- feat(conjugate): stamp the Metropolis acceptance rate on the posterior attrs by @thomaspinder in #210
- feat(conjugate): expose model evidence and Bayes-factor comparison by @thomaspinder in #160
- feat(spec): Student-t observation errors and predictive draws by @thomaspinder in #168
- feat(identification): long-run (Blanchard-Quah) structural restrictions by @thomaspinder in #183
- feat(stationarity): ADF, KPSS and Johansen diagnostics with integration-order bookkeeping by @thomaspinder in #197
- feat(identification): combined zero-and-sign restrictions (ARW construction) by @thomaspinder in #218
- feat(predictive): prior_predictive on VAR, posterior_predictive on FittedVAR by @thomaspinder in #230
- feat(granger): Bayesian Granger causality with Toda-Yamamoto robustness by @thomaspinder in #226
🐛 Bug Fixes
- fix(init): module-level lazy-import table and dir by @thomaspinder in #156
- fix(spec): safe default sampler with cores=1 in VAR.fit by @thomaspinder in #157
- fix(identification): weakref-validated posterior cache for ProxySVAR by @thomaspinder in #234
- fix(scenario): finite shock-matrix guard; infer shock order in from_zero_restrictions by @thomaspinder in #223
- fix(stationarity): re-emit non-target KPSS warnings; define p in the Johansen snippet by @thomaspinder in #212
💥 Breaking Changes
- fix(data): reject duplicate and overlapping variable names in VARData by @thomaspinder in #206
- fix(identification): return the ordered Cholesky factor in data row order by @thomaspinder in #208
- fix(conjugate): reject volatility adapters with no hyperparameters to estimate by @thomaspinder in #233
- fix(spec): scale the B_exog prior to the data instead of pinning sigma=1 by @thomaspinder in #237
- fix(observation): prior_alpha > 1 guard and 5-dim innovation-covariance coverage by @thomaspinder in #211
- fix(sv): re-apply the per-variable log-vol level in the SV forecast (#241) by @thomaspinder in #268
📖 Documentation
- docs(reference): conjugate and volatility reference pages by @thomaspinder in #207
- docs: add a Minnesota prior tutorial for new users by @thomaspinder in #117
Full Changelog: v0.0.8...v0.0.9