Nesse post, vou mostrar um exemplo que fiz de como usar as UFuncs do Numpy. Me baseei neste link (Escrevendo sua própria ufunc) para fazer esse código.
No exemplo, eu criei duas funções em C para usar no Python. Segue o código do arquivo "minhasufuncs.c".
#include "Python.h"
#include "math.h"
#include "numpy/ndarraytypes.h"
#include "numpy/ufuncobject.h"
// Estrutura usada para descrever um método de um tipo de extensão.
static PyMethodDef MinhasufuncsMethods[] = {
{NULL, NULL, 0, NULL}
};
//Função 1
static void double_FtoERB(char **args, npy_intp *dimensions,
npy_intp* steps, void* data)
{
npy_intp i;
npy_intp n = dimensions[0];
char *in = args[0], *out = args[1];
npy_intp in_step = steps[0], out_step = steps[1];
for (i = 0; i < n; i++) {
*((double *)out) = 24.7 * (4.37 * 1E-3 * (*(double *)in) + 1.);
in += in_step;
out += out_step;
}
}
// Função 2
static void double_sinc(char **args, npy_intp *dimensions,
npy_intp* steps, void* data)
{
npy_intp i;
npy_intp n = dimensions[0];
char *in = args[0], *out = args[1];
npy_intp in_step = steps[0], out_step = steps[1];
for (i = 0; i < n; i++) {
*((double *)out) = sin((*(double *)in)) / (*(double *)in) ;
in += in_step;
out += out_step;
}
}
// Estes são ponteiros para as funções acima
PyUFuncGenericFunction FtoERBfuncs[1] = {&double_FtoERB};
PyUFuncGenericFunction sincfuncs[1] = {&double_sinc};
// Estes são as entradas e retorna os dtypes
static char FtoERBtypes[2] = {NPY_DOUBLE, NPY_DOUBLE};
static char sinctypes[2] = {NPY_DOUBLE, NPY_DOUBLE};
static void *FtoERBdata[1] = {NULL};
static void *sincdata[1] = {NULL};
// Inicializa o módulo "minhasufuncs"
PyMODINIT_FUNC initminhasufuncs(void)
{
PyObject *m, *FtoERB, *sinc, *d;
m = Py_InitModule("minhasufuncs", MinhasufuncsMethods);
if (m == NULL) {
return;
}
import_array();
import_umath();
FtoERB = PyUFunc_FromFuncAndData(FtoERBfuncs, FtoERBdata, FtoERBtypes, 1, 1, 1,
PyUFunc_None, "FtoERB",
"FtoERB_docstring", 0);
sinc = PyUFunc_FromFuncAndData(sincfuncs, sincdata, sinctypes, 1, 1, 1,
PyUFunc_None, "sinc",
"sinc_docstring", 0);
d = PyModule_GetDict(m);
PyDict_SetItemString(d, "FtoERB", FtoERB);
Py_DECREF(FtoERB);
PyDict_SetItemString(d, "sinc", sinc);
Py_DECREF(sinc);
}
São criadas duas funções para ser usadas no Python: "FtoERB" e "sinc". Tais funções serão chamadas a partir de um módulo a ser importado no Python, nesse caso, chamado "minhasufuncs". Para gerar a biblioteca compartilhada, usei um arquivo "setup.py". Segue:
def configuration(parent_package='', top_path=None):
import numpy
from numpy.distutils.misc_util import Configuration
config = Configuration('',
parent_package,
top_path)
config.add_extension('minhasufuncs', ['minhasufuncs.c'])
return config
if __name__ == "__main__":
from numpy.distutils.core import setup
setup(configuration=configuration)
E rode o comando:
$ python setup.py build_ext --inplace
Com isso, será gerado um arquivo "minhasufuncs.so". É só chama-lo no Python. Então segue um código-exemplo que chama essas funções.
# -*- coding: utf-8 -*-
#/usr/bin/python
import numpy as np
import minhasufuncs
import matplotlib.pyplot as mpl
x1 = np.linspace(-30,30,8000)
y1 = minhasufuncs.sinc(x1)
x2 = np.linspace(0,8000,8000)
y2 = minhasufuncs.FtoERB(x2)
mpl.figure(figsize=(7,12))
mpl.subplot(211)
mpl.plot(x1,y1,'k',lw=2)
mpl.grid()
mpl.subplot(212)
mpl.plot(x2,y2,'k',lw=2)
mpl.grid()
mpl.savefig('minhasufuncs.png')
Os gráficos gerados foram:
CLIQUE AQUI para baixar os meus arquivos.
É isso aí!
Nenhum comentário:
Postar um comentário