/** * 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 ZMatrixRMaj householderVector(ZMatrixRMaj x) { ZMatrixRMaj u = (ZMatrixRMaj)x.copy(); double max = CommonOps_ZDRM.elementMaxAbs(u); CommonOps_ZDRM.elementDivide(u, max, 0, u); double nx = NormOps_ZDRM.normF(u); Complex_F64 c = new Complex_F64(); u.get(0, 0, c); double 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_ZDRM.elementDivide(u, u.getReal(0, 0), u.getImag(0, 0), u); return(u); }
/** * <p> * Creates a reflector from the provided vector.<br> * <br> * Q = I - γ u u<sup>T</sup><br> * γ = 2/||u||<sup>2</sup> * </p> * * @param u A vector. Not modified. * @return An orthogonal reflector. */ public static ZMatrixRMaj createReflector(ZMatrixRMaj u) { if (!MatrixFeatures_ZDRM.isVector(u)) { throw new ArgumentException("u must be a vector"); } double norm = NormOps_ZDRM.normF(u); double gamma = -2.0 / (norm * norm); ZMatrixRMaj Q = CommonOps_ZDRM.identity(u.getNumElements()); CommonOps_ZDRM.multAddTransB(gamma, 0, u, u, Q); return(Q); }