gnu.gleem.linalg Class NonSquareMatrixException java.lang.Object | +--java.lang.Throwable | +--java.lang.Exception | +--java.lang.RuntimeException | +--gnu.gleem.linalg.NonSquareMatrixException All Implemented Interfaces: java.io.Serializable Download package gnu.gleem.linalg.* =======================================================================================
/** * FileName: Matrix.java * Author: Shiuh-Sheng Yu * Date: 4/13/1998 * Last Update: 4/13/2003 */ public class Matrix { private double[][] data; public Matrix(double[][] array) { data = array; } /** * 高斯消去法求反矩陣 */ public Matrix inverse() throws NonSquareMatrixException { int n = data.length; if (n != data[0].length) { throw new NonSquareMatrixException(); } double factor, tmp; // 建立兩陣列,左邊同原資料,右邊為單位矩陣 double[][] rel = new double[n][n]; double[][] left = new double[n][n]; for (int row=0; row<n; row++) { for (int col=0; col<n; col++) { left[row][col] = data[row][col]; if (row==col) { rel[row][col]=1; } else { rel[row][col]=0; } } } /* 消去左下角 */ for (int col=0; col<n; col++) { // 由左而右 int nonzero; for (nonzero=col; nonzero<n && left[nonzero][col]==0; nonzero++) ; // 找非0之元素 if (nonzero==n) { // 反矩陣不存在 return null; } if (nonzero != col) { // 需要列交換,記得要乘-1 for (int each=0; each<n; each++) { tmp = left[col][each]; left[col][each] = left[nonzero][each]; left[nonzero][each] = -tmp; tmp = rel[col][each]; rel[col][each] = rel[nonzero][each]; rel[nonzero][each] = -tmp; } } for (int row=col+1;row<n;row++) { // 由上而下 if (left[row][col] != 0) { // 需要做列運算 factor = left[row][col]/left[col][col]; for (int each=0; each<n; each++) { // 由左而右做列運算 left[row][each] -= left[col][each]*factor; rel[row][each] -= rel[col][each]*factor; } } } } /* 消去右上角, 此時對角線上不可能是0 */ for (int col=n-1; col>0; col--) { // 由右而左 for (int row=col-1; row>=0; row--) { // 由下而上 if (left[row][col] != 0) { factor = left[row][col]/left[col][col]; for (int each=0; each<n; each++) { // 由左而右做列運算 // 左邊陣列的右上角不必管了 rel[row][each] -= rel[col][each]*factor; } } } } /* 將只剩對角線的左邊矩陣變成單位矩陣 */ for (int row=0; row<n; row++) { for (int col=0; col<n; col++) { rel[row][col] /= left[row][row]; } } return new Matrix(rel); } /** * 高斯消去法求值 */ public double value() throws NonSquareMatrixException { int n = data.length; if (n != data[0].length) { throw new NonSquareMatrixException(); } double tmp, factor, result = 1.0; // 複製原矩陣 double[][] right = new double[n][n]; for (int row=0; row<n; row++) { for (int col=0; col<n; col++) { right[row][col] = data[row][col]; } } for (int col=0; col<n-1; col++) { // 由左而右 int nonzero; for (nonzero=col; nonzero<n && right[nonzero][col]==0; nonzero++) ; // 找非0之元素 if (nonzero==n) { // 矩陣值為0 return 0; } if (nonzero != col) { // 列交換 result *= -1.0; for (int each=0; each<n; each++) { tmp = right[col][each]; right[col][each] = right[nonzero][each]; right[nonzero][each] = tmp; } } for (int row=col+1; row<n; row++) { // 由上而下 if (right[row][col] != 0) { // 需要列運算 factor = right[row][col]/right[col][col]; right[row][col]=0; // col左邊的怎麼算都是0,不用管他 for (int each=col+1; each<n; each++) { right[row][each] -= right[col][each]*factor; } } } } // 對角線上的連乘績即為行列式值 result *= right[0][0]; for (int i=1; i<n; i++) { result*=right[i][i]; } return result; } }