Преобразуйте boost :: array в NumericVector в Rcpp - PullRequest
0 голосов
/ 25 апреля 2018

В моем скрипте C ++ (запускается в R с использованием Rcpp) я определил:

typedef boost::array< double ,3 > state_type;

Теперь я хочу создать функцию для преобразования переменной state_type в переменную Rcpp :: NumericVector и другуюфункция, которая делает обратное.Как это сделать?Мне нужно сделать это, чтобы использовать функцию R в C ++.

Ответы [ 2 ]

0 голосов
/ 25 апреля 2018

Если вы хотите иметь бесшовную интеграцию, вам придется расширить Rcpp::as<T>(obj) и Rcpp::wrap(obj). Как это сделать, описано в виньетке Расширение Rcpp . Однако в галерее Rcpp также есть отличная запись , которая уже охватывает очень похожий случай: преобразование в boost::numeric::ublas::vector<double>.

.

Если вы удовлетворены только использованием state_type, а не общим шаблоном, то вы можете использовать что-то вроде этого:

#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)
*/
0 голосов
/ 25 апреля 2018

Как насчет

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

Если вам приходится делать это много раз.Возможно, это не самый эффективный способ преобразования.Но теперь вы должны посмотреть, что nvec уже выделен на правильный размер.

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