首页 > 解决方案 > 可以在 std::pair 中使用 R 对象(NumericVector、NumericMatrix)吗?

问题描述

我是 Rcpp 的新手(也是 cpp 的新手),我一直在纠结如何正确使用 std::pair 。

我正在使用图表,图表的数据结构是: std::vector<std::vector<std::pair<int, double> > >

我需要扩展单个重量的概念。我写了几个简约的例子。所有这些都接受一个矩阵,并返回相同的矩阵(在运行所需的操作之后,它将在实际代码中进行。因此,图形数据结构必须是std::vector<std::vector<std::pair<int, ?> > >holding向量执行推回,并且使用末尾Rcpp::NumericMatrix的元素返回):holding

1.

Rcpp::cppFunction('
  NumericMatrix test_stdvector(Rcpp::NumericMatrix x) {
  
    std::vector<std::pair<int, std::vector<double> > > holding(x.nrow());
    
    for (int i=0; i < x.nrow(); i++) {
      NumericVector nv_x = x.row(i);
      std::vector<double> b =  Rcpp::as<std::vector<double> >(nv_x);
      holding.push_back(std::make_pair(i, b));
    }
  
    Rcpp::NumericMatrix y(x.nrow(), x.ncol());
    for (int i=0; i < x.nrow(); i++) {
    
      NumericVector b = wrap(holding[i].second);
      y(i, _) = b;
    }
    
    return y;
  }
') 
Rcpp::cppFunction('
  NumericMatrix test_numericvector(Rcpp::NumericMatrix x) {
  
    std::vector<std::pair<int, Rcpp::NumericVector> > holding(x.nrow());
    
    for (int i=0; i < x.nrow(); i++) {
      holding.push_back(std::make_pair(i, x(i, _)));
    }
  
    Rcpp::NumericMatrix y(x.nrow(), x.ncol());
    for (int i=0; i < x.nrow(); i++) {
    
      y(i, _) = holding[i].second;
    }
    
    return y;
  }
')

这两个函数都编译得很好,但是对于 input x = matrix(1:100, nrow=10),输出很奇怪:

               [,1]          [,2]          [,3]          [,4]          [,5]          [,6]          [,7]          [,8]          [,9]
 [1,] 1.356944e-311 2.121996e-314 1.356944e-311 1.355961e-311 1.355961e-311 1.355967e-311 1.356944e-311 1.356944e-311 2.121996e-314
 [2,] 1.356944e-311 9.881313e-324 1.356944e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.356944e-311 2.121996e-314
 [3,] 1.356944e-311 9.881313e-324 1.356944e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.356944e-311 2.121996e-314
 [4,] 1.356944e-311 9.881313e-324 1.356944e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.356944e-311 2.121996e-314
 [5,] 1.356944e-311 9.881313e-324 1.356944e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.356944e-311 2.121996e-314
 [6,] 1.356944e-311 9.881313e-324 1.356944e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.356944e-311 2.121996e-314
 [7,] 1.356944e-311 9.881313e-324 1.356944e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.356944e-311 2.262910e-314
 [8,] 1.356944e-311 9.881313e-324 1.356944e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.356944e-311 2.121996e-314
 [9,] 1.356944e-311 9.881313e-324 1.356944e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.356944e-311 2.121996e-314
[10,] 1.356944e-311 9.881313e-324 1.356944e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.355961e-311 1.356944e-311 2.121996e-314
              [,10]
 [1,] 1.356944e-311
 [2,] 1.356944e-311
 [3,] 1.356944e-311
 [4,] 1.356944e-311
 [5,] 1.356944e-311
 [6,] 1.356944e-311
 [7,] 1.356944e-311
 [8,] 1.356944e-311
 [9,] 1.356944e-311
[10,] 1.356944e-311

有人可以解释发生了什么吗?

提前致谢

标签: c++rrcpp

解决方案


我建议仔细调试和索引检查,可能使用较小的示例。

您还可以在开始检查获取数据的过程中打印矩阵,print(x);C++ 级别的简单操作就可以了。y回国前也一样。

我可能会从 3x3 示例开始,并会尝试正确处理这些示例。而且我认为我们没有std::pair.

最后,有时是小事: y(i, _) = holding[i].second;实际上,当你提取和重新分配时,你实际上是同时做几件事。有时它有助于提取到临时变量,然后分配该临时变量。


推荐阅读