Transform a boost::array into NumericVector in Rcpp

久未见 提交于 2019-12-20 04:13:03

问题


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 transform a state_type variable to a Rcpp::NumericVector variable, and another function that do the inverse. How can do that? I need to do that in order to use R function into C++.


回答1:


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);



回答2:


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


来源:https://stackoverflow.com/questions/50018887/transform-a-boostarray-into-numericvector-in-rcpp

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!