Java實現的LU分解,高斯消去法求線性方程組的解

LU分解在本質上是高斯消元法的一種表達形式。實質上是將A通過初等行變換變成一個上三角矩陣,其變換矩陣就是一個單位下三角矩陣。這正是所謂的杜爾裏特算法(Doolittle algorithm)
重點內容
高斯消去法分爲
(1)LU分解 (2)前代 (3)回代

實例:題目:a)用高斯消去法解方程組Ax = b,其中

A=242491237

b=2810

b)用得到的A的LU分解,解方程Ay=c
    -

LU分解

1.定義
LU分解是矩陣分解的一種,可以將係數矩陣A轉變成等價兩個矩陣L和U的乘機,其中L和U分別是下三角和上三角矩陣,A = LU.
2.例子
對如下矩陣A,對A進行LU分解

A=242491237

(1)先解出A的上三角矩陣U
這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述

U=200410212

(2)解出A的下三角矩陣L
下三角矩陣L中對應位置的元素就是求解上三角矩陣時對應位置的乘數因子.對應上述矩陣, L21 = 2; L31 = -1; L32 = 3,對角線上的數爲1,
故下三角矩陣爲:
$$
L = \left[\begin{matrix}1 & 0& 0 \2& 1 & 0 \-1 & 3 & 1 \
\end{matrix} \right]
(3)代碼如下
private static List<double[][]> decomposition(double[][]a){
        double[][] U = a;  //a是要分解的矩陣
        double[][] L = createIndentityMatrix(a.length);  

        for(int j=0; j<a[0].length - 1; j++) {             
            if(a[j][j] == 0) {  
                 throw new IllegalArgumentException("zero pivot encountered.");  
             }  

            for(int i=j+1; i<a.length; i++) {  
                 double mult = a[i][j] / a[j][j];   
                for(int k=j; k<a[i].length; k++) {  
                     U[i][k] = a[i][k] - a[j][k] * mult; 
                     //得出上三角矩陣U,通過減去矩陣的第一行,第二行,第一行(第二行)得到上三角矩陣
                 }  
                L[i][j] = mult;  //得到下三角矩陣是得出上三角矩陣的乘積因子
            }  
        }  
        return Arrays.asList(L, U);

    }
    -

前代

(1)因爲LUx = b,

LUx=b

Ux=V

LV=b

121013001.V=2810

V=240

(2)代碼如下
 private static double[] getUMultiX(double[][] a, double[] b, double[][] L) {  
        double[] UMultiX = new double[a.length];  
        for(int i=0; i<a.length; i++) {  
            double right_hand = b[i];  
            for(int j=0; j<i; j++) {  
                right_hand -= L[i][j] * UMultiX[j];  //
            }  
            UMultiX[i] = right_hand / L[i][i];  
        }  
        return UMultiX;  
    }  

回代

(1)將得到V代入,得到x

Ux=V

200410212.x=240

x=740

(2)代碼如下
private static double[] getSolution(double[][] a, double[][] U,  
            double[] UMultiX) {  
        double[] solutions = new double[a[0].length];  
        for(int i=U.length-1; i>=0; i--) {  
            double right_hand = UMultiX[i];  
            for(int j=U.length-1; j>i; j--) {  
                right_hand -= U[i][j] * solutions[j];  
            }  
            solutions[i] = right_hand / U[i][i];  
        }  
        return solutions;  
    }  

 - 


如果不夠清楚,可以看下方總體代碼

import java.util.Arrays;
import java.util.List;

public class Decomposition {

    public static void main(String[] args) {
        double [][]A ={{2,4,-2},{4,9,-3},{-2,-1,7}};
        double []b = {2,8,10};
        int row = 3;
        double[]x = solve(A, b);
        for(int i = 0;i<x.length;i++){
            System.out.println(x[i]);
        }

    }
    public static double[] solve(double[][] a, double[] b) {          
        List<double[][]> LAndU = decomposition(a);  //LU decomposition  
        double[][] L = LAndU.get(0);  
        double[][] U = LAndU.get(1);  
        double[] UMultiX = getUMultiX(a, b, L);   //前代    
        return getSolution(a, U, UMultiX);        //回代
    }  

    /** 
     * Get solution of the equations 
     * @param a - Coefficient matrix of the equations 
     * @param U - U of LU Decomposition 
     * @param UMultiX - U multiply X 
     * @return Equations solution 
     */  
    private static double[] getSolution(double[][] a, double[][] U,  
            double[] UMultiX) {  
        double[] solutions = new double[a[0].length];  
        for(int i=U.length-1; i>=0; i--) {  
            double right_hand = UMultiX[i];  
            for(int j=U.length-1; j>i; j--) {  
                right_hand -= U[i][j] * solutions[j];  
            }  
            solutions[i] = right_hand / U[i][i];  
        }  
        return solutions;  
    }  

    /** 
     * Get U multiply X 
     * @param a - Coefficient matrix of the equations 
     * @param b - right-hand side of the equations 
     * @param L - L of LU Decomposition 
     * @return U multiply X 
     */  
    private static double[] getUMultiX(double[][] a, double[] b, double[][] L) {  
        double[] UMultiX = new double[a.length];  
        for(int i=0; i<a.length; i++) {  
            double right_hand = b[i];  
            for(int j=0; j<i; j++) {  
                right_hand -= L[i][j] * UMultiX[j];  //
            }  
            UMultiX[i] = right_hand / L[i][i];  
        }  
        return UMultiX;  
    }  

    private static List<double[][]> decomposition(double[][]a){
        double[][] U = a;  //a是要分解的矩陣
        double[][] L = createIndentityMatrix(a.length);  

        for(int j=0; j<a[0].length - 1; j++) {             
            if(a[j][j] == 0) {  
                 throw new IllegalArgumentException("zero pivot encountered.");  
             }  

            for(int i=j+1; i<a.length; i++) {  
                 double mult = a[i][j] / a[j][j];   
                for(int k=j; k<a[i].length; k++) {  
                     U[i][k] = a[i][k] - a[j][k] * mult; 
                     //得出上三角矩陣U,通過減去矩陣的第一行,第二行,第一行(第二行)得到上三角矩陣
                 }  
                L[i][j] = mult;  //得到下三角矩陣是得出上三角矩陣的乘積因子
            }  
        }  
        return Arrays.asList(L, U);

    }
    private static double[][]createIndentityMatrix(int row){
        double[][]identityMatrix = new double[row][row];
        for(int i=0;i<identityMatrix.length;i++){
            for(int j=i;j<identityMatrix[i].length;j++){
                if(j==i){
                    if (j==i) {
                        identityMatrix[i][j]= 1;
                    }else {
                        identityMatrix[i][j] = 0;
                    }
                }
            }
        }
        return identityMatrix;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章