A student was having difficulty using a class I had created to represent transfer function objects. I discovered that they were actually placing these objects in a numpy.matrix and trying to multiply things by one another. To my surprise, this actually worked! I had to investigate. The code here is all in Python.
I created a quick tracing object which just kind of logs the operations that are done on it as an expression:
class operation:
def __init__(self, name):
self.string = name
def __repr__(self):
return self.string
def __str__(self):
return self.string
def __add__(self, other):
return operation("({} + {})".format(str(self), str(other)))
def __mul__(self, other):
return operation("{}*{}".format(str(self), str(other)))
def __radd__(self, other):
return operation("({} + {})".format(str(other), str(self)))
def __rmul__(self, other):
return operation("{}*{}".format(str(other), str(self)))
Now I can do some interesting stuff:
In []: a*b
Out[]: a*b
In []: a + b
Out[]: (a + b)
Ok, but what about matrix multiplication?
import numpy as np In []: tracer = np.matrix([[a, b, c], [d, e, f], [g, h, i]]) In []: tracer*tracer Out[]: matrix([[((a*a + b*d) + c*g), ((a*b + b*e) + c*h), ((a*c + b*f) + c*i)], [((d*a + e*d) + f*g), ((d*b + e*e) + f*h), ((d*c + e*f) + f*i)], [((g*a + h*d) + i*g), ((g*b + h*e) + i*h), ((g*c + h*f) + i*i)]], dtype=object)
That kind of blew me away! It means I can probably get away with a whole lot less code than I thought I would need to implement my own matrix-like objects.
In addition, it appears that some numpy functions will attempt to call corresponding functions in the object they act on:
In []: np.exp(a) --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) in () ----> 1 np.exp(a) AttributeError: exp
This error shows that np.exp is trying to access the exp attribute on this object. Let’s extend our object with an exp method like this:
def exp(self):
return operation("e^({})".format(self))
Now (after re-instantiating a-i from above), we have
In []: np.exp(a) Out[]: e^(a)
This is going to be super useful.
Leave a Reply