2017-07-03 59 views
1

當我嘗試從犰狳立方體(使用管或切片)獲取矢量/雙精度時,出現編譯錯誤。如何從立方體到(行)vec?我找不到優雅的演員/變形犰狳功能。犰狳:將立方體子視圖(管)轉換爲矢量

#include <RcppArmadillo.h> 
//#include <Rcpp.h> 
using namespace Rcpp; 

// [[Rcpp::export]] 
void testarma() { 
    arma::mat B; 

    B << 0.555950 << 0.274690 << 0.540605 << 0.798938 << arma::endr 
    << 0.108929 << 0.83<< 0.891726 << 0.895283 << arma::endr 
    << 0.948014 << 0.973234 << 0.216504 << 0.883152 << arma::endr 
    << 0.023787 << 0.675382 << 0.231751 << 0.450332 << arma::endr; 

    B.print("B:"); 

    // cubes ("3D matrices") 
    arma::cube Q(B.n_rows, B.n_cols, 4); 

    Q.slice(0) = B; 
    Q.slice(1) = 2.0 * B; 
    Q.slice(2) = 3.0 * B; 
    Q.slice(3) = 4.0 * B; 

    Q.print("Q:"); 

    Rcpp::Rcout << "Q.tube(0, 1): " << std::endl << Q.tube(0, 1) << std::endl; 

    arma::rowvec whatIwant = arma::rowvec(4).fill(0.0); 

    for (int i = 0; i < 4; i++) { 
    // This gives an error. cannot convert 'arma::subview_col<double>' to 'double' in assignment 
    //whatIwant[i] = Q.slice(i).row(0).col(1); 
    Rcpp::Rcout << "At slice i=" << i << " value=" << Q.slice(i).row(0).col(1) << std::endl; 
    } 

    // But I don't want to write for loop. I am sure there exists 
    // an "armadillo" way (function) that does exactly this 
    // How to convert output of tube to rowvec? 
} 
+0

請示例代碼可重複.... – coatless

+0

@coatless:很想,但它必須數百行代碼。問題是如何獲得arma :: rowvec作爲i,j元素(在我的情況下(0,1))來自armadillo cube的所有片的每個矩陣。 – Samo

+0

你可以在這種情況下創建一個玩具的例子嗎? – coatless

回答

3

有三種方式我認爲做到這一點:

  1. 使用循環與as_scalar()到最後的子集轉換爲double
  2. 子集向立方體,然後使用共享內存指針
  3. 直子集到rowvec

最後一個選項是最有可能你想要的東西,因爲它可以在線完成。

在你的情況下,操作將是:

arma::rowvec A = Q(arma::span(0), arma::span(1), arma::span::all); 

這是從文檔的子集subcube截面中截取。


上述每種情況的實現如下所示。

#include <RcppArmadillo.h> 

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

// [[Rcpp::export]] 
void cube_subset_to_rowvec() { 
    // Sample data 
    arma::mat B; 

    B << 0.555950 << 0.274690 << 0.540605 << 0.798938 << arma::endr 
     << 0.108929 << 0.83<< 0.891726 << 0.895283 << arma::endr 
     << 0.948014 << 0.973234 << 0.216504 << 0.883152 << arma::endr 
     << 0.023787 << 0.675382 << 0.231751 << 0.450332 << arma::endr; 

    // cubes ("3D matrices") 
    arma::cube Q(B.n_rows, B.n_cols, 4); 

    Q.slice(0) = B; 
    Q.slice(1) = 2.0 * B; 
    Q.slice(2) = 3.0 * B; 
    Q.slice(3) = 4.0 * B; 

    // Objective 
    Rcpp::Rcout << "Q.tube(0, 1): " << std::endl << Q.tube(0, 1) << std::endl; 

    // Individually loading elements 
    arma::rowvec individual_elements(4); 
    for (int i = 0; i < 4; i++) { 
     individual_elements[i] = arma::as_scalar(Q.slice(i).row(0).col(1)); 
     Rcpp::Rcout << "At slice i=" << i << " value=" << individual_elements[i] << std::endl; 
    } 

    // Subset to cube then use a shared memory pointer 
    arma::cube mem_ex = Q.tube(0,1); 
    arma::rowvec cub_subset = arma::rowvec(mem_ex.memptr(), mem_ex.n_elem, 1, false); 
    Rcpp::Rcout << cub_subset << std::endl; 

    // Direct subset to a rowvec 
    arma::rowvec direct_subset = Q(arma::span(0), arma::span(1), arma::span::all); 
    Rcpp::Rcout << direct_subset << std::endl; 

} 

運行:

cube_subset_to_rowvec() 

輸出:

Q.tube(0, 1): 
[cube slice 0] 
    0.2747 

[cube slice 1] 
    0.5494 

[cube slice 2] 
    0.8241 

[cube slice 3] 
    1.0988 


At slice i=0 value=0.27469 
At slice i=1 value=0.54938 
At slice i=2 value=0.82407 
At slice i=3 value=1.09876 
    0.2747 0.5494 0.8241 1.0988 

    0.2747 0.5494 0.8241 1.0988 
+0

太糟糕了,我們無法在這裏爲三個答案提供三次贊助:) –