Custom family works in Stan but not in brms

Hi - I have a working custom likelihood in Stan and would like to convert it to a custom family in brms.

The following Stan model works:

stan
functions{
  real paretocounts_lpdf(vector x, real b, vector counts){
    vector[num_elements(x)] temp; //array that stores densities
        real sumcx;
        for(i in 1:num_elements(x)){  //loop over data and store each density
            temp[i] = counts[i]*log(x[i]); 
        }
    sumcx = sum(temp);
    real xmin;
    real xmax;
    xmin = min(x);
    xmax = max(x);
    return(sum(counts)*log((b + 1)/(xmax^(b+1) - xmin^(b+1))) + b*sumcx);
    }
}
    
data {
	int<lower=0> N;
	vector[N] x;
	vector[N] counts;
}

parameters {
	real b;
}

model {
	b ~ normal(-2, 1);
	target += paretocounts_lpdf(x|b, counts);
}
R
# sim data
N = 30
xmin = 0.01
xmax = 1000
b = -1.4
x = abs(rnorm(N, 2, 1))
counts = abs(rnorm(N, 2, 1))


# fit stan model
fit_counts <- stan(file = "models/stan_pareto_truncated_counts.stan",
                   data = list(N = N, 
                               x = x,
                               counts = counts))

But when I try to add this to brms, it gives the following error:

Compiling Stan program…
Error in stanc(file = file, model_code = model_code, model_name = model_name, :
0

Semantic error in ‘string’, line 43, column 16 to column 55:

Ill-typed arguments supplied to function ‘paretocounts_lpdf’. Available signatures:
(vector, real, vector) => real
Instead supplied arguments of incompatible type: real, real, vector.

Here is what I’ve tried in brms. This generates the error above.

paretocounts <- custom_family(
  "paretocounts", dpars = "mu",
  links = (""), lb = NA,
  type = "real", 
  vars = "counts"
)

# define the corresponding Stan density function
stan_paretocounts <- "
  real paretocounts_lpdf(vector x, real b, vector counts){
    vector[num_elements(x)] temp; //array that stores densities
        real sumcx;
        for(i in 1:num_elements(x)){  //loop over data and store each density
            temp[i] = counts[i]*log(x[i]); 
        }
    sumcx = sum(temp);
    real xmin;
    real xmax;
    xmin = min(x);
    xmax = max(x);
    return(sum(counts)*log((b + 1)/(xmax^(b+1) - xmin^(b+1))) + b*sumcx);
    }
"
stanvars <- stanvar(counts, name = "counts") + 
                      stanvar(scode = stan_paretocounts, block = "functions")

# this model gives an error
brm_pareto <- brm(x ~ 1, data = tibble(x = x, counts = counts), 
           family = paretocounts, stanvars = stanvars)

I’ve looked at it long enough that I cannot see an error in there. Any help is much appreciated. Thanks!

  • Operating System: Microsoft Windows 10 Enterprise
  • brms Version: 2.17.0

I’m not 100% sure this will fix it, but it looks like you’ve written paretocounts to vectorize over the data and the linear predictor. Try setting loop = F in your call to custom_family or alternatively writing paretocounts to be evaluated row-wise over the data in a for loop.

Thanks jsocolar. Changing loop = F didn’t work, unfortunately. I got a similar error. I’m new to stan so am not sure how to recode the stan syntax to evaluate row-wise as you mentioned. Will work on that…