2017-03-02 10 views
0

++ 함수 아래와 같이순회 비제 소자 매트릭스 클래스 dgCMatrix 속하는 R.에서 고유 I는 C로 (테스트) 적은 희소 행렬을 통과하고

5 x 5 sparse Matrix of class "dgCMatrix" 

[1,] . . . . . 
[2,] 1 1 . . . 
[3,] . . . . . 
[4,] . . 1 . . 
[5,] . 1 . . . 

I를 반복하고 이 행렬은 설명서 here에서 언급 한 것과 같습니다. 내 함수는 반복자와 행 인덱스, 열 인덱스의 값을 출력합니다.

함수는 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=0 
value=156148016 
it.row=66211520 
it.col=0 
index=66211520 
k=1 
value=0 
it.row=0 
it.col=1 
index=0 
k=1 
value=1 
it.row=4 
it.col=1 
index=4 
k=2 
value=1 
it.row=3 
it.col=2 
index=3 

1) 상관 설명? 이것들이 행렬을 잘못 전달했기 때문일 수 있습니까?

2.) k는 outerSize에 대해 5를 반복하며, k = 3,4에 대해 iterating하지 않는 이유는 무엇입니까? 스파 스 매트릭스 (sparseMatrix)라고 생각하면이 동작은 반복기에서 예상됩니다.

+0

spmat의 선언을 다음과 같이 변경합니다. const SparseMatrix spmat (> (sparse_mat)); 이 문제는 k = 0에 대해 해결되었습니다. 그러나 나는 아직도 그 이유를 모른다. – TUSHAr

답변

4

156148016 또는 66211520과 같이 매우 큰 숫자가 표시 될 때마다 정의되지 않은 동작 (UB)이 있거나 값을 적절히 초기화하지 않은 것입니다. 이 경우 나중에 있습니다. 구체적으로 dgCMatrix class '기본 유형은 double이 아니며 int이 아닙니다.

dgCMatrix 클래스는 압축 된 스파 스 열 기반 형식의 스파 스 수치 행렬 클래스입니다. 이 구현에서는, 열의 0 이외의 요소가 늘어나는 행 순서로 소트됩니다. dgCMatrixMatrix 패키지의 스파 스 수치 행렬에 대한 "표준"클래스입니다. 당신이 기본 RObject의 메모리 위치에 대한지도를 만들려고 할 때

따라서, 요청 된 다른 유형에 새롭게 오브젝트를 재 작성하는 데 필요한 추가 단계가있다. const 용어를 추가 한 후에는 컴파일러가 중간 개체를 메모리에 유지할 가능성이 높으므로 항목이 예상대로 제공 될 것입니다.

그래서 변화는 다음

MappedSparseMatrix<int> spmat(as<MappedSparseMatrix<int> >(sparse_mat)); 

에 :

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

이 충분해야한다.


linked example 여기 당신이 MappedSparseMatrix를 사용하는 SparseMatrix 매트릭스를 사용하지만 설정 두 번째 루프 MappedSparseMatrix::InnerIterator 적절한하지 않습니다.

따라서, 우리는이 :

for(SparseMatrix<int,Eigen::ColMajor>::InnerIterator it(spmat,k);it;++it){ 

가 간다 :

for(MappedSparseMatrix<double>::InnerIterator it(spmat,k);it;++it){ 

는 또한, SparseMatrix<int, Eigen::ColMajor>::InnerIteratorEigen::ColMajor의 사용이 that is the default initialization으로 필요하지 않습니다 있습니다. 그래서 나는이 진술을 삭제했다.


두 번째 질문에 대해서는 k을 반복하십시오.

k (k=3,4)을 반복하지만이 열에는 요소가 없습니다. 따라서 k이 출력되는 내부 루프는 이 아니며이 호출됩니다.

두 개의 k 선언 출력 문을 외부 및 내부 루프에 넣으면 쉽게 알 수 있습니다.

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

, 네임 스페이스 때로는 의도하지 않은 한 결과, 특히 하나의 큰 std로 추가 using namespace 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) 
*/ 

출력 :에 대한 자세한 내용은

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 

Eigen과 Rcpp의 드문 드문 한 행렬 들인 경우, Soren Hojsgaard와 Dou의 Rcpp Gallery: Using iterators for sparse vectors and matrices을 읽을 수 있습니다. g Bates.

+1

그런 설명을 해주셔서 감사합니다. – TUSHAr

+0

Seconded. 좋은 일, 다시 한번. –