使用dnorm与RcppArmadillo

时间:2016-10-13 21:26:16

标签: c++ r rcpp

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;
}

请参阅this answer以查看我从哪里获得该功能。这会引发错误:

no matching function for call to 'dnorm4'

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

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

通过将上面的dnorm替换为R::dnorm4来修复

1 个答案:

答案 0 :(得分:6)

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

  1. 注意命名空间。如果有疑问,不要走向全球。
  2. 检查标题以了解实际定义。您错过了标量版本R::dnorm()中的第四个参数。
  3. 这是一个修复版本,包含了您可能感兴趣的第二个变体:

    #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>