/** * <p>Hermitian matrix is a square matrix with complex entries that are equal to its own conjugate transpose.</p> * * <p>a[i,j] = conj(a[j,i])</p> * * @param Q The matrix being tested. Not modified. * @param tol Tolerance. * @return True if it passes the test. */ public static bool isHermitian(CMatrixRMaj Q, float tol) { if (Q.numCols != Q.numRows) { return(false); } Complex_F32 a = new Complex_F32(); Complex_F32 b = new Complex_F32(); for (int i = 0; i < Q.numCols; i++) { for (int j = i; j < Q.numCols; j++) { Q.get(i, j, a); Q.get(j, i, b); if (Math.Abs(a.real - b.real) > tol) { return(false); } if (Math.Abs(a.imaginary + b.imaginary) > tol) { return(false); } } } return(true); }
/** * Computes the householder vector used in QR decomposition. * * u = x / max(x) * u(0) = u(0) + |u| * u = u / u(0) * * @param x Input vector. Unmodified. * @return The found householder reflector vector */ public static CMatrixRMaj householderVector(CMatrixRMaj x) { CMatrixRMaj u = (CMatrixRMaj)x.copy(); float max = CommonOps_CDRM.elementMaxAbs(u); CommonOps_CDRM.elementDivide(u, max, 0, u); float nx = NormOps_CDRM.normF(u); Complex_F32 c = new Complex_F32(); u.get(0, 0, c); float realTau, imagTau; if (c.getMagnitude() == 0) { realTau = nx; imagTau = 0; } else { realTau = c.real / c.getMagnitude() * nx; imagTau = c.imaginary / c.getMagnitude() * nx; } u.set(0, 0, c.real + realTau, c.imaginary + imagTau); CommonOps_CDRM.elementDivide(u, u.getReal(0, 0), u.getImag(0, 0), u); return(u); }