Laplace fails with sum_to_zero_vectors

While optimizing works fine, I get this with Laplace (cmdstanr):

> fit1 <- m$laplace(data = stan_data, draws=400)
Initial log joint probability = -47756.7 
    Iter      log prob        ||dx||      ||grad||       alpha      alpha0  # evals  Notes  
      99      -5966.96     0.0715766       222.449           1           1      104    
    Iter      log prob        ||dx||      ||grad||       alpha      alpha0  # evals  Notes  
     199      -5805.67     0.0299648       49.5217      0.9362      0.9362      213    
    Iter      log prob        ||dx||      ||grad||       alpha      alpha0  # evals  Notes  
     299      -5795.26    0.00369043       12.4433           1           1      322    
    Iter      log prob        ||dx||      ||grad||       alpha      alpha0  # evals  Notes  
     399      -5795.13   0.000200631       0.25514           1           1      428    
Optimization terminated normally:  
  Convergence detected: relative gradient magnitude is below tolerance 
Finished in  1.8 seconds.
Chain 1 Exception: stan::math::sum_to_zero_free: sum_to_zero variable does not sum to zero. sum(sum_to_zero variable) = 6e-07, but should be 0 (in '/tmp/Rtmp7bVu5w/model-308c2f68083034.stan', line 19, column 4 to column 42)
Chain 1 Bad or missing parameter values, cannot unconstrain.
Chain 1 
Warning: Fitting finished unexpectedly! Use the $output() method for more information.

Finished in  0.2 seconds.

From the optimization (with jacobian=T to get the optimum of Laplace), the MAP of the offending parameter looks fine:

grade_intercept[1] grade_intercept[2] grade_intercept[3] grade_intercept[4] grade_intercept[5] 
      -5.89484e-01       -1.60943e-01        2.46965e-01        5.43507e-01       -4.00442e-02 

I can use approximate centering in my code so it’s not a showstopper, but maybe someone would like to look at it? (My code and data are not exactly secrets, esp. code, so I can share at least the code if needed.)

You likely need to request a higher precision from cmdstanr

2 Likes

Oh right, the params go in between to Cmdstanr, thanks.

Can we just change the default, please? This has been a recurring problem for years. I think it would make sense to change the default in CmdStan. Alternatively, change the check tolerance in Stan. It just doesn’t make sense to keep that mismatch between the saving accuracy and the check tolerance accuracy

I’d rather keep my files smaller and letting Stan be looser with the constraints, if possible. (The optimum doesn’t really take space, but the samples would.)

The difference is 33% bigger, looser constraint check is likely to lead to errors in the built-in checks (6 digits is really low), and I’d rather keep users not getting errors by default. Of course, compressed binary output would be eventually better (real double accuracy), but that change is much bigger and is unlikely to happen soon.

I wouldn’t object. Want to make a cmdstan issue and see if others do?

You can, at compile time, pass -DSTAN_MATH_CONSTRAINT_TOLERANCE=1E-6 (or any value) to change what tolerance all of our floating point checks use. The default is 1E-8, which is almost exactly misaligned with only saving 6 digits in cmdstan

More motivation for @mitzimorris

1 Like
3 Likes