Передача вектора или матрицы из R в функцию C с использованием Rcpp без локальной копии? - PullRequest
4 голосов
/ 12 октября 2019

Вот иллюстрация того, что я сейчас делаю с двумя функциями.

В обоих случаях я создаю локальные копии: либо экземпляр std::vector<GLfloat>, либо std::vector<GLdouble>.

Нет ли ярлыка, не включающего копии, куда я мог бы перейтиRcpp::NumericMatrix до GLfloat * / GLdouble * более прямым способом?

#include <Rcpp.h>
#include <GLFW/glfw3.h>
using namespace Rcpp;

//' @export
// [[Rcpp::export("glLoadMatrixf")]]
void gl_load_matrixf(Rcpp::NumericMatrix m) {

  std::vector<GLfloat> float_v = Rcpp::as<std::vector<GLfloat> >(m);
  const GLfloat * _float_v = &float_v[0];

  glLoadMatrixf(_float_v);
}

//' @export
// [[Rcpp::export("glLoadMatrixd")]]
void gl_load_matrixd(Rcpp::NumericMatrix m) {

  std::vector<GLdouble> double_v = Rcpp::as<std::vector<GLdouble> >(m);
  const GLdouble * _double_v = &double_v[0];

  glLoadMatrixd(_double_v);
}

1 Ответ

3 голосов
/ 12 октября 2019

В моей системе GLfloat и GLdouble определены как:

typedef float GLfloat;
typedef double GLdouble;

И числовой тип данных R всегда равен double. Таким образом, вы можете использовать &m[0] или m.begin() напрямую, чтобы получить что-то конвертируемое в GLdouble * без необходимости копировать данные. Для GLfloat это невозможно, поскольку требуется преобразование (с потерями) для перехода от (64-битного) double, используемого R, к (32-битному) float.

Некоторый код какИллюстрация:

Sys.setenv(PKG_LIBS="-lGL -lglfw")

Rcpp::sourceCpp(code = '
#include <Rcpp.h>
#include <GLFW/glfw3.h>
using namespace Rcpp;

// [[Rcpp::export("glLoadMatrixd")]]
void gl_load_matrixd(Rcpp::NumericMatrix m) {

     const GLdouble * _double_v = &m[0];

     glLoadMatrixd(_double_v);
}
')


glLoadMatrixd(matrix(runif(10), 2, 5))

Кстати, я понятия не имею, какие размеры должна иметь такая матрица. 2х5, вероятно, неверно ...

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