[MATRIX-SIG] reverse of take?

P.S.Craig@durham.ac.uk P.S.Craig@durham.ac.uk
Tue, 1 Jul 1997 13:35:06 +0100 (BST)


onrad Hinsen writes:
> 
> > I propose that arraytype[arraytype] automatically be interpreted
> > as (1) gather as a value (2) scatter as an l-value.  I apologize if
> > this is obviously dumb, incompatible with existing usage, or
> > already proposed (I'm new, remember, don't hurt me!) :). 
> 
> Probably it has already been proposed, since anything imaginable has
> already been proposed.  ;-)
> 
> Let's make this a bit more specific:
> 
>   array[sequence [, sequence [, sequence ...]]
> 
> would be the most general form, with any sequence of integers allowed.
> But if we allow tuples, we have to decide on the interpretation of
> 
>   array[(2, 3)]
> 
> For compatibility this will have to remain equivalent to array[2, 3].
> (In fact we have little choice there; this equivalence is enforced by
> the interpreter.) So allowing tuples creates trouble. On the other
> hand, not allowing tuples creates a very unpythonic restriction. So
> there's the first problem to be resolved.

I think this does expose a flaw in the way in which multiple indexing
is handled in python. That we cannot distinguish a[(2,3)] from a[2,3]
is unfortunate. However, the potential ambiguity only arises if we
allow rank 1 arrays to be indices for arrays of higher rank. If we
don't, I can't see a problem.  This is a convenience which S (and
S-PLus) allow. However, in Numerical Python we can write ravel(a)[b]
which is not (efficiently) available in S. It should be OK as an
lvalue since ravel(a) does not copy a's data but creates a new
reference. If this is too cumbersome, surely we can find some
shorthand for the ravelling operation.

> 
> Second problem: do we allow arrays of rank > 1 as indices? If yes,
> what are the exact semantics? One interpretation would make
> 
>   a[b]
> 
> an array of the same shape as b with a[b][i, j, k,...] = a[b[i, j, k,...]].
> This gets a bit complicated when a has rank > 1, but it's still doable
> and probably useful.

How about this?  Suppose that b.shape[-1]==len(a.shape) Then
a[b].shape will be b.shape[:-1] and, for example, a[b][i,j,k] =
a[b[i,j,k,:]] as you propose (of course the latter may be written
a[b[i,j,k]] because ofthe way Numerical Python works. This extends
what happens in S to rank(b)>2. I think it's also consistent with what
I said earlier.

I think it may even be possible to go beyond this to the situation
where b.shape[-1]<len(a.shape). Then a[b].shape will be the
concatenation of b.shape[:-1] and a.shape[b.shape[-1]:]. and again
a[b][i,j,k] = a[b[i,j,k]]

In fact, we might be able to go yet further to, for example,
a[:,b]. This would have shape the concatentaion of a.shape[0],
b.shape[:-1] and a.shape[1+b.shape[-1]:] and a[:,b][i,j,k] would be
the same as a[i][b[j,k]]

I'd better stop, but I think the possibilities are tremendous. Of
course, someone will probably spot an ambiguity somewhere!

> 
> Third problem: an index sequence can contain the same index more than
> once. Fine for extracting data from an array, but what is supposed
> to happen if this occurs on the left-hand side? For example, what is
> 
>   a[[0, 1, 0]] = [1, 2, 3]
> 
> supposed to do?
> -- 

In S-Plus, a[0] becomes 3. In other words, some form of left to right
evaluation should be used? We would have to be very careful to avoid
ambiguity.

New problem:  Can we allow an expression such as

a[b][c] = d

In other words, c is applied as an index to the array a[b]. I think
that any situation like this can be written as

a[bc] = d

where bc is suitable determined from b, c and the shape of a. The idea
is to avoid computation of a[b] which is likely to require copying of
data.

At this point, I'm willing to volunteer to do some of the work
involved in making all this happen as I wish to use python as the base
for developing ideas that go beyond what we have in S and
S-Plus. Anyone got any suggestions as to how we should organise
things? 

Peter Craig



_______________
MATRIX-SIG  - SIG on Matrix Math for Python

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