[英]How to handle error in integration in GSL
我正在編寫需要真正快速地計算大量積分的python代碼,因此,不是使用c
函數使用scipy.integrate
,而是使用ctypes
計算c
所有積分。
我使用以下代碼導入c函數:
ctypes.CDLL('/usr/lib/i386-linux-gnu/libgslcblas.so', mode=ctypes.RTLD_GLOBAL)
ctypes.CDLL('/usr/lib/i386-linux-gnu/libgsl.so', mode=ctypes.RTLD_GLOBAL)
lib = ctypes.CDLL('/home/aurelien/Desktop/Project/within_opt_model_1/integral_test.so')
在c中,我使用以下公式計算積分:
gsl_integration_workspace *w = gsl_integration_workspace_alloc(200);
double result, err;
gsl_function F;
F.function = &integral;
F.params = ¶ms;
gsl_integration_qags(&F, z, 1, 1e-6, 1e-6, 200, w, &result, &err);
gsl_integration_workspace_free(w);
問題是,有時(〜5%的時間),由於我的積分正在緩慢收斂,它將殺死我的程序並打印:
gsl: qags.c:563: ERROR: interval is divergent, or slowly convergent
Default GSL error handler invoked
Aborted (core dumped)
如果我使用1e-10
而不是1e-6
,則不會發生此問題,但會使積分計算變慢得多。
我想要一種方法來try, catch
以便在大多數情況下使用1e-6
並快速進行,而在失敗時使用1e-10
。
我試着做:
int status = gsl_integration_qags(&F, z, 1, 1e-6, 1e-6, 200, w, &result, &err);
printf("%i\n", status);
但這只會顯示0,因為錯誤會在返回任何值之前中止。
我的猜測是我需要創建自己的錯誤處理程序方法,但是我不知道該怎么做。
非常感謝你! (如果有幫助,我可以向您展示更多代碼,我試圖使所有內容保持簡潔)。
您需要做的就是通過設置自己的錯誤處理程序
https://www.gnu.org/software/gsl/doc/html/err.html#c.gsl_set_error_handler
參見例如帶有ctypes的回調(如何從C調用python函數)如何聲明適當的回調並將其傳遞。
默認處理程序中止(如上面的文檔鏈接中所述),但是當然不這樣做是您的特權:)
來自GCC GSL:
錯誤處理程序
GSL錯誤處理程序的默認行為是打印一條短消息並調用abort()。 使用此默認值時,每當庫例程報告錯誤時,程序都將通過core-dump停止。 對於不檢查庫例程的返回狀態的程序,這是作為故障安全默認值(我們不鼓勵您以這種方式編寫程序)。
您可以調用gsl_set_error_handler_off()
禁用默認錯誤處理程序(此函數通過定義不執行任何操作的錯誤處理程序來關閉錯誤處理程序)。
我認為以下將完成工作
gsl_set_error_handler_off()
gsl_integration_workspace *w = gsl_integration_workspace_alloc(200);
double result, err;
gsl_function F;
F.function = &integral;
F.params = ¶ms;
int status = gsl_integration_qags(&F, z, 1, 1e-6, 1e-6, 200, w, &result, &err);
if(status == GSL_EDIVERGE){
status = gsl_integration_qags(&F, z, 1, 1e-10, 1e-10, 200, w, &result, &err);
/*handle other errors here...*/
}
gsl_integration_workspace_free(w);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.