如何在Python中使用*运算符执行矩阵向量乘法?

时间:2019-06-09 16:51:32

标签: python-3.x operator-overloading matrix-multiplication multiplication vector-multiplication

我想在Python中重载乘法运算符。 我真正想做的是将4x4矩阵与 4D向量。

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)

如您所见,我已经尝试实现它。它对我不起作用。 结果应该是向量。

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)

结果应为“ 1.00 2.00 3.00 4.00”。

但这会导致错误:

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'

我该怎么办?我究竟做错了什么? 有人告诉我使用嵌套循环,但是我对此并不熟悉。

请帮助我!

谢谢!

1 个答案:

答案 0 :(得分:1)

您在values中有Vec4,在m_values中有Matrix4。当您从self类中引用Matrix4时,这就是您要引用的Matrix4的实例。从该类的方法中,您需要引用self.m_values来获取Vec4的数组或self.m_values[i].values来访问Vec4的内容。

如果您同时覆盖两个索引操作符,则可能会更容易。例如,对于Vec4,请在def类中添加

def __getitem__(self, i):
    return self.values[i]
def __setitem__(self, i, v):
    self.values[i] = v

当您详细了解操作方法时,我建议您查看以下内容:https://mathoverflow.net/questions/34173/fast-matrix-multiplication

请注意,numpy提供了有效的矩阵乘法,可以为您节省一些麻烦。