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;
 }
예제 #2
0
  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);
    }
  }