извикване на дефинирана от потребителя R функция от C++ с помощта на Rcpp

Имам R код с куп дефинирани от потребителя R функции. Опитвам се да направя кода да работи по-бързо и разбира се най-добрият вариант е да използвам Rcpp. Моят код включва функции, които се извикват взаимно. Следователно, ако напиша някои функции в C++, трябва да мога да извикам и да стартирам някои от моите R функции в моя c++ код. В прост пример разгледайте кода по-долу в R:

mySum <- function(x, y){
 return(2*x + 3*y)
}
x <<- 1
y <<- 1

Сега разгледайте C++ кода, в който се опитвам да осъществя достъп до функцията по-горе:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
int mySuminC(){
 Environment myEnv = Environment::global_env();
 Function mySum = myEnv["mySum"];
 int x = myEnv["x"];
 int y = myEnv["y"];
 return wrap(mySum(Rcpp::Named("x", x), Rcpp::Named("y", y)));
 }

Когато извличам файла в R с вградената функция sourceCpp(), получавам грешката:

 "invalid conversion from 'SEXPREC*' to int

Може ли някой да ми помогне с отстраняването на грешки в кода? Моят код ефективен ли е? Може ли да се обобщи? Има ли по-добра идея да използвам функцията mySum от това, което направих в моя код?

Благодаря ви много за помощта.


person Sam    schedule 20.01.2014    source източник
comment
@DirkEddelbuettel, с голямо уважение, не съм съгласен - връзката по-горе адресира съвсем различен проблем.   -  person Sam    schedule 20.01.2014
comment
В него се посочва, че а) е лесно да се извика функция, б) че не е по-бързо да се извика R функция от C++, отколкото от R (и не беше ясно дали сте измамили това) и в) вашият проблем с преобразуването на int е несвързан проблем за начинаещи.   -  person Dirk Eddelbuettel    schedule 20.01.2014


Отговори (1)


Вие декларирате, че функцията трябва да върне int, но използвайте wrap, което показва, че върнатият обект трябва да бъде SEXP. Освен това извикването на R функция от Rcpp (през Function) също връща SEXP.

Искате нещо като:

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
SEXP mySuminC(){
  Environment myEnv = Environment::global_env();
  Function mySum = myEnv["mySum"];
  int x = myEnv["x"];
  int y = myEnv["y"];
  return mySum(Rcpp::Named("x", x), Rcpp::Named("y", y));
}

(или оставете връщането на функцията като int и използвайте as<int> на мястото на wrap).

Въпреки това, това е вид неидиоматичен Rcpp код. Не забравяйте, че извикването на R функции от C++ все още ще бъде бавно.

person Kevin Ushey    schedule 20.01.2014
comment
да Тук има няколко предишни отговора, които правят същата гледна точка. - person Dirk Eddelbuettel; 20.01.2014
comment
@DirkEddelbuettel и Кевин, имам друг въпрос относно тази публикация. Помислете за типична C++ програма, която има куп функции, декларирани извън int main() chunk и се използват в chunk. Сега разгледайте аргумента body в cxxfunction(), за мен body е донякъде като това, което е вътре в int main() частта. Въпросът ми е къде да декларирам онези функции, които са извън main() и се използват вътре в него в cxxfunction()? - person Sam; 20.01.2014
comment
@DirkEddelbuettel, абсолютно. - person Sam; 20.01.2014
comment
как да получа върнатите стойности от функцията R? Всъщност stackoverflow.com/a/21225890/9113303 тук извикваме R функцията mySum. Така че трябва да получим върнатата стойност return(2*x + 3*y). Но получавам Rcpp::sourceCpp('Desktop/cuda_pgm_cpp/mySum.cpp') като резултат, докато изпълнявам R studio. - person 9113303; 27.06.2018