/** * Q = I - gamma*u*u<sup>H</sup> */ public static ZMatrixRMaj householder(ZMatrixRMaj u, double gamma) { int N = u.getDataLength() / 2; // u*u^H ZMatrixRMaj uut = new ZMatrixRMaj(N, N); VectorVectorMult_ZDRM.outerProdH(u, u, uut); // foo = -gamma*u*u^H CommonOps_ZDRM.elementMultiply(uut, -gamma, 0, uut); // I + foo for (int i = 0; i < N; i++) { int index = (i * uut.numCols + i) * 2; uut.data[index] = 1 + uut.data[index]; } return(uut); }
/** * <p> * Unitary matrices have the following properties:<br><br> * Q*Q<sup>H</sup> = I * </p> * <p> * This is the complex equivalent of orthogonal matrix. * </p> * @param Q The matrix being tested. Not modified. * @param tol Tolerance. * @return True if it passes the test. */ public static bool isUnitary(ZMatrixRMaj Q, double tol) { if (Q.numRows < Q.numCols) { throw new ArgumentException("The number of rows must be more than or equal to the number of columns"); } Complex_F64 prod = new Complex_F64(); ZMatrixRMaj[] u = CommonOps_ZDRM.columnsToVector(Q, null); for (int i = 0; i < u.Length; i++) { ZMatrixRMaj a = u[i]; VectorVectorMult_ZDRM.innerProdH(a, a, prod); if (Math.Abs(prod.real - 1) > tol) { return(false); } if (Math.Abs(prod.imaginary) > tol) { return(false); } for (int j = i + 1; j < u.Length; j++) { VectorVectorMult_ZDRM.innerProdH(a, u[j], prod); if (!(prod.getMagnitude2() <= tol * tol)) { return(false); } } } return(true); }