[PYTHON MATRIX-SIG] A ramble on ofunc's and omath

James Hugunin jjh@mama-bear.lcs.mit.edu
Thu, 14 Dec 95 13:43:08 -0500


This relates to both Konrad's and Jim's recent posts.  Also, this is a bit  
of a rambling set of comments rather than a coherent argument.  I just want  
people to understand where this weird ofunc thing came from, and what it  
does now.

1) What is an Optimized FUNCtion?

An ofunc is a python object that contains C code to execute a function on  
arrays of raw C numbers (or on raw python objects, but that's another story)  
at close to compiled speed.  Each function takes an arbitrary number of  
arguments of given types, and produces an arbitrary number of results of  
given types.  For every desired combination of types that the function  
should operate on, there is another bit of C code to do the actual  
computation.


2) Why not bundle it into the matrix object?

For one thing, I'd like to eventually clean things up and document them  
well enough that anybody can create an ofunc.  They're really useful little  
critters for doing very fast computations on arrays of numbers.

Also, there are things like generalized reductions that need to have  
something to grab onto as the function to reduce over.  Without ofuncs as  
real python objects, I don't have any good way to express something like:

add.reduce(m)
(equivalent to but much faster than reduce(lambda x, y: x+y, m) ).

There are also many of these creatures that don't really belong with the  
matrixobject, but which should behave in exactly the same way as "built-in"  
functions like add.  These include things like hypot.


3) Why the current weird dependency on import omath?

I wanted to have a module which defined add and subtract as ofuncs so that  
they could be used in things like add.reduce.

I also wanted to be able to play with different implementations of the  
ofuncs for different purposes.  For example, it should be possible to do the  
usual numeric tricks of special casing the currently very general inner  
loops to gain speed improvements.  Using the current setup, this can be done  
by creating a new module, and using the ofuncs for things like add and  
subtract defined in this new module in the matrix object.

Also, I noticed that the matrix object was quite useful without any math  
functions at all, and I thought that it was a nice coincidence that this  
arrangement made it possible to have a "stripped-down" matrixobject with no  
numerical capabilites if you so desired.


4) How this turned into a generalized math package

I started to notice a certain duplication of code going on.  For example,  
mathmodule now had a function to take the sin of a double, cmathmodule had  
one to take the sin of a complex number, and omathmodule (for these ofuncs  
I'd created) had one to take the sin of a matrix of doubles, complex, or  
even of generic python objects (that had a sin method).  This made it a very  
small jump to allow a single double or complex to be treated as a 0d  
matrix, and completely replace the code in mathmodule and cmathmodule with  
omathmodule.

This is what turned into the generic math module that now exists.  I have  
no arguments with giving it a name more fitting of its new role.

If nobody has any objections, or better ideas, I'll change the name to  
"umath" (gxxxx always makes me think of gnu code) for the upcoming bug-fix  
release.

-Jim

=================
MATRIX-SIG  - SIG on Matrix Math for Python

send messages to: matrix-sig@python.org
administrivia to: matrix-sig-request@python.org
=================