MappedSparseMatrix特征中非零元素的迭代 我将一个小的稀疏矩阵传递给测试,从R到C++函数。矩阵属于类DGCMatrix,如下所示: 5 x 5 sparse Matrix of class "dgCMatrix" [1,] . . . . . [2,] 1 1 . . . [3,] . . . . . [4,] . . 1 . . [5,] . 1 . . .

MappedSparseMatrix特征中非零元素的迭代 我将一个小的稀疏矩阵传递给测试,从R到C++函数。矩阵属于类DGCMatrix,如下所示: 5 x 5 sparse Matrix of class "dgCMatrix" [1,] . . . . . [2,] 1 1 . . . [3,] . . . . . [4,] . . 1 . . [5,] . 1 . . .,c++,r,sparse-matrix,eigen,rcpp,C++,R,Sparse Matrix,Eigen,Rcpp,我正在迭代文档中提到的这个矩阵。 我的函数输出迭代器的值和行索引、列索引 C++函数定义如下: #include <RcppEigen.h> // [[Rcpp::depends(RcppEigen)]] using Eigen::MappedSparseMatrix; using Eigen::SparseMatrix; using Eigen::VectorXi; using Eigen::Map; using namespace Rcpp; using namespace s

我正在迭代文档中提到的这个矩阵。 我的函数输出迭代器的值和行索引、列索引

C++函数定义如下:

#include <RcppEigen.h>
// [[Rcpp::depends(RcppEigen)]]
using Eigen::MappedSparseMatrix;
using Eigen::SparseMatrix;
using Eigen::VectorXi;
using Eigen::Map;
using namespace Rcpp;
using namespace std;

// [[Rcpp::export]]
void createRec(RObject sparse_mat, IntegerVector sparse_vec) {

const MappedSparseMatrix<int> spmat(as<MappedSparseMatrix<int> >(sparse_mat));
long int nrow = spmat.rows();
long int ncol = spmat.cols();
NumericVector sim(nrow);

for(int k=0;k<spmat.outerSize();k++){
    for(SparseMatrix<int,Eigen::ColMajor>::InnerIterator it(spmat,k);it;++it){
        cout<<"k="<<k<<endl;
        cout<<"value="<<it.value()<<endl;
        cout<<"it.row="<<it.row()<<endl;
        cout<<"it.col="<<it.col()<<endl;
        cout<<"index="<<it.index()<<endl;
    }
}
}
一,。对k=0对应的值有何解释?这些可能是由于以错误的方式传递矩阵造成的吗


二,。k在outerSize上迭代,它等于5,为什么k=3,4不迭代呢?考虑到它是sparseMatrix,迭代器会出现这种行为。

每当您看到非常大的数字(如156148016或66211520)时,可能是您有未定义的行为UB或值未正确初始化。在这种情况下,它是后者。具体地说,基础类型是double而不是int

dgCMatrix类是一类压缩、稀疏、面向列格式的稀疏数值矩阵。在此实现中,列中的非零元素按递增的行顺序排序。dgCMatrix是矩阵包中稀疏数值矩阵的标准类

因此,当您试图创建到底层RObject的内存位置的映射时,需要另外一个步骤以请求的不同类型重新创建对象。在添加const项之后,我敢打赌这些条目与预期的一样,因为编译器可能会在内存中保留中间对象

因此,变化如下:

MappedSparseMatrix<int> spmat(as<MappedSparseMatrix<int> >(sparse_mat));
前往:

