// -*- 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