【问题标题】:Vector mean in RcppRcpp 中的向量均值
【发布时间】:2017-01-29 14:56:25
【问题描述】:

我正在尝试将 r 函数转换为 Rcpp 以尝试加快速度,因为它涉及 for 循环。在此过程中,我需要计算向量条目的平均值,在 R 中它就像 mean(x) 一样简单,但它似乎在 Rcpp 中不起作用,每次都给我 0 0 作为结果。

我的代码如下所示:

cppFunction(
  "NumericVector fun(int n, double lambda, ...) {
   ...
   NumericVector y = rpois(n, lambda);
   NumericVector w = dpois(y, lambda);
   NumericVector x = w*y;
   double z = mean(x);
   return z;
}")

编辑:所以我认为我的错误是由于上面提到的,而返回一个双倍 z 只是我试图隔离问题。但是以下代码仍然不起作用:

cppFunction(
   "NumericVector zstat(int n, double lambda, double lambda0, int m) {
   NumericVector z(m);
   for (int i=1; i<m; ++i){
   NumericVector y = rpois(n, lambda0);
   NumericVector w = dpois(y, lambda)/dpois(y,lambda0);
   double x = mean(w*y);
   z[i] = (x-2)/(sqrt(2/n));
   }
   return z;
}")

【问题讨论】:

    标签: r rcpp


    【解决方案1】:

    您的函数的返回类型是NumericVector,但Rcpp::mean 返回一个可转换为double 的标量值。解决此问题将更正问题:

    library(Rcpp)
    
    cppFunction(
      "double fun(int n, double lambda) {
       NumericVector y = rpois(n, lambda);
       NumericVector w = dpois(y, lambda);
       NumericVector x = w*y;
       double z = mean(x);
       return z;
    }")
    
    set.seed(123)
    fun(50, 1.5)
    # [1] 0.2992908
    

    您的代码中发生的事情是因为NumericVector 被指定为返回类型this constructor is called

    template <typename T>
    Vector(T size, 
        typename Rcpp::traits::enable_if<traits::is_arithmetic<T>::value, void>::type* = 0) {
        Storage::set__( Rf_allocVector( RTYPE, size) ) ;
        init() ;
    }
    

    double 转换为整数类型并创建一个长度等于double 截断值的NumericVector。为了演示,

    #include <Rcpp.h>
    using namespace Rcpp;
    
    // [[Rcpp::export]]
    NumericVector from_double(double x) {
        return x;
    }
    
    /*** R
    
    sapply(0.5:4.5, from_double)
    # [[1]]
    # numeric(0)
    #
    # [[2]]
    # [1] 0
    #
    # [[3]]
    # [1] 0 0
    #
    # [[4]]
    # [1] 0 0 0
    #
    # [[5]]
    # [1] 0 0 0 0
    
    */
    

    编辑:关于您的 second 问题,您除以sqrt(2 / n),其中2n 都是整数,在大多数情况下最终会导致除以零-因此结果向量中的所有Inf 值。您可以使用2.0 而不是2 来解决此问题:

    #include <Rcpp.h>
    using namespace Rcpp;
    
    // [[Rcpp::export]]
    NumericVector zstat(int n, double lambda, double lambda0, int m) {
        NumericVector z(m);
        for (int i=1; i<m; ++i){
            NumericVector y = rpois(n, lambda0);
            NumericVector w = dpois(y, lambda)/dpois(y,lambda0);
            double x = mean(w * y);
            // z[i] = (x - 2) / sqrt(2 / n);
            //                       ^^^^^
            z[i] = (x - 2) / sqrt(2.0 / n);
            //                    ^^^^^^^
       }
       return z;
    }
    
    /*** R
    
    set.seed(123)
    zstat(25, 2, 3, 10)
    # [1]  0.0000000 -0.4427721  0.3199805  0.1016661  0.4078687  0.4054078
    # [7] -0.1591861  0.9717596  0.6325110  0.1269779
    
    */
    

    C++ 不是 R——您需要更加小心变量的类型。

    【讨论】:

    • 谢谢。但是我发现我的代码有错误的问题,你能看一下完整的吗?
    • 你是什么意思“不起作用”?你需要展示你是如何调用这个函数的,并说明想要的结果是什么。
    • 如果我使用 zstat(25,2,3,100) 调用它,我会得到 0 Inf -Inf -Inf -Inf Inf Inf -Inf ... 结果,这不是有意的。期望的结果应该是第一个代码(在它被修复之后)给出的但 m 次,存储在向量 z 中。
    • 谢谢。我现在看到了
    • 很好和耐心的回答,@RenéSchou,既然您接受了它,您不妨点赞(点击向上箭头)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-24
    • 2017-03-13
    • 1970-01-01
    • 2016-03-20
    相关资源
    最近更新 更多