// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- /* :tabSize=4:indentSize=4:noTabs=false:folding=explicit:collapseFolds=1: */ // // RcppArmadilloWrap.h: Rcpp/Armadillo glue // // Copyright (C) 2010 - 2013 Dirk Eddelbuettel, Romain Francois and Douglas Bates // // This file is part of RcppArmadillo. // // RcppArmadillo is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 2 of the License, or // (at your option) any later version. // // RcppArmadillo is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with RcppArmadillo. If not, see . #ifndef RcppArmadillo__RcppArmadilloWrap__h #define RcppArmadillo__RcppArmadilloWrap__h namespace Rcpp{ namespace RcppArmadillo{ template SEXP arma_wrap( const T& object, const ::Rcpp::Dimension& dim){ ::Rcpp::RObject x = ::Rcpp::wrap( object.memptr() , object.memptr() + object.n_elem ) ; x.attr( "dim" ) = dim ; return x; } // DE 03-Aug-2013 // here is an alternate form which would not set dimension which we could do // for row and column vectors -- but the current form of return row and col // as matrix types with one col (or row, respectively) is now entrenched template SEXP arma_wrap(const T& object) { return ::Rcpp::wrap(object.memptr() , object.memptr() + object.n_elem); } template SEXP arma_subview_wrap( const arma::subview& data, int nrows, int ncols ){ const int RTYPE = Rcpp::traits::r_sexptype_traits::rtype ; Rcpp::Matrix mat( nrows, ncols ) ; for( int j=0, k=0; j SEXP wrap ( const arma::Mat& data ){ return RcppArmadillo::arma_wrap( data, Dimension( data.n_rows, data.n_cols ) ) ; } template SEXP wrap( const arma::Col& data ){ return RcppArmadillo::arma_wrap( data, Dimension( data.n_elem, 1) ) ; } template SEXP wrap( const arma::Row& data ){ return RcppArmadillo::arma_wrap(data, Dimension( 1, data.n_elem ) ) ; } template SEXP wrap( const arma::Cube& data ){ return RcppArmadillo::arma_wrap(data, Dimension( data.n_rows, data.n_cols, data.n_slices ) ) ; } template SEXP wrap( const arma::subview& data ){ return RcppArmadillo::arma_subview_wrap( data, data.n_rows, data.n_cols ) ; } template SEXP wrap ( const arma::SpMat& sm ){ const int RTYPE = Rcpp::traits::r_sexptype_traits::rtype; IntegerVector dim = IntegerVector::create( sm.n_rows, sm.n_cols ); // copy the data into R objects Vector x(sm.values, sm.values + sm.n_nonzero ) ; IntegerVector i(sm.row_indices, sm.row_indices + sm.n_nonzero); IntegerVector p(sm.col_ptrs, sm.col_ptrs + sm.n_cols+1 ) ; std::string klass ; switch( RTYPE ){ case REALSXP: klass = "dgCMatrix" ; break ; // case INTSXP : klass = "igCMatrix" ; break ; class not exported case LGLSXP : klass = "lgCMatrix" ; break ; default: throw std::invalid_argument( "RTYPE not matched in conversion to sparse matrix" ) ; } S4 s(klass); s.slot("i") = i; s.slot("p") = p; s.slot("x") = x; s.slot("Dim") = dim; return s; } namespace RcppArmadillo { /* Importer class for field */ template class FieldImporter { public: typedef T r_import_type ; FieldImporter( const arma::field& data_ ) : data(data_){} inline int size() const { return data.n_elem ; } inline T get(int i) const { return data[i] ; } inline SEXP wrap( int i) const { return ::Rcpp::wrap( data[i] ) ; } private: const arma::field& data ; } ; } // namespace RcppArmadillo template SEXP wrap( const arma::field& data){ RObject x = wrap( RcppArmadillo::FieldImporter( data ) ) ; x.attr("dim" ) = Dimension( data.n_rows, data.n_cols ) ; return x ; } /* TODO: maybe we could use the advanced constructor to avoid creating the temporary Mat */ template SEXP wrap(const arma::Glue& X ){ return wrap( arma::Mat(X) ) ; } template SEXP wrap(const arma::Op& X ){ return wrap( arma::Mat(X) ) ; } template SEXP wrap(const arma::OpCube& X ){ return wrap( arma::Cube(X) ) ; } template SEXP wrap(const arma::GlueCube& X ){ return wrap( arma::Cube(X) ) ; } template SEXP wrap(const arma::GenCube& X){ return wrap( arma::Cube( X ) ) ; } namespace RcppArmadillo{ /* we can intercept and directly build the resulting matrix using memory allocated by R */ template SEXP wrap_eglue( const arma::eGlue& X, ::Rcpp::traits::false_type ){ int n_rows = X.P1.get_n_rows() ; int n_cols = X.P1.get_n_cols() ; typedef typename ::Rcpp::Vector< ::Rcpp::traits::r_sexptype_traits< typename T1::elem_type>::rtype > VECTOR ; VECTOR res(::Rcpp::Dimension( n_rows , n_cols )) ; ::arma::Mat result( res.begin(), n_rows, n_cols, false ) ; result = X ; return res ; } template SEXP wrap_eglue( const arma::eGlue& X, ::Rcpp::traits::true_type ){ return ::Rcpp::wrap( arma::Mat(X) ) ; } template SEXP wrap_eop( const arma::eOp& X, ::Rcpp::traits::false_type ){ int n_rows = X.get_n_rows(); int n_cols = X.get_n_cols(); typedef typename ::Rcpp::Vector< ::Rcpp::traits::r_sexptype_traits< typename T1::elem_type>::rtype > VECTOR ; VECTOR res(::Rcpp::Dimension( n_rows , n_cols )) ; ::arma::Mat result( res.begin(), n_rows, n_cols, false ) ; result = X ; return res ; } template SEXP wrap_eop( const arma::eOp& X, ::Rcpp::traits::true_type ){ return ::Rcpp::wrap( arma::Mat(X) ) ; } // template // SEXP wrap_mtop( const arma::mtOp& X, ::Rcpp::traits::false_type ){ // // int n_rows = X.P.n_rows ; // // int n_cols = X.P.n_cols ; // // typedef typename ::Rcpp::Vector< ::Rcpp::traits::r_sexptype_traits< typename T1::elem_type>::rtype > VECTOR ; // // VECTOR res(::Rcpp::Dimension( n_rows , n_cols )) ; // // ::arma::Mat result( res.begin(), n_rows, n_cols, false ) ; // // result = X ; // // return res ; // return ::Rcpp::wrap( arma::Mat(X) ) ; // } // // template // SEXP wrap_mtop( const arma::mtOp& X, ::Rcpp::traits::true_type ){ // return ::Rcpp::wrap( arma::Mat(X) ) ; // } // // template // SEXP wrap_mtglue( const arma::mtGlue& X, ::Rcpp::traits::false_type ){ // // int n_rows = X.P1.n_rows ; // // int n_cols = X.P1.n_cols ; // // typedef typename ::Rcpp::Vector< ::Rcpp::traits::r_sexptype_traits< typename T1::elem_type>::rtype > VECTOR ; // // VECTOR res(::Rcpp::Dimension( n_rows , n_cols )) ; // // ::arma::Mat result( res.begin(), n_rows, n_cols, false ) ; // // result = X ; // // return res ; // return ::Rcpp::wrap( arma::Mat(X) ) ; // } // // template // SEXP wrap_mtglue( const arma::mtGlue& X , ::Rcpp::traits::true_type ){ // return ::Rcpp::wrap( arma::Mat(X) ) ; // } } // namespace RcppArmadillo template SEXP wrap(const arma::eGlue& X ){ return RcppArmadillo::wrap_eglue( X, typename traits::r_sexptype_needscast::type() ) ; } template SEXP wrap(const arma::eOp& X ){ return RcppArmadillo::wrap_eop( X, typename traits::r_sexptype_needscast::type() ) ; } template SEXP wrap(const arma::eOpCube& X ){ return wrap( arma::Cube(X) ) ; } template SEXP wrap(const arma::eGlueCube& X ){ return wrap( arma::Cube(X) ) ; } template SEXP wrap( const arma::mtOp& X ){ // return RcppArmadillo::wrap_mtop( X, typename traits::r_sexptype_needscast::type() ) ; return wrap( arma::Mat( X ) ) ; } template SEXP wrap( const arma::mtGlue& X ){ // return RcppArmadillo::wrap_mtglue( X, typename traits::r_sexptype_needscast::type() ) ; return wrap( arma::Mat( X ) ) ; } template SEXP wrap( const arma::Gen& X){ return wrap( eT(X) ) ; } } #endif