本文介绍了将dnorm与RcppArmadillo一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

R 中,我试图在此文件上运行 sourceCpp :

From R, I'm trying to run sourceCpp on this file:

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

请参见此答案,以了解我从何处获得了该功能.这会引发错误:

See this answer to see where I got the function from. This throws the error:

没有用于调用"dnorm4"的匹配功能

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

Which is the exact error I was hoping to prevent by using the loop, since the referenced answer mentions that dnorm is only vectorized with respect to its first argument. I fear the answer is obvious, but I've tried adding R:: before the dnorm, tried using NumericVector instead of vec, without using log() in front. No luck. However, adding R:: before dnorm does produce a separate error:

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

通过将上面的 dnorm 替换为 R :: dnorm4 来修复不是的问题.

Which is not fixed by replacing dnorm above with R::dnorm4.

推荐答案

这里有两个不错的教学时间:

There are two nice teachable moments here:

  1. 请注意名称空间.如有疑问,请不要全球化.
  2. 检查标题以获取实际定义.您错过了 scalar 版本 R :: dnorm()中的第四个参数.
  1. Pay attention to namespaces. If in doubt, don't go global.
  2. Check the headers for the actual definitions. You missed the fourth argument in the scalar version R::dnorm().

这是经过修复的版本,其中包括您可能会感兴趣的第二种变体:

Here is a repaired version, included is a second variant you may find interesting:

#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允许我们要求采用对数.

When we source this, both return the same result because the R API allows us to ask for logarithms to be taken.

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>

这篇关于将dnorm与RcppArmadillo一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-06 19:30