User guide

NumPy User Guide, Release 1.9.0
S0 = astrides[0]/sizeof(double);
S1=astrides[1]/sizeof(double);
for (i=1; i<M-1; i++) {
r = i
*
S0; rp1 = r+S0; rm1 = r-S0;
for (j=1; j<N-1; j++) {
c = j
*
S1; cp1 = j+S1; cm1 = j-S1;
b[i
*
N+j] = a[r+c] + \
(a[rp1+c] + a[rm1+c] + \
a[r+cp1] + a[r+cm1])
*
0.5 + \
(a[rp1+cp1] + a[rp1+cm1] + \
a[rm1+cp1] + a[rm1+cp1])
*
0.25;
}
}
}
A possible advantage this code has over the Fortran-equivalent code is that it takes arbitrarily strided (i.e. non-
contiguous arrays) and may also run faster depending on the optimization capability of your compiler. But, it is a
obviously more complicated than the simple code in filter.f. This code must be compiled into a shared library. On my
Linux system this is accomplished using:
gcc -o code.so -shared code.c
Which creates a shared_library named code.so in the current directory. On Windows don’t forget to either add __de-
clspec(dllexport) in front of void on the line preceeding each function definition, or write a code.def file that lists the
names of the functions to be exported.
A suitable Python interface to this shared library should be constructed. To do this create a file named interface.py
with the following lines at the top:
__all__ = [’add’, ’filter2d’]
import numpy as N
import os
_path = os.path.dirname(’__file__’)
lib = N.ctypeslib.load_library(’code’, _path)
_typedict = {’zadd’ : complex, ’sadd’ : N.single,
’cadd’ : N.csingle, ’dadd’ : float}
for name in _typedict.keys():
val = getattr(lib, name)
val.restype = None
_type = _typedict[name]
val.argtypes = [N.ctypeslib.ndpointer(_type,
flags=’aligned, contiguous’),
N.ctypeslib.ndpointer(_type,
flags=’aligned, contiguous’),
N.ctypeslib.ndpointer(_type,
flags=’aligned, contiguous,’\
’writeable’),
N.ctypeslib.c_intp]
This code loads the shared library named code.{ext} located in the same path as this file. It then adds a return type
of void to the functions contained in the library. It also adds argument checking to the functions in the library so
that ndarrays can be passed as the first three arguments along with an integer (large enough to hold a pointer on the
platform) as the fourth argument.
Setting up the filtering function is similar and allows the filtering function to be called with ndarray arguments as the
first two arguments and with pointers to integers (large enough to handle the strides and shape of an ndarray) as the
last two arguments.:
76 Chapter 5. Using Numpy C-API