On Sat, Jan 31, 2009 at 10:30, Sebastian Walter email@example.com wrote:
Wouldn't it be nice to have numpy a little more generic? All that would be needed was a little check of the arguments.
If I do: numpy.trace(4) shouldn't numpy be smart enough to regard the 4 as a 1x1 array?
Why? It's not a 1x1 array. It's a scalar. If you want a 1x1 array, give it a 1x1 array.
Yes, numpy.sin() operates on scalars in addition to arrays.
and if x = my_class(4)
wouldn't it be nice if
numpy.trace(x) would call x.trace() ?
Wouldn't it be nice if numpy worked a little more consistent. Is this worth a ticket? Or am I missing something here?
numpy.sin() is a ufunc. Unary ufuncs will call the method of the same name on objects in an object array (or the scalar itself if given an object scalar). For example:
In : class MyClass(object): ...: def __init__(self, x): ...: self.x = x ...: def __repr__(self): ...: return 'MyClass(%r)' % (self.x,) ...: def sin(self): ...: return MyClass(self.x+1) ...: ...:
In : sin(MyClass(4)) Out: MyClass(5)
In : sin([MyClass(4), MyClass(5)]) Out: array([MyClass(5), MyClass(6)], dtype=object)
You'll notice that numpy.sin() does not try to call the list.sin() method when given the list. It interprets it as an object array, and calls the MyClass.sin() method on each of the elements.
numpy.trace() is not an unary ufunc. It's just a function that operates on (N>=2)-D arrays. You simply couldn't apply the same rules as numpy.sin(). Otherwise, it would try to call the .trace() method on each of the objects in your container, and obviously you can't implement trace that way.
Having numpy.trace(x) simply call x.trace() would not be making numpy more consistent.
Now, that said, the implementation of numpy.trace(x, *args) is actually simply asarray(x).trace(*args). That should probably be asanyarray(x) in order to allow ndarray subclasses. But this only works because ndarray.trace() already exists. Making every function in numpy check for a method first is just not going to happen.