[PYTHON MATRIX-SIG] Functions and names
Konrad HINSEN
hinsenk@ere.umontreal.ca
Tue, 20 Feb 1996 15:12:08 -0500
I have made an attempt to put some order into the array functions. I
have made a list of functions that should be available and proposed a
name for each function. Until now I have covered constructors
and structural functions; the rest will follow later, assuming
I am not hit by too many 16-ton weights before ;-)
Lines that describe new or modified operations are marked with a
'+'. Comments are at the end of the file.
As I have suggested before, it is useful to have an additional module
defining abbreviations and/or more meaningful names for often-used
combinations. These should not be part of the standard module to
reduce name space pollution and learning overhead, but they should
nevertheless be part of the standard distribution to ensure
uniformity. I'll include recommended abbreviations in the respective
sections.
Comments of any kind are of course welcome.
Constructors
============
1) Construct an array from an arbitrary sequence object or a function:
+ array(sequenceOrFunction, shape=None, type=None)
Returns an array of the given shape and type using the
elements from the flattened sequence. If not all
elements of the sequence are used, the rest is discarded.
If more elements are needed, the sequence is reused from
the beginning.
If a callable object is passed instead of a sequence,
it is called for each element with its indices as
parameters.
Calling the current constructor oldArray(), the new one
behaves like
def array(sequenceOrFunction, shape=None, type=None):
if isSequence(sequenceOrFunction):
a = oldArray(sequence, type)
if shape is not None:
a = copyAndReshape(a, shape)
return a
else:
return fromFunction(map(shape), sequenceOrFunction)
This constructor replaces the current constructors
array(), copyAndReshape(), and fromFunction(), and
makes special cases like zeros() so easy that they
don't have to be standard functions any more.
2) Construct a rank-1 array of equally spaced points:
+ arrayRange(x1, x2=None, x3=None)
Currently: function arange() does exactly the same.
Abbreviations:
zeros(n1,n2,...) equals array(0,(n1,n2,...))
ones(n1,n2,...) equals array(1,(n1,n2,...))
unitMatrix(n) equals array([1]+n*[0], (n,n))
arange equals arrayRange
Structural array operations
===========================
1) Selecting subarrays
1.1) Selecting on a "raster" along each coordinate:
Done by indexing with integers and slices
1.2) Selecting arbitrary elements specified by an array of indices i:
+ take(a, i, axis=0)
Conditions: i must be of an integer array type,
minimum.reduce(ravel(i)) >= 0,
maximum.reduce(ravel(i)) < a.shape[axis]
Currently: method a.take(i, axis=0), i can be of any type, but
must have rank 1.
1.3) Selecting the diagonal, i.e. those values where the indices
along two axes are equal (see comment 1):
+ diagonal(a, axis1=0, axis2=1)
Conditions: axis1 < len(a.shape), axis2 < len(a.shape),
a.shape[axis1] == a.shape[axis2]
2) Rearranging array elements
2.1) Changing the shape
2.1.1) General reshaping:
+ reshape(a,shape)
shape can be of any non-nested sequence type
Condition: multiply.reduce(shape) == multiply.reduce(a.shape)
Currently: method a.reshape(shape), shape must be a tuple
2.1.2) Reshaping to a rank-1 array:
ravel(a)
equivalent to reshape(a,(multiply.reduce(a.shape),))
2.1.3) Combining a group of axes into one axis (see comment 2):
+ a[i1, i2, ......, i3, i4] (see comment 3)
The double ellipsis works similar to the single one, but
contracts all the axes covered into a single axis.
2.1.4) Adding an axis of length 1:
a[..., NewAxis, ...]
2.2) Transposition:
+ transpose(a, axes)
axes is a non-nested sequence of non-negative integers
with maximum.reduce(axes) < len(a.shape)
Currently: method a.transpose(axes) does the same, but
there is a bug that sometimes gives wrong results if
an axis is used more than once in the list. It also
insists that len(axes) == len(a.shape), although there
is no need for this restriction.
3) Replicating and combining array elements
3.1) Replicating elements along an axis:
+ repeat(a, n, axis=0)
n is a non-nested integer sequence with len(n) == a.shape[axis]
Each element in a is repeated as often as indicated by
the corresponding element in n. The length of the result
along the specified axis is add.reduce(n).
Currently: function compress(n, a, axis=0) is a special case
limited to boolean (0/1) elements in n.
3.2) Concatenation of arrays along an axis:
+ concatenate((a1,a2,a3,...), axis=0)
Condition: all arrays must have the same shape for the
remaining axes.
Currently: method a.concat(a1,a2,a3,...) works only along
first axis.
3.3) Concatenation of arrays along a new axis:
Can be done by combining concatenate() and indexing with NewAxis.
(see comment 4)
Abbreviation:
reverse(a) = a[::-1]
Comments
========
1) APL uses a special case of transposition for selecting a
diagonal, but this is very confusing.
2) In J this is done by using ravel() with reduced rank, but
as long as we don't have functions with bounded ranks,
we need a special function.
3) I tried to find a construction that does not require
yet another syntax and this is the best I could think
of. But I am not particularly attached to it, so feel
free to think of something better.
4) APL does this with fractional indices, which is probably
the weirdest feature in APL.
-------------------------------------------------------------------------------
Konrad Hinsen | E-Mail: hinsenk@ere.umontreal.ca
Departement de chimie | Tel.: +1-514-343-6111 ext. 3953
Universite de Montreal | Fax: +1-514-343-7586
C.P. 6128, succ. Centre-Ville | Deutsch/Esperanto/English/Nederlands/
Montreal (QC) H3C 3J7 | Francais (phase experimentale)
-------------------------------------------------------------------------------
=================
MATRIX-SIG - SIG on Matrix Math for Python
send messages to: matrix-sig@python.org
administrivia to: matrix-sig-request@python.org
=================