zoukankan      html  css  js  c++  java
  • 数值分析实验之矩阵的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矩阵:
    ',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) #解线性方程组的第二种方法,将系数矩阵的逆矩阵左乘到方程右端

        运行结果:

          

  • 相关阅读:
    java 复习001
    Some_sort_algorithms
    Install_pygments
    Install_ruby
    Ubuntu_wifi&pppoe
    Some_problem_with_octopress
    复习C语言
    VSim [a Racing-simulator by Vell001]
    Hello, Github Blog
    我的新计划 《2Dof Racing Simulator》2014/3/9 20:30:00
  • 原文地址:https://www.cnblogs.com/ynly/p/12879529.html
Copyright © 2011-2022 走看看