簡體   English   中英

使用提供的R函數使用gsl_function

[英]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 = &params;
  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實現要快得多。

快速評論:

  1. 您這樣寫: 我的C代碼調用了一個保存在全局環境中的用戶定義的R函數(以下代碼中的SomeRFunction)。 所以,你的代碼將很多在每個功能評價仍然減慢由於調用R的成本,R的速度較慢

  2. 我的RcppDE包(也用於優化)作為使用外部指針( Rcpp::XPtr )將用戶定義的C函數向下傳遞給優化器的示例。 同樣的靈活性。 更好的速度。

  3. 您的編譯錯誤正好在該交集處-您不能“僅僅”將Rcpp對象傳遞給void指針。 Rcpp::XPtr在這里可以為您Rcpp::XPtr幫助,但是您也需要知道自己在做什么,因此,一個有效的示例可能會有所幫助。

  4. 這確實是一個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 = &params;

通過使用一些C ++ 11可變參數模板和元組,您可以將其推廣到任何東西,而不是( doubleint )對,但這需要更多工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM