我读过这里,它可以从C++程序调用Stan例程(并且我解释得很简单)。
我有一些复杂的日志似然函数,我用C++编写了这些函数,我真的不知道如何用Stan语言对它们进行编码。是否可以使用我已经在C++中编写的日志似然函数调用Stan中的Monte例程?若然,是否有这方面的例子?
这似乎是一件很自然的事情,但我找不到任何例子或指示如何做到这一点。
发布于 2015-08-07 17:21:36
经过进一步的检查(您可能想不接受我以前的答案),您可以尝试这样做:在.stan块中编写一个用户定义函数的functions程序,该程序具有正确的签名(和解析),但基本上什么也不做。然后,像这个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文件作为中间步骤。在.hpp的主体中编辑foo_log文件,以调用模板化的C++函数,并#包含定义其内容的头文件。然后重新编译并执行二进制文件。
这实际上可能对您有用,但是如果您所做的任何操作都有广泛的用处,我们希望您能够为C++贡献一些东西。
发布于 2015-08-07 01:57:53
我觉得你的问题和你的问题有点不同。他有一个完整的Stan程序,并希望从C++驱动它,而您是在问您是否可以通过调用外部C++函数来计算日志的可能性来绕过编写Stan程序。但这不会让你走得太远,因为你仍然需要以斯坦可以处理的形式传递数据,向斯坦声明未知的参数(加上它们的支持)等等。所以,我认为你不能(或者应该)回避学习斯坦语。
但是,向Stan语言公开C++函数是相当容易的,这实际上只是将my_loglikelihood.hpp文件添加到${STAN_HOME}/lib/stan_math_${VERSION}/stan/math/下的正确位置,向该子目录中的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程序的model块中调用。
因此,简单地说,我认为将C++函数重写为Stan函数可能是最简单的。但是,您的日志可能涉及到一些异国情调,目前还没有相应的Stan语法。在这种情况下,您可以重新将这个C++函数公开给Stan语言,并向stan下的GitHub上的数学和stan存储库发出拉请求,以便其他人可以使用它(尽管这样,您还必须编写单元测试、文档等)。
https://stackoverflow.com/questions/31862831
复制相似问题