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