2017-08-22 17 views
5

6DでPythonで数値積分をする必要があります。 scipy.integrate.nquad関数は遅いので、現在は被積分関数をNumbaでscipy.LowLevelCallableとして定義することで処理速度を上げようとしています。私はhere与えられた例を複製することによってscipy.integrate.quadと1Dにこれを行うことができたnquadとの効率的な統合のために、NumbaからCコールバックを実装するにはどうすればよいですか?

import numpy as np 
from numba import cfunc 
from scipy import integrate 

def integrand(t): 
    return np.exp(-t)/t**2 

nb_integrand = cfunc("float64(float64)")(integrand) 

# regular integration 
%timeit integrate.quad(integrand, 1, np.inf) 

10000ループ、3の最もよい:ループ当たり128マイクロ秒

# integration with compiled function 
%timeit integrate.quad(nb_integrand.ctypes, 1, np.inf) 

100000ループ、最高3:ループあたり7.08μs

これをnquadで今すぐ実行したい場合、nquadのドキュメントには、

と書かれています。

If the user desires improved integration performance, then f may be a scipy.LowLevelCallable with one of the signatures:

double func(int n, double *xx) 
double func(int n, double *xx, void *user_data) 

where n is the number of extra parameters and args is an array of doubles of the additional parameters, the xx array contains the coordinates. The user_data is the data contained in the scipy.LowLevelCallable.

しかし、次のコードは私にエラー与える:

from numba import cfunc 
import ctypes 

def func(n_arg,x): 
    xe = x[0] 
    xh = x[1] 
    return np.sin(2*np.pi*xe)*np.sin(2*np.pi*xh) 

nb_func = cfunc("float64(int64,CPointer(float64))")(func) 

integrate.nquad(nb_func.ctypes, [[0,1],[0,1]], full_output=True) 

エラー:クワッド:最初の引数が間違って署名

とのctypes関数ポインタであることがnumbaと機能をコンパイルすることは可能ですが、そのコード内で直接nquadを使用したり、外部ファイルに関数を定義したりすることなく使用できますか?

ありがとうございます! scipy.LowLevelCallableに機能をラップ

答えて

3

nquadを幸せにする:

si.nquad(sp.LowLevelCallable(nb_func.ctypes), [[0,1],[0,1]], full_output=True) 
# (-2.3958561404687756e-19, 7.002641250699693e-15, {'neval': 1323}) 
関連する問題