[PYTHON MATRIX-SIG] Pseudo Indices
James Hugunin
jjh@Goldilocks.LCS.MIT.EDU
Tue, 30 Jan 96 12:42:49 EST
Well, here's a fairly long and slightly confusing response, but what
do you expect from a first draft?
The idea of pseudo indices comes from the language Yorick created by
Dave Munro at LLNL, not from APL/J.
Everybody expects this to work:
a = array([1,2,3])
a+2 -> array([3,4,5])
2 is 0-dimensional array with shape [], and a has shape [3]. The rule
says that any non-existent dimension is "broadcast" to match a higher
dimensional array as required.
The idea is to extend this notion of broadcasting to any dimension of
length one. So the following will also work:
a+array([2]) -> array([3,4,5])
array([2]) has shape [1], and a has shape [3]. The [1] is broadcast
to match the [3].
The classic example of where this is useful is in taking an
outer product.
b = array([10, 20])
a * b.reshape(2, 1) -> array([[11, 12, 13], [21, 22, 23]])
a has shape [3], and b.reshape(2,1) has shape [2, 1]. The result of a binary
operator applied to them has shape [2,3].
In order to make such code easier to read, Yorick introduces the
notion of a pseudo index that can be added to any multidimensional index
and means, add a new dimension here.
ie. b[2, PseudoIndex] <--> b.reshape(2, 1)
"All" is not in fact related to Yorick pseudo indices at all, but is
related to Slices.
c = array([[1,2,3], [11,12,13]])
I'd really like to be able to say c[:, 3] -> array([3,13]). Python
syntax doesn't currently allow this, so until somebody convinces Guido
to make the change, the following objects are used instead.
c[:, 1:2] --> c[Slice(), Slice(1,2)]
All = Slice()
One more piece is needed to handle multidimensional indexing properly.
Let's say that I want to extract the third element from the last
dimension of an array.
In Yorick that would look like a[.., 3]. Since Python doesn't yet
have this rubber index, I use the following:
a[RubberIndex, 3].
So, the following special symbols are needed to properly treat
multidimensional indexing:
Slice
PseudoIndex
RubberIndex
My current feeling on the best way to do this is to keep Slice's as
they are (until somebody lobbys Guido for a better system).
Define string constants
NewAxis = "NewAxis"
Ellipses = "Ellipses"
NewAxis is equivalent to the current "None" and indicates a
PseudoIndex
Ellipses is equivalent to the current "RubberIndex" and indicates
standard ellipses as in, fill in what should naturally go here.
Comments?
-Jim
=================
MATRIX-SIG - SIG on Matrix Math for Python
send messages to: matrix-sig@python.org
administrivia to: matrix-sig-request@python.org
=================