[MATRIX-SIG] FancyArray

Timothy A. Hochberg hochberg@wwa.com
Fri, 29 Aug 1997 17:15:11 -0500 (CDT)

On Fri, 29 Aug 1997, Janko Hauser wrote:

> Hi, I haven't played with it yet, but here is a solution to the
> reshape problem.
> First, reshape does function here, but returns not an UserArray
> object. 
> >>> a
> UserArray([0, 1, 2, 3, 4, 5, 6, 7, 8])
> >>> reshape(a,(3,3))
> array([[0, 1, 2],
>        [3, 4, 5],
>        [6, 7, 8]])
> But according to the docs of reshape this is a behavior, which can be
> expected in some sense, because reshape returns a copy. 

Yes, but I'd still argue that the natural thing to get back is a copy of
the same type as what you put in. Reshaping a UserArray should really
return a UserArray.

Or maybe not. It doesn't bother me that reshaping a tuple gives me an
array. Hmmmm.... Now I'm thinking you might want both. Numeric.reshape
which has the current behaviour and UserArray.reshape which preserves the
class of the reshaped object.

> reshape is
> also not an builtin function, so I see no way to deal with it in the
> class itself. 

The way to deal with this is to shadow the functions from multiarray with
python functions in order to "add extra intelligence to the basic C
functions" (from Numeric.py). In order to fix reshape, for instance,  one
could use something like:

def reshape(a, shape):
	if type(a) === InstanceType:
	   	return a.__class__(reshape(a,shape))
	 	return reshape(a, shape)

A bunch of these shadow functions would need to be constructed, but
they're all essentially the same. As I mentioned, UserArray would probably
be a good place for them.

> But the docs emphasize, that one should use  
> a.shape=(3,3) for inplace reshaping. This can be handled by the class
> with following method:
>     def __setattr__(self,att,value):
> 	if att == 'shape':
> 	    self.__dict__['shape']=value
> 	    self.array.shape=value
> 	else:
> 	    self.__dict__[att]=value

This fix looks good for UserArray. And I could do something similar
for FancyArray. To be honest, I'd completely forgotten that setting shape
reshaped the arrray. I think I would raise an exception when attributes
other than shape get set though.

> >>> c=myUserArray.UserArray(range(9))
> >>> c
> UserArray
> [0 1 2 3 4 5 6 7 8]
> >>> c.shape=(3,3)
> >>> c
> UserArray
> [[0 1 2]
>  [3 4 5]
>  [6 7 8]]
> >>> 
> If there are some more drawbacks or wishful things for the UserArray
> class, please mention it. I see many useful way to use UserArray, so
> this class should be as powerful as possible.

Well I haven't used UserArray much yet, so my list is pretty short.

* Write shadow functions (I just thought of a clever way to do that.)

* Figure out what __float__ is doing there. As far as I can tell float
never suceeds for UserArrays or Normal arrays, so what is it doing there?

* The indexing on UserArray isn't quite right - sometimes is returns a
copy when it should be returning a reference. This is fixed in FancyArray

Has anyone used UserArray much? Have you had any problems with it?
Successes? I'm mostly just curious...


|Tim Hochberg            Research Assistant      |
|hochberg <at> wwa.com   University of Illinois  |
|                        Electrical Engineering  |

MATRIX-SIG  - SIG on Matrix Math for Python

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