数值分析实验之矩阵的LU分解及在解线性方程组中的应用(Python 代码)

一、实验目的

  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矩阵:\n',A)
59     if Master_Sequential(A,n) != False:
60         L,U=LU_decomposition(A)
61         print('L矩阵:\n',L, '\nU矩阵:\n',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) #解线性方程组的第二种方法,将系数矩阵的逆矩阵左乘到方程右端

    运行结果:

      

猜你喜欢

转载自www.cnblogs.com/ynly/p/12879529.html