Varying formula over time/space

Hi, I was trying to fit a non-linear model where the formulat changes over time/space, like linear up to point t and exponential after it. In raw stan I would do something like:

for (x in 1:N)
  if (x < t)
    y[i] ~ normal(a + b * m, sigma1)
  else if (x >= t)
    y[i] ~ normal(p + exp(b * r), sigma2)

I couldn’t find an ovious way to implement it in brms

thank you very much

you can try the following. First, define variables xlt = x < t in your data. Then specify the formula as follows:

bform <- bf(
  xlt * (a + b * m) + (1 - xlt) * (p + exp(b * r)),
  a + b + p ~ 1,
  sigma ~ 0 + xlt
  nl = TRUE
)

thanks, but what if “t” is unknown and has to estimated from the data? I was thinking about defining a custum brm response function…maybe it will work

You could try:

bform <- bf(
  (x < t) * (a + b * m) + (x >= t) * (p + exp(b * r)),
  a + b + p + t ~ 1,
  nl = TRUE
)

trying to reproduce but getting a error about x not being recognized as data (I suppose):

a=1; b=0.1; r=0.01; t=20
x=1:100
y=sapply(x, function(i) if(i<t) a + b * i else (b * t) + exp(r * i))

bform ← bf(
y ~ (x < t) * (a + b * x) + (x >= t) * (p * exp(r * x)),
a + b + p + r + t ~ 1,
nl = TRUE
)

fit<-brm(bform, data=data.frame(y=y, x=1:length(y)), prior = c(prior(normal(0, 10), nlpar= a),prior(normal(0, 1), nlpar= b), prior(normal(0, 10), nlpar= p), prior(normal(0, 0.1), nlpar= r), prior(normal(0, 10), nlpar= t)))

SYNTAX ERROR, MESSAGE(S) FROM PARSER:

variable “x” does not exist.
error in ‘model69132a36ad22_file6913163a1d08’ at line 42, column 15

40:   for (n in 1:N) { 
41:     // compute non-linear predictor 
42:     mu[n] = (x<t) * (nlp_a[n] + nlp_b[n] * C_1[n]) + (x>=t) * (nlp_p[n] * exp(nlp_r[n] * C_1[n]));
                  ^
43:   } 

Error in stanc(model_code = paste(program, collapse = “\n”), model_name = model_cppname, :
failed to parse Stan model ‘file6913163a1d08’ due to the above error.

Let me check what is going wrong. I will come back to you later on.

The problem should now be fixed in the github version of brms. Here is an example model:

set.seed(1234)
a = 1
b = 10
p = 1
r = 1
t = 0.3
x = seq(0, 1, length.out = 101)
y = ifelse(x < t, a + b * x, p + exp(r * x)) + rnorm(101)
plot(x, y, type = "l")

bform <- bf(
  y ~ (x < t) * (a + b * x) + (x >= t) * (p * exp(r * x)),
  a + b + p + r + t ~ 1,
  nl = TRUE
)

fit <- brm(
  bform, data = data.frame(y, x), 
  prior = c(prior(normal(0, 1), nlpar = a),
            prior(normal(0, 10), nlpar = b), 
            prior(normal(0, 1), nlpar = p), 
            prior(normal(0, 1), nlpar = r), 
            prior(uniform(0, 1), nlpar = t, lb = 0, ub = 1)),
  chains = 1
)

The model has some convergence problems, but that’s unrelated to the model specification used in brms.

thanks, it works like a charm now,