留学生朋友问我有没有学过《数值分析》

发布于:2022-12-22 ⋅ 阅读:(369) ⋅ 点赞:(0)

前言+说明

在这里插入图片描述

❤️旺仔兄弟们!留学生朋友问的这道题目是需要用LU分解法解方程组Ax=b
    相信大家本科都学过《线性代数》,研究生应该都学过《数值分析》,下面可以开始慢慢解放双手了。
    博主将分以下三步来解答:
    (1)先用《线性代数》里的线性方程组的知识来对其进行求解;
    (2)再用《数值分析》里的LU分解对其进行求解;
    (3)最后解放双手,将LU分解法用java代码对其进行实现。

    【效果为】:在程序中输入方程等号左边的矩阵A和方程等号右边的系数b后,程序输出对应的LU两个矩阵X方程解
    如果觉得博主分享的不错,希望能留下您的一键❤️三连❤️(点赞+评论+收藏) ,您的支持就是我前进的动力❤️,您的三连对我特别重要!


原题重现

在这里插入图片描述

一、 线性代数求解

1、化简构造矩阵[A|b],将A化简成单位矩阵。过程如下:
在这里插入图片描述

2、求得方程的解为:
在这里插入图片描述

二、数值分析LU分解求解

1、理论知识回忆:
  (1)LU分解的目的是简化方程的求解过程,将矩阵A转化成LU矩阵,即:A=LU。
    L(low)矩阵为下三角矩阵,U(up)矩阵为上三角矩阵。L矩阵和U矩阵的具体特点如下所示。
在这里插入图片描述  (2)方程AX=b可转换成L(UX)=b;令UX=Y,可得LY=b,通过L矩阵的特性可轻松解出Y的值;
      又因为前面令UX=Y,所以可继续通过U矩阵的特性轻松解出X的值。


2、针对上题作出解答:

  (1)求LU矩阵
在这里插入图片描述

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

  (2)求解方程
      A=LU,即:AX=b,可转化为L(UX)=b.令UX=Y,可得LY=b.
      Y的求解如下:
在这里插入图片描述
      UX=Y,X的求解如下:
在这里插入图片描述

三、LU分解代码实现(java)

输入描述

1、第一行为系数矩阵A的维度n
2、第二行到倒数第二行为系数矩阵A,每行内的数值以“,”隔开
3、最后一行开始输入矩阵b,数值之间以“,”隔开

输出描述

输出LU分解的L矩阵,U矩阵;计算过程中的数组Y,和最终结果X。

样例输入

4
12,    -3,    3,    4
-18,    3,    -1,    -1
1,      1,      1,    1
3,      1,     -1,    1
15,    -15,    6,    2

样例输出

 L=
[1.0, 0.0, 0.0, 0.0]
[-1.5, 1.0, 0.0, 0.0]
[0.08333333333333333, -0.8333333333333334, 1.0, 0.0]
[0.25, -1.1666666666666667, 0.6363636363636365, 1.0]
U=
[12.0, -3.0, 3.0, 4.0]
[0.0, -1.5, 3.5, 5.0]
[0.0, 0.0, 3.666666666666667, 4.833333333333334]
[0.0, 0.0, 0.0, 2.7575757575757573]
Y=[15.0, 7.5, 11.0, -0.0]
X=[1.0, 2.0, 3.0, -0.0]

  1. getSolution()方法为LU分解时的最终结果X数组的求解函数。
  2. getUMultiX()方法为LU分解计算过程中的Y数组的求解函数。
  3. solve()方法为getSolution()方法和getUMultiX()方法的综合函数。
  4. decomposition()方法为LU分解的L矩阵和U矩阵的计算过程。
  5. createIdentityMatrix()方法为创建L矩阵的初始矩阵函数。
  6. printMatrix()方法为n×n矩阵的输出方法。
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

public class LUDecomposition {
    public static void main(String[] args) {
        System.out.println("1.请在第一行输入系数矩阵A的维度n.....\n" +
                "2.请从第二行开始输入系数矩阵A.....\n" +
                "3.请在最后一行开始输入矩阵b.....");
        Scanner sc = new Scanner(System.in);
        int n = Integer.parseInt(sc.nextLine());
        double[][] a = new double[n][n];
        double[] b = new double[n];
        String[] tempStr = null;
        for (int i=0; i<=n; i++){
            tempStr = sc.nextLine().split(",");
            if(i == n){
                for(int j=0; j<n; j++){
                    b[j] = Double.parseDouble(tempStr[j]);
                }
                break;
            }
            for (int j=0; j<n; j++){
                a[i][j] = Double.parseDouble(tempStr[j]);
            }

        }

        LUDecomposition lUDecomposition = new LUDecomposition();
        double[] X = lUDecomposition.solve(a, b);
        DecimalFormat df = new DecimalFormat("#.0000");//计算结果精确到小数点四位数
        for (int i=0; i<X.length; i++){
            X[i] = Double.parseDouble(df.format(X[i]));
        }
        System.out.println("X=" + Arrays.toString(X));

    }
    /**
     * Get solutions of the equations
     * @param a - Coefficient matrix of the equations
     * @param b - right-hand side of the equations
     * @return solution of the equations
     */
    public double[] solve(double[][] a, double[] b) {
        List<double[][]> LAndU = decomposition(a);
        double[][] L = LAndU.get(0);
        double[][] U = LAndU.get(1);
        double[] UMultiX = getUMultiX(a, b, L);

        //Y的值保留四位小数
        DecimalFormat df = new DecimalFormat("#.0000");
        for (int i=0; i<UMultiX.length; i++){
            UMultiX[i] = Double.parseDouble(df.format(UMultiX[i]));
        }
        System.out.println("Y="+Arrays.toString(UMultiX));
        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 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;
    }

    /**
     * Get matrix L and U. list.get(0) for L, list.get(1) for U
     * @param a - Coefficient matrix of the equations
     * @return matrix L and U, list.get(0) for L, list.get(1) for U
     */
    private List<double[][]> decomposition(double[][] a) {
       
        double[][] U = a;
        double[][] L = createIdentityMatrix(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;
                }
                L[i][j] = mult;
            }
        }
        System.out.println("L=");
        printMatrix(L);
        System.out.println("U=");
        printMatrix(U);
        return Arrays.asList(L, U);
    }

    private double[][] createIdentityMatrix(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) {
                    identityMatrix[i][j] = 1;
                } else {
                    identityMatrix[i][j] = 0;
                }
            }
        }
        return identityMatrix;
    }
    private void printMatrix(double[][] matrix){
        int m = matrix.length;
        for (int i=0;i<m;i++){
            System.out.println(Arrays.toString(matrix[i]));
        }
    }
}             

在这里插入图片描述

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到