//реализация алгоритма поиска собственных знаечний: QR - итерации
        public List <double> Find_Eigenvalues_QR_Iterations(Matrix A, QR_Decomposition.QR_Algorithm Method)
        {
            //список собственных значений
            var EigenValues = new List <double>();
            int iter        = 0;

            //итерационный процесс
            while (A.M != 1)
            {
                //обновление спсика собственных значений
                for (int i = A.M - 1; i > 0; i--)
                {
                    //если элемент A[i][i-1] == 0, A[i][i] - собственное значение
                    if (Math.Abs(A.Elem[i][i - 1]) < 1e-6)
                    {
                        EigenValues.Add(A.Elem[i][i - 1]);
                        //исключаем i-ые строку и столбец
                        Delete_Row_Column(A, i);
                        i = A.M;
                    }
                }

                if (A.M == 1)
                {
                    break;
                }

                //прямой сдвиг
                double shift = Rayleigh_Shift(A);
                Shift(A, -shift);

                //QR-разложение
                var QR = new QR_Decomposition(A, Method);

                //новая матрица А
                A = QR.R * QR.Q;

                //обратный сдвиг
                Shift(A, shift);
            }

            //дополняем список последним оставшимся собственным значением
            //EigenValues.Add(A.Elem[0][0]);

            //сортируем по возрастанию и формируем результат
            EigenValues.Sort((double X, double Y) => { if (X > Y)
                                                       {
                                                           return(0);
                                                       }
                                                       else
                                                       {
                                                           return(1);
                                                       } });

            return(EigenValues);
        }
예제 #2
0
        public List <double> Eigenvalues(QR_Decomposition.QR_Algorithm Method)
        {
            if (N != M)
            {
                throw new Exception("Eigenvalues: invalid size of matrix...");
            }

            //создадим копию данной матрицы, чтобы не изменять её
            Matrix T = new Matrix(N, N);

            T.Copy(this);
            List <double> RES = new List <double>();


            //приведём матрицу к верхней форме Хессенберга
            T.Hessenberg_Matrix();
            int t = 1;

            //QR-итерации
            while (T.M != 1)
            {
                Console.WriteLine("Iteration {0} ", t);
                T.Console_Write_Matrix();
                Console.WriteLine(" ");

                for (int i = T.M - 1; i > 0; i--)
                {
                    //если элемент А[i][i-1] == 0, то A[i][i] - собственное значение
                    if (Math.Abs(T.Elem[i][i - 1]) < 1e-6)
                    {
                        RES.Add(T.Elem[i][i]);
                        //исключаем i-ые строку и столбец
                        T.Delete_Row_Column(i);
                        i = T.M;
                    }
                }

                if (T.M == 1)
                {
                    break;
                }

                //прямой сдвиг
                double shift = Eigenvalue_Problem.Rayleigh_Shift(T);
                Eigenvalue_Problem.Shift(T, -shift);

                var QR = new QR_Decomposition(T, Method);

                T = QR.R * QR.Q;

                Eigenvalue_Problem.Shift(T, shift);

                //аварийное завершение цикла
                t++;
                if (t == 100)
                {
                    break;
                }
            }

            //дополняем список последним оставшимся собственным значением
            RES.Add(T.Elem[0][0]);

            //сортируем по возрастанию и формируем результат
            RES.Sort((double X, double Y) => { if (X > Y)
                                               {
                                                   return(0);
                                               }
                                               return(1); });

            return(RES);
        }