要求完成课堂上讲的关于矩阵分解的LU、QR(Gram-Schmidt)、Orthogonal Reduction (Householder reduction 和Givens reduction)和 URV程序实现,要求如下:
1、一个综合程序,根据选择参数的不同,实现不同的矩阵分解;在此基础上,实现Ax=b方程组的求解,以及计算A的行列式;
2、可以用matlab、Python等编写程序,需附上简单的程序说明,比如参数代表什么意思,输入什么,输出什么等等,附上相应的例子;
3、一定是可执行文件,例如 .m文件等,不能是word或者txt文档。附上源代码,不能为直接调用matlab等函数库;
import numpy as np
import copy
#LU分解函数
def LU_Factorization(A):
#输入:N * N的方阵A
#输出:对角元全为1的下三角矩阵L与对角元素不为0的上三角元素U
A = np.array(A)
B = copy.deepcopy(A)
n = B.shape[0]
L = np.identity(n, dtype=int)
U = np.zeros_like(A)
for i in range(n):
for j in range(i+1, n):
L[j][i] = B[j][i] / B[i][i]
B[j] = B[j] - L[j][i]*B[i]
U[i] = B[i]
return L, U
#LU分解函数
def LU_Factorization2(A):
#输入:N * N的方阵A
#输出:对角元全为1的下三角矩阵L与对角元素不为0的上三角元素U
n = len(A[0])
L = [[0] * n for i in range(n)]
U = [[0] * n for i in range(n)]
B = copy.deepcopy(A)
for i in range(n):
L[i][i] = 1
U[i][i] = B[i][i]
for j in range(i+1, n):
L[j][i] = B[j][i] / B[i][i]
for k in range(n):
B[j][k] = B[j][k] - L[j][i]*B[i][k]
U[i][j] = B[i][j]
return L, U
#QR分解的函数
def QR_Factorization(A):
#输入:N * N的方阵A
#方法:使用Gram-Schmidt正交化方法 A = QR
#输出:单位正交矩阵Q与对角元素不为0的上三角元素R
A = np.array(A, dtype=float)
n = A.shape[0]
Q = copy.deepcopy(A)
R = np.zeros_like(A)
for i in range(n):
for j in range(i):
temp = np.sum(Q[:, j]*A[:, i])
R[j][i] = temp
Q[:, i] -= temp*Q[:, j]
num = 0
for k in range(n):
num += Q[k][i]**2
num = np.sqrt(num)
Q[:, i] = Q[:, i] / num
R[i][i] = num
# R[i][i] = np.linalg.norm(Q[:, i])
# Q[:, i] = Q[:, i] / np.linalg.norm(Q[:, i])
return Q, R
#利用Householder reduction进行Orthogonal Reduction
def HouseHolder(A):
#输入:N * N的方阵A
#方法:使用Householder变换正交化方法,PA=T
#输出:P为正交矩阵 T为上三角矩阵
A = np.mat(A, dtype=float)
n = A.shape[0]
T = copy.deepcopy(A)
P = np.eye(n)
for i in range(n-1):
sub_A = T[i:, i:]
R = np.eye(n)
e = np.zeros_like(sub_A[:, 0])
e[0] = 1.0
u = sub_A[:, 0] - np.linalg.norm(sub_A[:, 0]) * e
R_ = np.eye((n-i)) - 2*u.dot(u.T) / (u.T.dot(u))
R[i:, i:] = R_
T = R.dot(T)
P = R.dot(P)
return P, T
#利用Givens reduction进行Orthogonal Reduction
def Givens(A):
#输入:N * N的方阵A
#方法:使用Givens变换正交化方法,PA=T
#输出:P为正交矩阵 T为上三角矩阵
A = np.array(A, dtype=float)
n = A.shape[0]
T = copy.deepcopy(A)
P = np.eye(n)
for i in range(n):
for j in range(i+1, n):
P_ = np.eye(n)
c, s = T[i, i], T[j, i]
c, s = c/np.sqrt(c**2+s**2), s/np.sqrt(c**2+s**2)
P_[i, i] = c
P_[i, j] = s
P_[j, i] = -s
P_[j, j] = c
P = P_.dot(P)
T = P_.dot(T)
return P, T
#利用URV分解
def URV_Factorization(A):
#输入:N * N的方阵A
#方法:
# U的前r列为R(A)的标准正交基
# U的后m-r列为N(A.T)的标准正交基
# V的前r列为R(A.T)的标准正交基
# V的后n-r列为N(A)的标准正交基
# 可以利用Householder或者Givens reduction方法来获得标准正交基P满足PA=(B|0).T
# 对B.T再使用一次Householder或者Givens reduction方法得到标准正交基Q和非奇异上三角矩阵T
#输出:P为正交矩阵 T为上三角矩阵
A = np.array(A, dtype=float)
U, B = HouseHolder(A)
rank_A = np.linalg.matrix_rank(A)
P = B[:rank_A, :]
Q, T = HouseHolder(B.T)
rank_B = np.linalg.matrix_rank(B.T)
V = Q.T
T = T[:rank_B, :]
R = np.zeros_like(A, dtype=float)
R[: rank_B, :rank_B] = T.T
U = P
return U, R, V
if __name__ == "__main__":
'''该程序将会对给定的矩阵A进行LU、QR(Gram-Schmidt)
Orthogonal Reduction (Householder reduction 和Givens reduction)和URV分解
运行程序时需要numpy的环境 如果未安装则需要在python环境中进行pip install numpy的操作
运行时需要输入1-5的数字进行分解的选择,输入其他字符程序无法运行
输入完毕后可以输入1或0自己选择是使用程序给定的样例A与b进行运行或者自己输入A和b进行运算
最后会对矩阵A进行相应的分解操作获得分解后的矩阵并对Ax=b进行求解同时计算出A的行列式
'''
num = int(input('请输入1-5来选择进行何种分解\n'
'1:LU\n'
'2:QR\n'
'3:HouseHolder\n'
'4:Givens\n'
'5:URV\n'))
if num not in [i for i in range(1, 6)]:
print('请输入1-5的数字')
exit()
print('将在给定的A矩阵进行相应的分解操作,并求得AX=b的解与A的行列式')
mode = ['LU', 'QR', 'HouseHolder', 'Givens', 'URV'][num-1]
flag = int(input('输入1将使用程序给定的A和b\n'
'输入0用户可以自己输入一个矩阵A和b\n'))
if flag == 1:
b = np.array([12, 24, 12], dtype=float)
if mode == 'LU':
A = [[2, 2, 2],
[4, 7, 7],
[6, 18, 22]]
print("A矩阵:\n", A)
L, U = LU_Factorization(A)
print("矩阵A经过LU分解后得到的结果:")
print("L矩阵:\n", L)
print("U矩阵:\n", U)
n = len(A[0])
x = np.zeros_like(A[0])
y = np.zeros_like(A[0])
for i in range(n):
y[i] = b[i]
for j in range(i):
y[i] = y[i] - y[j] * L[i][j]
for i in range(n):
x[n - i - 1] = y[n - i - 1]
for j in range(i):
x[n - i - 1] = x[n - i - 1] - x[n - j - 1] * U[n - i - 1][n - j - 1]
x[n - i - 1] /= U[n - i - 1][n - i - 1]
print("AX=B的解如下:")
print("X:", x)
det_L, det_U = 1, 1
for i in range(n):
det_L = det_L * L[i][i]
det_U = det_U * U[i][i]
det_A = det_L * det_U
print("A的行列式为:", det_A)
elif mode == 'QR':
A = [[0, -20, -14],
[3, 27, -4],
[4, 11, -2]]
print("A矩阵:\n", A)
Q, R = QR_Factorization(A)
print("矩阵A经过QR分解后得到的结果:")
print("Q矩阵:\n", Q)
print("R矩阵:\n", R)
n = len(A[0])
x = np.zeros_like(A[0])
b = Q.dot(b.T)
for i in range(n):
x[i] = b[i]
for j in range(i):
x[i] = x[i] - x[j] * R[i][j]
print("AX=B的解如下:")
print("X:", x)
det_R = 1
for i in range(n):
det_R = det_R * R[i][i]
det_A = det_R
print("A的行列式为:", det_A)
elif mode == 'HouseHolder':
A = [[0, -20, -14],
[3, 27, -4],
[4, 11, -2]]
print("A矩阵:\n", A)
P, T = HouseHolder(A)
print("矩阵A经过HousHolder变换后得到的结果:")
print("P矩阵:\n", P)
print("T矩阵:\n", T)
n = len(A[0])
x = np.zeros_like(A[0])
b = P.dot(b.T)
for i in range(n):
x[i] = b[i]
for j in range(i):
x[i] = x[i] - x[j] * T[i, j]
print("AX=B的解如下:")
print("X:", x)
det_T = 1
for i in range(n):
det_T = det_T * T[i, i]
det_A = det_T
print("A的行列式为:", det_A)
elif mode == 'Givens':
A = [[0, -20, -14],
[3, 27, -4],
[4, 11, -2]]
P, T = Givens(A)
print("A矩阵:\n", A)
print("矩阵A经过Givens变换后得到的结果:")
print("P矩阵:\n", P)
print("T矩阵:\n", T)
n = len(A[0])
x = np.zeros_like(A[0])
b = P.dot(b.T)
for i in range(n):
x[i] = b[i]
for j in range(i):
x[i] = x[i] - x[j] * T[i, j]
print("AX=B的解如下:")
print("X:", x)
det_T = 1
for i in range(n):
det_T = det_T * T[i, i]
det_A = det_T
print("A的行列式为:", det_A)
elif mode == 'URV':
A = [[0, -20, -14],
[3, 27, -4],
[4, 11, -2]]
U, R, V = URV_Factorization(A)
n = len(A[0])
x = np.zeros_like(A[0])
y = np.zeros_like(A[0])
b = U.dot(b.T)
for i in range(n):
y[i] = b[0, i]
for j in range(i):
y[i] = y[i] - y[j] * R[i, j]
print(y)
x = V.dot(y.T)
print("AX=B的解如下:")
print("X:", x)
det_A = 1
for i in range(n):
if R[i, i] == 0:
break
det_A = det_A * R[i, i]
print("A的行列式为:", det_A)
else:
print('无法选择其他方法!')
elif flag == 0:
n = int(input('请输入矩阵A的大小\n'))
b_input = input('请输入'+str(n)+'个数\n')
A_input = input('请输入'+str(n*n)+'个数\n')
b = [int(temp) for temp in b_input.split(' ')]
b = np.array(b, dtype=float)
A = [int(temp) for temp in A_input.split(' ')]
A = np.array(A, dtype=float)
A = A.reshape(n, n)
if mode == 'LU':
print("A矩阵:\n", A)
L, U = LU_Factorization(A)
print("矩阵A经过LU分解后得到的结果:")
print("L矩阵:\n", L)
print("U矩阵:\n", U)
n = len(A[0])
x = np.zeros_like(A[0])
y = np.zeros_like(A[0])
for i in range(n):
y[i] = b[i]
for j in range(i):
y[i] = y[i] - y[j] * L[i][j]
for i in range(n):
x[n - i - 1] = y[n - i - 1]
for j in range(i):
x[n - i - 1] = x[n - i - 1] - x[n - j - 1] * U[n - i - 1][n - j - 1]
x[n - i - 1] /= U[n - i - 1][n - i - 1]
print("AX=B的解如下:")
print("X:", x)
det_L, det_U = 1, 1
for i in range(n):
det_L = det_L * L[i][i]
det_U = det_U * U[i][i]
det_A = det_L * det_U
print("A的行列式为:", det_A)
elif mode == 'QR':
A = [[0, -20, -14],
[3, 27, -4],
[4, 11, -2]]
print("A矩阵:\n", A)
Q, R = QR_Factorization(A)
print("矩阵A经过QR分解后得到的结果:")
print("Q矩阵:\n", Q)
print("R矩阵:\n", R)
n = len(A[0])
x = np.zeros_like(A[0])
b = Q.dot(b.T)
for i in range(n):
x[i] = b[i]
for j in range(i):
x[i] = x[i] - x[j] * R[i][j]
print("AX=B的解如下:")
print("X:", x)
det_R = 1
for i in range(n):
det_R = det_R * R[i][i]
det_A = det_R
print("A的行列式为:", det_A)
elif mode == 'HouseHolder':
A = [[0, -20, -14],
[3, 27, -4],
[4, 11, -2]]
print("A矩阵:\n", A)
P, T = HouseHolder(A)
print("矩阵A经过HousHolder变换后得到的结果:")
print("P矩阵:\n", P)
print("T矩阵:\n", T)
n = len(A[0])
x = np.zeros_like(A[0])
b = P.dot(b.T)
for i in range(n):
x[i] = b[i]
for j in range(i):
x[i] = x[i] - x[j] * T[i, j]
print("AX=B的解如下:")
print("X:", x)
det_T = 1
for i in range(n):
det_T = det_T * T[i, i]
det_A = det_T
print("A的行列式为:", det_A)
elif mode == 'Givens':
A = [[0, -20, -14],
[3, 27, -4],
[4, 11, -2]]
P, T = Givens(A)
print("A矩阵:\n", A)
print("矩阵A经过Givens变换后得到的结果:")
print("P矩阵:\n", P)
print("T矩阵:\n", T)
n = len(A[0])
x = np.zeros_like(A[0])
b = P.dot(b.T)
for i in range(n):
x[i] = b[i]
for j in range(i):
x[i] = x[i] - x[j] * T[i, j]
print("AX=B的解如下:")
print("X:", x)
det_T = 1
for i in range(n):
det_T = det_T * T[i, i]
det_A = det_T
print("A的行列式为:", det_A)
elif mode == 'URV':
A = [[0, -20, -14],
[3, 27, -4],
[4, 11, -2]]
U, R, V = URV_Factorization(A)
n = len(A[0])
x = np.zeros_like(A[0])
y = np.zeros_like(A[0])
b = U.dot(b.T)
for i in range(n):
y[i] = b[0, i]
for j in range(i):
y[i] = y[i] - y[j] * R[i, j]
print(y)
x = V.dot(y.T)
print("AX=B的解如下:")
print("X:", x)
det_A = 1
for i in range(n):
if R[i, i] == 0:
break
det_A = det_A * R[i, i]
print("A的行列式为:", det_A)
else:
print('无法选择其他方法!')
else:
print("只能输入1和0")