〖數學算法〗逆矩陣算法

矩陣大家一定都很熟悉,它是線性代數中的一個術語,它在生產實踐,科研,等各學科都有不可替代的作用,求逆矩陣當然是矩陣的一種常用操作,今天就寫了個求逆矩陣的程序鞏固下基本功。

首先讓我們回憶一下你矩陣的定義:

逆矩陣設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

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章