求逆矩阵 —— LU分解法「建议收藏」

求逆矩阵 —— LU分解法「建议收藏」LU分解:算法步骤:1.将A矩阵分解为L下三角矩阵和U上三角矩阵。step1.L对角线填充为1step2.step3.step4.U是按行迭代计算,L是按列迭代计算,UL交错计算,且U先L一步fork=1tom-1:{}2.分别对L和U求逆,得到Linv和Uinv.step1….


Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

LU分解:

A=L*U\Rightarrow A^{-1} = (L*U)^{-1}=L^{-1}*U^{-1}

算法步骤:

1. 将 A 矩阵分解为 L 下三角矩阵和 U 上三角矩阵。

step1. L对角线填充为1

step2. U_{0,j}=A_{0,j}(j=0,...,m-1)

step3. L_{i,0}=\frac{A_{i,0}}{U_{0,0}},(i=1,...,m-1)

step4. U是按行迭代计算,L是按列迭代计算,UL交错计算,且U先L一步

    for  k = 1  to  m-1: {

   U_{k,j}=\frac{A_{k,j}-\sum_{t=0}^{k-1}(L_{i,t}U_{t,j})}{L_{k,k}}=A_{k,j}-\sum_{t=0}^{k-1}(L_{k,t} U_{t,j}),(j=k,...,m-1)

L_{i,k}=\frac{A_{i,k}-\sum_{t=0}^{k-1}(L_{i,t}U_{t,k})}{U_{k,k}},(i=k,...,m-1)

}

2. 分别对 L 和 U 求逆,得到 Linv 和 Uinv.

step1. 列顺序行顺序, for  j = 0  to  m-1, i = j  to  m-1

3. Ainv = Linv * Uinv. 

实现代码(java):

public class TestMain {

	public static void main(String[] args) {
		double[][] A = { { 4, 2, 1, 5 }, { 8, 7, 2, 10 }, { 4, 8, 3, 6 }, { 6, 8, 4, 9 } };
		double[][] U = new double[4][4];
		double[][] L = new double[4][4];
		double[][] Uinv = new double[4][4];
		double[][] Linv = new double[4][4];
		print(A);
		int size = 4;
		// fill 1 at L's diagonal
		for (int i = 0; i < size; i++) {
			L[i][i] = 1.0;
		}
		// calculate the U's first row
		for (int j = 0; j < size; j++) {
			U[0][j] = A[0][j];
		}
		// calculate the L's first column
		for (int i = 1; i < size; i++) {
			L[i][0] = A[i][0] / U[0][0];
		}
		// iterative calculation of other rows and columns
		for (int k = 1; k < size; k++) {
			// the k_th row of U
			for (int j = k; j < size; j++) {
				// sum(L_kt*U_tj),t
				double s = 0.0;
				for (int t = 0; t < k; t++) {
					s += L[k][t] * U[t][j];
				}
				// U_kj = A_kj - s
				U[k][j] = A[k][j] - s;
			}
			// the k_th column of L
			for (int i = k; i < size; i++) {
				// sum(L_it*U_tk),t
				double s = 0.0;
				for (int t = 0; t < k; t++) {
					s += L[i][t] * U[t][k];
				}
				// L_ik = (A_ik - s) / U_kk
				L[i][k] = (A[i][k] - s) / U[k][k];
			}
		}
		
		// calculate L_inv
		for (int j = 0; j < size; j++) {
			for (int i = j; i < size; i++) {
				if (i == j) Linv[i][j] = 1 / L[i][j];
				else if (i < j) Linv[i][j] = 0;
				else {
					double s = 0.0;
					for (int k = j; k < i; k++) {
						s += L[i][k] * Linv[k][j];
					}
					Linv[i][j] = -Linv[j][j] * s;
				}
			}
		}
		
		// calculate U_inv
		for (int j = 0; j < size; j++) {
			for (int i = j; i >= 0; i--) {
				if (i == j) Uinv[i][j] = 1 / U[i][j]; 
				else if (i > j) Uinv[i][j] = 0;
				else {
					double s = 0.0;
					for (int k = i + 1; k <= j; k++) {
						s += U[i][k] * Uinv[k][j];
					}
					Uinv[i][j] = -1 / U[i][i] * s;
				}
			}
		}
		
		double[][] inv = new double[4][4];
		for (int i = 0; i < size; i++) {
			for (int j = 0; j < size; j++) {
				for (int k = 0; k < size; k++) {
					inv[i][j] += Uinv[i][k] * Linv[k][j];
				}
			}
		}
		
		print(L);
		print(U);
		print(Linv);
		print(Uinv);
		print(inv);
	}

