在阅读本文之前,通过阅读/略读扩展和嵌入Python解释器的
第1部分中的教程以及如何扩展NumPy,可以帮助您熟悉Python的C扩展基础知识。
umath模块是一个计算机生成的C模块,可以创建许多ufunc。它提供了许多如何创建通用函数的示例。使用ufunc机制创建自己的ufunc也不困难。假设您有一个函数,您想要在其输入上逐个元素地操作。通过创建一个新的ufunc,您将获得一个处理的函数
创建自己的ufunc并不困难。所需要的只是您想要支持的每种数据类型的1-d循环。每个1-d循环必须具有特定签名,并且只能使用固定大小数据类型的ufunc。下面给出了用于创建新的ufunc以处理内置数据类型的函数调用。使用不同的机制为用户定义的数据类型注册ufunc。
在接下来的几节中,我们提供了可以轻松修改的示例代码,以创建自己的ufunc。这些示例是logit函数的连续更完整或复杂版本,这是统计建模中的常见功能。Logit也很有趣,因为由于IEEE标准(特别是IEEE 754)的神奇之处,下面创建的所有logit函数都自动具有以下行为。
>>> logit(0)-inf>>> logit(1)inf>>> logit(2)nan>>> logit(-2)nan这很好,因为函数编写器不必手动传播infs或nans。
为了比较和阅读器的一般启发,我们提供了一个简单的logit C扩展实现,它没有使用numpy。
为此,我们需要两个文件。第一个是包含实际代码的C文件,第二个是用于创建模块的setup.py文件。
#include #include /* * spammodule.c * This is the C code for a non-numpy Python extension to * define the logit function, where logit(p) = log(p/(1-p)). * This function will not work on numpy arrays automatically. * numpy.vectorize must be called in python to generate * a numpy-friendly function. * * Details explaining the Python-C API can be found under * 'Extending and Embedding' and 'Python/C API' at * docs.python.org . *//* This declares the logit function */static PyObject* spam_logit(PyObject *self, PyObject *args);/* * This tells Python what methods this module has. * See the Python-C API for more information. */static PyMethodDef SpamMethods[] = { {"logit", spam_logit, METH_VARARGS, "compute logit"}, {NULL, NULL, 0, NULL}};/* * This actually defines the logit function for * input args from Python. */static PyObject* spam_logit(PyObject *self, PyObject *args){ double p; /* This parses the Python argument into a double */ if(!PyArg_ParseTuple(args, "d", &p)) { return NULL; } /* THE ACTUAL LOGIT FUNCTION */ p = p/(1-p); p = log(p); /*This builds the answer back into a python object */ return Py_BuildValue("d", p);}/* This initiates the module using the above definitions. */#if PY_VERSION_HEX >= 0x03000000static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, "spam", NULL, -1, SpamMethods, NULL, NULL, NULL, NULL};PyMODINIT_FUNC PyInit_spam(void){ PyObject *m; m = PyModule_Create(&moduledef); if (!m) { return NULL; } return m;}#elsePyMODINIT_FUNC initspam(void){ PyObject *m; m = Py_InitModule("spam", SpamMethods); if (m == NULL) { return; }}#endif 要使用setup.py文件,请将setup.py和spammodule.c放在同一文件夹中。然后python setup.py build将构建要导入的模块,或者setup.py install将模块安装到您的site-packages目录。
。。。。。。。。。。。。。
作者:柯广
篇幅有限更多请见扩展链接:http://www.mark-to-win.com/tutorial/52201.html
| 留言与评论(共有 0 条评论) “” |