用Java代码来解答留学生朋友的数值分析问题
前言+说明
❤️旺仔兄弟们!留学生朋友问的这道题目是需要用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]
- getSolution()方法为LU分解时的最终结果X数组的求解函数。
- getUMultiX()方法为LU分解计算过程中的Y数组的求解函数。
- solve()方法为getSolution()方法和getUMultiX()方法的综合函数。
- decomposition()方法为LU分解的L矩阵和U矩阵的计算过程。
- createIdentityMatrix()方法为创建L矩阵的初始矩阵函数。
- 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]));
}
}
}