I think your question is a bit different from the one you linked to. He had a complete Stan program and wanted to drive it from C++, whereas you are asking if you could circumvent writing a Stan program by calling an external C++ function to evaluate the log-likelihood. But that would not get you very far because you still have to pass in the data in a form that Stan can handle, declare to Stan what are the unknown parameters (plus their support), etc. So, I don't think you can (or should) evade learning the Stan language.
But it is fairly easy to expose a C++ function to the Stan language, which essentially just involves adding your my_loglikelihood.hpp file in the right place under ${STAN_HOME}/lib/stan_math_${VERSION}/stan/math/
, adding an include statement to the math.hpp file in that subdirectory, and editing ${STAN_HOME}/src/stan/lang/function_signatures.h
. At that point, your .stan program could look as simple as
data {
// declare data like y, X, etc.
}
parameters {
// declare parameters like theta
}
model {
// call y ~ my_logliklihood_log(theta, X)
}
But I think the real answer to your question is that if you have already written a C++ function to evaluate the log-likelihood, then rewriting it in the Stan language shouldn't take more than a few minutes. The Stan language is very C-like so that it is easier to parse the .stan file into a C++ source file. Here is a Stan function I wrote for the log-likelihood of a conditionally Gaussian outcome in a regression context:
functions {
/**
* Increments the log-posterior with the logarithm of a multivariate normal
* likelihood with a scalar standard deviation for all errors
* Equivalent to y ~ normal(intercept + X * beta, sigma) but faster
* @param beta vector of coefficients (excluding intercept)
* @param b precomputed vector of OLS coefficients (excluding intercept)
* @param middle matrix (excluding ones) typically precomputed as crossprod(X)
* @param intercept scalar (assuming X is centered)
* @param ybar precomputed sample mean of the outcome
* @param SSR positive precomputed value of the sum of squared OLS residuals
* @param sigma positive value for the standard deviation of the errors
* @param N integer equal to the number of observations
*/
void ll_mvn_ols_lp(vector beta, vector b, matrix middle,
real intercept, real ybar,
real SSR, real sigma, int N) {
increment_log_prob( -0.5 * (quad_form_sym(middle, beta - b) +
N * square(intercept - ybar) + SSR) /
square(sigma) - # 0.91... is log(sqrt(2 * pi()))
N * (log(sigma) + 0.91893853320467267) );
}
}
which is basically just me dumping what could otherwise be C-syntax into the body of a function in the Stan language that is then callable in the model
block of a .stan program.
So, in short, I think it would probably be easiest for you to rewrite your C++ function as a Stan function. However, it is possible that your log-likelihood involves something exotic for which there is currently no corresponding Stan syntax. In that case, you could fall back to exposing that C++ function to the Stan language and ideally making pull requests to the math and stan repositories on GitHub under stan-dev so that other people could use it (although then you would also have to write unit-tests, documentation, etc.).