import random
class Matrix:
"""
Represents a rectangular matrix with n rows and m columns.
"""
def __init__(self, n,m):
"""
Create an n-by-m matrix of zeros.
"""
assert n > 0 and m > 0
self.rows = [[0]*m for i in range(n)]
def dim(self):
return len(self.rows), len(self.rows[0])
def __repr__(self):
return "<Matrix {}>".format(self.rows)
def __eq__(self, other):
return isinstance(other, Matrix) and self.rows == other.rows
def __getitem__(self, ij):
i,j = ij
if isinstance(i, int) and isinstance(j, int):
return self.rows[i][j]
elif isinstance(i, slice) and isinstance(j, slice):
M = Matrix(1,1)
M.rows = [row[j] for row in self.rows[i]]
return M
else:
return NotImplemented
def __setitem__(self, ij, val):
i,j = ij
if isinstance(i,int) and isinstance(j,int):
assert isinstance(val, (int, float, complex))
self.rows[i][j] = val
elif isinstance(i, slice) and isinstance(j,slice):
assert isinstance(val, Matrix)
n,m = val.dim()
s_rows = self.rows[i]
assert n == len(s_rows) and m == len(s_rows[0][j])
for s_row, v_row in zip(s_rows, val.rows):
s_row[j] = v_row
else:
return NotImplemented
def __add__(self, other):
if not isinstance(other, Matrix):
return NotImplemented
assert self.dim() == other.dim()
n,m = self.dim()
M = Matrix(n,m)
for i in range(n):
for j in range(m):
M[i,j] = self[i,j] + other[i,j]
return M
def __sub__(self, other):
if not isinstance(other, Matrix):
return NotImplemented
assert self.dim() == other.dim()
n,m = self.dim()
M = Matrix(n,m)
for i in range(n):
for j in range(m):
M[i,j] = self[i,j] - other[i,j]
return M
def __neg__(self):
n,m = self.dim()
return Matrix(n,m) - self
def __mul__(self, other):
if isinstance(other, Matrix):
return self.multiply_by_matrix(other)
elif isinstance(other, (int, float, complex)):
return self.multiply_by_scalar(other)
else:
return NotImplemented
__rmul__ = __mul__
def multiply_by_scalar(self, val):
n,m = self.dim()
M = Matrix(n,m)
for i in range(n):
for j in range(m):
M[i,j] = self[i,j] * val
return M
def multiply_by_matrix(self, other):
assert isinstance(other, Matrix)
n,m = self.dim()
n2,m2 = other.dim()
assert m == n2
M = Matrix(n,m2)
for i in range(n):
for j in range(m2):
M[i,j] = sum(self[i,k] * other[k,j] for k in range(m))
return M