Brms predict() issue when using a stan function in a non-linear model fit

I’m trying to fit a simple two piece function to some count data.

brmsformula(y ~  0 - (46 - fmax(x0, x)) * (y0/(46 - x0)),
       x0 ~ 1,
       y0 ~ -1 + male)

I’m able to fit this formula, but when I try to use brms’s predict() function, I get the error

Error in fmax(x0, x) : could not find function "fmax"
 Most likely this is because you used a Stan function in the non-linear model formula that is not defined in R. If this is a user-defined function, please run 'expose_functions(., vectorize = TRUE)' on your fitted model and try again.

While I understand the issue, I can’t seem to find a solution.
For example, if I define fmax <- function(x,y) max(x,y) within my R session the error goes away, but the output from predict() consists solely of 0s.

Is there a work around for this?

  • Operating System: Ubuntu 22.04
  • brms Version: 2.18.0
1 Like

Did anyone solve this as I am having a similar problem.

I don’t think this is right:

In R, the function should be vectorized. One can use the built-in element-wise max function pmax .

Since there is no reprex I had chatgpt write one and it does appear to fix the issue:

library(brms)

set.seed(1)

# Fake data
N <- 100
x <- runif(N, 0, 50)
x0 <- 20
y0 <- 10
mu <- (46 - pmax(x0, x)) * (y0 / (46 - x0))
y <- rpois(N, lambda = pmax(mu, 0.1))
dat <- data.frame(x, y, male = rbinom(N, 1, 0.5))

form <- bf(
  y ~ (46 - fmax(x0, x)) * (y0 / (46 - x0)),
  x0 ~ 1,          # x0 has only an intercept
  y0 ~ 1 + male,   # y0 depends on sex
  nl = TRUE
)

priors <- c(
  prior(normal(20, 5), nlpar = "x0"),
  prior(normal(10, 5), nlpar = "y0")
)

fit <- brm(
  form,
  data = dat,
  family = poisson(),
  prior = priors,
  iter = 1000,
  chains = 2,
  control = list(adapt_delta = 0.9)
)

summary(fit)

# errors
pred <- predict(fit)

fmax <- pmax

# success
pred <- predict(fit)
head(pred)
1 Like

Well that was embarassingly easy. Thank you.