[Numpy-discussion] subclassing matrix
Fri Jan 11 22:59:55 CST 2008
On Jan 11, 2008, Colin J. Williams wrote:
> You make a good case that it's good not
> to need to ponder what sort of
> vector you are dealing with.
> My guess is that the answer to your
> question is "no" but I would need to
> play with your code to see that. My
> feeling is that, at the bottom of
> the __new__ module, the returned object
> should be an instance of the
> Vector class.
> It's been a while since I've worked with
> numpy and so I'll look at it
> and hope that someone gives you a
> definitive answer before I sort it out.
> Colin W.
Well, let's say that I get rid of that class promotion line. When the
input object to the constructor is a string or a tuple
such as Vector('1 2 3') or Vector([1,2,3]), then the returned object
is always an instance of Vector. However, when the input object is a
numpy.matrix instance, the returned object remains a numpy.matrix
instance! So by doing that little hack, I promote it to Vector.
It seems that I have solved only half of my problem here. The other
half rears its ugly head when I perform operations between instances
of numpy.matrix and Vector. The result ends up returning a matrix,
which is bad because it has no knowledge of any custom Vector
attributes. Here's a simple case:
u = Vector('1 2 3') #Vector instance
P = numpy.mat(numpy.eye(3)) #matrix instance
u_new = P*u #matrix instance, not desirable!
u_new_as_Vector = Vector(P*u) #Vector instance
I'd rather not have to remember to re-instantiate the result in client
code. I think I understand why this is happening - the code in
numpy.core.defmatrix.matrix.__mul__ goes like this:
def __mul__(self, other):
if isinstance(other,(N.ndarray, list, tuple)) :
# This promotes 1-D vectors to row vectors
return N.dot(self, asmatrix(other))
if N.isscalar(other) or not hasattr(other, '__rmul__') :
return N.dot(self, other)
It passes the first condition: isinstance(other,(N.ndarray)) is true;
and so the return value becomes a matrix.
Do I also need to override a few overloaded methods like __mul__,
__rmul__, etc. to make this work?
More information about the Numpy-discussion