используйте класс C ++ с R cpp, чтобы изменить его с C или R - PullRequest
2 голосов
/ 14 февраля 2020

Я начинаю играть с r cpp, и я хотел бы создать объект, в котором я могу изменять переменные из R или r cpp. Кажется, что создание класса является каким-то хорошим решением, так как я могу изменить поля, используя '$' из R, или напрямую используя функции R cpp. Моя проблема в том, что когда я пытаюсь изменить переменную моего класса из r cpp с помощью метода класса, R просто падает ...

ниже - небольшой пример. Класс содержит несколько переменных разных типов, плюс конструктор и две функции, одну для печати значений (для проверки, если изменения выполняются полностью, когда я что-то делаю) и одну для изменения переменных класса.

library(Rcpp)
library(RcppArmadillo)

# ODEs can also be described using Rcpp
Rcpp::sourceCpp(code = '

#include <Rcpp.h>
//#include <RcppArmadillo.h>
using namespace Rcpp;

// [[Rcpp::export]]
class parameters{
public:
  NumericMatrix mat;
  double val;
  int n;
  NumericVector dB;

  parameters(double x):
    val(x) {}

  NumericVector changes(){
    dB[0] = val;
    dB[1] = 12;
    //dB[1] = mean(mat(1,_));
  } 

  void print(){
    Rcout << "val:"  << std::endl << val << std::endl;
    Rcout << "mat:"  << std::endl << mat << std::endl;
  }
};

RCPP_MODULE(ParamModule){
using namespace Rcpp;
  class_<parameters>("parameters")

  .constructor<double>("constructor")

  .method("changes", &parameters::changes)
  .method("print", &parameters::print)

  .field("val", &parameters::val)
  .field("mat", &parameters::mat)
  .field("n", &parameters::n)
  .field("dB", &parameters::dB)
  ;  
}

// [[Rcpp::export]]
NumericMatrix addVal(NumericMatrix mat, double val, int n){
  int i = 0;
  for (i=0; i<n; i++){
    mat(i, 1) = mat(i,1) + val;
  }

  return mat;
}


')

и вот код, который я использую для его проверки:

p = new(parameters,5)
str(p) # constructor initialise the field val, ok
p$mat = matrix(5, nrow = 5, ncol = 5)
p$print()  # field mat initialised, ok
p$mat = matrix(0.1, nrow = 5, ncol = 5)
p$print()  # field mat changed, ok
addVal(p$mat, 2, 5)
p$print() # sounds like p is a pointer, ok
p$changes() #...

В этой последней строке возникает проблема (сообщения об ошибке нет, поскольку R просто падает).

Когда я компилирую класс, у меня появляется следующее предупреждение:

Warning message:
No function found for Rcpp::export attribute at file215bf0ef501.cpp:8 

Кроме того, я увидел здесь , что мне может понадобиться использовать эти две строки:

ParamModule = Module("ParamModule")
parameters = ParamModule$parameters

но я получаю сообщение об ошибке при запуске последнего:

Error in Module(module, mustStart = TRUE) : 
  Failed to initialize module pointer: Error in FUN(X[[i]], ...): no such symbol _rcpp_module_boot_ParamModule in package .GlobalEnv

(ParamModule присутствует как среда в глобальной среде).

Итак, мои вопросы являются:

1) Почему не работает функция p $ changes ()

2) Нужно ли загружать paramModule? Кажется, это ничего не меняет ...

Спасибо!

Ответы [ 2 ]

3 голосов
/ 14 февраля 2020

Существует поддержка экспонирования классов C ++ с помощью модулей R cpp, которые вы нашли.

Также в пакете, менее известном, но добавленном самим Джоном Чамберсом, есть R cpp Classes, расширение для модулей R cpp, которое кажется именно тем, о чем вы просите .

Имеется в примере в комплекте полного примера , который поставляется с R cpp как полный каталог и тест . В комплект также входит документация.

0 голосов
/ 14 февраля 2020

Небольшая версия проблемного метода c решила проблему. Я в основном допустил две (глупые) ошибки:

1) Я не возвратил что-то, даже если ожидалось, что функция вернет числовой c вектор (я удивлен, что это скомпилировано)

2) Я использовал db [0] вместо db (0)

, поэтому новая отредактированная функция:

NumericVector changes(){
    dB(0) = val;
    dB(1) = 12;
    //dB[1] = mean(mat(1,_));
    return dB;
  } 

без пальто и Dirk, спасибо за ваши ответы, но это кажется, что нет необходимости использовать их в пакете (поскольку то, что я сделал, работает правильно). Я что-то пропустил?

...