python 实现矩阵类
python上课作业手写一个矩阵类,实现矩阵的加法、减法、矩阵乘法、矩阵数乘、转置、求逆,记录一下实现过程
前置知识
- class类的使用
- 重载运算符
- 矩阵求逆(高斯-约旦消元)
首先定义一个矩阵类
class Matrix(object):
# 矩阵类
def __init__(self, n: int, m: int, matrix = None):
if(matrix):
if(matrix_is(matrix, n, m)):
self.n = n
self.m = m
self.matrix = matrix
return
self.n = n
self.m = m
self.matrix = [[0 for i in range(m)] for j in range(n)]
其中 n , m , m a t r i x n,m,matrix n,m,matrix 分别表示矩阵的行数、列数、矩阵,初始化可以传入矩阵也可以不传入矩阵,不传入矩阵则生成一个 n ∗ m n*m n∗m 的 0 0 0 矩阵
重载加法运算
def __add__(self, other: "Matrix"):
if(self.get_size() != other.get_size()):
print("矩阵大小不匹配")
return
new = Matrix(self.n,self.m)
for i in range(self.n):
for j in range(self.m):
new.matrix[i][j] = self.matrix[i][j] + other.matrix[i][j]
return new
重载减法运算
def __sub__(self, other:"Matrix"):
if(self.get_size() != other.get_size()):
print("矩阵大小不匹配")
return
new = Matrix(self.n,self.m)
for i in range(self.n):
for j in range(self.m):
new.matrix[i][j] = self.matrix[i][j] - other.matrix[i][j]
return new
重载数乘
def __mul__(self, other: int):
new = Matrix(self.n,self.m)
for i in range(self.n):
for j in range(self.m):
new.matrix[i][j] = self.matrix[i][j] * other
return new
矩阵乘法
def dot(self, other: "Matrix"):
if(self.m != other.n):
print("矩阵大小不匹配")
return
new = Matrix(self.n,other.m)
for i in range(self.n):
for j in range(other.m):
sum = 0
for k in range(self.m):
sum += self.matrix[i][k] * other.matrix[k][j]
new.matrix[i][j] = sum
return new
下面是重头戏:矩阵求逆
思路
- 求 A A A 的逆矩阵,把 A A A 和单位阵 E E E 放在一个矩阵里
- 对 A A A 进行加减消元使 A A A 化成单位矩阵
- 此时原来的 E E E 即为逆矩阵
举个栗子
求
[
2
−
1
0
−
1
2
−
1
0
−
1
2
]
\begin{bmatrix}2&-1&0\\-1&2&-1\\0&-1&2\end{bmatrix}
2−10−12−10−12
的逆矩阵
首先
[
2
−
1
0
1
0
0
−
1
2
−
1
0
1
0
0
−
1
2
0
0
1
]
\begin{bmatrix}2&-1&0&1&0&0\\-1&2&-1&0&1&0\\0&-1&2&0&0&1\end{bmatrix}
2−10−12−10−12100010001
将左边矩阵消元可得
[
2
−
1
0
1
0
0
0
3
2
−
1
1
2
1
0
0
0
4
3
1
3
2
3
1
]
\begin{bmatrix}2&-1&0&1&0&0\\0&\frac{3}{2}&-1&\frac{1}{2}&1&0\\0&0&\frac{4}{3}&\frac{1}{3}&\frac{2}{3}&1\end{bmatrix}
200−12300−134121310132001
这是高斯消元可以得到的结果,即上三角矩阵,之后高斯消元开始回代,但约旦消元会消成对角矩阵
[
2
0
0
3
2
1
1
2
0
3
2
0
3
4
3
2
3
4
0
0
4
3
1
3
2
3
1
]
\begin{bmatrix}2&0&0&\frac{3}{2}&1&\frac{1}{2}\\0&\frac{3}{2}&0&\frac{3}{4}&\frac{3}{2}&\frac{3}{4}\\0&0&\frac{4}{3}&\frac{1}{3}&\frac{2}{3}&1\end{bmatrix}
200023000342343311233221431
最后每行除以系数
[
1
0
0
3
4
1
2
1
4
0
1
0
1
2
1
1
2
0
1
1
2
1
4
1
2
3
4
]
\begin{bmatrix}1&0&0&\frac{3}{4}&\frac{1}{2}&\frac{1}{4}\\0&1&0&\frac{1}{2}&1&\frac{1}{2}\\0&1&\frac{1}{2}&\frac{1}{4}&\frac{1}{2}&\frac{3}{4}\end{bmatrix}
100011002143214121121412143
此时右半边即为所求逆矩阵
def inv(self):
if(self.n != self.m):
print("矩阵不可逆")
return
new = Matrix(self.n,self.m)
for i in range(self.n):
new.matrix[i][i] = 1
for i in range(self.n):
k = i
for j in range(i + 1,self.n):
if(abs(self.matrix[j][i]) > abs(self.matrix[k][i])):
k = j
self.matrix[i], self.matrix[k] = self.matrix[k], self.matrix[i]
new.matrix[i], new.matrix[k] = new.matrix[k], new.matrix[i]
if(self.matrix[i][i] == 0):
print("矩阵不可逆")
return
for j in range(0,self.n):
if(j != i):
temp = self.matrix[j][i] / self.matrix[i][i]
for t in range(self.n):
self.matrix[j][t] -= self.matrix[i][t] * temp
new.matrix[j][t] -= new.matrix[i][t] * temp
for i in range(self.n):
for j in range(self.n):
new.matrix[i][j] = new.matrix[i][j] / self.matrix[i][i]
return new
完整代码
def matrix_is(matrix, n: int, m: int):
if(len(matrix) == n):
for i in range(n):
if(len(matrix[i]) != m):
return False
for j in range(len(matrix[i])):
if(type(matrix[i][j]) != int):
return False
else:
return False
return True
class Matrix(object):
# 矩阵类
def __init__(self, n: int, m: int, matrix = None):
if(matrix):
if(matrix_is(matrix, n, m)):
self.n = n
self.m = m
self.matrix = matrix
return
self.n = n
self.m = m
self.matrix = [[0 for i in range(m)] for j in range(n)]
def get_size(self):
return self.n, self.m
def __add__(self, other: "Matrix"):
if(self.get_size() != other.get_size()):
print("矩阵大小不匹配")
return
new = Matrix(self.n,self.m)
for i in range(self.n):
for j in range(self.m):
new.matrix[i][j] = self.matrix[i][j] + other.matrix[i][j]
return new
def __sub__(self, other:"Matrix"):
if(self.get_size() != other.get_size()):
print("矩阵大小不匹配")
return
new = Matrix(self.n,self.m)
for i in range(self.n):
for j in range(self.m):
new.matrix[i][j] = self.matrix[i][j] - other.matrix[i][j]
return new
def __mul__(self, other: int):
new = Matrix(self.n,self.m)
for i in range(self.n):
for j in range(self.m):
new.matrix[i][j] = self.matrix[i][j] * other
return new
def dot(self, other: "Matrix"):
if(self.m != other.n):
print("矩阵大小不匹配")
return
new = Matrix(self.n,other.m)
for i in range(self.n):
for j in range(other.m):
sum = 0
for k in range(self.m):
sum += self.matrix[i][k] * other.matrix[k][j]
new.matrix[i][j] = sum
return new
def inv(self):
if(self.n != self.m):
print("矩阵不可逆")
return
new = Matrix(self.n,self.m)
for i in range(self.n):
new.matrix[i][i] = 1
for i in range(self.n):
k = i
for j in range(i + 1,self.n):
if(abs(self.matrix[j][i]) > abs(self.matrix[k][i])):
k = j
self.matrix[i], self.matrix[k] = self.matrix[k], self.matrix[i]
new.matrix[i], new.matrix[k] = new.matrix[k], new.matrix[i]
if(self.matrix[i][i] == 0):
print("矩阵不可逆")
return
for j in range(0,self.n):
if(j != i):
temp = self.matrix[j][i] / self.matrix[i][i]
for t in range(self.n):
self.matrix[j][t] -= self.matrix[i][t] * temp
new.matrix[j][t] -= new.matrix[i][t] * temp
for i in range(self.n):
for j in range(self.n):
new.matrix[i][j] = new.matrix[i][j] / self.matrix[i][i]
return new
if __name__ == '__main__':
matrix1 = [[2,-1,0],[-1,2,-1],[0,-1,2]]
matrix2 = [[1,1],[1,1]]
matrix3 = [[2,2],[2,2]]
matrix1 = Matrix(3,3,matrix1)
matrix2 = Matrix(2,2,matrix2)
matrix3 = Matrix(2,2,matrix3)
matrix4 = matrix2 + matrix3
for i in range(matrix4.n):
for j in range(matrix4.m):
print(matrix4.matrix[i][j],end = ' ')
print()
print()
matrix5 = matrix2 - matrix3
matrix1 = matrix1.inv()
for i in range(matrix1.n):
for j in range(matrix1.m):
print(matrix1.matrix[i][j],end = ' ')
print()
print()
for i in range(matrix4.n):
for j in range(matrix4.m):
print(matrix4.matrix[i][j],end = ' ')
print()
print()
for i in range(matrix5.n):
for j in range(matrix5.m):
print(matrix5.matrix[i][j],end = ' ')
print()
print()