/// <summary> /// Получить собственные (и присоединённые) векторы матрицы. /// </summary> /// <param name="originMatrix">Входная матрица.</param> /// <returns>Матрица, состоящая из комплексных чисел.</returns> public static SquareMatrix GetEigenvectors(this SquareMatrix originMatrix) { var eigenvalues = originMatrix.Eigenvalues(); if (eigenvalues.Any(v => v.Im != 0)) { throw new ComplexEigenvaluesException("Комплексные собственные значения не поддерживаются."); } const double max = 1.0; const double min = 0.0; var eigenvectors = new SquareMatrix(originMatrix.Dimension); var identityMatrix = SquareMatrixHelper.GetIdentityMatrix(originMatrix.Dimension); // Два различных собственных значения. if (!(eigenvalues[0] - eigenvalues[1]).Re.IsZero()) { var eigenSol1 = originMatrix - eigenvalues[0].Re * identityMatrix; var eigenSol2 = originMatrix - eigenvalues[1].Re * identityMatrix; if (!eigenSol1.Row(0).IsZero()) { eigenvectors = new SquareMatrix(new [, ] { { eigenSol1[0, 1], eigenSol2[0, 1] }, { -eigenSol1[0, 0], -eigenSol2[0, 0] } }); } else { eigenvectors = new SquareMatrix(new [, ] { { eigenSol1[1, 1], eigenSol2[0, 1] }, { -eigenSol1[1, 0], -eigenSol2[0, 0] } }); } } else if ((eigenvalues[0] - eigenvalues[1]).Re.IsZero()) { while (true) { if ((originMatrix - eigenvalues[1].Re * identityMatrix).GetRank() != 0) { var possibleAttachedVectorEntries = GetRandomColumnVector(max, min); var possibleAttachedVector = new ColumnVector(possibleAttachedVectorEntries); var possibleEigenvector = (originMatrix - eigenvalues[1].Re * identityMatrix) * possibleAttachedVector; if (originMatrix * possibleAttachedVector == eigenvalues[1].Re * possibleAttachedVector) { continue; } if (possibleEigenvector.OneNorm().IsZero()) { continue; } if (((originMatrix - eigenvalues[0].Re * identityMatrix) * possibleEigenvector).OneNorm().IsZero()) { eigenvectors = new SquareMatrix(new [, ] { { possibleEigenvector[0], possibleAttachedVector[0] }, { possibleEigenvector[1], possibleAttachedVector[1] } }); break; } } eigenvectors = new SquareMatrix(new [, ] { { 1.0, 0.0 }, { 0.0, 1.0 } }); break; } } return(eigenvectors); }
/// <summary> /// Получить геометрическую кратность собственного значения матрицы. /// </summary> /// <param name="originMatrix">Исходная матрица.</param> /// <param name="eigenvalue">Собственное значение.</param> /// <returns></returns> public static int GetGeometricMultiplicity(this SquareMatrix originMatrix, double eigenvalue) { var identityMatrix = SquareMatrixHelper.GetIdentityMatrix(originMatrix.Dimension); return(originMatrix.Dimension - (originMatrix - eigenvalue * identityMatrix).GetRank()); }