[英]Using gsl_function using a supplied R function
我目前正在嘗試使用.cpp文件通過RcppGSL使用GSL庫中的gsl_function,並使用sourceCpp()調用它。 這個想法是用同樣來自GSL的gsl_integration_qags執行數值積分。 我的C代碼調用了一個保存在全局環境中的用戶定義的R函數(下面的代碼中為SomeRFunction)。 代碼是:
#include <RcppGSL.h>
#include <stdio.h>
#include <math.h>
#include <gsl/gsl_integration.h>
#include <gsl/gsl_vector.h>
// [[Rcpp::depends(RcppGSL)]]
// [[Rcpp::export]]
double integfn1(double ub, double lb, double abserr, double Rsq, int pA){
double result, abserror;
Rcpp::Environment global = Rcpp::Environment::global_env();
Rcpp::Function f1 = global["SomeRFunction"];
struct my_f_params { double Rsq; int pA; };
struct my_f_params params = { Rsq, pA };
gsl_function F;
F.function = & f1;
F.params = ¶ms;
double lb1 = lb;
double ub1 = ub;
gsl_integration_workspace * w = gsl_integration_workspace_alloc (1000);
gsl_integration_qags (&F, lb1, ub1, 1e-8, 1e-8, 1000, w, &result, &abserror);
printf ("result = % .18f\n", result);
printf ("estimated error = % .18f\n", abserror);
gsl_integration_workspace_free (w);
return result;
}
然后出現以下錯誤:
"cannot convert 'Rcpp::Function* {aka Rcpp::Function_Impl<Rcpp::PreserveStorage>*}' to 'double (*)(double, void*)' "
問題出在我聲明要集成的函數的行中(即“ F.function = & f1;
”)。
我查找了類似的問題,但找不到任何列出的內容...任何提示將不勝感激!
非常感謝
我創建了一個工作示例(並將其與C同步),在該示例中,您可以將任意用戶定義的R函數傳遞給GSL函數QAWF。 您也應該能夠將其推廣到其他gsl函數。
請參閱以下示例: https : //sites.google.com/site/andrassali/computing/user-supplied-functions-in-rcppgsl
如上所述,競爭的C實現要快得多。
快速評論:
您這樣寫: 我的C代碼調用了一個保存在全局環境中的用戶定義的R函數(以下代碼中的SomeRFunction)。 所以,你的代碼將很多在每個功能評價仍然減慢由於調用R的成本,R的速度較慢
我的RcppDE包(也用於優化)作為使用外部指針( Rcpp::XPtr
)將用戶定義的C函數向下傳遞給優化器的示例。 同樣的靈活性。 更好的速度。
您的編譯錯誤正好在該交集處-您不能“僅僅”將Rcpp對象傳遞給void指針。 Rcpp::XPtr
在這里可以為您Rcpp::XPtr
幫助,但是您也需要知道自己在做什么,因此,一個有效的示例可能會有所幫助。
這確實是一個Rcpp問題,但是您沒有添加標簽,所以我做了。
F.function
期望此簽名為double (*) (double x, void * params)
的函數,因此該函數接受double
然后是void*
。 如果您希望它飛起來,則需要幫助Rcpp::Function
。
這是典型的C
api剝離類型。 因此,您需要作為function
的東西可以理解您具有的params
,並能夠使用正確的參數調用R函數並轉換為雙精度型。 執行此操作的簡單方法是將R函數視為數據,因此請擴展struct
使其類似於以下內容:
struct my_f_params { double Rsq; int pA; Function& rfun };
這樣,您作為function
傳遞的function
可能是這樣的:
double proxy_fun( double x, void* params ){
my_f_params* data = reinterpret_cast<my_f_params*>(params) ;
return as<double>( data->rfun(x, data->Rsq, data->pA ) ) ;
} ;
因此,您可以像下面這樣構建gsl_function
:
my_f_params params = { Rsq, pA, f1 };
gsl_function F ;
F.function = &proxy_fun ;
F.params = ¶ms;
通過使用一些C ++ 11可變參數模板和元組,您可以將其推廣到任何東西,而不是( double
, int
)對,但這需要更多工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.