Шаблонная функция RcppEigen для заполнения единичными нормалями - PullRequest
0 голосов
/ 18 октября 2018

У меня есть следующий код:

#include <RcppEigen.h>
using namespace Rcpp;
using Eigen::MatrixXd;
using Eigen::VectorXd;
using Eigen::Lower;
using Eigen::Map;

// fills passed dense objects with unit normal random variables
template <typename Derived>
void fillUnitNormal(Eigen::DenseBase<Derived>& Z){
  int m = Z.rows();
  int n = Z.cols();
  NumericVector r(m*n);
  r = rnorm(m*n, 0, 1); // using vectorization from Rcpp sugar
  Map<VectorXd> rvec(as<Map<VectorXd> >(r));
  Map<MatrixXd> rmat(rvec.data(), m, n);
  Z = rmat;
}

Это работало хорошо для меня в течение некоторого времени.Тем не менее, я понял, что если Z является объектом VectorXd, то функция потерпит неудачу.Как правильно заполнить каждый элемент объекта Eigen, унаследованного от класса Eigen :: DenseBase, нормальным (0,1) рисованием?

1 Ответ

0 голосов
/ 18 октября 2018

Одним из способов будет просто std::copy случайные значения в Z.Поскольку Eigen не поддерживает std::begin(), я решил использовать необработанный указатель, предоставленный .data().Однако это недоступно на уровне Eigen::DenseBase.Два уровня вверх по иерархии на Eigen::PlainObjectBase это работает, хотя:

// [[Rcpp::depends(RcppEigen)]]
#include <RcppEigen.h>

// fills passed dense objects with unit normal random variables
template <typename T>
void fillUnitNormal(Eigen::PlainObjectBase<T>& Z){
  int m = Z.rows();
  int n = Z.cols();
  Rcpp::NumericVector r(m*n);
  r = Rcpp::rnorm(m*n, 0, 1); // using vectorization from Rcpp sugar
  std::copy(std::begin(r), std::end(r), Z.data());
}


// [[Rcpp::export]]
Rcpp::List test(int n) {
  Eigen::MatrixXd mat(n, n);
  Eigen::VectorXd vec(n);
  fillUnitNormal(mat);
  fillUnitNormal(vec);
  // gives compile time error: fillUnitNormal(Rcpp::NumericVector::create(n));
  return Rcpp::List::create(mat, vec);
}

/*** R
test(5)
*/
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...