2016-01-25 3 views
2

В R существует возможность иметь функцию, которая создает другую функцию, например.Функция Rcpp для построения функции

create_ax2 <- function(a) { 

    ax2 <- function(x) { 
    y <- a * x^2 
    return(y) 
    } 

    return(ax2) 
} 

Результат которого является

> fun <- create_ax2(3) 
> fun(1) 
[1] 3 
> fun(2) 
[1] 12 
> fun(2.5) 
[1] 18.75 

У меня есть такая сложная функция создания в R, которые принимают пару аргументов, устанавливает некоторые из констант, используемых в возвращаемой функции, делают некоторые промежуточные вычисления и т. д. Но результат - это функция, которая слишком медленная. Поэтому я попытался перевести код на C++, чтобы использовать его с Rcpp. Тем не менее, я не могу придумать, как построить функцию внутри функции C++ и вернуть его можно использовать в R.

Это то, что я до сих пор:

Rcpp::Function createax2Rcpp(int a) { 

    double ax2(double x) { 
    return(a * pow(x, 2)); 
    }; 

    return (ax2); 
} 

Это дает мне определение ошибки "здесь не допускается", я зациклился на том, как создать функцию.

EDIT: Вопрос RcppArmadillo pass user-defined function близок, но насколько я могу судить, он предоставляет только способ передачи функции C++ в R. Он не предоставляет способ инициализировать некоторые значения в функции C++ до того, как он передано R.

+0

Это не является проблемой Rcpp, C++ не допускают локальные объявления функций. Таким образом, вам нужно либо определить эту функцию за пределами локальной области, либо обернуть ее в классе. – m0nhawk

+1

@ m0nhawk, конечно, –

+0

@SeverinPappadeux Конечно, я могу использовать 'std :: function' и lambdas, но вы не можете определить их, как в приведенном выше коде. – m0nhawk

ответ

1

Хорошо, насколько я понимаю, вы хотите, чтобы функция возвращала функцию с закрытием, иначе «функция, определенная в замыкании» запоминает «среду, в которой она была создана».

В C++ 11 и выше, вполне возможно определить такую ​​функцию, вдоль линий

std::function<double(double)> createax2Rcpp(int a) { 
    auto ax2 = [a](double x) { return(double(a) * pow(x, 2)); }; 
    return ax2; 
} 

Что происходит, анонимный класс и объект с перегруженным operator() будет создан, он будет фиксировать замыкание и вышла из функции создателя. Возврат будет зафиксирован в виде std :: function с типом стирания и т. Д.

Но! Функция C/C++ в R требует, чтобы быть определенного типа, который узкий (как противоположный широкой, вы могли бы захватить узкие объекты в широкий один, но не наоборот).

Таким образом, я не знаю, как сделать из std :: function a R функция, похоже, что это невозможно.

Возможно, эмуляция закрытия, как показано ниже может помочь

static int __a; 

double ax2(double x) { 
    return(__a * pow(x, 2)); 
} 

Rcpp::Function createax2Rcpp(int a) { 
    __a = a; 

    return (ax2); 
} 
+0

Спасибо. Цель состояла в том, чтобы создать функцию, которая «запоминает» среду, в которой она была создана, так что мне не нужно передавать дополнительные переменные (в данном случае «a»). Поскольку это кажется невозможным, я отмечаю это как принятое и непосредственно определяю функцию как «double ax2 (double x, int a)». – Akkariz

Смежные вопросы