In my C++ script (run in R using Rcpp), I defined :
typedef boost::array< double ,3 > state_type;
Now, I want to create a function to tra
How about
Rcpp::NumericVector boost_array_to_nvec(state_type const& s) {
Rcpp::NumericVector nvec(s.size());
for (size_t i = 0; i < s.size(); ++i) {
nvec[i] = s[i];
}
return nvec;
}
state_type nvec_to_boost_array(Rcpp::NumericVector const& nvec) {
state_type s;
for (size_t i = 0; i < s.size(); ++i) {
s[i] = nvec[i];
}
return s;
}
...
state_type s {0,0,0};
Rcpp::NumericVector nvec = boost_array_to_nvec(s);
s = nvec_to_boost_array(nvec);
If you have to do this a lot of times. This might not be the most efficient way of doing the transformation. But now you have to look that nvec is already allocated to the correct size.
void boost_array_to_nvec(state_type const& s, Rcpp::NumericVector& nvec) {
for (size_t i = 0; i < s.size(); ++i) {
nvec[i] = s[i];
}
}
void nvec_to_boost_array (Rcpp::NumericVector const& nvec, state_type& s) {
for (size_t i = 0; i < s.size(); ++i) {
s[i] = nvec[i];
}
}
...
state_type s {0,0,0};
Rcpp::NumericVector nv(3);
boost_array_to_nvec(s, nv);
nvec_to_boost_array(nv, s);
If you want to have seamless integration you will have to extend Rcpp::as<T>(obj)
and Rcpp::wrap(obj)
. How to do this is covered in the vignette Extending Rcpp. However, there is also an excellent entry in the Rcpp gallery that already covers a very similar case: Converting to and from boost::numeric::ublas::vector<double>
.
If you are content with only using state_type
and not the general template, then you can use something like this:
#include <RcppCommon.h>
// [[Rcpp::depends(BH)]]
#include <boost/array.hpp>
typedef boost::array< double ,3 > state_type;
namespace Rcpp {
// non-intrusive extension via template specialisation
template <> state_type as(SEXP s);
// non-intrusive extension via template specialisation
template <> SEXP wrap(const state_type &s);
}
#include <Rcpp.h>
// define template specialisations for as and wrap
namespace Rcpp {
template <> state_type as(SEXP stsexp) {
Rcpp::NumericVector st(stsexp);
state_type result;
if (st.size() != result.size()) Rcpp::stop("Incompatible length!");
std::copy(st.begin(), st.end(), result.begin());
return result;
}
template <> SEXP wrap(const state_type &st) {
Rcpp::NumericVector result(st.size());
std::copy(st.begin(), st.end(), result.begin());
return Rcpp::wrap(result);
}
}
// make use of the new possibilities
// [[Rcpp::export]]
state_type alterStateType(state_type &st) {
for (size_t i = 0; i < st.size(); ++i) {
st[i] = i * st[i];
}
return st;
}
/*** R
alterStateType(1:3)
*/