在Rcpp中初始化NumericMatrix类成员后的未启动输出

时间:2015-03-20 09:32:45

标签: c++ r rcpp

在使用a调整类NumericMatrix的{​​{1}}类型myclass(使用RCPP_EXPOSED_CLASS调用)时,我似乎正在影响其他成员{{ 1}},莫名其妙地与myclass::fill_values具有相同的价值。

Rcpp代码是:

b

a输出为:

#include <Rcpp.h>

using namespace Rcpp ;

class myclass{
    public:
        NumericMatrix a;
        NumericMatrix b;

        void init(const int&, const int&);
        void fill_values(const int&, const int&, const double&);
};

void myclass::init(const int& nrow, const int& ncol){

    NumericMatrix numeric_zeros(nrow,ncol);
    for (int i = 0 ; i < nrow ; ++i){
        for (int j = 0; j < ncol ; ++j){
            numeric_zeros(i,j) = 0.0;
        }
    }
    a = numeric_zeros;
    b = numeric_zeros;
}

void myclass::fill_values(const int& nrow, const int& ncol, const double& value){

    for (int i = 0 ; i < nrow ; ++i){
        for (int j = 0; j < ncol ; ++j){
            a(i,j) = value;
        }
    }
}

RCPP_EXPOSED_CLASS(myclass)

// [[Rcpp::export]]
NumericMatrix simple(const int& nrow, const int& ncol, const double& value){
    myclass mymember;
    mymember.init(nrow,ncol);
    mymember.fill_values(nrow,ncol,value);
    return(mymember.b);
}

我怀疑这个错误源于我的初始化函数R,但我还没有能够在找到错误方面取得很大进展。

我的代码有什么问题,有人可以建议初始化> simple(2,2,15.0) [,1] [,2] [1,] 15 15 [2,] 15 15 > 班级成员的最佳方法吗?

1 个答案:

答案 0 :(得分:0)

我不太清楚为什么会这样,但我可以提出一些改变:

  1. 删除init成员函数 - NumericMatrix对象默认使用0初始化,因此无需循环遍历每个元素并自行完成。即使忽略循环,您也可以通过在member initializer list中直接初始化numeric_zerosa来节省自己创建中间对象(而不仅仅是b)。这通常建议用于非整数数据类型(例如NumericMatrix)。
  2. 就您的示例而言,您可以摆脱fill_values方法并在您自己的构造函数中实现其功能(而不是使用编译器生成的方法)。
  3. 这是一个可能的实现,它考虑了以上几点:

    #include <Rcpp.h>
    
    class myclass2 {
    public:
    
      myclass2(int nrow_, int ncol_, double value_ = 0.0) 
      : a(nrow_, ncol_), b(nrow_, ncol_)
      {
        for (int i = 0; i < nrow_; i++) {
          a(i, Rcpp::_) = Rcpp::NumericVector(ncol_, value_);
        }
      }
    
      Rcpp::NumericMatrix a;
      Rcpp::NumericMatrix b;
    };
    
    RCPP_EXPOSED_CLASS(myclass2)
    
    // [[Rcpp::export("simplea2")]]
    Rcpp::NumericMatrix simplea(int nrow, int ncol, double value){
      myclass2 mymember(nrow, ncol, value);
      return(mymember.a);
    }
    
    // [[Rcpp::export("simpleb2")]]
    Rcpp::NumericMatrix simpleb( int nrow, int ncol, double value){
      myclass2 mymember(nrow, ncol, value);
      return(mymember.b);
    }
    

    myclass2源文件中,我定义了simplea2simpleb2(分别返回数据成员ab);并对包含myclass原始定义的源文件执行相同操作,即

    /* 
     * Class definition from your question...
     */
    
    // [[Rcpp::export]]
    Rcpp::NumericMatrix simplea(const int nrow, const int ncol, const double value){
      myclass mymember;
      mymember.init(nrow,ncol);
      mymember.fill_values(nrow,ncol,value);
      return(mymember.a);
    }
    
    // [[Rcpp::export]]
    Rcpp::NumericMatrix simpleb(const int nrow, const int ncol, const double value){
      myclass mymember;
      mymember.init(nrow,ncol);
      mymember.fill_values(nrow,ncol,value);
      return(mymember.b);
    }
    

    比较这两个类,

    R> simplea(2,2,15.0)
         [,1] [,2]
    [1,]   15   15
    [2,]   15   15
    R> simpleb(2,2,15.0)
         [,1] [,2]
    [1,]   15   15
    [2,]   15   15
    ##
    R> simplea2(2,2,15.0)
         [,1] [,2]
    [1,]   15   15
    [2,]   15   15
    R> simpleb2(2,2,15.0)
         [,1] [,2]
    [1,]    0    0
    [2,]    0    0
    

    您可以看到b不再受a所做的更改影响。