В начало

Нахождение наименьшего собственного значения симметричной матрицы на С++

С.И.Хашин


eigen_min.h - заголовочный файл
eigen_min.cpp - реализация.

     Введение
     Программа
     Как это работает

Введение

Нахождение собственных векторов и собственных значений матрицы — важнейшая задача линейной алгебры, см., например здесь и здесь . Предлагаемые алгоритмы достаточно сложны. Причем, их не удастся значительно упростить, просто из-за сложности самой задачи. В случае симметричной матрицы задача упрощается, однако предлагаемые алгоритмы всё равно сложны.

Однако, если мы хотим найти не все собственные значения, а лишь одно из них — наименьшее, можно привести достаточно простой и эффективный алгоритм.

К удивлению, ни в одном из известных учебников по численым методам этот алгоритм не приводится, хотя все необоходимые идеи в них есть, нет только последнего шага. Если всё-же алгоритм где-то найдется, сообщите, пожалуйста.

Программа

В предлагаемом варианте решения задачи не используются никакие дополнительные библиотеки и даже не вводится никаких типов данных. Для матрицы размера N*N используется одномерный массив размера N*N.

В следующих модулях приведена функция на С++, позволяющую решать эту задачу:
eigen_min.h - заголовочный файл
eigen_min.cpp - реализация.

В модуле имеется, фактически, одна-единственная функция

double  EigenMin(int N, double *a, double *evec); // evec - eigenvectors of positive symmetric matrix with minimal eigenvalue (returned)

На самом деле имеются еще несколько вспомогательных, совсем простых функций, реализующих некоторые элементарные операции с векторами из действительых чисел:

double vdbl_len2(int N, double *a);                             // |A|^2
void   vdbl_normal(int N, double *a);                           // length(a):=1
double vdbl_scprod(int N, double *a, double *b);                // (a,b)
void   vdbl_add(int N, double *a, double *b, double R);         // a += R*b
void   vdbl_mult(int N, double *res, double *matr, double* v);  // res = matr*v

Как это работает

Пусть A — симметричная матрица размера n*n. Нам надо найти ненулевой вектор v на котором функция

R(v) = (v, Av)/(v,v)

принимает наименьшее значение. Будем искать его методом последовательных приближений. Начиная с произвольного вектора v=v0 будем строить приближения
v0, v1, v2, ...

Рассмотрим алгоритм нахождения для произвольного вектора v следующего вектора w, который будет иметь вид w=v+ t Av для некоторого t.

Пусть v — произвольный вектор. Введем обозначения:

f0 = (v,v),
f1 = (v, Av),
f2 = (v, A2v),
f3 = (v, A3v).

Найдем минимум значений функции R на векторах вида v + t Av:

Производная по t обращается в 0, если t удовлетворяет уравнению
Для нахождения следующего приближения найдем корни этого уравнения t1 и t2, вычислим для них функцию R(v+tAv) по приведенной выше формуле и выберем из этих двух значений наименьшее.

Замечание 1. f3 = (v, A3v) = (Av, A2v) , поэтому достаточно вычислить вектора Av и A2v, вектор A3v можно не вычислять.

Замечание 2. Если размерность пространства равна 2, то предлагаемый метод даст точный ответ за один шаг.

free counters