Changelog

0.11.0 Our BART is eternal and will live in my disk forever (2026-06-28)

  • New stochtree-compatible interface bartz.stochtree.BARTModel

    • incl. stochtree-like X preprocessing: one-hot encode categoricals, but preserving the a priori variable selection probability as if it was a single column, works on polars and pandas dataframes

  • Error term settings overhaul (breaking)

    • Bart: sigest/sigdf/sigquant/lambda_ replaced by sigma_df/sigma_scale/sigma_init

      • the default error variance prior is scaled by the total variance only, no OLS

      • the default error variance prior keeps into account missingness and heteroskedasticity

    • Bart parameter w renamed to error_scale (also in predict), to avoid ambiguity with the common convention of using w to mean precision weights, and matching mcmcstep.init()

    • init and State: all error-related params passed through a Wishart or DiagWishart dataclass

  • Save to disk with Bart.dump(path) / Bart.load(path)

  • MCMC logging improvements

    • Progress bar instead of line logging

    • Log effective number of predictors when variable selection is active

    • More interpretable tree depth diagnostic

    • Diagnostics are averaged over the last iterations instead of the current state only

  • mc_gbart / gbart changes

    • x_train/x_test now have layout (n, p) instead of (p, n), matching BART3

    • w accepts a pandas Series

  • Performance: multiple improvements across the library in speed and memory usage

  • run_mcmc is chunking-invariant

  • Bug fixes

    • Fixed bug in the MCMC that changed the prior definition, making the trees a bit shallower

    • Fixed bug that would ignore a correlated leaf prior with multivariate outcomes

    • Cap auto chain sharding to the device pool

  • Many improvements to the testing data generator bartz.testing.gen_data()

  • Fully typed library, ship py.typed marker such that type checkers are allowed to use its types

  • Move R packages wrappers to new package rbartpackages (on PyPI)

  • Exclude jax 0.10.2 (GPU perf regression)

0.10.0 What do you mean “Maybe I lost a datapoint”. You don’t just LOSE a datapoint. What happens is that you are an IDIOT and THEN you lose the datapoint. If you weren’t IDIOT the datapoint wouldn’t be lost, FACTS and LOGIC. The continued survival of this company never ceases to fuel my bewilderment as I am clearly surrounded by IDIOTS. Now listen carefully. As the good idiot you are, you go and flag this datapoint as missing. “Missing” means that you set the “missing” flag to “True”. You don’t set it to to “False”, because evidently “missing=False” would imply we were supposed to have the actual bleeding datapoint in place instead of whatever garbage you managed to conjure in that array. Now get the foobar out of here. (2026-05-27)

This release features some improvements to multivariate outcome modeling, better out-of-the-box experience with the Bart interface, and some optimizations.

  • New features for multivariate outcomes

    • Heteroskedasticity with fixed weights, both scalar (one weight per unit) and vector (one weight per outcome component)

    • Partial missingness: each unit can have any subset of outcome components observed; forces diagonal error covariance matrix

  • Optimizations

    • Predictor subsampling support, automatic sigest now handles large n

    • All Bart methods are jitted

    • Avoid redundant copies further

    • Reduced MCMC memory usage with multiple chains

    • Increased performance with device sharding; still not thoroughly optimized

  • Bart interface changes

    • binner=... instead of usequants and numcut parameters

    • devices='cpu' / 'gpu' for brevity instead of passing a jax device object

    • Chain auto-sharding on cpu; previously mc_bart-only

    • Accept dataframes all inputs; previously just X and y

    • Properties Bart.n_save and Bart.num_chains

    • Rename MCMC schedule parameters to match run_mcmc: ndpostn_save, nskipn_burn, keepeveryn_skip

    • get_error_sdev() now averages variance rather than precision across the posterior

0.9.0 This release creates a shared environment where response variable components of different types are given equal consideration without residual correlations (2026-04-20)

The highlight of this release is exposing the multivariate outcome regression functionality in the high-level interface.

  • New features

    • Multivariate outcomes exposed in the high-level interface bartz.Bart (thanks @miaoqingyu2)

    • Binary and mixed binary-continuous multivariate outcomes, but without error correlations

    • Bart can compute outcome-level samples in predictions (i.e., “sample the likelihood”)

    • varprob input parameter to mc_gbart and Bart, to set or initialize the a priori importance of each predictor

  • Bart changes

    • New defaults nskip=1000, numcut=255, num_chains=4

    • Prediction properties yhat_train, yhat_test, etc., integrated into Bart.predict

    • Standard deviation properties sigma and sigma_ replaced by methods get_latent_prec() and get_error_sdev()

    • y_train must be floating point for binary regression instead of boolean (also in mc_gbart)

    • Default arguments num_trees=200 and keepevery=1 unconditionally instead of changing based on continuous/binary like mc_gbart

    • Property Bart.num_trees

  • Other changes

    • Removed profile mode, detailed jax profiling is available only on gpu

    • Moved various debug methods from debug_mc_gbart to Bart

    • Moved various tree inspection functions from bartz.debug to bartz.grove

    • mcmcstep.init() may now steal the buffers of most array inputs

    • mcmcstep.init() always returns a State with strong-typed arrays

    • mcmcloop.run_mcmc() returns a named tuple instead of a plain tuple, for convenience

    • Added bartz.__version_info__ to allow comparing version numbers directly with tuple comparison

  • Dependencies: introduced a policy of supporting all the officially supported Python releases (last 5 releases, currently Python 3.10 to 3.14) and Python package releases no older than 1 year ago, rounded to the first release towards the past. Informally, the main dependencies (jax, numpy, scipy) are actually supported for 1 year rather than up to 1 year.

