从c++程序中调用Stan例程



我在这里读到从c++程序中调用Stan例程是可能的(我解释得很简单)。

我有一些复杂的对数似然函数,我用c++编写,真的不知道如何使用Stan语言编写它们。是否有可能调用蒙特卡洛例程在斯坦使用对数似然函数我已经在c++编码?如果有,有这样的例子吗?

这似乎是一件很自然的事情,但我找不到任何例子或指针,如何做到这一点。

在进一步检查之后(您可能不想接受我之前的答案),您可以尝试这样做:在functions块中编写一个带有用户定义函数的.stan程序,该函数具有正确的签名(和解析),但基本上什么都不做。像这样 functions { real foo_log(real[] y, vector beta, matrix X, real sigma) { return not_a_number(); // replace this after parsing to C++ } } data { int<lower=1> N; int<lower=1> K; matrix[N,K] X; real y[N]; } parameters { vector[K] beta; real<lower=0> sigma; } model { y ~ foo(beta, X, sigma); // priors here } 然后,使用CmdStan编译该模型,这将生成一个.hpp文件作为中间步骤。编辑foo_log体内的。hpp文件,以调用模板化的c++函数,并#包括头文件(s),其中定义了您的东西。然后重新编译并执行二进制文件。

这实际上可能对你有用,但如果你所做的是广泛有用的,我们希望你能贡献c++的东西。

我认为你的问题与你所链接的问题有点不同。他有一个完整的Stan程序,想从c++中驱动它,而你在问你是否可以通过调用外部c++函数来计算对数似然来避免编写Stan程序。但这不会让您走得太远,因为您仍然需要以Stan可以处理的形式传递数据,向Stan声明未知参数是什么(以及它们的支持),等等。所以,我不认为你可以(或者应该)逃避学习Stan语言。

但是,向Stan语言公开c++函数是相当容易的,这实际上只需要将my_loglikelihood.hpp文件添加到${STAN_HOME}/lib/stan_math_${VERSION}/stan/math/下的正确位置,将include语句添加到该子目录中的math.hpp文件,并编辑${STAN_HOME}/src/stan/lang/function_signatures.h。此时,.stan程序看起来就像 data { // declare data like y, X, etc. } parameters { // declare parameters like theta } model { // call y ~ my_logliklihood_log(theta, X) } 但我认为你的问题的真正答案是,如果你已经写了一个c++函数来评估对数似然,那么在Stan语言中重写它不应该花费超过几分钟。Stan语言与C语言非常相似,因此更容易将. Stan文件解析为c++源文件。以下是我为回归环境中有条件高斯结果的对数似然写的Stan函数: 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) ); } } 这基本上只是我把原本可能是c语法的东西倾倒到Stan语言的函数体中,然后可以在。Stan程序的model块中调用。

所以,简而言之,我认为将c++函数重写为Stan函数可能是最简单的。但是,您的对数似然可能涉及一些当前没有相应Stan语法的外来内容。在这种情况下,您可以退回到将c++函数暴露给Stan语言,理想情况下,在Stan -dev下向GitHub上的数学和Stan存储库发出pull请求,以便其他人可以使用它(尽管这样您还必须编写单元测试,文档等)。

最新更新