OK. I have the problem surrounded. This works, i.e. just declare real zeta(real alpha);
but don’t define a power_law
function that calls it:
functions{
real zeta(real s);
/*TODO: implement rng for prior and posterior predictive checks*/
}
data{
int<lower=0> K; // number of unique values
int values[K];
int<lower=0> frequencies[K];
}
parameters{
real <lower=1> alpha;
}
model{
real constant = log(zeta(alpha));
for (k in 1:K) {
target += frequencies[k] * (-alpha * log(values[k]) - constant);
}
}
That is actually better (iff alpha
is a scalar) because it only evaluates the zeta
function once. But it does not answer the question (for @Bob_Carpenter or @seantalts) of why you can declare a zeta
function, define it in an external C++ file, but not call it from another Stan function without incurring a linker error. In other words, the original Stan program fails to link, even though it should inline to the same thing
functions{
real zeta(real s);
real power_law_lpmf(int x, real alpha){
return (-alpha * log(x) - log(zeta(alpha)) );
}
/*TODO: implement rng for prior and posterior predictive checks*/
}
data{
int<lower=0> K; // number of unique values
int values[K];
int<lower=0> frequencies[K];
}
parameters{
real <lower=1> alpha;
}
model{
for (k in 1:K) target += frequencies[k] * power_law_lpmf(values[k] | alpha);
}
with errors like