LU分解求逆


文章轉自:

https://www.cnblogs.com/bigmonkey/p/9555710.html

https://blog.csdn.net/xx_123_1_rj/article/details/39553809

什么是LU分解

在線性代數中, LU分解是矩陣分解的一種,可以將一個矩陣分解為一個單位下三角矩陣和一個上三角矩陣的乘積(有時是它們和一個置換矩陣的乘積)

如果有一個矩陣A,將A表示成下三角矩陣L和上三角矩陣U的乘積,稱為A的LU分解。

 

  更進一步,我們希望下三角矩陣的對角元素都為1:

LU分解的步驟

  上一章講到,對於滿秩矩陣A來說,通過左乘一個消元矩陣,可以得到一個上三角矩陣U。

  可以看到,L實際上就是消元矩陣的逆。容易知道二階矩陣的逆:

 

  現在假設A是一個3×3矩陣,在不考慮行交換的情況下,通過消元得到上三角矩陣的過程是:

 

 

LU 分解的前提

  並非所有矩陣都能進行LU分解,能夠LU分解的矩陣需要滿足以下三個條件:

  1. 矩陣是方陣(LU分解主要是針對方陣);
  2. 矩陣是可逆的,也就是該矩陣是滿秩矩陣,每一行都是獨立向量;
  3. 消元過程中沒有0主元出現,也就是消元過程中不能出現行交換的初等變換

 示例

  

  如果A存在LU分解存,a,b滿足什么條件?

  使用消元法逐一消去主元:

  由於E31 中出現了 –b/a,所以a ≠ 0

 

  b可以是任意常數。

 

具體的算法流程可以是:

 

1)進行LU分解;

2)對分解后的L陣(下三角矩陣)和U陣(上三角矩陣)進行求逆;

3)L陣的逆矩陣和U陣的逆矩陣相乘,即可求得原來矩陣的逆。即:

