`

〖数学算法〗逆矩阵算法

 
阅读更多

矩阵大家一定都很熟悉,它是线性代数中的一个术语,它在生产实践,科研,等各学科都有不可替代的作用,求逆矩阵当然是矩阵的一种常用操作,今天就写了个求逆矩阵的程序巩固下基本功。

首先让我们回忆一下你矩阵的定义:

逆矩阵设A是数域上的一个n阶方阵,若在相同数域上存在另一个n阶矩阵B,使得: AB=BA=E。 则我们称B是A的逆矩阵,而A则被称为可逆矩阵

接下来我带大家回忆一下在“线性代数”中求逆矩阵的两种方法

(以下方法来至维基百科)


1.伴随矩阵法

如果矩阵A可逆,则A^{-1}=\frac{A^*}{|A|}其中A^*A伴随矩阵

注意:A^*中元素的排列特点是A^*的第k元素是A的第k元素的代数余子式。要求得A^*即为求解A余因子矩阵转置矩阵

2.初等变换法

由条件AB=BA以及矩阵乘法的定义可知,矩阵AB都是方阵。再由条件AB=I以及定理“两个矩阵的乘积的行列式等于这两个矩阵的行列式的乘积”可知,这两个矩阵的行列式都不为0。也就是说,这两个矩阵的秩等于它们的级数(或称为阶,也就是说,A与B都是n\times n方阵,且rank(A) = rank(B) = n)。换句话说,这两个矩阵可以只经由初等行变换,或者只经由初等列变换,变为单位矩阵。

因为对矩阵A施以初等行变换(初等列变换)就相当于在A的左边(右边)乘以相应的初等矩阵,所以我们可以同时对AI施以相同的初等行变换(初等列变换)。这样,当矩阵A被变为I时,I就被变为A的逆阵B


接下来让我们来分别看看两个实际的小题,回忆一下解法:


1.伴随矩阵法求逆矩阵:

问题:

求解过程:

解得:


2.初等变换法:

问题:

求A的逆矩阵

求解过程:

解得:


接下来我就用第二种方法,做一下第一题,代码如下:

public class NiMatrix {

	private double[][] getNiMatrix(double[][] matrix) {//求逆矩阵函数
		
		/*定义扩展矩阵*/
		double[][] expand_matrix = new double[matrix.length][matrix.length * 2];
		/*定义得到的逆矩阵*/
		double[][] new_matrix = new double[matrix.length][matrix.length];
		/*初始化扩展矩阵*/
		initExpandMatrix(matrix,expand_matrix);
		/*调整扩展矩阵,若某一列全为0,则行列式的值等于0,不存在逆矩阵*/
		boolean canAdjust = adjustMatrix(expand_matrix);
		if(false == canAdjust)//如果不存在逆矩阵,返回NULL
			return null;
		/*计算扩展矩阵*/
		calculateExpandMatrix(expand_matrix);
		/*用计算过的扩展矩阵取后面的N*N矩阵,为所求*/
		getNewMatrix(expand_matrix,new_matrix);		
		
		return new_matrix;
	}

	/*初始化扩展矩阵*/
	private void initExpandMatrix(double[][] init_matrix,double[][] expand_matrix) {
		
		for (int i = 0; i < expand_matrix.length; i++)
			for (int j = 0; j < expand_matrix[i].length; j++) {
				if (j < expand_matrix.length) {//左边的N*N矩阵原样赋值
					expand_matrix[i][j] = init_matrix[i][j];
				} else {	//右边N*N赋值为单位矩阵
					if (j == expand_matrix.length + i)//如果为右边矩阵的对角线就赋值为1
						expand_matrix[i][j] = 1;
					else
						expand_matrix[i][j] = 0;
				}
			}
		
	}

	/*调整扩展矩阵,若某一列全为0,则行列式的值等于0,不存在逆矩阵*/
	private boolean adjustMatrix(double[][] expand_matrix) {
		
		for (int i = 0; i < expand_matrix.length; i++) {
			if (expand_matrix[i][i] == 0) {//如果某行对角线数值为0
				int j;
				/*搜索该列其他不为0的行,如果都为0,则返回false*/
				for (j = 0; j < expand_matrix.length; j++) {

					if (expand_matrix[j][i] != 0) {//如果有不为0的行,交换这两行
						double[] temp = expand_matrix[i];
						expand_matrix[i] = expand_matrix[j];
						expand_matrix[j] = temp;
						break;
					}

				}
				if (j >= expand_matrix.length) {//没有不为0的行
					System.out.println("此矩阵没有逆矩阵");
					return false;
				}
			}
		}
		return true;
	}
	/*计算扩展矩阵*/
	private void calculateExpandMatrix(double[][] expand_matrix) {
		
		for (int i = 0; i < expand_matrix.length; i++) {

			double first_element = expand_matrix[i][i];

			for (int j = 0; j < expand_matrix[i].length; j++)

				expand_matrix[i][j] /= first_element;//将该行所有元素除以首元素
			
			/*把其他行再该列的数值都化为0*/
			for (int m = 0; m < expand_matrix.length; m++) {
				if (m == i)//遇到自己的行跳过
					continue;

				double beishu = expand_matrix[m][i];
				for (int n = 0; n < expand_matrix[i].length; n++) {				
					expand_matrix[m][n] -= expand_matrix[i][n] * beishu;
				}
			}

		}
		
	}
	/*用计算过的扩展矩阵取后面的N*N矩阵,为所求*/
	private void getNewMatrix(double[][] expand_matrix, double[][] new_matrix) {
		
		for(int i = 0; i < expand_matrix.length; i++)
			for(int j = 0; j < expand_matrix[i].length; j++){
				if(j >= expand_matrix.length)
					new_matrix[i][j-expand_matrix.length] = expand_matrix[i][j];
			}
		
	}

	/*打印矩阵*/
	public void printMatrix(double[][] matrix){

		for (double[] tempi : matrix) {
			for (double tempj : tempi) {
				System.out.print(tempj + "  ");
			}
			System.out.println();
		}
		
	}
	/*矩阵做乘法,验证结果*/
	private static double[][] getProductMatrix(double[][] init_matrix,
			double[][] new_matrix) {
		
		int len = init_matrix.length;
		double[][] product_matrix = new double[len][len];
		for(int i = 0; i < len; i++){
			for(int j = 0; j < len; j++)
				for(int k = 0; k < len; k++)
					product_matrix[i][j] += init_matrix[i][k] * new_matrix[k][j];
		}
		return product_matrix;
	}
	

	public static void main(String[] args) {
		
		NiMatrix _robot = new NiMatrix();
		
		System.out.println("=====原矩阵=====");
		double init_matrix[][] = { 
				{ 1, 2, -1 },
				{ 3, 4, -2 }, 
				{ 5, -4, 1 } 
			};
		_robot.printMatrix(init_matrix);
		
		System.out.println("=====逆矩阵=====");
		double new_matrix[][] = _robot.getNiMatrix(init_matrix);
		_robot.printMatrix(new_matrix);
		
		System.out.println("=====原矩阵*逆矩阵=====");
		double[][] product_matrix = getProductMatrix(init_matrix,new_matrix);
		_robot.printMatrix(product_matrix);
	}

}
测试结果:


==================================================================================================

作者:nash_ 欢迎转载,与人分享是进步的源泉!

转载请保留原文地址http://blog.csdn.net/nash_/article/details/8241348

===================================================================================================

分享到:
评论

相关推荐

    常用矩阵数学算法

    常用矩阵数学算法

    C++离散数学算法判断对称矩阵

    C++离散数学算法判断对称矩阵,是一个6*6的矩阵,输入时候可要仔细一点,输入错误的话矩阵就没意义了,VC++写这类矩阵程序,其实也并不复杂哦,判断是否是配对矩阵,其实是很有意思的事。

    分块五对角矩阵求逆的快速算法.pdf

    (1.西北工业大学应用数学系,陕西西安710072;2.西安邮电学院应用数理系。陕西西安710121}3....文章利用分块五对角矩阵的特殊结构,给出了求分块五对角矩阵逆矩阵的快速算法,最后通过 算例来说明算法的有效性。

    数学常用算法C++版

    数学常用算法的代码,包括矩阵的加减乘除,求逆等等。

    组合数学及其算法

    1.1 组合数学研究的对象 1.2 组合问题典型实例 1.2.1 分派问题 1. 2.2 染色问题 1.2.3 幻方问题 1.2.4 36军官问题 1.2.5 中国邮路问题 习 题 第二章 排列与组合 2.1 两个基本计数原理 2.2 无...

    数学算法原书光盘

    卷积和逆卷积的快速算法 6.离散相关和自相关的快速算法 7.多维快速傅里叶变换算法 第11章数据的统计描述 1.分布的矩——均值、平均差、标准差、方差、斜差和峰态 2.中位数的搜索 3.均值与方差的显著性...

    《数学算法》原书光盘

    《数学算法》原书光盘,目录列表: 第1章线性代数方程组的解法 1.全主元高斯约当消去法 2.LU分解法 3.追赶法 4.五对角线性方程组解法 5.线性方程组解的迭代改善 6.范德蒙方程组解法 7.托伯利兹方程组解法 8...

    数学建模竞赛中应当掌握的十类算法

    求解、矩阵运算、函数积分等算法就需要额外编写库函数进行调用。 0.图象处理算法。赛题中有一类问题与图形有关,即使问题与图形无关,论文中也会需要图片来说明 问题,这些图形如何展示以及如何处理就是需要解决的...

    矩阵类的数学操作和最小二乘法算法

    矩阵类的数学操作,功能基本上实现,满足普通的求解算法.对于矩阵的求逆,乘法,LU分解都已实现.然后用矩阵类实现一个用线性拟合最小二乘法求解一个方程的系数...

    用C++语言编写数学常用算法PDF

    本书主要研究用C++语言编写各种与实数和复数有关的常用的数学算法的程序,如线性代数,矩阵运算,实数方程求解,插值,拟合,数值积分,微分方程求解,特殊函数,函数变换,回归分析等等。本书给读者提供两个方便...

    数学建模算法

    9.数值分析算法(如果在比赛中采用高级语言进行编程的话,那一些数值分析中常用的算法比如方程组求解、矩阵运算、函数积分等算法就需要额外编写库函数进行调用) 10.图象处理算法(赛题中有一类问题与图形有关,即使与...

    计算机图像处理的数学和算法基础(高清版本)

    计算机图像处理领域相关的数学和算法基础知识,从事图像处理必备。包括的基础知识如:函数、极限、概率论、矩阵等傅里叶变换、图像数据表示方法、图像变换、增强、恢复、重建、编码、图像分割、边缘检测等

    有关数学算法的原书光盘

    数学算法原书光盘 本书目录列表: 第1章线性代数方程组的解法 1.全主元高斯约当消去法 2.LU分解法 3.追赶法 4.五对角线性方程组解法 5.线性方程组解的迭代改善 6.范德蒙方程组解法 7.托伯利兹方程组解法 8.奇异值...

    C#,数值计算,希尔伯特矩阵(Hilbert Matrix)的算法与源代码

    希尔伯特矩阵是一种数学变换矩阵,正定,且高度病态(即,任何一个元素发生一点变动,整个矩阵的行列式的值和逆矩阵都会发生巨大变化),病态程度和阶数相关。 希尔伯特矩阵是一种特殊的汉克尔矩阵。 3 汉克尔矩阵...

    机器学习数学基础:线性代数+微积分+概率统计+优化算法 矩阵运算助力特征提取,导数分析优化模型性能,概率评估数据分布,优化算法寻

    机器学习数学基础:线性代数+微积分+概率统计+优化算法 机器学习作为现代科技的璀璨明珠,正在逐渐改变我们的生活。而在这背后,数学扮演着至关重要的角色。线性代数、微积分、概率统计和优化算法,这四大数学领域...

    通过 Schur-Pade 算法计算矩阵的任意实幂:通过 Schur-Pade 算法计算方阵的任意实幂。-matlab开发

    X = POWERM_PADE(A,P) 通过 Schur-Pade 算法计算矩阵 A 的 P 次幂 X,对于没有非正实数特征值的任意实数 P 和 A。 [X,NSQ,M] = POWERM_PADE(A, P) 返回计算的矩阵平方根的数 NSQ 和使用的 Pade 近似的度数 M。 如果...

    用C++语言编写数学常用算法

    包括了当前的很多C++编写的算法,算法很多,希望对大家有用

    数学建模算法合集,包含算法理论和程序实现,几乎涵盖所有数学建模常用算法

    生成全排列矩阵 递推关系式作图 数据集合 模拟退火应用 画等温线 最短路和次短路 时间序列分析 等等还有很多 0-1背包问题动态规划模型 马尔科夫预测模型 神经网络分类模型 BP神经网络模型 支持向量机模型 Kmeans...

Global site tag (gtag.js) - Google Analytics