/** * 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); }
/** * Decomposes the input matrix 'a' and makes sure it isn't modified. */ public static bool decomposeSafe(DecompositionInterface <ZMatrixRMaj> decomposition, ZMatrixRMaj a) { if (decomposition.inputModified()) { a = (ZMatrixRMaj)a.copy(); } return(decomposition.decompose(a)); }
/** * Returns the determinant of the matrix. If the inverse of the matrix is also * needed, then using {@link LUDecompositionAlt_ZDRM} directly (or any * similar algorithm) can be more efficient. * * @param mat The matrix whose determinant is to be computed. Not modified. * @return The determinant. */ public static Complex_F64 det(ZMatrixRMaj mat) { LUDecompositionAlt_ZDRM alg = new LUDecompositionAlt_ZDRM(); if (alg.inputModified()) { mat = mat.copy(); } if (!alg.decompose(mat)) { return(new Complex_F64()); } return(alg.computeDeterminant()); }
/** * <p> * Checks to see if the matrix is positive definite. * </p> * <p> * x<sup>T</sup> A x > 0<br> * for all x where x is a non-zero vector and A is a hermitian matrix. * </p> * * @param A square hermitian matrix. Not modified. * * @return True if it is positive definite and false if it is not. */ public static bool isPositiveDefinite(ZMatrixRMaj A) { if (A.numCols != A.numRows) { return(false); } CholeskyDecompositionInner_ZDRM chol = new CholeskyDecompositionInner_ZDRM(true); if (chol.inputModified()) { A = (ZMatrixRMaj)A.copy(); } return(chol.decompose(A)); }
/** * <p> * Performs a matrix inversion operation that does not modify the original * and stores the results in another matrix. The two matrices must have the * same dimension.<br> * <br> * b = a<sup>-1</sup> * </p> * * <p> * If the algorithm could not invert the matrix then false is returned. If it returns true * that just means the algorithm finished. The results could still be bad * because the matrix is singular or nearly singular. * </p> * * <p> * For medium to large matrices there might be a slight performance boost to using * {@link LinearSolverFactory_ZDRM} instead. * </p> * * @param input The matrix that is to be inverted. Not modified. * @param output Where the inverse matrix is stored. Modified. * @return true if it could invert the matrix false if it could not. */ public static bool invert(ZMatrixRMaj input, ZMatrixRMaj output) { LinearSolverDense <ZMatrixRMaj> solver = LinearSolverFactory_ZDRM.lu(input.numRows); if (solver.modifiesA()) { input = input.copy(); } if (!solver.setA(input)) { return(false); } solver.invert(output); return(true); }