// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- /* :tabSize=4:indentSize=4:noTabs=false:folding=explicit:collapseFolds=1: */ // // RcppArmadilloAs.h: Rcpp/Armadillo glue, support for as // // Copyright (C) 2013 - 2015 Dirk Eddelbuettel and Romain Francois // // 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__RcppArmadilloAs__h #define RcppArmadillo__RcppArmadilloAs__h namespace Rcpp{ namespace traits { template class Exporter< arma::field > { public: Exporter(SEXP x) : data(x){} inline arma::field get() { size_t n = data.size() ; arma::field out( n ) ; for(size_t i=0; i(data[i]) ; } return out ; } private: List data ; }; template class Exporter< arma::Col > : public IndexingExporter< arma::Col, T > { public: Exporter(SEXP x) : IndexingExporter< arma::Col, T >(x){} }; template class Exporter< arma::Row > : public IndexingExporter< arma::Row, T > { public: Exporter(SEXP x) : IndexingExporter< arma::Row, T >(x){} }; template class Exporter< arma::Mat > : public MatrixExporter< arma::Mat, T > { public: Exporter(SEXP x) : MatrixExporter< arma::Mat, T >(x){} }; template class Exporter< const arma::Mat& > { public: typedef typename Rcpp::Matrix< Rcpp::traits::r_sexptype_traits::rtype > MATRIX ; Exporter(SEXP x) : mat(x) {} inline arma::Mat* get(){ return new arma::Mat( mat.begin(), mat.nrow(), mat.ncol(), false ) ; } private: MATRIX mat ; }; template class Exporter< arma::SpMat > { public: Exporter( SEXP x ) : mat(x){} arma::SpMat get(){ const int RTYPE = Rcpp::traits::r_sexptype_traits::rtype; IntegerVector dims = mat.slot("Dim"); IntegerVector i = mat.slot("i") ; IntegerVector p = mat.slot("p") ; Vector x = mat.slot("x") ; // Creating an empty SpMat arma::SpMat res((unsigned) dims[0], (unsigned) dims[1]); // Making space for the elements res.mem_resize((unsigned) x.size()); // Copying elements std::copy(i.begin(), i.end(), arma::access::rwp(res.row_indices)); std::copy(p.begin(), p.end(), arma::access::rwp(res.col_ptrs)); std::copy(x.begin(), x.end(), arma::access::rwp(res.values)); // Setting the sentinel arma::access::rw(res.col_ptrs[(unsigned) dims[1] + 1]) = std::numeric_limits::max(); return res; } private: S4 mat ; } ; // 30 November 2015 // default Exporter-Cube specialization: // handles cube, icube, and cx_cube // fails on fcube, ucube, and cx_fcube template class Exporter< arma::Cube > { public: typedef arma::Cube cube_t; enum { RTYPE = Rcpp::traits::r_sexptype_traits::rtype }; typedef typename Rcpp::traits::storage_type::type value_t; Exporter(SEXP x) : vec(x) {} cube_t get() { Rcpp::Vector dims = vec.attr("dim"); if (dims.size() != 3) { std::string msg = "Error converting object to arma::Cube:\n" "Input array must have exactly 3 dimensions.\n"; Rcpp::stop(msg); } cube_t result( reinterpret_cast(vec.begin()), dims[0], dims[1], dims[2], false); return result; } private: Rcpp::Vector vec; }; // specializations for 3 cube typedefs that fail above // first use viable conversion SEXP -> Cube // then use conv_to::from(other_t other) template <> class Exporter { public: typedef arma::fcube cube_t; Exporter(SEXP x) : tmp(Exporter(x).get()) {} cube_t get() { cube_t result = arma::conv_to::from(tmp); return result; } private: typedef arma::cube other_t; other_t tmp; }; template <> class Exporter { public: typedef arma::ucube cube_t; Exporter(SEXP x) : tmp(Exporter(x).get()) {} cube_t get() { cube_t result = arma::conv_to::from(tmp); return result; } private: typedef arma::icube other_t; other_t tmp; }; template <> class Exporter { public: typedef arma::cx_fcube cube_t; Exporter(SEXP x) : tmp(Exporter(x).get()) {} cube_t get() { cube_t result = arma::conv_to::from(tmp); return result; } private: typedef arma::cx_cube other_t; other_t tmp; }; } // end traits /* Begin Armadillo vector as support classes */ template ::type> class ArmaMat_InputParameter; template class ArmaMat_InputParameter { public: ArmaMat_InputParameter(SEXP x_) : m(x_), mat(reinterpret_cast(m.begin()), m.nrow(), m.ncol(), false) {} inline operator REF(){ return mat ; } private: Rcpp::Matrix< Rcpp::traits::r_sexptype_traits::rtype > m ; MAT mat ; } ; template class ArmaMat_InputParameter { public: ArmaMat_InputParameter( SEXP x_ ): m(x_), mat( as(m) ) {} inline operator REF(){ return mat ; } private: Rcpp::Matrix< Rcpp::traits::r_sexptype_traits::rtype > m ; MAT mat ; } ; /* End Armadillo vector as support classes */ /* Begin Armadillo vector as support classes */ template ::type> class ArmaVec_InputParameter; template class ArmaVec_InputParameter { public: ArmaVec_InputParameter( SEXP x_ ) : v(x_), vec( reinterpret_cast( v.begin() ), v.size(), false ){} inline operator REF(){ return vec ; } private: Rcpp::Vector< Rcpp::traits::r_sexptype_traits::rtype > v ; VEC vec ; } ; template class ArmaVec_InputParameter { public: ArmaVec_InputParameter( SEXP x_ ): v(x_), vec( as(v) ) {} inline operator REF(){ return vec ; } private: Rcpp::Vector< Rcpp::traits::r_sexptype_traits::rtype > v ; VEC vec ; } ; /* End Armadillo vector as support classes */ #define MAKE_INPUT_PARAMETER(INPUT_TYPE,TYPE,REF) \ template \ class INPUT_TYPE : public ArmaVec_InputParameter{ \ public: \ INPUT_TYPE( SEXP x) : ArmaVec_InputParameter(x){} \ } ; MAKE_INPUT_PARAMETER(ConstReferenceInputParameter, arma::Col, const arma::Col& ) MAKE_INPUT_PARAMETER(ReferenceInputParameter , arma::Col, arma::Col& ) MAKE_INPUT_PARAMETER(ConstInputParameter , arma::Col, const arma::Col ) MAKE_INPUT_PARAMETER(ConstReferenceInputParameter, arma::Row, const arma::Row& ) MAKE_INPUT_PARAMETER(ReferenceInputParameter , arma::Row, arma::Row& ) MAKE_INPUT_PARAMETER(ConstInputParameter , arma::Row, const arma::Row ) #undef MAKE_INPUT_PARAMETER #define MAKE_INPUT_PARAMETER(INPUT_TYPE,TYPE,REF) \ template \ class INPUT_TYPE : public ArmaMat_InputParameter{ \ public: \ INPUT_TYPE( SEXP x) : ArmaMat_InputParameter(x){} \ } ; MAKE_INPUT_PARAMETER(ConstReferenceInputParameter, arma::Mat, const arma::Mat& ) MAKE_INPUT_PARAMETER(ReferenceInputParameter , arma::Mat, arma::Mat& ) MAKE_INPUT_PARAMETER(ConstInputParameter , arma::Mat, const arma::Mat ) #undef MAKE_INPUT_PARAMETER } #endif