/** * <p> * Given a set of polynomial coefficients, compute the roots of the polynomial. Depending on * the polynomial being considered the roots may contain complex number. When complex numbers are * present they will come in pairs of complex conjugates. * </p> * * <p> * Coefficients are ordered from least to most significant, e.g: y = c[0] + x*c[1] + x*x*c[2]. * </p> * * @param coefficients Coefficients of the polynomial. * @return The roots of the polynomial */ public static Complex_F64[] findRoots(params double[] coefficients) { int N = coefficients.Length - 1; // Construct the companion matrix DMatrixRMaj c = new DMatrixRMaj(N, N); double a = coefficients[N]; for (int i = 0; i < N; i++) { c.set(i, N - 1, -coefficients[i] / a); } for (int i = 1; i < N; i++) { c.set(i, i - 1, 1); } // use generalized eigenvalue decomposition to find the roots EigenDecomposition_F64 <DMatrixRMaj> evd = DecompositionFactory_DDRM.eig(N, false); evd.decompose(c); Complex_F64[] roots = new Complex_F64[N]; for (int i = 0; i < N; i++) { roots[i] = evd.getEigenvalue(i); } return(roots); }
/** * @param tol Tolerance for a matrix being symmetric */ //public SwitchingEigenDecomposition_DDRM(int matrixSize, bool computeVectors, double tol) //{ // symmetricAlg = DecompositionFactory_DDRM.eig(matrixSize, computeVectors, true); // generalAlg = DecompositionFactory_DDRM.eig(matrixSize, computeVectors, false); // this.computeVectors = computeVectors; // this.tol = tol; //} public SwitchingEigenDecomposition_DDRM(EigenDecomposition_F64 <DMatrixRMaj> symmetricAlg, EigenDecomposition_F64 <DMatrixRMaj> generalAlg, double tol) { this.symmetricAlg = symmetricAlg; this.generalAlg = generalAlg; this.tol = tol; }
/** * * @param computeVectors * @param tol Tolerance for a matrix being symmetric */ public SwitchingEigenDecomposition_DDRM(int matrixSize, bool computeVectors, double tol) { symmetricAlg = DecompositionFactory_DDRM.eig(matrixSize, computeVectors, true); generalAlg = DecompositionFactory_DDRM.eig(matrixSize, computeVectors, false); this.computeVectors = computeVectors; this.tol = tol; }
/** * <p> * Computes a metric which measures the the quality of an eigen value decomposition. If a * value is returned that is close to or smaller than 1e-15 then it is within machine precision. * </p> * <p> * EVD quality is defined as:<br> * <br> * Quality = ||A*V - V*D|| / ||A*V||. * </p> * * @param orig The original matrix. Not modified. * @param eig EVD of the original matrix. Not modified. * @return The quality of the decomposition. */ public static double quality(DMatrixRMaj orig, EigenDecomposition_F64 <DMatrixRMaj> eig) { DMatrixRMaj A = orig; DMatrixRMaj V = EigenOps_DDRM.createMatrixV(eig); DMatrixRMaj D = EigenOps_DDRM.createMatrixD(eig); // L = A*V DMatrixRMaj L = new DMatrixRMaj(A.numRows, V.numCols); CommonOps_DDRM.mult(A, V, L); // R = V*D DMatrixRMaj R = new DMatrixRMaj(V.numRows, D.numCols); CommonOps_DDRM.mult(V, D, R); DMatrixRMaj diff = new DMatrixRMaj(L.numRows, L.numCols); CommonOps_DDRM.subtract(L, R, diff); double top = NormOps_DDRM.normF(diff); double bottom = NormOps_DDRM.normF(L); double error = top / bottom; return(error); }
/** * <p> * Checks to see if the matrix is positive semidefinite: * </p> * <p> * x<sup>T</sup> A x ≥ 0<br> * for all x where x is a non-zero vector and A is a symmetric matrix. * </p> * * @param A square symmetric matrix. Not modified. * * @return True if it is positive semidefinite and false if it is not. */ public static bool isPositiveSemidefinite(DMatrixRMaj A) { if (!isSquare(A)) { return(false); } EigenDecomposition_F64 <DMatrixRMaj> eig = DecompositionFactory_DDRM.eig(A.numCols, false); if (eig.inputModified()) { A = (DMatrixRMaj)A.copy(); } eig.decompose(A); for (int i = 0; i < A.numRows; i++) { Complex_F64 v = eig.getEigenvalue(i); if (v.getReal() < 0) { return(false); } } return(true); }
/** * <p> * Puts all the real eigenvectors into the columns of a matrix. If an eigenvalue is imaginary * then the corresponding eigenvector will have zeros in its column. * </p> * * @param eig An eigenvalue decomposition which has already decomposed a matrix. * @return An m by m matrix containing eigenvectors in its columns. */ public static DMatrixRMaj createMatrixV(EigenDecomposition_F64 <DMatrixRMaj> eig) { int N = eig.getNumberOfEigenvalues(); DMatrixRMaj V = new DMatrixRMaj(N, N); for (int i = 0; i < N; i++) { Complex_F64 c = eig.getEigenvalue(i); if (c.isReal()) { DMatrixRMaj v = eig.getEigenVector(i); if (v != null) { for (int j = 0; j < N; j++) { V.set(j, i, v.get(j, 0)); } } } } return(V); }
/** * <p> * A diagonal matrix where real diagonal element contains a real eigenvalue. If an eigenvalue * is imaginary then zero is stored in its place. * </p> * * @param eig An eigenvalue decomposition which has already decomposed a matrix. * @return A diagonal matrix containing the eigenvalues. */ public static DMatrixRMaj createMatrixD(EigenDecomposition_F64 <DMatrixRMaj> eig) { int N = eig.getNumberOfEigenvalues(); DMatrixRMaj D = new DMatrixRMaj(N, N); for (int i = 0; i < N; i++) { Complex_F64 c = eig.getEigenvalue(i); if (c.isReal()) { D.set(i, i, c.real); } } return(D); }