Текст подпрограммы и версий
aes1r_c.zip
Тексты тестовых примеров
taes1r_c.zip

Подпрограмма:  aes1r_c

Назначение

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

Математическое описание

Метод Ланцоша для заданной симметричной матрицы А порядка N и начального вектора v  ЕN ,  v ≠ 0 ,  строит последовательность векторов Ланцоша  v1, v2, ..., vj и последовательность трехдиагональных матриц  Т1, Т2, ..., Тj по следующим формулам процесса (1):

      v1 = v / (vTv)1/2  ,     β1 = 0  , 
      ui = Avi - βivi-1  ,     αi = uiTvi  , 
  T1 =  α1 ,                            i = 1 ,

          |               |  0 |
          |               |  .  |
  Ti =  |    Ti-1     |  0 |  ,          i > 1 ,
          | _______| βi |
          | 0 ... 0 βi   αi |
   wi+1 = ui - αivi ,    βi+1 = (wTi+1wi+1)1/2 ,    vi+1 = wi+1 / βi+1  ,
    i = 1, ..., j 

Подпрограмма aes1r_c использует следующее свойство метода Ланцоша: в спектре трехдиагональной матрицы Тj , полученной при выполнении достаточно большого числа j (j ~ 2N,...,6N) шагов алгоритма (1), появляются приближения ко всем различным собственным значениям исходной матрицы А.

В подпрограмме aes1r_c на шагах с номерами

       p = mi = M1 + (i - 1)*MH ,   i = 1, 2, ...,   (М1, МН - заданные числа) 

процесс (1) прерывается и вычисляются собственные значения матриц Тp. Для разделения собственных значений матриц Тp на "истинные" и "лишние" применяется критерий, использующий собственные значения матрицы Тp^ , получаемой из Тp вычеркиванием первой строки и первого столбца. Для истинных собственных значений матриц Тp вычисляются оценки точности.

Пусть Кj - число истинных собственных значений матрицы Тj , К'j - число истинных значений Тj , являющихся приближениями к собственным значениям матрицы А с точностью max { ЕРS, 10*j*ε }*|| А ||2, где ЕРS - заданная пользователем величина, ε - относительная машинная точность, || А ||2 - спектральная норма матрицы А.

Выход из подпрограммы aes1r_c происходит

1) при выполнении одного из соотношений

        K'p = Kp = Kp1 ,   K'p = N ;   ( где p1 = mi-1 ) 

2) по заданному ограничению на число шагов процесса (1);

3) если очередное вычисленное значение βj+1 очень мало;

4) если при работе подпрограммы aee2r_c, используемой для вычисления собственных значений трехдиагональных матриц, произошла фатальная ошибка.

Метод Ланцоша использует исходную матрицу только в операциях умножения матрицы на вектор, поэтому информацию о матрице А удобно задавать в виде подпрограммы умножения матрицы на вектор, в которой пользователь может максимально учесть специфику матрицы.

Сullum J., Donath W.Е. Lanczos and thе computation in specified intervals of thе spectrum of large, sparse real symmetric matrices. Sparse Мatrix Рroc., Кnoxville, Тen., 1978. Рhiladelphia, Pа, 1979, 220-255.

Х.Д. Икрамов. Разреженные матрицы. Математический анализ. Т. 20. (Итоги науки и техн. ВИНИТИ АН СССР). М., 1982.

Использование

    int aes1r_c (integer *n, integer *m0, integer *m1, integer *mh,
                 integer *m2, real *eps, S_fp ff, real *vj, real *w, real *e, real *
                 d, integer *l, real *ev, real *er, integer *ir, integer *ip)

Параметры

n - порядок исходной матрицы (тип: целый);
m0 - целочисленная переменная, содержащая на входе в подпрограмму число уже выполненых (при предыдущих обращениях к подпрограмме) шагов процесса (1), при этом процесс (1) будет продолжен, начиная с (m0+1) - го шага; при первом обращении к подпрограмме m0 = 0, на выходе из подпрограммы m0 содержит суммарное число выполненных шагов алгоритма (1);
m1 - задаваемый номер шага, на котором происходит первое прерывание процесса (1) (тип: целый);
mh - задаваемый промежуток между двумя последовательными прерываниями процесса (1) (тип: целый);
m2 - задаваемое максимальное число шагов процесса (1) (тип: целый);
eps - вещественная переменная, содержащая на входе в подпрограмму требуемую относительную точность для вычисляемых собственных значений (под относительной точностью здесь подразумевается отношение абсолютной ошибки вычисленных приближенных собственных значений к спектральной норме матрицы A); на выходе из подпрограммы eps = max { eps, 10*m0*ε } , где ε - относительная машинная точность;
ff - имя подпрограммы вычисления w:  = (A - s*I) v - w ; первый оператор подпрограммы должен иметь вид:
 
