//реализация алгоритма поиска собственных знаечний: 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); }
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); }