从Fortran / C调用Python函数

我正在编写Fortran代码,我想使用Python库中的一些特殊函数和方法。 这是一个Python代码:

from mpmath import * from scipy.optimize import * def g(A,B,t): return newton(lambda x: (x - A*polylog(1.5, B*exp(-t*x))), 0.0) 

在fortran代码中,我想传递实数值A,B,t并获得g(A,B,t)的值(可能是复数)。 这也可以在C中完成。

我想提一下,将Python与其他语言混合对我来说是新鲜事。

如果有人感兴趣,我已经解决了这个问题。 以下是非常有用的 : stackoverflow和yolinux 。

rootC.c

 #include "rootC.h" #include  #include  void Initialize () { Py_Initialize(); } void Finalize () { Py_Finalize(); } void root_(double* A, double* B, double* t, double* x) { PyObject *pName, *pModule, *pFunc; PyObject *pArgs, *pValue, *sys, *path; static int i; if (i == 0) { ++i; Initialize(); atexit(Finalize); } sys = PyImport_ImportModule("sys"); path = PyObject_GetAttrString(sys, "path"); PyList_Append(path, PyString_FromString(".")); pName = PyString_FromString("rootPY"); pModule = PyImport_Import(pName); if (!pModule) { PyErr_Print(); printf("ERROR in pModule\n"); exit(1); } pFunc = PyObject_GetAttrString(pModule, "root"); pArgs = PyTuple_New(3); PyTuple_SetItem(pArgs, 0, PyFloat_FromDouble((*A))); PyTuple_SetItem(pArgs, 1, PyFloat_FromDouble((*B))); PyTuple_SetItem(pArgs, 2, PyFloat_FromDouble((*t))); pValue = PyObject_CallObject(pFunc, pArgs); *x = PyFloat_AsDouble(pValue); } 

rootC.h

 #ifndef ROOT_H_ #define ROOT_H_ void Initialize(); void Finalize(); void root_(double*, double*, double*, double*); #endif 

rootPY.py

 from mpmath import polylog, exp from scipy.optimize import newton def root(A,B,t): return abs(newton(lambda x: (x - A*polylog(1.5, B*exp(-t*x))), 0.0)) 

rootF.F90

 program main implicit none real*8 A, B, t, x A = 0.4d0 B = 0.3d0 t = 0.1d0 call root(A,B,t,x) write(*,*) x end program main 

main.c中

 #include "rootC.h" #include  int main() { double A = 0.4, B = 0.3, t = 0.1, x = 0.0; root_(&A,&B,&t,&x); printf("A = %f, B = %f, t = %f\n", A, B, t); printf("x = %.15f\n", x); return 0; } 

Makefile文件

 CC = gcc FC = gfortran CFLAGS = -I/usr/include/python2.7 LFLAGS = -L/usr/local/lib -lpython2.7 -lm .PHONY: all clean all: rootF main rootF: rootF.o rootC.o $(FC) $^ -o $@ $(LFLAGS) rootF.o: rootF.F90 $(FC) -c $< -o $@ main: main.o rootC.o $(CC) $^ -o $@ $(LFLAGS) main.o: main.c $(CC) $(CFLAGS) -c $< -o $@ rootC.o: rootC.c $(CC) $(CFLAGS) -c $< -o $@ clean: rm -f *.o