〖数学算法〗逆矩阵算法

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

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

逆矩阵设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的逆矩阵

求解过程:

解得:


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

  1. public class NiMatrix {  
  2.   
  3.     private double[][] getNiMatrix(double[][] matrix) {//求逆矩阵函数   
  4.           
  5.         /*定义扩展矩阵*/  
  6.         double[][] expand_matrix = new double[matrix.length][matrix.length * 2];  
  7.         /*定义得到的逆矩阵*/  
  8.         double[][] new_matrix = new double[matrix.length][matrix.length];  
  9.         /*初始化扩展矩阵*/  
  10.         initExpandMatrix(matrix,expand_matrix);  
  11.         /*调整扩展矩阵,若某一列全为0,则行列式的值等于0,不存在逆矩阵*/  
  12.         boolean canAdjust = adjustMatrix(expand_matrix);  
  13.         if(false == canAdjust)//如果不存在逆矩阵,返回NULL   
  14.             return null;  
  15.         /*计算扩展矩阵*/  
  16.         calculateExpandMatrix(expand_matrix);  
  17.         /*用计算过的扩展矩阵取后面的N*N矩阵,为所求*/  
  18.         getNewMatrix(expand_matrix,new_matrix);       
  19.           
  20.         return new_matrix;  
  21.     }  
  22.   
  23.     /*初始化扩展矩阵*/  
  24.     private void initExpandMatrix(double[][] init_matrix,double[][] expand_matrix) {  
  25.           
  26.         for (int i = 0; i < expand_matrix.length; i++)  
  27.             for (int j = 0; j < expand_matrix[i].length; j++) {  
  28.                 if (j < expand_matrix.length) {//左边的N*N矩阵原样赋值   
  29.                     expand_matrix[i][j] = init_matrix[i][j];  
  30.                 } else {    //右边N*N赋值为单位矩阵   
  31.                     if (j == expand_matrix.length + i)//如果为右边矩阵的对角线就赋值为1   
  32.                         expand_matrix[i][j] = 1;  
  33.                     else  
  34.                         expand_matrix[i][j] = 0;  
  35.                 }  
  36.             }  
  37.           
  38.     }  
  39.   
  40.     /*调整扩展矩阵,若某一列全为0,则行列式的值等于0,不存在逆矩阵*/  
  41.     private boolean adjustMatrix(double[][] expand_matrix) {  
  42.           
  43.         for (int i = 0; i < expand_matrix.length; i++) {  
  44.             if (expand_matrix[i][i] == 0) {//如果某行对角线数值为0   
  45.                 int j;  
  46.                 /*搜索该列其他不为0的行,如果都为0,则返回false*/  
  47.                 for (j = 0; j < expand_matrix.length; j++) {  
  48.   
  49.                     if (expand_matrix[j][i] != 0) {//如果有不为0的行,交换这两行   
  50.                         double[] temp = expand_matrix[i];  
  51.                         expand_matrix[i] = expand_matrix[j];  
  52.                         expand_matrix[j] = temp;  
  53.                         break;  
  54.                     }  
  55.   
  56.                 }  
  57.                 if (j >= expand_matrix.length) {//没有不为0的行   
  58.                     System.out.println("此矩阵没有逆矩阵");  
  59.                     return false;  
  60.                 }  
  61.             }  
  62.         }  
  63.         return true;  
  64.     }  
  65.     /*计算扩展矩阵*/  
  66.     private void calculateExpandMatrix(double[][] expand_matrix) {  
  67.           
  68.         for (int i = 0; i < expand_matrix.length; i++) {  
  69.   
  70.             double first_element = expand_matrix[i][i];  
  71.   
  72.             for (int j = 0; j < expand_matrix[i].length; j++)  
  73.   
  74.                 expand_matrix[i][j] /= first_element;//将该行所有元素除以首元素   
  75.               
  76.             /*把其他行再该列的数值都化为0*/  
  77.             for (int m = 0; m < expand_matrix.length; m++) {  
  78.                 if (m == i)//遇到自己的行跳过   
  79.                     continue;  
  80.   
  81.                 double beishu = expand_matrix[m][i];  
  82.                 for (int n = 0; n < expand_matrix[i].length; n++) {                
  83.                     expand_matrix[m][n] -= expand_matrix[i][n] * beishu;  
  84.                 }  
  85.             }  
  86.   
  87.         }  
  88.           
  89.     }  
  90.     /*用计算过的扩展矩阵取后面的N*N矩阵,为所求*/  
  91.     private void getNewMatrix(double[][] expand_matrix, double[][] new_matrix) {  
  92.           
  93.         for(int i = 0; i < expand_matrix.length; i++)  
  94.             for(int j = 0; j < expand_matrix[i].length; j++){  
  95.                 if(j >= expand_matrix.length)  
  96.                     new_matrix[i][j-expand_matrix.length] = expand_matrix[i][j];  
  97.             }  
  98.           
  99.     }  
  100.   
  101.     /*打印矩阵*/  
  102.     public void printMatrix(double[][] matrix){  
  103.   
  104.         for (double[] tempi : matrix) {  
  105.             for (double tempj : tempi) {  
  106.                 System.out.print(tempj + "  ");  
  107.             }  
  108.             System.out.println();  
  109.         }  
  110.           
  111.     }  
  112.     /*矩阵做乘法,验证结果*/  
  113.     private static double[][] getProductMatrix(double[][] init_matrix,  
  114.             double[][] new_matrix) {  
  115.           
  116.         int len = init_matrix.length;  
  117.         double[][] product_matrix = new double[len][len];  
  118.         for(int i = 0; i < len; i++){  
  119.             for(int j = 0; j < len; j++)  
  120.                 for(int k = 0; k < len; k++)  
  121.                     product_matrix[i][j] += init_matrix[i][k] * new_matrix[k][j];  
  122.         }  
  123.         return product_matrix;  
  124.     }  
  125.       
  126.   
  127.     public static void main(String[] args) {  
  128.           
  129.         NiMatrix _robot = new NiMatrix();  
  130.           
  131.         System.out.println("=====原矩阵=====");  
  132.         double init_matrix[][] = {   
  133.                 { 12, -1 },  
  134.                 { 34, -2 },   
  135.                 { 5, -41 }   
  136.             };  
  137.         _robot.printMatrix(init_matrix);  
  138.           
  139.         System.out.println("=====逆矩阵=====");  
  140.         double new_matrix[][] = _robot.getNiMatrix(init_matrix);  
  141.         _robot.printMatrix(new_matrix);  
  142.           
  143.         System.out.println("=====原矩阵*逆矩阵=====");  
  144.         double[][] product_matrix = getProductMatrix(init_matrix,new_matrix);  
  145.         _robot.printMatrix(product_matrix);  
  146.     }  
  147.   
  148. }  
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

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

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值