Hey folks
I'm new to bayesian modeling with Stan, and after reading the forum and relevant parts of the manual (I hope) I'm not totally sure if I'm properly implementing a transformation of a variable. I've copy-pasted my full code below.
The fundamental issue is that I have a prior on a transformed variable, but the inverse transformation cannot be written down with pen and paper (although it's probably invertible).
To give a simple illustration of the problem, imagine I have something like:
Simple Pseudocode:
data {
int<lower=0> N;
int<lower=1> K;
vector[N] y;
matrix[N,K] x;
}
parameters {
vector[K] beta;
real a0;
}
model {
f(a0) ~ uniform(log(1),log(N)); // f is an invertible transform from reals to reals, but it's inverse can't be written down
target += log(f'(a0)); // The jacobian adjustment
target += g(a0,betas,x,y); // g is some complicated expression -- the point is that I need to use a0 here
}
Is it ok to continue to use a0 in the third line of the model, or do I need to write things in terms of the inverse of f? If it's the latter, then the problem is that it's impossible for me to write down the inverse of f with pen and paper -- is there a workaround?
My code below is a little more complicated than this, but I think this captures the basic idea. In the above example, "f" would be "log_sum_pis" below.
Thank you for your help!
David
Actual Code:
model_code = """
data {
int<lower=0> N;
int<lower=1> K;
vector[N] y;
matrix[N,K] x;
real<lower=0> lambda;
vector[K] exp_term;
}
parameters {
vector[K] beta;
real a0;
}
transformed parameters {
real<lower=0> squared_error;
real<lower=0> lambda_delta;
vector[K] pis;
vector[K] pi2exp;
real log_sum_pis;
squared_error = dot_self(y - x * beta) / N;
lambda_delta = lambda * 100;
for (i in 1:K)
pis[i] = 1/(1+exp(-a0-exp_term[i]));
for (i in 1:K)
pi2exp[i] = exp(-exp_term[i])/(1+exp(-a0-exp_term[i]))/(1+exp(-a0-exp_term[i]));
log_sum_pis = log(sum(pis));
}
model {
log_sum_pis ~ uniform(log(1),log(N));
target += log(sum(pi2exp)/sum(pis)); //The Jacobian adjustment for the above line
target += -squared_error;
for (k in 1:K)
target += log_sum_exp(log(pis[k]*lambda/2) - lambda * fabs(beta[k]),log((1-pis[k])*lambda_delta/2) - lambda_delta * fabs(beta[k])); //Note that this line uses "pis" and not "log_sum_pis".
}
"""