/** * 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); }
/** * Decomposes the input matrix 'a' and makes sure it isn't modified. */ public static bool decomposeSafe(DecompositionInterface <CMatrixRMaj> decomposition, CMatrixRMaj a) { if (decomposition.inputModified()) { a = (CMatrixRMaj)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_CDRM} 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_F32 det(CMatrixRMaj mat) { LUDecompositionAlt_CDRM alg = new LUDecompositionAlt_CDRM(); if (alg.inputModified()) { mat = (CMatrixRMaj)mat.copy(); } if (!alg.decompose(mat)) { return(new Complex_F32()); } 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(CMatrixRMaj A) { if (A.numCols != A.numRows) { return(false); } CholeskyDecompositionInner_CDRM chol = new CholeskyDecompositionInner_CDRM(true); if (chol.inputModified()) { A = (CMatrixRMaj)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_CDRM} 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(CMatrixRMaj input, CMatrixRMaj output) { LinearSolverDense <CMatrixRMaj> solver = LinearSolverFactory_CDRM.lu(input.numRows); if (solver.modifiesA()) { input = (CMatrixRMaj)input.copy(); } if (!solver.setA(input)) { return(false); } solver.invert(output); return(true); }