0.8.0 The Dark Side of Big Bayes (2026-02-04)

The highlights of this release are multiple parallel Markov chains and splitting data and/or chains across multiple devices. The repository has been moved to bartz-org to welcome the first contributor @miaoqingyu2.

  • New features

    • New interface bartz.Bart intended to supersede bartz.BART.gbart. gbart will continue to match the R package BART3, while new functionality will be added in bartz.Bart.

    • Built-in support for running multiple independent chains in parallel. At the interface level, this is available through bartz.Bart and bartz.BART.mc_gbart.

    • Support for multiple devices. Data and/or chains can be split across gpus. This can be controlled only through the new interface bartz.Bart, while mc_gbart will shard chains automatically on cpu but otherwise not provide settings.

    • Multivariate regression thanks to @miaoqingyu2. This is currently only implemented at low level, not in the easy to use interface.

  • Performance improvements

    • Generally faster, in particular on gpu at low \(n\) and on cpu with heteroskedasticity.

    • Fixed a performance regression in v0.7.0 where the running time per iteration would grow with the total number of iterations because the full trace array was duplicated on each iteration.

    • Undid the weird thing where if the number of iterations is not a multiple of printevery there are leftover iterations which are performed but not saved.

    • run_mcmc will raise an error if for any reason the MCMC code is compiled twice. This can be triggered by internal errors or by misconfiguration.

  • Bugs fixed

    • Fixed wrong rare misspecified corner cases in the MCMC.

    • Fixed binary regression producing nans/infs on gpu.

    • Fixed slightly out of sync MCMC iteration logging on gpu.

  • Usability improvements

    • Convenience attribute bartz.BART.mc_gbart.sigma_ for accessing the post-burnin sigma samples.

    • Extras bartz[cuda12] and bartz[cuda13] to easily install dependencies for working with nvidia gpus; they simply mirror the corresponding jax extras.

    • Variable selection has been integrated into bartz.mcmcstep.step.

    • The MCMC state class bartz.mcmcstep.State has a new config attribute that, amongst other things, tracks the number of steps done on the state.

0.7.0 Every woman knows the pain of deciding which predictors to throw away when her design matrix is full to the brim and the last season brought out new lagged features. Our 100% money-back guarantee Bayesian variable selection Dirichlet prior will pick out the best predictors for you automatically while the MCMC is running! (2025-07-07)

The highlight of this release is the implementation of variable selection.

  • Changes apparent through the gbart interface:

    • Parameters sparse, theta, rho, a, b to activate and configure variable selection

    • The MCMC logging shows a fill metric which is how much the tree arrays are filled, to check the trees are not being constrained by the maximum depth limit

    • Parameter xinfo to set manually the grid cutpoints for decision rules

    • Fixed a stochastic bug with binary regression that would become likely with >1000 datapoints

    • Parameter rm_const to decide how to handle “blocked” predictors that have no possible decision rules

    • The defaults of parameters ntree and keepevery now depend on whether the regression is continuous or binary, as in the R package BART

    • New attributes of gbart objects, matching those of R’s BART::gbart:

      • prob_train, prob_test, prob_train_mean, prob_test_mean (for binary regression)

      • sigma includes burn-in samples, and first_sigma is gone

      • sigma_mean (the mean is only over kept samples)

      • varcount, varcount_mean

      • varprob, varprob_mean

  • The bartz.debug submodule is now officially public, the main functionality is:

    • The class debug_gbart that adds some debugging methods to gbart

    • trees_BART_to_bartz to read trees in the format of R’s BART package

    • sample_prior to sample from the BART prior

  • Changes to internals:

    • More typing in general

    • Changes to run_mcmc:

      • MCMC traces are dataclasses instead of dictionaries

      • Switch back to using only one callback instead of two

        • I realized that jax.lax.cond makes the additional callback pointless. I previously had a cached heuristic to not use lax.cond because it’s not efficiently vmappable, but for all practical uses in the MCMC it would be.

      • The callback accepts a jax random key, useful to implement additional MCMC steps

      • Simplified main/burn-in distinction for custom trace extractors

    • Changes to the MCMC internals:

      • min_points_per_decision_node intended as replacement to min_points_per_leaf

        • min_points_per_leaf is still available to allow the gbart interface to mimic R’s BART

        • This different constraint is easier to take into account exactly in the Metropolis-Hastings ratio, while min_points_per_leaf leads to a deviation from the stated distribution

      • The tree structure MH should now match exactly the distributions written on paper, if min_points_per_leaf is not set

      • The tree structure MH never proposes zero-probability states, if min_points_per_leaf is not set

    • Valid usage should not produce infs or nans internally any more, so jax.debug_infs and jax.debug_nans can be used

