java实现求可逆矩阵使用单位矩阵拼接的形式
2015-06-29 10:33
495 查看
import java.text.DecimalFormat; /** * 使用单位矩阵拼接的形式 * @author imlilu * */ public class InverseMatrixSecond { /*** * 增广矩阵机型初等行变化的算法 * * @param value * 需要算的增广矩阵 * @return 计算的结果 */ public static double[][] mathDeterminantCalculation(double[][] value) throws Exception { // 当矩阵的行数大于2时 for (int i = 0; i < value.length; i++) { // 检查数组对角线位置的数值是否是0,如果是零则对该数组进行调换,查找到一行不为0的进行调换 if (value[i][i] == 0) { value = changeDeterminantNoZero(value, i, i); } for (int j = 0; j < i; j++) { // 让开始处理的行的首位为0处理为三角形式 // 如果要处理的列为0则和自己调换一下位置,这样就省去了计算 if (value[i][j] == 0) { continue; } // 如果要是要处理的行是0则和上面的一行进行调换 if (value[j][j] == 0) { double[] temp = value[i]; value[i] = value[i - 1]; value[i - 1] = temp; continue; } double ratio = -(value[i][j] / value[j][j]); value[i] = addValue(value[i], value[j], ratio); } } return value; } /** * 检查矩阵是否可逆 * * @param value * 要检查的矩阵 * @return 矩阵的行列式的值 * @throws Exception * 抛出的异常 */ public static double mathDeterminantCalculationValue(double[][] value) throws Exception { value = mathDeterminantCalculation(value); DecimalFormat df = new DecimalFormat(".##"); return Double.parseDouble(df.format(mathValue(value, 1))); } /** * 计算行列式的结果 * * @param value * @return */ public static double mathValue(double[][] value, double result) throws Exception { for (int i = 0; i < value.length; i++) { // 如果对角线上有一个值为0则全部为0,直接返回结果 if (value[i][i] == 0) { return 0; } result *= value[i][i]; } return result; } /*** * 将i行之前的每一行乘以一个系数,使得从i行的第i列之前的数字置换为0 * * @param currentRow * 当前要处理的行 * @param frontRow * i行之前的遍历的行 * @param ratio * 要乘以的系数 * @return 将i行i列之前数字置换为0后的新的行 */ public static double[] addValue(double[] currentRow, double[] frontRow, double ratio) throws Exception { for (int i = 0; i < currentRow.length; i++) { currentRow[i] += frontRow[i] * ratio; } return currentRow; } /** * 指定列的位置是否为0,查找第一个不为0的位置的行进行位置调换,如果没有则返回原来的值 * * @param determinant * 需要处理的行列式 * @param line * 要调换的行 * @param row * 要判断的列 */ public static double[][] changeDeterminantNoZero(double[][] determinant, int line, int row) throws Exception { for (int j = line; j < determinant.length; j++) { // 进行行调换 if (determinant[j][row] != 0) { double[] temp = determinant[line]; determinant[line] = determinant[j]; determinant[j] = temp; return determinant; } } return determinant; } /** * 将矩阵转化为单位阵和矩阵的拼接 * * @param inverseResult * 需要转换的矩阵 */ public static void changeMatixToUnit(double[][] inverseResult) { //将行和列都需要倒着进行运算 for (int i = inverseResult.length - 1; i > -1; i--) { for (int j = inverseResult.length -1; j > i-1; j--) { // 将需要修改的阶梯矩阵的前部分转换成为单位矩阵 if (j == i && inverseResult[i][j] != 0) { double temp = inverseResult[i][j]; // 当需要转换为单位阵的部分对角线上元素不为0的时候,整行除以这个数 for (int j2 = 0; j2 < inverseResult[i].length; j2++) { inverseResult[i][j2] = inverseResult[i][j2] / temp; } } else { // 如果不是对角线上的元素时,找下面的那行乘以一个系数然后和当前行的元素相加,变为0 for (int j2 = 1; j2 < inverseResult.length-j+2; j2++) { if (inverseResult[i+j2][j] != 0) { double temp = inverseResult[i][j] / inverseResult[i+j2][j]; for (int k = 0; k < inverseResult[i].length; k++) { inverseResult[i][k] -= (inverseResult[i+j2][k] * temp); } break; } } } } } } public static void main(String[] args) { // double[][] test = { { 2, 1, 1 }, { 3, 1, 2 }, { 1, -1, 0 } }; // double[][] test = {{3,-2,0,0},{5,-3,0,0},{0,0,3,4},{0,0,1,1}}; double[][] test = {{0,0,0,1,2},{0,0,0,2,3},{1,1,0,0,0},{0,1,1,0,0},{0,0,1,0,0}}; double result; try { // 将二维数组中的元素添加上等量的单位矩阵 double[][] temp = new double[test.length][test[0].length * 2]; // 在矩阵后边补加上单位矩阵 for (int i = 0; i < test.length; i++) { for (int j = 0; j < temp[i].length; j++) { if (j < test[i].length) { temp[i][j] = test[i][j]; } else if (j - test[i].length == i) { temp[i][j] = 1; } else { temp[i][j] = 0; } } } // 先计算矩阵的行列式的值是否等于0,如果不等于0则该矩阵是可逆的 result = mathDeterminantCalculationValue(test); if (result == 0) { System.out.println("矩阵不可逆"); } else { System.out.println("矩阵可逆"); // 转换成阶梯矩阵 double[][] inverseResult = mathDeterminantCalculation(temp); changeMatixToUnit(inverseResult); //去除前面的单位矩阵后 DecimalFormat df = new DecimalFormat(".##"); for (int i = 0; i < test.length; i++) { for (int j = 0; j < test[i].length; j++) { test[i][j] = Double.parseDouble(df.format(inverseResult[i][j+test.length])); } } // 将阶梯矩阵中的前部分转化为单位阵。 for (int i = 0; i < test.length; i++) { for (int j = 0; j < test[i].length; j++) { System.out.print(test[i][j] + " "); } System.out.println(); } } } catch (Exception e) { e.printStackTrace(); System.out.println("不是正确的行列式!!"); } } }
相关文章推荐
- 清除eclipse中 Launch configuration的历史记录
- java实现求可逆矩阵使用代数余子式的形式
- java通过JDBC链接SQLServer2012
- Byte转KB/MB/GB
- java实现N元一次方程组求解
- eclipse的安装配置
- #笔记#圣思园 JavaWeb 第12讲——JSP基础知识、语法、内置对象、表单、客户机交互
- Java连接并操作Sedna XML数据库的方法
- Java基础:字符串
- java如何实现系统监控、系统信息收集、sigar开源API的学习
- eclipse svn 修改了类名之后提交
- Java基础:泛型及其擦除性、不可协变性
- 使用 Google Guava 美化你的 Java 代码
- 关于Java浮点数运算精度丢失问题
- Eclipse jar包不能放在一个文件夹
- Java POI Word 写文档
- poi读写word模板 / java生成word文档
- Java学习笔记:JFrame与Frame的区别
- java---使用日志输出信息的方法
- JAVA安装