int ff(float *v, float *w, int *n, float *s)
Здесь:
v - заданный вещественный вектор длины n;
w - вещественный вектор длины n, содержащий на входе в подпрограмму заданный вектор, а на выходе из подпрограммы - вычисленный вектор (A - s*I) v - w ;
n - порядок матрицы A (тип: целый);
s - простая переменная (тип: вещественный);
vj - вещественный вектор длины n, содержащий на входе в подпрограмму заданный начальный вектор; если vj = 0, то в качестве начального будет взят вектор
v = (1., 1., ..., 1.)t;
w - вещественный вектор длины n, используемый как рабочий;
e - вещественный вектор длины 2*m2 + 1, содержащий в своих первых m2 + 1 компонентах, начиная со второй, вычисленные поддиагональные элементы трехдиагональной матрицы t;
d - вещественный вектор длины m2, содержащий вычисленные диагональные элементы трехдиагональной матрицы t;
l - число вычисленных собственных значений (тип: целый);
ev - вещественный вектор длины m2, в первых l (при l ≠ 0) компонентах которого на выходе из подпрограммы расположены в порядке возрастания вычисленные собственные значения;
er - вещественный вектор длины m2, в i - ой компоненте которого, 1 ≤ i ≤ l , на выходе из подпрограммы содержится мантисса вычисленной оценки ошибки для ev (i);
ir - целочисленный вектор длины m2, в i - ой компоненте которого, 1 ≤ i ≤ l , на выходе из подпрограммы содержится двоичный порядок вычисленной оценки ошибки для ev (i);
ip - целочисленная переменная, содержащая на выходе из подпрограммы признак выхода, причем
ip = 0 ,  если  Kp = n;
ip = 1 ,  если  Kp = K'p = Kp1 < n ;
ip = 2 ,  если выполнено заданное число m2 шагов, а требуемая точность еще не достигнута;
ip = 3 ,  если получено слишком малое значение βj+1 , причем Kj < n ;
ip =-1 ,  если при использовании подпрограммы aee2r_c произошла фатальная ошибка.

Версии : нет

Вызываемые подпрограммы

aee2r_c - подпрограмма вычисления всех собственных значений симметричной трехдиагональной матрицы с помощью неявного QL - алгоpитма.

Замечания по использованию

  1. 

Наименование подпрограммы, соответствующей формальному параметру ff, должно быть указано в операторе extern в вызывающей подпрограмме.

  2. 

Подпрограмма ff должна сохранять вектор v.

  3. 

Если на выходе из подпрограммы ip = 2, то, обратившись к ней повторно, можно продолжить уже начатый процесс (1), указав число m0 выполненных шагов и задав новые значения m1, mh, m2, eps; информация о выполненных шагах хранится в векторах e, d, vj, w.

  4. 

Если на выходе из подпрограммы ip = 1 или ip = 3, то K < n и, вообще говоря, нет гарантии, что вычислены все различные собственные значения, поэтому при ip = 1, 3 полезно обратиться к подпрограмме еще раз с другим начальным вектором.

  5. 

При ip = -1 повторное обращение к подпрограмме aes1r_c для продолжения процесса (1) невозможно.

  6.  Подпрограмма av04r1 используется в качестве рабочей.

Пример использования

    int main(void)
{
        
    static float vj[6] = { 1.f,1.f,1.f,1.f,1.f,1.f };

        
        int i__1;

        
    static float teta[28];
    extern int aes1r_c (int *, int *, int *, int *, int *, float *, U_fp,
                       float *, float *, float *, float *, int *, float *,
                       float *, int *, int *);
    static float a[28], b[57];
    static int i__, k;
    static float w[6];
    extern int f0_c ();
    static int m0, ip, ir[28];
    static float rr[28], eps0;

    eps0 = 1e-6f;
    m0 = 0;
    aes1r_c (&c__6, &m0, &c__4, &c__4, &c__28, &eps0, (U_fp)f0_c, vj, w, b, a,
            &k, teta, rr, ir, &ip);

    printf("\n %5i %5i %5i \n", k, ip, m0);
    for (i__ = 0; i__ <= 3; i__+=3) {
        printf("\n %15.7e %15.7e %15.7e \n",
                teta[i__], teta[i__+1], teta[i__+2]);
    }
    printf("\n %10.2e %10.2e %10.2e %10.2e %10.2e %10.2e \n",
                rr[0], rr[1], rr[2], rr[3], rr[4], rr[5]);
    printf("\n %5i %5i %5i %5i %5i %5i \n",
                ir[0], ir[1], ir[2], ir[3], ir[4], ir[5]);
    return 0;
}     

    int f0_c (float *v, float *w, int *n, float *s)
{
        
        int i__1;

        
    static int i__;

        
    --w;
    --v;

        
    i__1 = *n;
    for (i__ = 1; i__ <= i__1; ++i__) {
        w[i__] = (i__ - *s) * v[i__] - w[i__];
    
    }
    return 0;
}     

Результаты:

      k  =  6,  ip  =  0
      teta  =   (1., 2., 3., 4., 5., 6.)
      rr  =   (1., 1., 1., 1., 1., 1.)
      ir  =   (-12, -12, -12, -12, -12, -12)