程序實現如下:

 

  1 #include<stdio.h>
  2 #include <string.h>
  3 #define N 4
  4 void main()
  5 { 
  6     float a[N][N];
  7     float L[N][N],U[N][N],out[N][N], out1[N][N];
  8     float r[N][N],u[N][N];
  9     memset( a , 0 , sizeof(a));  //初始化
 10     memset( L , 0 , sizeof(L));
 11     memset( U , 0 , sizeof(U));
 12     memset( r , 0 , sizeof(r));
 13     memset( u , 0 , sizeof(u));
 14     int n=N;
 15     int k,i,j;
 16     int flag=1;
 17     float s,t;
 18     ////////////////////input a matrix////
 19     printf("input A=\n");
 20     for(i=0;i<n;i++)
 21         for(j=0;j<n;j++)
 22             scanf("%f",&a[i][j]);
 23         //////////////////figure the input matrix//////////////////////////
 24         printf("輸入矩陣:\n");
 25         for(i=0;i<n;i++)
 26         {
 27             for (j = 0; j < n; j++)
 28             {
 29                 printf("%lf ", a[i][j]);
 30             }
 31             printf("\n");
 32         }
 33         for(j=0;j<n;j++)
 34             a[0][j]=a[0][j];  //計算U矩陣的第一行
 35         
 36         for(i=1;i<n;i++)
 37             a[i][0]=a[i][0]/a[0][0];   //計算L矩陣的第1列
 38         for(k=1;k<n;k++)
 39         {
 40             for(j=k;j<n;j++)
 41             {
 42                 s=0;
 43                 for (i=0;i<k;i++)
 44                     s=s+a[k][i]*a[i][j];   //累加
 45                 a[k][j]=a[k][j]-s; //計算U矩陣的其他元素
 46             }
 47             for(i=k+1;i<n;i++)
 48             {
 49                 t=0;
 50                 for(j=0;j<k;j++)
 51                     t=t+a[i][j]*a[j][k];   //累加
 52                 a[i][k]=(a[i][k]-t)/a[k][k];    //計算L矩陣的其他元素
 53             }
 54         }
 55         for(i=0;i<n;i++)
 56             for(j=0;j<n;j++)
 57             { 
 58                 if(i>j)
 59                 { 
 60                     L[i][j]=a[i][j]; 
 61                     U[i][j]=0;
 62                 }//如果i>j,說明行大於列,計算矩陣的下三角部分,得出L的值,U的//為0
 63                 else
 64                 {
 65                     U[i][j]=a[i][j];
 66                     if(i==j) 
 67                         L[i][j]=1;  //否則如果i<j,說明行小於列,計算矩陣的上三角部分,得出U的//值,L的為0
 68                     else 
 69                         L[i][j]=0;
 70                 }
 71             }  
 72             if(U[1][1]*U[2][2]*U[3][3]*U[4][4]==0)
 73             {
 74                 flag=0;
 75                 printf("\n逆矩陣不存在");}
 76             if(flag==1)
 77             {
 78                 /////////////////////求L和U矩陣的逆
 79                 for (i=0;i<n;i++) /*求矩陣U的逆 */
 80                 {
 81                     u[i][i]=1/U[i][i];//對角元素的值,直接取倒數
 82                     for (k=i-1;k>=0;k--)
 83                     {
 84                         s=0;
 85                         for (j=k+1;j<=i;j++)
 86                             s=s+U[k][j]*u[j][i];
 87                         u[k][i]=-s/U[k][k];//迭代計算,按列倒序依次得到每一個值,
 88                     }
 89                 }
 90                 for (i=0;i<n;i++) //求矩陣L的逆 
 91                 {
 92                     r[i][i]=1; //對角元素的值,直接取倒數,這里為1
 93                     for (k=i+1;k<n;k++)
 94                     {
 95                         for (j=i;j<=k-1;j++)
 96                             r[k][i]=r[k][i]-L[k][j]*r[j][i];   //迭代計算,按列順序依次得到每一個值
 97                     }
 98                 }
 99                 /////////////////繪制矩陣LU分解后的L和U矩陣///////////////////////
100                 printf("\nLU分解后L矩陣:");
101                 for(i=0;i<n;i++)
102                 { 
103                     printf("\n");
104                     for(j=0;j<n;j++)
105                         printf(" %lf",L[i][j]);
106                 }
107                 printf("\nLU分解后U矩陣:");
108                 for(i=0;i<n;i++)
109                 { 
110                     printf("\n");
111                     for(j=0;j<n;j++)
112                         printf(" %lf",U[i][j]);
113                 }
114                 printf("\n");
115                 ////////繪制L和U矩陣的逆矩陣
116                 printf("\nL矩陣的逆矩陣:");
117                 for(i=0;i<n;i++)
118                 { 
119                     printf("\n");
120                     for(j=0;j<n;j++)
121                         printf(" %lf",r[i][j]);
122                 }
123                 printf("\nU矩陣的逆矩陣:");
124                 for(i=0;i<n;i++)
125                 { 
126                     printf("\n");
127                     for(j=0;j<n;j++)
128                         printf(" %lf",u[i][j]);
129                 }
130                 printf("\n");
131                 //驗證將L和U相乘,得到原矩陣
132                 printf("\nL矩陣和U矩陣乘積\n");
133                 for(i=0;i<n;i++)
134                 {
135                     for(j=0;j<n;j++)
136                     {
137                         out[i][j]=0;
138                     }
139                 }
140                 for(i=0;i<n;i++)
141                 {
142                     for(j=0;j<n;j++)
143                     {
144                         for(k=0;k<n;k++)
145                         {
146                             out[i][j]+=L[i][k]*U[k][j];
147                         }
148                     }  
149                 }
150                 for(i=0;i<n;i++)
151                 {
152                     for(j=0;j<n;j++)
153                     {
154                         printf("%lf\t",out[i][j]);
155                     }
156                     printf("\r\n");
157                 }
158                 //////////將r和u相乘,得到逆矩陣
159                 printf("\n原矩陣的逆矩陣:\n");
160                 for(i=0;i<n;i++)
161                 {
162                     for(j=0;j<n;j++)
163                     {out1[i][j]=0;}
164                 }
165                 for(i=0;i<n;i++)
166                 {
167                     for(j=0;j<n;j++)
168                     {
169                         for(k=0;k<n;k++)            
170                         {
171                             out1[i][j]+=u[i][k]*r[k][j];
172                         }
173                     }  
174                 }
175                 for(i=0;i<n;i++)
176                 {
177                     for(j=0;j<n;j++)
178                     {
179                         printf("%lf\t",out1[i][j]);
180                     }
181                     printf("\r\n");
182                 }
183             }
184  }

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM