python - Python 中的 C 函数 : Return an Array and Variables

标签 python c arrays function return

我刚从 Matlab 转入 Python,我知道调用 C 函数与 Matlab mex 不同。由于缺乏适当的文档,我已经在网上搜索了好几天,但找不到解决我的简单问题的方法。

基本上我想在 Python 中调用一个 C 函数,输入 2 个整数和一个二维数组,进行一些计算,然后返回一个二维数组。我也想输出一些其他变量(这可能需要使用结构)。我知道这是非常基本的东西,但如果有人能帮助我,我将不胜感激。

所以我希望的是在 matlab 中的等价物!谢谢!!!

[Nxy,outArray] = Function(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();
}

最佳答案

可以使用 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.]]

请注意,在这种情况下,无需将数组维度 NxNy 传递给函数,因为它们可以通过 inArray 访问。 Cython 中的形状

请引用Cython documentation有关 Numpy 的进一步优化细节。

关于python - Python 中的 C 函数 : Return an Array and Variables,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28833776/

相关文章:

python - 带有自定义 Estimator 的 Tensorflow 指标

c - 内存泄漏: Reading and returning line from file

c - 告诉我编译器在这里做什么?

java - 在java中使用选择排序对整数数组进行排序。找不到我的错误

arrays - 使用下标扩展数组 (Swift)。 Xcode 6 beta 7 中的错误?

python - map() 函数获取输入

python - IO错误 : No space left on device - which device?

python - 神经网络 - 输入标准化

c++ - 如何在 Windows 上以编程方式设置 GPU 核心和内存时钟?

c# - 数组中的 ArgumentOutOfRange 异常