for(MappedSparseMatrix<double>::InnerIterator it(spmat,k);it;++it){
避免使用名称空间std

在名称空间中添加有时会产生意想不到的后果,特别是像std这样大的后果

根据上面的要点并稍微简化您的示例,我们有以下简单的工作示例:

#include <RcppEigen.h>
// [[Rcpp::depends(RcppEigen)]]
using Eigen::MappedSparseMatrix;
using Eigen::SparseMatrix;
using Eigen::VectorXi;
using Eigen::Map;

// [[Rcpp::export]]
void createRec(Rcpp::RObject sparse_mat) {

  MappedSparseMatrix<double> spmat(Rcpp::as<MappedSparseMatrix<double> >(sparse_mat));

  long int nrow = spmat.rows();
  Rcpp::NumericVector sim(nrow);

  for(int k = 0; k < spmat.outerSize(); ++k) {
    Rcpp::Rcout << "Overall k = " << k << std::endl << std::endl;
    for(MappedSparseMatrix<double>::InnerIterator it(spmat,k); it; ++it) {
      Rcpp::Rcout << "Inner k = " << k << std::endl
                  << "value = " << it.value() << std::endl
                  << "it.row = " << it.row() << std::endl
                  << "it.col = " << it.col() << std::endl
                  << "index = " << it.index() << std::endl;
    }


  }
}

/***R

# Setup values
id_row = c(2, 2, 4, 5)
id_col = c(1, 2, 3, 2)
vals   = rep(1,4)

# Make the matrix
x = sparseMatrix(id_row, id_col, x = vals, dims = c(5, 5))

# Test the function
createRec(x)
*/

有关Eigen和Rcpp中稀疏矩阵的更多详细信息,您可能希望阅读Soren Hojsgaard和Doug Bates的文章。

每当您看到非常大的数字,如156148016或66211520,可能是您有未定义的行为UB或值未正确初始化。在这种情况下,它是后者。具体地说,基础类型是double而不是int

dgCMatrix类是一类压缩、稀疏、面向列格式的稀疏数值矩阵。在此实现中,列中的非零元素按递增的行顺序排序。dgCMatrix是矩阵包中稀疏数值矩阵的标准类

因此,当您试图创建到底层RObject的内存位置的映射时,需要另外一个步骤以请求的不同类型重新创建对象。在添加const项之后,我敢打赌这些条目与预期的一样,因为编译器可能会在内存中保留中间对象

因此,变化如下:

MappedSparseMatrix<int> spmat(as<MappedSparseMatrix<int> >(sparse_mat));
前往:

for(MappedSparseMatrix<double>::InnerIterator it(spmat,k);it;++it){
避免使用名称空间std

在名称空间中添加有时会产生意想不到的后果,特别是像std这样大的后果

根据上面的要点并稍微简化您的示例,我们有以下简单的工作示例:

#include <RcppEigen.h>
// [[Rcpp::depends(RcppEigen)]]
using Eigen::MappedSparseMatrix;
using Eigen::SparseMatrix;
using Eigen::VectorXi;
using Eigen::Map;

// [[Rcpp::export]]
void createRec(Rcpp::RObject sparse_mat) {

  MappedSparseMatrix<double> spmat(Rcpp::as<MappedSparseMatrix<double> >(sparse_mat));

  long int nrow = spmat.rows();
  Rcpp::NumericVector sim(nrow);

  for(int k = 0; k < spmat.outerSize(); ++k) {
    Rcpp::Rcout << "Overall k = " << k << std::endl << std::endl;
    for(MappedSparseMatrix<double>::InnerIterator it(spmat,k); it; ++it) {
      Rcpp::Rcout << "Inner k = " << k << std::endl
                  << "value = " << it.value() << std::endl
                  << "it.row = " << it.row() << std::endl
                  << "it.col = " << it.col() << std::endl
                  << "index = " << it.index() << std::endl;
    }


  }
}

/***R

# Setup values
id_row = c(2, 2, 4, 5)
id_col = c(1, 2, 3, 2)
vals   = rep(1,4)

# Make the matrix
x = sparseMatrix(id_row, id_col, x = vals, dims = c(5, 5))

# Test the function
createRec(x)
*/

有关Eigen和Rcpp中稀疏矩阵的更多详细信息,请阅读Soren Hojsgaard和Doug Bates的声明。

如果我将spmat的声明更改为:const SparseMatrix spmatassparse_mat;该问题在k=0时得到解决。但是我仍然不知道它的原因。如果我将spmat的声明更改为:const SparseMatrix spmatassparse_mat;该问题在k=0时得到解决。但是我还是不知道原因。谢谢你解释得这么详细。谢谢你解释得这么详细。
#include <RcppEigen.h>
// [[Rcpp::depends(RcppEigen)]]
using Eigen::MappedSparseMatrix;
using Eigen::SparseMatrix;
using Eigen::VectorXi;
using Eigen::Map;

// [[Rcpp::export]]
void createRec(Rcpp::RObject sparse_mat) {

  MappedSparseMatrix<double> spmat(Rcpp::as<MappedSparseMatrix<double> >(sparse_mat));

  long int nrow = spmat.rows();
  Rcpp::NumericVector sim(nrow);

  for(int k = 0; k < spmat.outerSize(); ++k) {
    Rcpp::Rcout << "Overall k = " << k << std::endl << std::endl;
    for(MappedSparseMatrix<double>::InnerIterator it(spmat,k); it; ++it) {
      Rcpp::Rcout << "Inner k = " << k << std::endl
                  << "value = " << it.value() << std::endl
                  << "it.row = " << it.row() << std::endl
                  << "it.col = " << it.col() << std::endl
                  << "index = " << it.index() << std::endl;
    }


  }
}

/***R

# Setup values
id_row = c(2, 2, 4, 5)
id_col = c(1, 2, 3, 2)
vals   = rep(1,4)

# Make the matrix
x = sparseMatrix(id_row, id_col, x = vals, dims = c(5, 5))

# Test the function
createRec(x)
*/
Overall k = 0

Inner k = 0
value = 1
it.row = 1
it.col = 0
index = 1
Overall k = 1

Inner k = 1
value = 1
it.row = 1
it.col = 1
index = 1
Inner k = 1
value = 1
it.row = 4
it.col = 1
index = 4
Overall k = 2

Inner k = 2
value = 1
it.row = 3
it.col = 2
index = 3
Overall k = 3

Overall k = 4