在RcppArmadillo中使用dnorm

Using dnorm with RcppArmadillo

本文关键字:dnorm RcppArmadillo      更新时间:2023-10-16

R,我试图在这个文件上运行sourceCpp:

#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace arma; 
using namespace Rcpp;
// [[Rcpp::export]]
vec dnormLog(vec x, vec means, vec sds) {
    int n = x.size();
    vec res(n);
    for(int i = 0; i < n; i++) {
        res[i] = log(dnorm(x[i], means[i], sds[i]));
    }
return res;
}

看看这个答案,看看我从哪里得到这个函数。这会抛出错误:

no matching function for call to 'dnorm4'

这正是我希望通过使用循环来防止的错误,因为引用的答案提到dnorm仅相对于其第一个参数进行矢量化。我担心答案是显而易见的,但我已经尝试在dnorm之前添加R::,尝试使用NumericVector而不是vec,而不使用log()在前面。没有运气。但是,在dnorm之前添加R::会产生一个单独的错误:

too few arguments to function call, expected 4, have 3; did you mean '::dnorm4'?

这是修复R::dnorm4代替dnorm以上

这里有两个很好的教育时刻:

  1. 注意名称空间。如果有疑问,就不要全局化。
  2. 检查实际定义的头。您错过了标量版本R::dnorm()中的第四个参数。

这是一个修复后的版本,包括第二个你可能会感兴趣的变体:

#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
arma::vec dnormLog(arma::vec x, arma::vec means, arma::vec sds) {
  int n = x.size();
  arma::vec res(n);
  for(int i = 0; i < n; i++) {
    res[i] = std::log(R::dnorm(x[i], means[i], sds[i], FALSE));
  }
  return res;
}
// [[Rcpp::export]]
arma::vec dnormLog2(arma::vec x, arma::vec means, arma::vec sds) {
  int n = x.size();
  arma::vec res(n);
  for(int i = 0; i < n; i++) {
    res[i] = R::dnorm(x[i], means[i], sds[i], TRUE);
  }
  return res;
}

/*** R
dnormLog( c(0.1,0.2,0.3), rep(0.0, 3), rep(1.0, 3))
dnormLog2(c(0.1,0.2,0.3), rep(0.0, 3), rep(1.0, 3))
*/

当我们引用它时,两者都返回相同的结果,因为R API允许我们请求取对数

R> sourceCpp("/tmp/dnorm.cpp")
R> dnormLog( c(0.1,0.2,0.3), rep(0.0, 3), rep(1.0, 3))
          [,1]
[1,] -0.923939
[2,] -0.938939
[3,] -0.963939
R> dnormLog2(c(0.1,0.2,0.3), rep(0.0, 3), rep(1.0, 3))
          [,1]
[1,] -0.923939
[2,] -0.938939
[3,] -0.963939
R>