在 Rcpp 中将 boost::array 转换为 NumericVector
Transform a boost::array into NumericVector in Rcpp
在我的 C++ 脚本中(运行 在 R 中使用 Rcpp),我定义了:
typedef boost::array< double ,3 > state_type;
现在,我想创建一个将 state_type 变量转换为 Rcpp::NumericVector 变量的函数,以及另一个执行相反操作的函数。怎么做到的?
我需要这样做才能在 C++ 中使用 R 函数。
怎么样
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);
如果您想要无缝 集成,您将必须扩展Rcpp::as<T>(obj)
和Rcpp::wrap(obj)
。小插图 Extending Rcpp. However, there is also an excellent entry in the Rcpp gallery 中介绍了如何执行此操作,该小插图已经涵盖了一个非常相似的案例:Converting to and from 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)
*/
在我的 C++ 脚本中(运行 在 R 中使用 Rcpp),我定义了:
typedef boost::array< double ,3 > state_type;
现在,我想创建一个将 state_type 变量转换为 Rcpp::NumericVector 变量的函数,以及另一个执行相反操作的函数。怎么做到的? 我需要这样做才能在 C++ 中使用 R 函数。
怎么样
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);
如果您想要无缝 集成,您将必须扩展Rcpp::as<T>(obj)
和Rcpp::wrap(obj)
。小插图 Extending Rcpp. However, there is also an excellent entry in the Rcpp gallery 中介绍了如何执行此操作,该小插图已经涵盖了一个非常相似的案例:Converting to and from 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)
*/