	public static void print(double[][] M) {
		for (int i = 0; i < M.length; i++) {
			for (int j = 0; j < M[0].length; j++) {
				System.out.printf("%8.2f ", M[i][j]);
			}
			System.out.println();
		}
		System.out.println();
	}

}

程序输出:

    4.00     2.00     1.00     5.00

    8.00     7.00     2.00    10.00

    4.00     8.00     3.00     6.00

    6.00     8.00     4.00     9.00

 

    1.00     0.00     0.00     0.00

    2.00     1.00     0.00     0.00

    1.00     2.00     1.00     0.00

    1.50     1.67     1.25     1.00

 

    4.00     2.00     1.00     5.00

    0.00     3.00     0.00     0.00

    0.00     0.00     2.00     1.00

    0.00     0.00     0.00     0.25

 

    1.00     0.00     0.00     0.00

   -2.00     1.00     0.00     0.00

    3.00    -2.00     1.00     0.00

   -1.92     0.83    -1.25     1.00

 

    0.25    -0.17    -0.13    -4.50

    0.00     0.33    -0.00    -0.00

    0.00     0.00     0.50    -2.00

    0.00     0.00     0.00     4.00

 

    8.83    -3.67     5.50    -4.50

   -0.67     0.33     0.00     0.00

    5.33    -2.67     3.00    -2.00

   -7.67     3.33    -5.00     4.00

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/171656.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 如何用猪脸识别降低死猪理赔成本?这支学生团队靠「进击的巨猪」打败了商业老兵

    如何用猪脸识别降低死猪理赔成本?这支学生团队靠「进击的巨猪」打败了商业老兵撰文|王艺编辑|藤子12月17日,历时40天的2017京东金融全球数据探索者大赛落下帷幕。本次大赛分为商业组和算法组两个组别,分别从商业及算法两个层面围绕「登录行为识别」、「店铺销量预测」、「信贷需求预测」以及「猪脸识别」四个赛题展开角逐。大赛于11月6日启动,共有4624支团队报名,经过选拔赛,最终有36支团队步入

    2022年6月21日
  • MVC三层架构的实现

    MVC三层架构的实现在MVC设计模式中认为,任何软件都可以分为三部分组成:1.控制程序流转的控制器Controller2.封装数据处理数据的模型Model3.负责展示数据的视图View在MVC设计思想中要求符合MVC设计思想的软件应该保证MVC这三部分相互独立,互不干扰,每一部分只负责自己擅长的部分。即某一个模块发生变化,应该尽量做到不影响其他两个模块,这样有利于后期的扩展和维护,代码也可复用…

    2022年6月25日
  • ABAP开发语言「建议收藏」

    ABAP开发语言「建议收藏」2.第二部分ABAP开发语言2.1.ABAP基础2.1.1.语言概述2.1.1.1.程序结构ABAP程序源码结构包括数据定义和处理块两部分;处理块又分为事件块,对话模块,过程。过程中可以定义自己的局部变量。事件块,对话模块,只能使用全局数据定义。2.1.1.2.程序类型可直接运行的应用程序(可分配事务代码)可执行程序Executableprogram,类型代码…

    2022年10月30日
  • idea2021激活码?【在线注册码/序列号/破解码】

    idea2021激活码?【在线注册码/序列号/破解码】,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月20日
  • php实现第三方登录

    php实现第三方登录

    2021年10月25日
  • Linux 删除文件夹

    Linux 删除文件夹inux删除目录很简单,很多人还是习惯用rmdir1.直接rm就可以了:rm-rf目录名字-r就是向下递归,不管有多少级目录,一并删除-f就是直接强行删除,不作任何提示的意思

    2022年7月4日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号