/** * 求矩阵的逆矩阵 为矩阵右加一个单位矩阵后进行初等行变换,当左边变成单位矩阵时,右边就是求得的逆矩阵。 矩阵的初等行变换法则 * (1)交换变换:交换两行 (2)倍法变换:给一行数据乘以一个非0常数 (3)消法变换:把一行所有元素的k倍加到另一行的对应元素上去 * 将上述规则中的行换成列同样有效 只有方阵才可能有逆矩阵! * * @return */ public Matrix inverseMatrix() { if (!this.isSquareMatrix()) { System.out.println("不是方阵没有逆矩阵!"); return null; } // 先在右边加上一个单位矩阵。 Matrix tempM = this.appendUnitMatrix(); // 再进行初等变换,把左边部分变成单位矩阵 double[][] tempData = tempM.getMatrixData(); int tempRow = tempData.length; int tempCol = tempData[0].length; // 对角线上数字为0时,用于交换的行号 int line = 0; // 对角线上数字的大小 double bs = 0; // 一个临时变量,用于交换数字时做中间结果用 double swap = 0; for (int i = 0; i < tempRow; i++) { // 将左边部分对角线上的数据等于0,与其他行进行交换 if (tempData[i][i] == 0) { if (++line >= tempRow) { System.out.println("此矩阵没有逆矩阵!"); return null; } for (int j = 0; j < tempCol; j++) { swap = tempData[i][j]; tempData[i][j] = tempData[line][j]; tempData[line][j] = swap; } // 当前行(第i行)与第line行进行交换后,需要重新对第i行进行处理 // 因此,需要将行标i减1,因为在for循环中会将i加1。 i--; // 继续第i行处理,此时第i行的数据是原来第line行的数据。 continue; } // 将左边部分矩阵对角线上的数据变成1.0 if (tempData[i][i] != 1) { bs = tempData[i][i]; for (int j = tempCol - 1; j >= 0; j--) { tempData[i][j] /= bs; } // 将左边部分矩阵变成上对角矩阵, // 所谓上对角矩阵是矩阵的左下角元素全为0 for (int iNow = i + 1; iNow < tempRow; iNow++) { for (int j = tempCol - 1; j >= i; j--) { tempData[iNow][j] -= tempData[i][j] * tempData[iNow][i]; } } } } // 将左边部分矩阵从上对角矩阵变成单位矩阵,即将矩阵的右上角元素也变为0 for (int i = 0; i < tempRow - 1; i++) { for (int iNow = i; iNow < tempRow - 1; iNow++) { for (int j = tempCol - 1; j >= 0; j--) { tempData[i][j] -= tempData[i][iNow + 1] * tempData[iNow + 1][j]; } } } // 右边部分就是它的逆矩阵 Matrix c = null; int cRow = tempRow; int cColumn = tempCol / 2; double[][] cData = new double[cRow][cColumn]; // 将右边部分的值赋给cData for (int i = 0; i < cRow; i++) { for (int j = 0; j < cColumn; j++) { cData[i][j] = tempData[i][cColumn + j]; } } // 得到逆矩阵,返回 c = new Matrix(cData); return c; }