I am trying to use C defined function for numerical integration in SciPy. The example case given here (SciPy documentation) works fine.
In my case, the testlib.c
file is
/* testlib.c */
#include <math.h>
#define PI 3.14159265358979323846
double factor(double phi, double r) {
double val = (2*PI)/(pow(r, 2) + 3*cos(phi));
return val;
}
//------------------------------------
double f2(int n, double *x, void *user_data) {
double c = *(double *)user_data;
double v1 = factor(c, 0.25); // value of phi defined inline but it is an argument
return v1 + x[0] - x[1] ; /* corresponds to v1 + x - y */
}
And, the test.py function calling the testlib.so
file obtained after compilation is below,
import os, ctypes
from scipy import integrate, LowLevelCallable
lib = ctypes.CDLL(os.path.abspath('testlib.so'))
# define return type in .restype
lib.f2.restype = ctypes.c_double
# define argument type in .argtypes
lib.f2.argtypes = (ctypes.c_int, ctypes.POINTER(ctypes.c_double), ctypes.c_void_p)
# additional argument, here a constant, casting needed
c = ctypes.c_double(1.0)
user_data = ctypes.cast(ctypes.pointer(c), ctypes.c_void_p)
# pass extra argument
func = LowLevelCallable(lib.f2, user_data)
# quadrature in 3-dimensions
out=integrate.nquad(func, [[0, 10], [-10, 0]])
print(out)
# -----------------------------------------------
phi = 0.25 # How to pass these to the C function
esv = 1.25
cv1 = 0.03
cv2 = -0.15
cv3 = 3.0
My question: How to pass additional arguments such as c
to the function f2
. In my case I have 5 such arguments, available as np.float64
in the calling py file.
I wonder if I can pass the arguments as array as user_data
to the function f2
.
From documentation for
nquad
, found that arguments are to be passed as array andint n
in the C function is the number of arguments passed.Also, I'm Open to try other options such as cython, pyCapsule but no experience there in. Found very similar question using numba and jit, where no additional arguments are passed. Using numba and jit for integration: SE
For compiling testlib.c
: $ gcc -shared -fPIC -o testlib.so testlib.c