CmdStan & Stan 2.40 Release Candidates

I am happy to announce that the latest release candidates of CmdStan and Stan are now available on Github!

You can find the release candidate for CmdStan here. Instructions for installing are given at the bottom of this post.

Please test the release candidate with your models and report if you experience any problems. We also kindly invite you to test the new features and provide feedback. If you feel some of the new features could be improved or should be changed before the release, please do not hesitate to comment.

The Stan development team appreciates your time and help in making Stan better.

If everything goes according to plan, the 2.40 version will be released next week.

Below are some of the highlights of the new release.

New options for 1d integration

Several new integration functions have been added:

  • integrate_1d_double_exponential, a variadic version of the existing 1-d integrator
  • integrate_1d_gauss_kronrod, a variadic function with a different quadrature rule

Preliminary documentation can be found here.

Matrix reshaping functions

New functions to_vector_array(matrix) -> array[] vector to_row_vector_array(matrix) -> array[] row_vector, as well as new overloads for to_matrix for arrays of (row-)vectors.

New poisson_binomial distribution

A new discrete PMF, CDF, CCDF, and RNG functions available.

Preliminary documentation is available here

Other changes

There have been various other bug fixes and usability improvements this release, thank you to everyone who reported a bug in the last few months!

The same .stanfunctions can be #included multiple times without leading to errors about duplicated function definitions.

Updated the Math library to use Eigen 5.0.1

The vectorized RNGs were updated to fix a crash when given size-0 inputs.

The compiler has fewer dependencies, with a smaller binary size and improved speeds.

More details on all of the above and more are available in the preliminary release notes

How to install?

Download the tar.gz file from the link above, extract it and use it the way you use any Cmdstan release. We also have an online Cmdstan guide available at CmdStan User’s Guide .

If you are using cmdstanpy you can install the release candidate using


cmdstanpy.install_cmdstan(version='2.40.0-rc1')

With CmdStanR you can install the release candidate using


cmdstanr::install_cmdstan(version = "2.40.0-rc1", cores = 4)

  1. I tested compiling a bunch of Stan files which use the new integrate and laplace functions, and all did compile.

  2. --Oexperimental fails with empty loops, e.g.

parameters { real y; }
model {
  real x = 0;
  for (i in 1:0) x += 1;
  y ~ std_normal();
}
  1. --Oexperimental fails with posteriordb model state_wide_presidential_votes-hierarchical_gp.stan. stanc accepts it, then g++ rejects the generated code:
stan::model::assign(lcm_sym82__, multiply(multiply(17, prop_var), tot_var),
                    "assigning variable lcm_sym82__");
→ candidate expects 4 arguments, 3 provided

Thanks Aki!

#2 has an easy fix and I’ve put up a PR. #3 actually looks like an older issue, since I can recreate it on 2.39. Could be Issue · GitHub

Not sure in which repo this should be fixed (cmdstanr or cmdstan), so I didn’t create an issue yet (and yesterday it was just too late that I didn’t have time to create issues, and also why I didn’t check the older version for #3).

  • stanc takes one optimization level and the last flag wins. For example, --Oexperimental --O1 is byte-identical to O1 output. cmdstanr composes <include-paths> <your stanc_options> <make/local STANCFLAGS>, and if make/local has STANCFLAGS=--O1, then stanc_options = list("Oexperimental") is silently downgraded

I think a lot of flags have this last-wins behavior, but it’s rather complicated how Make will compose variables from different sources, so putting anything in make/local you hope to override later is probably just a hazard

I made an cmdstanr issue to switch order of make/local and stanc_options, so that stanc_options can be used to overrule make/local defaults

This interacts with some of the changes on the v1.0 branch that I’ve been working on. I’ll check the issue to see if it adds anything beyond what’s already in the 1.0 plan. I agree that options explicitly specified via stanc_options should take precedence.

I do also agree with this in general.

I’d like to have -O1 as the default, and I have assumed make/local would be the right place. But then rarely I want to run experiments with -O0 or -Oexperimental, so what would be your recommendation for setting up defaults and being able to override them for specific cases?

My make/local has a few blocks in it, with most of them commented out at any time. When I want to run some experiments, I uncomment the relevant ones and comment the others.

If you ever use cmdstanr to manage the make local file I imagine this wouldn’t work, so I’m not sure how to advise… just know that we inherit some often unintuitive behavior from make when it comes to specifying the same variable multiple times

Can you say more about why you think this wouldn’t work with cmdstanr? You can’t tell cmdstanr to comment out lines for you (at least not currently), is that what you mean? Or am I overlooking something else?

I assumed that the write_make_local function removed what was there previously, does it not? Either way would require some manual intervention

There’s an argument that toggles whether we overwrite or append to the end of the file. But yeah to comment and uncomment sections would require manual intervention.