0.6.0 bruv bernoulli got gauss beat any time (2025-05-29)

  • binary regression with probit link

  • allow to interrupt the MCMC with ^C

  • logging shows how much the tree heaps are filled; if it’s above 50% you should definitely increase the number of trees and/or the maximum depth

  • BART.gbart(..., run_mcmc_kw=dict(...)) allows to pass additional arguments to mcmcloop.run_mcmc

  • option to disable logging

  • refactor internals

    • set offset in the MCMC state to avoid centering the responses

    • set leaf variance in the MCMC state to avoid rescaling responses

    • immutable dataclasses instead of dicts

    • improvements to mcmcloop.run_mcmc

      • simpler to use signature with only three required parameters

      • the callback is allowed to carry a state and to modify the chain state (opt-in)

      • custom functions to change what is extracted from the state and put into the traces

      • two distinct callbacks, one invoked under jit and one out of it

      • more sophisticate default logging callback

    • complete type hints

    • improved documentation

    • jaxext.split is a less error-prone alternative to jax.random.split

0.5.0 Our work promotes diversity in error variances by following heteroscedasticity best-practices such as multiplying the variance parameter by different factors (2025-05-16)

  • Heteroskedasticity with fixed weights.

  • The internal MCMC functions now follow the jax convention of having the key parameter first in the signature.

  • Fixed a bug where the MCMC callback would hang indefinitely.

  • The library is now routinely tested with the least recent supported dependencies.

0.4.1 Told it was, nigh the end of times, version numbers of dependencies all would rise (2025-04-23)

Somehow 1 year went by before I had some time to spend on this software.

Somehow 1 year was sufficient to break most of my dependency specifications, despite having only 4 dependencies.

This release provides no new features, it’s only a quick fix to make bartz go well with the latest jax and numpy versions.

0.4.0 The real treasure was the Markov chain samples we made along the way (2024-04-16)

  • 2x faster on GPU, due to parallelizing better the tree sampling step.

  • Uses less memory, now can do \(n=100\,000\) with \(10\,000\) trees on a V100. This was mostly an excessively large batch size for counting datapoints per leaf.

  • The Metropolis-Hastings ratio is saved only for the proposed move.

  • The grow and prune moves are merged into one object.

0.3.0

  • 2-3x faster on CPU.

  • Uses less memory.

  • Add initkw argument to BART.gbart for advanced configuration of the MCMC initialization.

  • Modified the automatic determination of sigest in BART.gbart to match the one of the R package.

  • Add usequants=False option to BART.gbart, which is now the default.

  • New function prepcovars.uniform_splits_from_matrix.

  • Add sum_trees=False option to grove.evaluate_forest to evaluate separately each tree.

  • Support non-batched arguments in jaxext.autobatch.

  • Fix a bug with empty arrays in jaxext.autobatch.

  • New option in mcmcstep.init to save the acceptance ratios.

  • Separate batching options for residuals and counts.

  • Sweeping changes to the tree move internals, more computations are parallel across trees.

  • Added support for dbarts in the unit tests.

0.2.1

  • Fix a bug that prevented using bart in a compiled function.

0.2.0

  • Rename bartz.BART to bartz.BART.gbart.

  • Expose submodule bartz.jaxext with auxiliary functions for jax.

  • Shorter compilation time if no burnin or saved samples are drawn. This is useful when using the interface only to create the initial MCMC state, or when saving all samples to inspect the warm-up phase.

  • 20x faster on GPU.

  • 2x faster on CPU.

  • Use less temporary memory to quantilize covariates, avoiding out-of-memory errors on GPU.

0.1.0

  • Optimize the MCMC step to only traverse each tree once.

  • Now bartz runs at the same speed as the R package BART (tested at \(p=10\), \(n=100\ldots 10000\)).

  • The MCMC functions are heavily changed, but the interface is the same.

0.0.1

  • BART has attributes maxdepth, sigest.

  • Fix errors with scaling of noise variance prior.

  • Fix iteration report when keepevery is not 1.

  • Lower required versions of dependencies to allow running on Colab.

0.0

First release.