`

矩阵求逆(JAVA)初等行变换

阅读更多
package gaodai.matrix;

import gaodai.determinant.DeterminantCalculation;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 * 矩阵求逆(初等行变换)
 * @author 邱万迟
 *
 */
public class InverseOfMatrix {
	
	private List<List<Double>> matrix;
	private int lineNum;
	private int columnNum;
	
	public InverseOfMatrix(List<List<Double>> data){
		matrix = data;
		lineNum = data.size();
		columnNum = data.get(0).size();
	}
	
	public void caculate() throws Exception{
		
		//1.非方正不能求逆
		//2.方正的行列式值为零不能求逆
		if( lineNum != columnNum){
			throw new Exception("此矩阵不能求逆>>>>>>>>>>>>>>>>>");
		}
		List<List<Double>> tempList = new ArrayList<List<Double>>();
		for(List<Double> l : matrix){
			List<Double> newList = new ArrayList<Double>();
			newList.addAll(l);
			tempList.add(newList);
		}
		
		DeterminantCalculation d = new DeterminantCalculation(tempList);
		d.chang2UpperTriangle();
		double result = d.getValue();
		if(result == 0){
			throw new Exception("此矩阵不能求逆>>>>>>>>>>>>>>>>>");
		}
		
		//增加单位矩阵
		for(int i = 0; i < lineNum; i++){
			List<Double> list = matrix.get(i);
			for(int j = 0; j < columnNum; j++){
				if(i == j){
					list.add(1.0);
				}else{
					list.add(0.0);
				}
			}
		}
		print();
		chang2UpperTriangle();//化为上三角
		changeReducedMatrix();//化为约化矩阵
		print();
	}
	
	public void getValue(){
		boolean flag = true;
		for(int i = 0; i < lineNum; i++){
			if(matrix.get(i).get(i) == 0){
				flag = false;
			}
			if(!flag){
				break;
			}
		}
		
		if(!flag){
			System.out.println("此矩阵不可逆>>>>>>>>>>>>>>");
		}else{
			
			for(int i = 0; i < lineNum; i++){
				List<Double> list = matrix.get(i);
				for(int j = 0; j < columnNum; j++){
					list.remove(0);
				}
			}
			System.out.println("逆矩阵为>>>>>>>>>>>>>>>>>");
			print();
		}
	}
	
	/**
	 * 打印
	 */
	public void print() {
		int i = 0, j = 0;
		for (List<Double> line : matrix) {
			for (double element : line) {
				System.out.print(element);
				System.out.print("(" + i + "," + j + ")  ");
				System.out.print("  ");
				j++;
			}
			System.out.println();
			i++;
			j = 0;
		}
		System.out.println();
	}
	
	/**
	 * 校验是否是上三角,不是就的继续计算
	 * 
	 * @return
	 */
	public boolean isCaculate() {
		boolean hasCaculate = false;
		for (int i = 0; i < matrix.size(); i++) {
			for (int j = 0; j < i; j++) {
				if (matrix.get(i).get(j) != 0.0) {
					System.out.println("(" + (i + 1) + "," + (j + 1) + ")元素值不为零");
					hasCaculate = true;
					break;
				}
			}
			if (hasCaculate) {
				break;
			}
		}
		return hasCaculate;
	}

	private int caculateTimes;

	/**
	 * 化为上三角
	 * @throws Exception
	 */
	public void chang2UpperTriangle() throws Exception {

		if (!isCaculate()) {
			return;
		}
		
		int min = lineNum;
		caculateTimes++;
		System.out.println("--------------第" + caculateTimes + "次计算--------------");
		for (int i = 0; i < min; i++) {
			for (int j = i + 1; j < min; j++) {
				double multiplyNum = -1 * matrix.get(j).get(i) / matrix.get(i).get(i);
				if (multiplyNum == 0) {
					continue;
				}
				this.lineMultiplyNumAdd2OtherLine(multiplyNum, (i + 1), (j + 1));
				print();
			}
		}
		print();
		chang2UpperTriangle();
	}
	
	/**
	 * 变为约化矩阵
	 */
	public void changeReducedMatrix() throws Exception{
		for(int i = 0; i < lineNum; i++){//行
			if(i == 0){
				//continue;
			}
			List<Double> temp = matrix.get(i);
			
			for(Double d : temp){
				if(d == 0){
					continue;
				}
				double multiplyNum = 1.0 / d;
				
				for(int a = 0; a < temp.size(); a++){
					temp.set(a, temp.get(a) * multiplyNum);
				}
				break;
			}
			print();
			for(int j = 0; j <= columnNum; j++){//列
				
				if(temp.get(j) != 0){//这个数不为零 ,此数为第 i行第j列
					for(int t = 0; t < lineNum; t++){//行
						if(t == i || matrix.get(t).get(j) == 0){//本列的其他行
							continue;
						}
						
						double multiplyNum = -1 * matrix.get(t).get(j) / temp.get(j);
						this.lineMultiplyNumAdd2OtherLine(multiplyNum, (i + 1), (t + 1));
						print();
					}
					break;
				}
			}
		}
	}
	
	/**
	 * 第a行乘以number 加到第b行上
	 * @param number 乘以的数
	 * @param a行号
	 * @param b行号
	 * @throws Exception
	 */
	public void lineMultiplyNumAdd2OtherLine(double number, int a, int b) throws Exception {
		if (a < 1 || a > matrix.size() || b < 1 || b > matrix.size()) {
			throw new Exception("输入的行号不合法");
		}
		List<Double> aLine = matrix.get(a - 1);
		List<Double> bLine = matrix.get(b - 1);

		for (int i = 0; i < bLine.size(); i++) {
			double temp = bLine.get(i) + aLine.get(i) * number;
			bLine.set(i, temp);
		}
		System.out.println("第" + a + "行乘以" + number + "加到第" + b + "行:");
	}
	
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		
		System.out.println("请输入矩阵的行数与列数,用逗号分隔:");
		
		String sn = scanner.next();
		String[] snArr = sn.split(",");
		int lineNum = Integer.valueOf(snArr[0]);
		int columnNum = Integer.valueOf(snArr[1]);
		List<List<Double>> matrix = new ArrayList<List<Double>>();
		for(int i = 0; i < lineNum; i++){
			System.out.println("请输入第" + (i + 1) + "行的数,用逗号分隔:");
			String lineData = scanner.next();
			String[] lineDataArr = lineData.split(","); 
			List<Double> line = new ArrayList<Double>();
			matrix.add(line);
			for(int j = 0; j < columnNum; j++){
				line.add(Double.valueOf(lineDataArr[j]));
			}
		}
		
		InverseOfMatrix m = new InverseOfMatrix(matrix);
		m.print();
		try {
			m.caculate();
			m.getValue();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

 

 

18
10
分享到:
评论

相关推荐

    matrix-inverse-calculator:逆矩阵的Java工具等

    1. 高斯-约旦消元法:通过行初等变换将矩阵变为单位矩阵,同时原矩阵右侧的单位矩阵会变成其逆矩阵。 2.伴随矩阵法:计算矩阵的行列式,若不为零,则可以通过取行列式的倒数与伴随矩阵相乘得到逆矩阵。 3.LU分解或QR...

    JAVA实现多元一次方程组的算法.docx

    - 使用初等行变换(即行互换、行乘以非零常数、行加上另一行的倍数)将增广矩阵化简为上三角矩阵或阶梯形矩阵。 - 此过程主要目的是消除下方元素,使矩阵的下部成为零。 2. **回代求解**: - 从最后一个方程开始...

    科学与工程数值计算算法

    2.16 约化一般实矩阵为赫申伯格矩阵的初等相似变换法 2.17 求赫申伯格矩阵全部特征值的QR方法 2.18 求实对称矩阵特征值与特征向量的雅可比法 2.19 求实对称矩阵特征值与特征向量的雅可比过关法 第3章 线性...

    Group-3.zip_Jordan

    高斯-乔丹消元法的核心思想是通过一系列行变换将系数矩阵与单位矩阵结合成一个上三角形矩阵,从而简化线性方程组的求解。具体步骤包括交换行、扩大某一行的倍数以及将某一行加上另一行的倍数。一旦得到上三角形矩阵...

    高斯算法易语言源码.7z

    1. **行标准化**:对系数矩阵进行初等行变换,使其变为上三角形或部分上三角形,即每一行的第一个非零元素(主元)位于该行的首列。 2. **回代求解**:从最后一行开始,利用上三角形矩阵的性质,逐行向上计算未知数...

    MatLab等软件在条件平差求解法方程过程中的应用探讨.pdf

    这些难题主要包括非线性和线性方程组的求解,常用的数学解法有高斯消元法、求逆法(包括初等变换、伴随矩阵和因式分解法)以及迭代法等。 MatLab软件在解决这些数学问题时表现出色。MatLab是MathWorks公司开发的...

    matlab集锦.docx

    3. 初等变换:rref。 4. 特殊矩阵:矩阵范数:norm 特征值:eig/eigs 条件数:cond。 5. 元素全为 1 的矩阵:ones 单位阵:eye 元素全为 0 的矩阵:zeros 魔方阵:magic。 MATLAB 随机数 1. 创建一个元素服从均匀...

    Matlab常见问题集锦.docx

    8. **矩阵分析**:`fliplr`、`flipud`、`transpose`、`inv`、`rref`、`norm`、`eig`、`cond`等函数分别用于矩阵的翻转、转置、求逆、初等行变换、范数、特征值和条件数。 9. **特殊矩阵**:`ones`、`eye`、`linspace...

    计算机数学基础(2)--线性方程组(02-10).pdf

    1. **高斯顺序消去法**:这是解线性方程组的常用方法,通过一系列初等行变换将增广矩阵 `[A|b]` 转换为上三角矩阵。过程中,确保在每一步 `k` 中,`akk ≠ 0`(`k = 1, 2, ..., n-1`),以保持矩阵的可逆性。一旦...

    Matlab常见问题集锦 (2).docx

    10. 矩阵操作:`fliplr`和`flipud`进行翻转,`transpose`转置,`inv`求逆,`rref`进行初等行变换,`norm`计算范数,`eig/eigs`求特征值,`cond`计算条件数。 11. 特殊矩阵:`ones`生成全1矩阵,`eye`生成单位阵,`...

    MATLAB快捷键大全_很全面_最新版

    * 矩阵求逆:inv * 矩阵范数:norm * 条件数:cond * 初等变换:rref * 特征值:eig/eigs Excel 数据导入 * 如何将 excel 数据导入 matlab?使用 ExcelLink。 * 关于 matlab 中的 xlsread 函数:这个函数可以读出 ...

    Matlab常见问题集锦.doc

    9. `fliplr`和`flipud`翻转矩阵,`transpose`转置,`inv`求逆,`norm`范数,`cond`条件数,`rref`初等行变换,`eig/eigs`求特征值。 10. `ones`、`zeros`、`eye`、`magic`、`linspace`、`cat/horzcat/vertcat`生成...

    Matlab在二次型求解中的应用.pdf

    二次型可以通过不同的方法转化为标准型,如正交变换法、配方法和初等变换法等。 #### 四、Matlab在二次型求解中的应用 ##### 4.1 计算标准化二次型的正交矩阵 利用Matlab可以很方便地求解二次型的标准型,并找到...

    ACM/ICPC模板

    --快速付利叶变换 --稳定婚姻问题 --SPFA(最短路快速算法) // thanks to love8909 几何相关 --初等几何学 --多边形几何 --几种凸包算法 --半平面交算法 --旋转卡壳算法 数据结构 --可合并堆(左偏树实现) --树状...

    算法导论(part1)

    书中的算法以英语加伪代码的形式给出,只要有一点程序设计经验的人都能读懂,并可以用任何计算机语言(如C/C++和Java等)方便地实现。在书中,作者将算法的讨论集中在一些比较现代的例子上,它们来自分子生物学(如...

    算法导论(part2)

    书中的算法以英语加伪代码的形式给出,只要有一点程序设计经验的人都能读懂,并可以用任何计算机语言(如C/C++和Java等)方便地实现。在书中,作者将算法的讨论集中在一些比较现代的例子上,它们来自分子生物学(如...

Global site tag (gtag.js) - Google Analytics