2017-07-03 6 views
1

アルマジロキューブ(チューブまたはスライスを使用)からベクトル/ダブルを取得しようとすると、コンパイルエラーが発生します。どのようにキューブから(行)vecに取得するには?私はエレガントなキャスト/変換アルマジロ機能を見つけることができません。Armadillo:キューブのサブビュー(チ​​ューブ)をベクトルに変換する

#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:大好きだけど、それは何百行ものコードを持っているでしょう。問題は、アルマジロキューブのすべてのスライスで、各行列のi、j要素(私の場合は(0、1))としてarma :: rowvecを取得する方法です。 – Samo

+0

その場合、おもちゃの例を作成できますか? – coatless

答えて

3

私はそれを行うには見る3つの方法があります。

  1. doubleに、最終的なサブセットを変換するas_scalar()でループを使用するには。
  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

あまりにも悪い私たちは3つの答えをここでupvoteできません:) –

関連する問題