[MATRIX-SIG] reverse of take?

Andrew P. Mullhaupt amullhau@ix.netcom.com
Mon, 30 Jun 1997 20:31:04 -0400


At 02:45 PM 6/30/97 -0400, Aaron Watters wrote:

> 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!) :). 

This proposal is OK with me and is essentially what a lot of people
wish Python did - and not just the numerical arrays. (No matter though-
the numerical arrays are probably general enough).

However, there are some variations that make sense and ought to be considered.

Can you index a multi-dimensional array with a one-dimensional array? In
other words does arraytype[range(10)] refer to the first 10 elements of
the array? I think this would be doable using other more verbose methods,
but this is a simple way to spell this.

Can you index a one-dimensional array with a multi-dimensional array? In
languages which provide this, this usually returns a value with the same
shape as the matrix and the values corresponding to the value in the vector
with that index. This is really nice for image processing - for example
palette remapping. You can get this by applying a function, but that is
usually a lot slower.

What about in between? I don't know of a language that permits these kinds
of shenanigins so I assume we can drop this possibility - undoubtedly now
someone will point out some language where this is a powerful tool...

If array0 is d-dimensional and arrayk is 1-dimensional for  1<=k<=d, does
array0[array1, ..., arrayd] refer to the elements corresponding to the
Cartesian product of array1 ... arrayd? It should. What is the shape
of the result when some of the index arrays have length 1? Should there be
an additional argument to control this? (In S, x[1,1:5] is 1-dimensional with
length 5 and x[1,1:5,drop=F] is 2-dimensional with shape (1, 5). - The reason
you probably want this is that it can be really annoying to reshape the
result which has been collapsed if it was an intermediate expression.)

There are some other approaches to multidimensional indexing and it does
not do to pick one without some consideration of the edge cases, etc..

Presumably the way to go is to make it possible to play with versions of this
so a concensus can emerge. This looks quite feasible in Python.

By the way, once you have powerful indexing, you will not need all the
functions you used to; but there are at least two which will emerge as
really useful now although only marginally useful previously.

1. A function which returns the permutation which would put the elements of
   a 1-d array in order. In APL this is called 'upgrade' and in S it is called
   'order'. A quick illustration of the use of this is computing the ranks
   of elements in a vector - I'll suppose we call the function order.

    def rank(x) :
            return order(order(x))

2. A function which returns the indices into a table where given keys are
   located. In APL this is called 'dyadic iota' and in S it is called 'match'.
   Strictly speaking you can implement this in terms of the order function
   described above - an O((n+m)log(n+m)) solution for searching m keys in a
   table of length n - but usually dyadic iota is implemented in terms of
   hashing which is much faster. Note that you want to locate stuff sprinkled
   around in arrays with this - it isn't clear to me at this point that Python
   dicts do/do not provide an efficient, perhaps more pythonistic alternative.

Later,
Andrew Mullhaupt

_______________
MATRIX-SIG  - SIG on Matrix Math for Python

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