2012-09-24 6 views
6

Sto tentando di mappare un array 1D sull'array 3D utilizzando l'elenco di dimensioni fornito.Costruzione di array 3D in Rcpp

Qui sono i miei componenti:

SEXP data; // my 1D array 
// I can initialise new 3D vector in the following way: 
NumericVector vector(Dimension(2, 2, 2); 
// or the following: 
NumericVector vector(data.begin(), data.end()); 

Quello che non ho a capire è come posso creare un NumericVector che avrebbe entrambi i miei dati e le dimensioni desiderate.

+1

Esempio con * RcppArmadillo cubo *: http://markovjumps.blogspot.be/2011/12/r-array-to-rcpparmadillo-cube.html –

risposta

5

È fattibile, ma un po 'doloroso. Immagino che un contributo decente (e testato) per il nuovo costruttore o la funzione di supporto sarebbe apprezzato.

Nel frattempo, è possibile eseguire l'esempio di seguito. Ma fai attenzione a row-major e col-major, ecc. Un'altra opzione è RcppArmadillo che ha le matrici generalizzate del tipo 'Cube' a 3-d.

R> library(inline) 
R> fx <- cxxfunction(signature(vs="numeric", ds="integer"), plugin="Rcpp", body=' 
+ Rcpp::NumericVector v(vs);   // get the data 
+ Rcpp::Dimension d(ds);    // get the dim object 
+ Rcpp::NumericVector r(d);    // create vec. with correct dims 
+ std::copy(v.begin(), v.end(), r.begin()); // and copy 
+ return Rcpp::List::create(v, d, r); 
+ ') 
R> fx(1:8, c(2,2,2)) 
[[1]] 
[1] 1 2 3 4 5 6 7 8 

[[2]] 
[1] 2 2 2 

[[3]] 
, , 1 

    [,1] [,2] 
[1,] 1 3 
[2,] 2 4 

, , 2 

    [,1] [,2] 
[1,] 5 7 
[2,] 6 8 


R> 
+0

d'accordo con la nuova funzione di costruzione, sarebbe molto utile. Potrei esaminarlo quando capirò come funzionano le cose in Rcpp. – Datageek

+1

FWIW, l'aggiunta di un altro costruttore al già gonfio modello 'Vector' sembra una cattiva idea. È possibile ottenere lo stesso con una funzione libera o una classe Array dedicata, come quella in Rcpp11. –

+2

Grazie per aver aggiornato una risposta di due anni. FWIW Ho usato RcppArmadillo in diverse occasioni poiché Armadillo ha 'Cube' come oggetto di prima classe. Per me va bene. –

10

C'è una soluzione più breve. Puoi rimodellare i dati utilizzando .attr. I dati possono essere creati o dati come input - non importa. Vedere di seguito:

library("Rcpp") 

cppFunction(code=' 
NumericVector arrayC(NumericVector input, IntegerVector dim) { 
    input.attr("dim") = dim; 
    return input; 
} 
') 
x = 1:8 
arrayC(x, c(2,2,2)) 
## , , 1 
## 
##  [,1] [,2] 
## [1,] 1 3 
## [2,] 2 4 
## 
## , , 2 
## 
##  [,1] [,2] 
## [1,] 5 7 
## [2,] 6 8