После консультации https://en.wikipedia.org/wiki/Matrix_multiplication, я сначала реализовал dot_product()
и попытался получить более общее решение:
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 get_column(self, j):
return [vec.values[j] for vec in self.m_values]
def get_row(self, i):
return self.m_values[i].values
def dot_product(self, m, i, j):
return sum([x * y for x, y in zip(self.get_row(i), \
m.get_column(j))])
def shape(self):
return len(self.m_values), len(self.m_values[0].values)
def __mul__(self, mat):
# m = len(self.m_values[0].values)
n = self.shape()[0]
p = mat.shape()[1]
return Matrix4(*[Vec4(*[self.dot_product(mat, i, j) for j in range(p)]) for i in range(n)])
A = Matrix4(Vec4(1, 0, 0, 0),
Vec4(0, 1, 0, 0),
Vec4(0, 0, 1, 0),
Vec4(0, 0, 0, 1))
B = Matrix4(Vec4(1,2,3,4),
Vec4(1,2,3,4),
Vec4(1,2,3,4),
Vec4(1,2,3,4))
print(A * B)
# 1.00 2.00 3.00 4.00
# 1.00 2.00 3.00 4.00
# 1.00 2.00 3.00 4.00
# 1.00 2.00 3.00 4.00
Общее решение
Для матриц произвольного размера.И с __repr__()
, так что не всегда нужно печатать print()
, чтобы увидеть строковое представление.
class Vec4():
def __init__(self, *args):
"""Generalized constructor for Vec4"""
self.values = args
def __str__(self):
"""Returns the vector as a string representation"""
if self.values == []:
return "Empy Vector of class Vec4"
else:
return ' '.join(["{0:.2f}".format(c) for c in self.values])
def __repr__(self):
return self.__str__()
class Matrix4():
def __init__(self, *args):
"""Constructor for Matrix4"""
self.values = args
def __str__(self):
"""Returns a string representation of the matrix"""
if self.values == []:
return "Empty Matrix of class Matrix4"
else:
return '\n'.join([str(v) for v in self.values])
def __repr__(self):
return self.__str__()
def get_column(self, j):
return [vec.values[j] for vec in self.values]
def get_row(self, i):
return self.values[i].values
def dot_product(self, m, i, j):
return sum([x * y for x, y in zip(self.get_row(i), \
m.get_column(j))])
def shape(self):
return len(self.values), len(self.values[0].values)
def __mul__(self, mat):
# m = len(self.values[0].values)
n = self.shape()[0]
p = mat.shape()[1]
return Matrix4(*[Vec4(*[self.dot_product(mat, i, j) for j in range(p)]) for i in range(n)])