Reputation: 165
I want to overload the multiplication operator in Python. What I exactly want to do is to multiply a 4x4 matrix with a 4D vector.
import math
class Vec4():
def __init__(self, x = 0, y = 0, z = 0, w = 0):
"""Constructor for Vec4
DO NOT MODIFY THIS METHOD"""
self.values = [x,y,z,w]
def __str__(self):
"""Returns the vector as a string representation
DO NOT MODIFY THIS METHOD"""
toReturn = ''
if self is None: return '0.00 0.00 0.00 0.00'
for c in range(0,4):
toReturn += "%.2f" % self.values[c]
if c != 3:
toReturn += ' '
return toReturn
class Matrix4():
def __init__(self, row1=None, row2=None, row3=None, row4=None):
"""Constructor for Matrix4
DO NOT MODIFY THIS METHOD"""
if row1 is None: row1 = Vec4()
if row2 is None: row2 = Vec4()
if row3 is None: row3 = Vec4()
if row4 is None: row4 = Vec4()
self.m_values = [row1,row2,row3,row4]
def __str__(self):
"""Returns a string representation of the matrix
DO NOT MODIFY THIS METHOD"""
toReturn = ''
if self is None: return '0.00 0.00 0.00 0.00\n0.00 0.00 0.00 0.00\n0.00 0.00 0.00 0.00\n0.00 0.00 0.00 0.00'
for r in range(0,4):
for c in range(0,4):
toReturn += "%.2f" % self.m_values[r].values[c]
if c != 3:
toReturn += ' '
toReturn += '\n'
return toReturn
def __mul__(self, v):
"""Element wise multiplication of self by vector v
Returns the result as a new vector"""
x = self.m_values[0][0]*self.values[0]+self.m_values[0][1]*self.values[1]+self.m_values[0][2]*self.values[2]+self.m_values[0][3]*self.values[3]
y = self.m_values[1][0]*self.values[0]+self.m_values[1][1]*self.values[1]+self.m_values[1][2]*self.values[2]+self.m_values[1][3]*self.values[3]
z = self.m_values[2][0]*self.values[0]+self.m_values[2][1]*self.values[1]+self.m_values[2][2]*self.values[2]+self.m_values[3][3]*self.values[3]
w = self.m_values[3][0]*self.values[0]+self.m_values[3][1]*self.values[1]+self.m_values[3][2]*self.values[2]+self.m_values[3][3]*self.values[3]
return Vec4(x,y,z,w)
As you can see, I have tried implement it. It doesn't work for me. The result should be a vector.
A = Matrix4(Vec4(1, 0, 0, 0),
Vec4(0, 1, 0, 0),
Vec4(0, 0, 1, 0),
Vec4(0, 0, 0, 1))
>>> V = Vec4(1,2,3,4)
>>> print(A*V)
Result should be "1.00 2.00 3.00 4.00".
But it causes an error:
Traceback (most recent call last):
File "<pyshell#27>", line 1, in <module>
print(A*V)
File "C:\Users\xxx\Downloads\Download-Stuff\Gmail\TransformMatrix.py", line 45, in __mul__
x = self.m_values[0].values[0]*self.values[0]+self.m_values[0].values[1]*self.values[1]+self.m_values[0].values[2]*self.values[2]+self.m_values[0].values[3]*self.values[3]
AttributeError: 'Matrix4' object has no attribute 'values'
What should I do? What am I doing wrong? Somebody told me to use nested loops, but I am not familiar with it.
Please help me!
Thanks in advance!
Upvotes: 0
Views: 274
Reputation: 365
You have values
in Vec4
and m_values
in Matrix4
. When you refer to self
from within the Matrix4
class this is an instance of Matrix4
that you are referring to. From within methods in that class, you either need to refer to self.m_values
to get the array of Vec4
or self.m_values[i].values
to access the contents of the Vec4
.
You might find it easier if you override the index operator for both. e.g., for Vec4
, include in the class def:
def __getitem__(self, i):
return self.values[i]
def __setitem__(self, i, v):
self.values[i] = v
When you get down to the detail of how to do it, I recommend checking out something like: https://mathoverflow.net/questions/34173/fast-matrix-multiplication
Note that numpy provides efficient matrix multiplication and may save you some trouble.
Upvotes: 1