public static boolean checkPosDef(DenseMatrix covar) { final EigenDecompositionRightMTJ decomp = EigenDecompositionRightMTJ.create(covar); for (final ComplexNumber eigenVal : decomp.getEigenValues()) { if (eigenVal.getRealPart() < 0) return false; } return true; }
public ComplexNumber logDeterminant() { if (this.isSquare() == false) { throw new IllegalArgumentException("Matrix must be square"); } DenseMatrix decompositionMatrix; if (this instanceof DenseMatrix) { decompositionMatrix = (DenseMatrix) this; } else { decompositionMatrix = new DenseMatrix(this); } boolean useEVD = false; if (useEVD) { EigenDecompositionRightMTJ evd = EigenDecompositionRightMTJ.create(decompositionMatrix); return evd.getLogDeterminant(); } else { // Note: It's generally faster to use LU decomposition for // determinants, but QR can be more stable in some circumstances no.uib.cipr.matrix.UpperTriangDenseMatrix triangularMatrix; boolean useQR = false; int sign; if (useQR) { no.uib.cipr.matrix.QR decomposition = no.uib.cipr.matrix.QR.factorize(this.internalMatrix); triangularMatrix = decomposition.getR(); sign = 1; } else { no.uib.cipr.matrix.DenseLU decomposition = no.uib.cipr.matrix.DenseLU.factorize(this.internalMatrix); triangularMatrix = decomposition.getU(); sign = 1; for (int i = 0; i < decomposition.getPivots().length; i++) { if (decomposition.getPivots()[i] != (i + 1)) { sign = -sign; } } } int M = triangularMatrix.numRows(); int N = triangularMatrix.numColumns(); int maxIndex = (M < N) ? M : N; // Both LU and QR return upper triangular matrices and the "L" and // "Q" matrices have a determinant of one, so the real action is // in the "U" and "R" matrices, which are both upper (right) // triangular. As we remember from our algebra courses, the // eigenvalues of a triangular matrix are the diagonal elements // themselves. We also remember that the product of the eigenvalues // is the determinant. // // The diagonal elements (for either LU or QR) will be REAL, but // they may be negative. The logarithm of a negative number is // the logarithm of the absolute value of the number, with an // imaginary part of PI. The exponential is all that matters, so // the log-determinant is equivalent, MODULO PI (3.14...), so // we just toggle this sign bit. double logsum = 0.0; for (int i = 0; i < maxIndex; i++) { double eigenvalue = triangularMatrix.get(i, i); if (eigenvalue < 0.0) { sign = -sign; logsum += Math.log(-eigenvalue); } else { logsum += Math.log(eigenvalue); } } return new ComplexNumber(logsum, (sign < 0) ? Math.PI : 0.0); } }