// [[Rcpp::depends(BH)]] // [[Rcpp::depends(RcppEigen)]] // [[Rcpp::depends(StanHeaders)]] // [[Rcpp::plugins(cpp14)]] /* based on http://gallery.rcpp.org/articles/custom-templated-wrap-and-as-for-seamingless-interfaces/ */ // -------------- Stage 1: Forward Declarations with `RcppCommon.h` #include #include // Provide Forward Declarations namespace Rcpp { namespace traits { // Setup non-intrusive extension via template specializations // Support for wrap (from Stan types to R / Rcpp types) template SEXP wrap(const stan::math::var& obj); template SEXP wrap(const stan::math::vector_v& obj); template SEXP wrap(const stan::math::matrix_v& obj); // Support for as (from R types to Stan types) template <> class Exporter< stan::math::var >; // template <> class Exporter< stan::math::vector_v >; // template <> class Exporter< stan::math::matrix_v >; } } // -------------- Stage 2: Including Rcpp.h // ------ Place AFTER the Forward Declaration!!!! #include #include // ------ Place Implementations of Forward Declarations AFTER ! // -------------- Stage 3: Implementation the Declarations // Define template specializations for as<> and wrap namespace Rcpp { namespace traits { // Defined wrap cases (from Stan types to R / Rcpp types) template SEXP wrap(const stan::math::var& obj) { Rcpp::ComplexVector out(1); Rcomplex o; o.r = obj.val(); o.i = obj.adj(); out(0) = o; return out; }; template SEXP wrap(const stan::math::vector_v& obj){ Rcpp::ComplexVector out(obj.rows()); for (size_t i = 0; i < obj.rows(); i++) { Rcomplex o; o.r = obj.coeffRef(i).val(); o.i = obj.coeffRef(i).adj(); out(i) = o; } return out; }; template SEXP wrap(const stan::math::matrix_v& obj){ Rcpp::ComplexMatrix out(obj.rows(), obj.cols()); for (size_t i = 0; i < obj.rows(); i++) { for (size_t j = 0; j < obj.cols(); j++) { Rcomplex o; o.r = obj.coeffRef(i, j).val(); o.i = obj.coeffRef(i, j).adj(); out(i,j) = o; } } return out; }; // Defined as cases (from R / Rcpp types to Stan types) template<> class Exporter< stan::math::var > { stan::math::var v_x; public: Exporter(SEXP x) : v_x(x) { Rcomplex o = Rcpp::as(x); double vi = o.i; v_x = vi == 0 ? stan::math::var(o.r) : stan::math::var(o.r / vi) * vi; } auto get() { return v_x; } }; /* These do not complile but maybe they are not actually necessary? template<> class Exporter< stan::math::vector_v > { stan::math::vector_v v_x; public: Exporter(SEXP x) : v_x(x) { Rcpp::ComplexVector vec = Rcpp::as(x); for (size_t i = 0; i < vec.size(); i++) { Rcomplex o = vec(i); double vi = o.i; v_x.coeffRef(i) = vi == 0 ? stan::math::var(o.r) : stan::math::var(o.r / vi) * vi; } } auto get() { return v_x; } }; template<> class Exporter< stan::math::matrix_v > { stan::math::matrix_v v_x; public: Exporter(SEXP x) : v_x(x) { Rcpp::ComplexMatrix mat = Rcpp::as(x); for (size_t i = 0; i < mat.rows(); i++) for (size_t j = 0; j < mat.cols(); j++) { Rcomplex o = mat(i, j); double vi = o.i; v_x.coeffRef(i, j) = vi == 0 ? stan::math::var(o.r) : stan::math::var(o.r / vi) * vi; } } auto get() { return v_x; } }; */ } } // -------------- Stage 4: Testing // [[Rcpp::export]] auto containment_test(Rcpp::ComplexVector x) { stan::math::vector_v v_x = Rcpp::as(x); Rcpp::Rcout << "v_x = " << v_x << std::endl; // Rcpp::ComplexVector y = Rcpp::wrap(v_x); int y = 0; return y; }