user2379123
user2379123

Reputation: 165

How can I perform matrix-vector-multiplication using the * operator in Python?

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

Answers (1)

James Brusey
James Brusey

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

Related Questions