一、实验目的
1. 借助矩阵理论进一步对消去法作分析,建立高斯消去法与矩阵因式分解的关系。
2. 会矩阵的紧凑格式的LU分解法、对称阵的分解法。
3. 会直接三角分解法线性方程组;会选列主元三角分解法解线性方程组。
4. 将第2个程序改为选列主元三角分解法解方程组的程序。
二、实验原理
Gauss-Jordan消元法;初等变换。
三、实验程序
四、实验内容
1. 求如下4阶矩阵的LU分解。
2. 用直接三角分解法,求一个4元线性方程组的解。
五、实验程序
• LU分解
1 from numpy import* 2 3 def decA(A): 4 A=array(A) 5 n=len(A) 6 L=zeros((n,n)) 7 U=zeros((n,n)) 8 U[0,:]=A[0,:] 9 L[:,0]=A[:,0]/U[0,0] 10 for i in range(n): 11 L[i,i]=1 12 for row in range(n-1): 13 flag=1 14 for col in range(row,n-1): 15 U[row+1,col+1]=A[row+1,col+1]-dot(L[row+1,:],U[:,col+1])#计算U矩阵非零元素 16 if (row+2<n)&(flag==1):#计算L矩阵非零元素 17 for k in range(1,row+2): 18 L[row+2,k]=(A[row+2,k]-dot(L[row+2,:],U[:,k]))/U[k,k] 19 flag+=1 20 print("U = ",U) 21 print("L = ",L) 22 23 def main(): 24 A=[[10, 7, 8, 7], 25 [7, 5, 6, 5], 26 [8, 6, 10, 9], 27 [7, 5, 9, 10]] 28 decA(A) 29 main()
运行结果:
• 直接三角分解法
1 import numpy as np 2 3 input001= list(map(int, input().split())) 4 n = int(input001[0]) 5 6 a = np.zeros((n,n),dtype = np.double) 7 for r in range(n): 8 a[r,:] = np.array(input().split(),dtype = np.double) 9 10 b = np.zeros((n,1),dtype= np.double) 11 for r in range(n): 12 b[r] = np.array(input(),dtype=np.double) 13 14 15 for i in range(n): 16 max = i#换行标记符 17 for i1 in range(i,n): 18 if(a[max][i]<a[i1][i]): 19 max = i1 20 if(max == i): 21 for k in range(i,n-1): 22 x = a[k+1][i]/a[i][i] 23 a[k+1][i] = x 24 for m in range (i+1,n): 25 a[k+1][m] = a[k+1][m] - x*a[i][m] 26 else: 27 for i2 in range (i,n): 28 temp = a[i][i2] 29 a[i][i2] = a[max][i2] 30 a[max][i2] = temp 31 temp = b[max][0] 32 b[max][0] = b[i][0] 33 b[i][0] = temp 34 for i3 in range(0,i): 35 temp = a[i][i3] 36 a[i][i3] = a[max][i3] 37 a[max][i3] = temp 38 for k in range(i,n-1): 39 x = a[k+1][i]/a[i][i] 40 #a1[k+1][i] = x 41 a[k+1][i] = x 42 for m in range (i+1,n): 43 a[k+1][m] = a[k+1][m] - x*a[i][m] 44 print(a) 45 46 47 for i in range (1,n): 48 x = 0 49 for i1 in range (0,i): 50 x = a[i][i1]*b[i1][0] + x 51 b[i] = (b[i][0] - x) 52 53 b[n-1][0] = b[n-1][0]/a[n-1][n-1] 54 for i in range(n-2,-1,-1): 55 x = 0 56 for i1 in range (i,n-1): 57 x = x + a[i][i1+1]*b[i1+1][0] 58 b[i][0] = (b[i][0]-x)/a[i][i] 59 print(b)
运行结果:
• 矩阵的三角分解要求矩阵的各阶顺序主子式均不为零,故在程序中加入对矩阵顺序主子式的判别,再进行LU分解
1 import numpy as np 2 import pandas as pd 3 4 #np.random.seed(2) 5 def det(A): #求A的行列式 6 if len(A) <= 0: 7 return None 8 elif len(A) == 1: 9 return A[0][0] 10 else: 11 s = 0 12 for i in range(len(A)): 13 n = [[row[a] for a in range(len(A)) if a != i] for row in A[1:]] # 这里生成余子式 14 s += A[0][i] * det(n) * (-1) ** (i ) 15 return s 16 17 def Master_Sequential(A,n): #判断A的k阶顺序主子式是否非零,非零满足LU分解的条件 18 for i in range(0,n): 19 Master = np.zeros([i+1,i+1]) 20 for row in range(0,i+1): 21 for a in range(0,i+1): 22 Master[row][a]=A[row][a] 23 if det(Master)==0: 24 done=False 25 return done 26 27 28 def LU_decomposition(A): 29 n=len(A[0]) 30 L = np.zeros([n,n]) 31 U = np.zeros([n, n]) 32 for i in range(n): 33 L[i][i]=1 34 if i==0: 35 U[0][0] = A[0][0] 36 for j in range(1,n): 37 U[0][j]=A[0][j] 38 L[j][0]=A[j][0]/U[0][0] 39 else: 40 for j in range(i, n):#U 41 temp=0 42 for k in range(0, i): 43 temp = temp+L[i][k] * U[k][j] 44 U[i][j]=A[i][j]-temp 45 for j in range(i+1, n):#L 46 temp = 0 47 for k in range(0, i ): 48 temp = temp + L[j][k] * U[k][i] 49 L[j][i] = (A[j][i] - temp)/U[i][i] 50 return L,U 51 52 if __name__ == '__main__': 53 n=3 54 A=[[10, 7, 8, 7], 55 [7, 5, 6, 5], 56 [8, 6, 10, 9], 57 [7, 5, 9, 10]] 58 print('A矩阵: ',A) 59 if Master_Sequential(A,n) != False: 60 L,U=LU_decomposition(A) 61 print('L矩阵: ',L, ' U矩阵: ',U) 62 else: 63 print('A的k阶主子式不全非零,不满足LU分解条件。')
运行结果:
• 平方根法
1 import numpy as np 2 A=[[10, 7, 8, 7], 3 [7, 5, 6, 5], 4 [8, 6, 10, 9], 5 [7, 5, 9, 10]] 6 b=[[32, 23, 33, 31]] 7 print (len(A)) 8 k=0 9 def get_under(A):#获取A的下三角矩阵 10 Under=list(np.zeros((len(A),len(A)))) 11 for i in A: 12 x=A.index(i) 13 n=0 14 for t in i: 15 if n<=x: 16 Under[x][n]=A[x][n] 17 n=n+1 18 d=[] 19 for i in Under: 20 d.append((list(i))) 21 return d 22 23 def get_base(m):#给一个矩阵为基,在这个基上修改得到我们的答案 24 base=list(np.zeros((len(A),len(A)))) 25 return base 26 27 def get_GT_D(a,base,k):#对于对角线上的元素有这样的算法 28 m=0 29 sum1=0.00000000000 30 while m < k: 31 sum1=sum1+(base[k][m])**2 32 m=m+1 33 base[k][k]=(a[k][k]-sum1)**(0.5000000000) 34 return base 35 36 def get_GT_ND(a,base,i,k):#对于非对角线上的元素有这样的解法,应该可以和上面一部分并在一块 37 if i==k: 38 return base 39 else: 40 sum1=0.0000000000000 41 m=0 42 if k-1<0: 43 base[i][k]=a[i][k]/base[k][k] 44 else: 45 while m<k: 46 sum1=sum1+base[i][m]*base[k][m] 47 m=m+1 48 base[i][k]=(a[i][k]-sum1)/base[k][k] 49 return base 50 51 def get_G(A):#导出我们需要的矩阵G 52 a=get_under(A) 53 base=get_base(A) 54 base[0][0]=a[0][0]**0.50000000000 55 n=[] 56 for i in base: 57 n.append(list(i)) 58 base=n 59 i=0 60 while i<len(A): 61 k=0 62 while k<i: 63 get_GT_ND(a,base,i,k) 64 k=k+1 65 get_GT_D(a,base,k) 66 i=i+1 67 return base 68 69 def build_matrix(A,b):#通过这段代码导出增广矩阵 70 B=[] 71 for i in A: 72 n=A.index(i) 73 i.append(b[0][n]) 74 B.append(i) 75 return B 76 77 def solve_lower(A,b):#解线性方程组的第一种方法,这里是Gy=b,顺序gauss消去法解出y 78 B=build_matrix(get_G(A),b) 79 C=[] 80 for i in B: 81 C.append(np.array(i)) 82 k=0 83 while k<len(A): 84 for i in range(k+1,len(A)): 85 C[i]=C[i]-C[k]*B[i][k]/B[k][k] 86 k=k+1 87 D=[] 88 for i in C: 89 D.append(list(i)) 90 ans=[] 91 for i in D: 92 for j in i: 93 if j==0: 94 pass 95 else: 96 ans.append(i[-1]/j) 97 break 98 ans1=[] 99 ans1.append(ans) 100 return ans1 101 102 b= solve_lower(A,b) 103 N=np.mat(get_G(A)).T 104 ee=np.mat(b).T 105 print (N.I*ee) #解线性方程组的第二种方法,将系数矩阵的逆矩阵左乘到方程右端
运行结果: