2016-10-24 1 views
-1

RcppArmadillo를 사용하여 Armadillo에서 arma:sp_mat 클래스의 희소 매트릭스의 0이 아닌 요소에 액세스하고 업데이트하는 데 어려움이 있습니다.Rcpp 코드를 사용하여 arma :: sp_mat 클래스의 스파 스 매트릭스의 0이 아닌 요소에 액세스하여 수정하십시오.

[email protected][] = xx 

xx 실제 비제 함유 새로운 벡터이고, 여기서, 예를 들어, 매트릭스 R 패키지, B 한 액세스하고 수행하여 비 영 요소를 수정할 수 있으며, 클래스 dgCMatrix의 희소 행렬이면 집단. 누군가 나를 아르마딜로 코드로 같은 일을하도록 도울 수 있습니까?

답변

3

불행히도 sp_mat에 항목 위치를 반환하는 멋진 접근자가 없습니다.

이 정보를 얻으려면 먼저 목록의 요소 수를 계산하고 umat 위치를 만든 다음 새로 sp_matusing a batch constructor as recommended by the API docs을 구성하십시오.

접근 코드

#include <RcppArmadillo.h> 
using namespace Rcpp; 

// [[Rcpp::depends(RcppArmadillo)]] 


// Obtains a list of coordinates from the sparse matrix by using iterators 
// First calculates total number of points and, then, obtains list. 
// [[Rcpp::export]] 
arma::umat get_locations(arma::sp_mat& B) 
{ 

    // Make const iterator 
    arma::sp_mat::const_iterator start = B.begin(); 
    arma::sp_mat::const_iterator end = B.end(); 

    // Calculate number of points 
    int n = std::distance(start, end); 

    // Kill process if no values are found (very sparse matrix) 
    if (n <= 0) { Rcpp::stop("No values found!"); } 

    // Build a location storage matrix 
    arma::umat locs(2, n); 

    // Create a vector to store each row information in. (Row, Col) 
    arma::uvec temp(2); 

    // Start collecting locations 
    arma::sp_mat::const_iterator it = start; 
    for(int i = 0; i < n; ++i) 
    { 
     temp(0) = it.row(); 
     temp(1) = it.col(); 
     locs.col(i) = temp; 
     ++it; // increment 
    } 

    return locs; 
} 

// Updates the sparse matrix by constructing a new one 
// [[Rcpp::export]] 
arma::sp_mat update_sp_matrix(arma::sp_mat& B, arma::vec values) 
{ 

    // Get all the locatoins 
    arma::umat locs = get_locations(B); 

    // Make sure we have the correct number 
    if (locs.n_rows != values.n_elem) { 
     Rcpp::stop("Length mismatch between locations and supplied values!"); 
    } 

    // The documentation recommends using batch constructor to rebuild matrix 
    B = arma::sp_mat(locs, values, B.n_rows, B.n_cols); 

    return B; 
} 

테스팅

2 sp_mat 구조를 반영하도록 변경된 get_location() 코드

// Generates a sparse matrix interally to test with 
// Dimensions are 10 x 10 with only 2 points filled in. 
arma::sp_mat make_test_sp() 
{ 

    // creates a matrix C++98 style 
    arma::umat locs; 
    locs << 4 << 7 << arma::endr 
     << 6 << 7 << arma::endr; 

    // creates a vector C++98 style 
    arma::vec vals; 
    vals << 4.5 << 8.2 << arma::endr; 

    arma::sp_mat B(locs, vals, 10, 10); 

    return B; 
} 

// Main runner calls the built in test generation function. 
// [[Rcpp::export]] 
arma::sp_mat test_me() 
{ 
    arma::sp_mat B = make_test_sp(); 
    arma::vec temp = arma::ones<arma::vec>(2); 
    return update_sp_matrix(B, temp); 
} 

편집

기능 설명 X N

대신 @ 에리히의 의견

+0

감사합니다 매우 무 코팅에

N × 2

감사의! 이것은 매우 유용한 코드입니다 !! 하지만 update_sp_matrix라는 함수의 반환 명령 바로 전에 약간의 오류가 수정되었습니다. 인수 locs는 다음과 같이 대체되어야합니다. – EricH

+0

B = arma :: sp_mat (trans (locs), values, B.n_rows, B.n_cols); – EricH

+0

@EricH, 위의 편집을 참조하십시오. 문제가 해결되어야합니다. 자유롭게 upvote & 답변을 수락하십시오. – coatless

관련 문제