/* ------------------------ Constructor * ------------------------ */ /** Cholesky algorithm for symmetric and positive definite matrix. @param A Square, symmetric matrix. @return Structure to access L and isspd flag. */ public CholeskyDecomposition(Matrix Arg) { // Initialize. double[][] A = Arg.getArray(); n = Arg.getRowDimension(); L = new double[n][]; for(int i = 0; i < n; i++) { L[n] = new double[n]; } isspd = (Arg.getColumnDimension() == n); // Main loop. for (int j = 0; j < n; j++) { double[] Lrowj = L[j]; double d = 0.0; for (int k = 0; k < j; k++) { double[] Lrowk = L[k]; double s = 0.0; for (int i = 0; i < k; i++) { s += Lrowk[i]*Lrowj[i]; } Lrowj[k] = s = (A[j][k] - s)/L[k][k]; d = d + s*s; isspd = isspd & (A[k][j] == A[j][k]); } d = A[j][j] - d; isspd = isspd & (d > 0.0); L[j][j] = Math.Sqrt(Math.Max(d,0.0)); for (int k = j+1; k < n; k++) { L[j][k] = 0.0; } } }
/* ------------------------ Constructor * ------------------------ */ /** Check for symmetry, then construct the eigenvalue decomposition @param A Square matrix @return Structure to access D and V. */ public EigenvalueDecomposition(Matrix Arg) { double[][] A = Arg.getArray(); n = Arg.getColumnDimension(); V = new double[n][]; for(int i = 0; i < n ; i++) { V[i]= new double [n]; } d = new double[n]; e = new double[n]; issymmetric = true; for (int j = 0; (j < n) & issymmetric; j++) { for (int i = 0; (i < n) & issymmetric; i++) { issymmetric = (A[i][j] == A[j][i]); } } if (issymmetric) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { V[i][j] = A[i][j]; } } // Tridiagonalize. tred2(); // Diagonalize. tql2(); } else { H = new double[n][]; for(int i = 0; i < n ; i++) { H[i]= new double [n]; } ort = new double[n]; for (int j = 0; j < n; j++) { for (int i = 0; i < n; i++) { H[i][j] = A[i][j]; } } // Reduce to Hessenberg form. orthes(); // Reduce Hessenberg to real Schur form. hqr2(); } }
/** Return the diagonal matrix of singular values @return S */ public Matrix getS() { Matrix X = new Matrix(n, n); double[][] S = X.getArray(); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { S[i][j] = 0.0; } S[i][i] = this.s[i]; } return X; }
/** Return the block diagonal eigenvalue matrix @return D */ public Matrix getD() { Matrix X = new Matrix(n,n); double[][] D = X.getArray(); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { D[i][j] = 0.0; } D[i][i] = d[i]; if (e[i] > 0) { D[i][i+1] = e[i]; } else if (e[i] < 0) { D[i][i-1] = e[i]; } } return X; }
/** Return upper triangular factor @return U */ public Matrix getU() { Matrix X = new Matrix(n, n); double[][] U = X.getArray(); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (i <= j) { U[i][j] = LU[i][j]; } else { U[i][j] = 0.0; } } } return X; }
/** Return lower triangular factor @return L */ public Matrix getL() { Matrix X = new Matrix(m, n); double[][] L = X.getArray(); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (i > j) { L[i][j] = LU[i][j]; } else if (i == j) { L[i][j] = 1.0; } else { L[i][j] = 0.0; } } } return X; }