/** * <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); }
public bool extractVectors(DMatrixRMaj Q_h) { Array.Clear(eigenvectorTemp.data, 0, eigenvectorTemp.data.Length); // extract eigenvectors from the shur matrix // start at the top left corner of the matrix bool triangular = true; for (int i = 0; i < N; i++) { Complex_F64 c = _implicit.eigenvalues[N - i - 1]; if (triangular && !c.isReal()) { triangular = false; } if (c.isReal() && eigenvectors[N - i - 1] == null) { solveEigenvectorDuplicateEigenvalue(c.real, i, triangular); } } // translate the eigenvectors into the frame of the original matrix if (Q_h != null) { DMatrixRMaj temp = new DMatrixRMaj(N, 1); for (int i = 0; i < N; i++) { DMatrixRMaj v = eigenvectors[i]; if (v != null) { CommonOps_DDRM.mult(Q_h, v, temp); eigenvectors[i] = temp; temp = v; } } } return(true); }
private void checkSplitPerformImplicit() { // check for splits for (int i = x2; i > x1; i--) { if (_implicit.isZero(i, i - 1)) { x1 = i; splits[numSplits++] = i - 1; // reduce the scope of what it is looking at return; } } // first try using known eigenvalues in the same order they were originally found if (onscript) { if (_implicit.steps > _implicit.exceptionalThreshold / 2) { onscript = false; } else { Complex_F64 a = origEigenvalues[indexVal]; // if no splits are found perform an implicit step if (a.isReal()) { _implicit.performImplicitSingleStep(x1, x2, a.getReal()); } else if (x2 - x1 >= 1 && x1 + 2 < N) { _implicit.performImplicitDoubleStep(x1, x2, a.real, a.imaginary); } else { onscript = false; } } } else { // that didn't work so try a modified order if (x2 - x1 >= 1 && x1 + 2 < N) { _implicit.implicitDoubleStep(x1, x2); } else { _implicit.performImplicitSingleStep(x1, x2, _implicit.A.get(x2, x2)); } } }
/** * <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); }
private void solveEigenvectorDuplicateEigenvalue(double real, int first, bool isTriangle) { double scale = Math.Abs(real); if (scale == 0) { scale = 1; } eigenvectorTemp.reshape(N, 1, false); eigenvectorTemp.zero(); if (first > 0) { if (isTriangle) { solveUsingTriangle(real, first, eigenvectorTemp); } else { solveWithLU(real, first, eigenvectorTemp); } } eigenvectorTemp.reshape(N, 1, false); for (int i = first; i < N; i++) { Complex_F64 c = _implicit.eigenvalues[N - i - 1]; if (c.isReal() && Math.Abs(c.real - real) / scale < 100.0 * UtilEjml.EPS) { eigenvectorTemp.data[i] = 1; DMatrixRMaj v = new DMatrixRMaj(N, 1); CommonOps_DDRM.multTransA(Q, eigenvectorTemp, v); eigenvectors[N - i - 1] = v; NormOps_DDRM.normalizeF(v); eigenvectorTemp.data[i] = 0; } } }