/// <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());
        }