1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
""" This setup demonstrates how to use the numarray code generation
facilities to define additional ufuncs at the user level. Universal
functions apply operators or C-functions elementwise to all of the
elements of an array or pair of arrays. This setup generates code
defining three universal functions which are installed as the
numarray.foo package: cos, bessel, and bar.
The ufuncs are used like this:
>>> import numarray as na
>>> import numarray.foo as foo
>>> a = na.array([1,2,3,4], type='Int32')
>>> foo.Cos(a)
array([ 0.54030228, -0.41614684, -0.9899925 , -0.65364361 ], type=Float32)
Note that since a is an Int32 array, Cos(a) first does blockwise
conversion of a to Float32 before calling the cosine library function.
"""
import distutils, os
from distutils.core import setup
from numarray.numarrayext import NumarrayExtension
from numarray.codegenerator import UfuncModule, make_stub
# ======================================================================
#
# Generate the C-code for the numarray.foo._foo extension:
#
m = UfuncModule("_foo")
# Inline the code for a couple C functions to be turned into ufuncs.
# This method lets you define your function here in the setup.py. An
# alternate approach would be to link with a libarary or additional C
# module.
m.add_code("""
static double c_bessel(double x, double y)
{
double x2=x*x, y2=y*y, diff=x2-y2;
return diff*diff/(x2+y2);
}
static UInt8 c_bar(UInt32 x )
{
return (x >> 24) & 0xFF;
}
extern int airy ( double x, double *ai, double *aip, double *bi, double *bip );
""")
# Method add_ufunc() defines the name of a ufunc, it's corresponding C
# function which is applied element-wise to all elements of an array,
# The arity of the ufunc (unary or binary only), and the I/O type
# signatures which are directly supported by the ufunc. Binary Ufunc
# "bessel" is implemented by the inline function "c_bessel" from the
# add_code() call above.
m.add_ufunc("bessel", "c_bessel", 2, [('Float32', 'Float32'),
('Float64', 'Float64')])
# Unary Ufunc "bar" only supports one builtin type signature:
# UInt32-->UInt8. Other types are blockwise converted by the ufunc
# machinery to UInt32 before "c_bar" is called.
m.add_ufunc("bar", "c_bar", 1, [('UInt32','UInt8')])
# Unary Ufunc "cos" is implemented by the C standard library function
# "cos". Given a Float32 array, it returns a Float32 array. Given a
# Float64 array, it returns a Float64 array. For other arrays,
# transparent conversion to one of the supported input types is performed
# by the ufunc machinery.
m.add_ufunc("cos", "cos", 1, [('Float32', 'Float32'),
('Float64', 'Float64')])
# N-ary ufunc "airy" is implemented in seperate C standard library file
# Src/airy.c with signature "int airy(double, double*, double* double* double*)"
# i.e. function returning int with 1 double input and 4 double outputs.
m.add_nary_ufunc("airy", signatures=[(('Float64',),
('Int32',) + ('Float64',)*4)],
forms=["vxfvvvv"])
# The generate() method writes out the complete extension module to the
# specified C file.
m.generate("Src/_foo.c")
# ======================================================================
# Create foo's __init__.py for defining UFuncs corresponding to CFuncs
# in _foo. make_stub() emits boiler-plate which makes your extension
# a package. The __init__ file imports all the public symbols from
# C extension _foo making them visible as numarray.foo.
make_stub("Lib/__init__", "_foo")
# ======================================================================
#
# Standard distutils setup for the generated code.
#
setup(name = "foo",
version = "0.1",
maintainer = "Todd Miller",
maintainer_email = "jmiller@stsci.edu",
description = "foo universal functions for numarray",
url = "http://www.stsci.edu/projects/foo/",
packages = ["numarray.foo"],
package_dir = { "numarray.foo":"Lib" },
ext_modules = [ NumarrayExtension( 'numarray.foo._foo',
['Src/_foo.c', 'Src/airy.c',
'Src/const.c', 'Src/polevl.c']
# libraries = ['ttf'],
# include_dirs = ['include'],
# library_dirs = ['lib']
)
]
)
|