paul-buerkner / brms

brms R package for Bayesian generalized multivariate non-linear multilevel models using Stan
https://paul-buerkner.github.io/brms/
GNU General Public License v2.0
1.28k stars 184 forks source link

issue with shifted lognormal families default prior on ndt parameters when using multiple responses #837

Closed laurentott closed 4 years ago

laurentott commented 4 years ago

Hi Paul, I get a compilation error when I try to fit 2 shifted lognormal in one go. Here is an example :

N1 = 50
ndt1 = 0.3
data1 = data.frame( RT1 = exp( rnorm(N1,-1,0.3) ) + ndt1  )

N2 = 75
ndt2 = 0.2
data2 = data.frame( RT2 = exp( rnorm(N2,-1,0.3) ) + ndt2  )

data1$subset1 = TRUE
data1$subset2 = FALSE
data1$RT2 =0

data2$subset1 = FALSE
data2$subset2 = TRUE
data2$RT1 = 0

data_all = rbind( data1 , data2 )

library(brms)

bf1 = bf( RT1 | subset(subset1) ~ 1 ) + shifted_lognormal()

bf2 = bf( RT2 | subset(subset2) ~ 1 ) + shifted_lognormal()

fit = brm( bf1 + bf2 + set_rescor(FALSE)
           , data = data_all
           , cores = parallel::detectCores()
           )

which gives the following compilation error

SYNTAX ERROR, MESSAGE(S) FROM PARSER:
Variable "min_Y" does not exist.
error in 'modela9ad2870986f_filea9ad237e42fb' at line 37, column 43
-------------------------------------------------
    35:   target += student_t_lpdf(sigma_RT1 | 3, 0, 10)
    36:     - 1 * student_t_lccdf(0 | 3, 0, 10);
    37:   target += uniform_lpdf(ndt_RT1 | 0, min_Y)
                                                  ^
    38:     - 1 * log_diff_exp(uniform_lcdf(min_Y | 0, min_Y), uniform_lcdf(0 | 0, min_Y));
-------------------------------------------------

Even if I specify manually some priors for the ndt parameters, the generated code still relies on min_Y and does not compile

fit = brm( bf1 + bf2 + set_rescor(FALSE)
           , data = data_all
           , prior = c( prior( uniform(0,0.3) , class = 'ndt' , resp = 'RT1' )
                       , prior( uniform(0,0.2) , class = 'ndt' , resp = 'RT2' )
                      )
           , cores = parallel::detectCores()
)
SYNTAX ERROR, MESSAGE(S) FROM PARSER:
Variable "min_Y" does not exist.
error in 'modela9ad267605ec_filea9ad7f87abf5' at line 37, column 41
-------------------------------------------------
    35:     - 1 * student_t_lccdf(0 | 3, 0, 10);
    36:   target += uniform_lpdf(ndt_RT1 | 0, 0.3)
    37:     - 1 * log_diff_exp(uniform_lcdf(min_Y | 0, 0.3), uniform_lcdf(0 | 0, 0.3));
                                                ^
    38:   target += student_t_lpdf(sigma_RT2 | 3, 0, 10)
-------------------------------------------------
paul-buerkner commented 4 years ago

Thanks! Should be fixed now.

laurentott commented 4 years ago

It works for the first case, but it leads to a failure to initialize the sampler due to a log prob of negative infinity when I specify manually the uniform prior. The generated stan code has the following line

  target += uniform_lpdf(ndt_RT1 | 0, 0.3)
    - 1 * log_diff_exp(uniform_lcdf(min_Y_RT1 | 0, 0.3), uniform_lcdf(0 | 0, 0.3));

which I think is problematic if min_Y_RT1 is outside the bound of the uniform distribution. Shouldn't it be instead

  target += uniform_lpdf(ndt_RT1 | 0, 0.3)
    - 1 * log_diff_exp(uniform_lcdf(0.3 | 0, 0.3), uniform_lcdf(0 | 0, 0.3));
paul-buerkner commented 4 years ago

Not sure if this is a bug to be honest. A prior should respect the natural boundaries of a parameter, that is, also not impose hard boundaries when there are non or when the boundaries are in other places.

laurentott commented 4 years ago

OK I get it, thanks