[PYTHON MATRIX-SIG] Time for recap?

Guido van Rossum guido@CNRI.Reston.VA.US
Sat, 30 Sep 1995 14:30:24 -0400

>    I think the best way to proceed is to use the built-in operators for
>    APL/J style elementwise operations and to have the specific 2D linear
>    algebra operations as methods.
> Why such a division? There is no clear borderline between "elementwise"
> and "linear algebra". If we should distinguish at all between methods
> and functions, I'd propose to use methods for procedures that change
> an array in place and functions for those that return a new array.

I just meant to end the debate about whether a*b should mean matrix
multiplication in the LA sense or elementwise multiplication like
APL/J.  This only an issue for * and /.  For / most people agree that
"matrix division" is numerically ill-defined and you should have
specified the particular decomposition you need instead.  This leaves
*, and, in spite of the elegance of linear algebra matrix
multiplication, I vote for the consistency of elementwise
multiplication.  This means that we need to define a method that
implements LA matrix multiply, e.g. a.mul(b).  Functions are out of
the question (since they would have to live in the namespace reserved
for built-in functions.)

>    To make efficient use of this, I propose that slicing and indexing, as
>    long as they return an object of rank >= 1, return an object that
>    points into the same representation sequence.
> Again, there are C++ classes that do this, and of course this makes
> slicing very efficient. On the other hand, it makes element assignment
> more complicated, since the array may have to be copied first.

I don't see much of a problem with that.  Functions/methods that take
an array and return a like-shaped array should always copy their
argument before modifying it.  Methods that are supposed to modify an
array in place should not also return a reference to the array.

Functions/methods that wish to modify the array only as a means of
calculating some property of the array should come in to flavors: a
"low-level" version whose name ends in "_inplace", which works on the
array in place, and a "high-level" version which copies the array and
then invokes the low-level version.  The user can then decide to use
the low-level version if performance so dictates, in which case the
consequences of course must be considerd first.  (I'd hate to see
optional "in-place" flag arguments -- in general, I don't like to see
flag arguments where the calls will always contain a constant argument

--Guido van Rossum <guido@CNRI.Reston.VA.US>
URL: <http://www.python.org/~guido/>

MATRIX-SIG  - SIG on Matrix Math for Python

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