我刚从Matlab过渡到Python,我知道调用C函数与Matlab mex不同。由于缺乏适当的文档,我现在已经鞭打了几天,无法找到解决我的简单问题的方法。
基本上我想在Python中调用C函数,输入2个整数和2D数组,进行一些计算,然后返回2D数组。我也想输出一些其他变量(这可能需要使用结构)。我知道这是非常基本的东西,但如果有人能帮助我,我将非常感激。
所以我希望在matlab中相当于这个! THX !!!
[Nxy,outArray] =功能(Nx,Ny,inArray)
setup.py代码
from distutils.core import setup, Extension
import numpy.distutils.misc_util
setup(
ext_modules=[Extension("myfunc", ["myfunc.c"])],
include_dirs=numpy.distutils.misc_util.get_numpy_include_dirs(),
)
myfunc.c的代码
static char module_docstring[] =
"This function does some calculations...";
static char Run_docstring[] =
"Run what ever algorithm there is!";
static PyObject *Run(PyObject *self, PyObject *args)
{
int i, j, Nx, Ny;
PyObject *Data;
/* Parse the input tuple */
if (!PyArg_ParseTuple(args, "iiO", &Nx, &Ny, &Data)) // Data is a 2D array
return NULL;
PyObject *array = PyArray_FROM_OTF(Data, NPY_DOUBLE, NPY_IN_ARRAY); // Interpret as numpy array
double *newData = (double*)PyArray_DATA(array); // Pointers to the data as C-types
double outData[Ny][Nx]; // Creating output 2D Array
int outCount;
// Calculations
outCount = Nx*Ny;
for (i=0; i<Nx; i++){
for (j=0; i<Ny; j++){
outData[j][i] = sqrt(Data[j][i]) + sqrt(outCount);
}
}
// Free memory used in PyObject
Py_DECREF(array);
// Return output Data
PyObject *ret = Py_BuildValue("i", outCount);
return ret, PyArray_Return(outData);
}
static PyMethodDef module_methods[] = {
{"Run", Run, METH_VARARGS, Run_docstring},
{NULL, NULL, 0, NULL}
};
PyMODINIT_FUNC initmyfunc(void)
{
PyObject *m = Py_InitModule3("myfunc", module_methods, module_docstring);
if (m == NULL)
return;
import_array();
}
答案 0 :(得分:1)
可以使用Cython从Python调用优化的C函数。
在这种特殊情况下,我们可以创建一个myfunc.pyx
文件,
import numpy as np
cimport numpy as np
from libc.math cimport sqrt
cpdef tuple myfunc(int Nx, int Ny, double[:,::1] inArray):
cdef double [:,::1] outData = np.zeros((Nx, Ny))
cdef int i,j, res
with nogil:
for i in range(Nx):
for j in range(Ny):
outData[i, j] = sqrt(inArray[i,j]) + sqrt(<double> Nx*Ny)
res = 0 # not sure how res is computed
return res, outData.base
可以使用以下setup.py
编译,
from distutils.core import setup, Extension
import numpy as np
from Cython.Distutils import build_ext
setup(
ext_modules=[Extension("myfunc", ["myfunc.pyx"])],
cmdclass = {'build_ext': build_ext},
include_dirs=[np.get_include()])
使用
$ python setup.py build_ext --inplace
这会生成并编译myfunc.c
。然后可以使用生成的Python模块,如下所示,
from myfunc import myfunc
import numpy as np
Nx, Ny = 2, 2
inArray = np.ones((Nx,Ny))
res, outArray = myfunc(Ny,Ny, inArray)
print(outArray)
# which would return
[[ 3. 3.]
[ 3. 3.]]
注意,在这种情况下,没有必要将数组维度Nx
,Ny
传递给函数,因为可以通过Cython中的inArray.shape
访问它们。
有关进一步优化的详细信息,请参阅有关Numpy的Cython documentation。
答案 1 :(得分:0)
我遵循了建议的内容,我在编译期间收到了此错误消息!
运行Anaconda 2.7,64位,win7x64
谢谢和干杯,