Текст подпрограммы и версий
aeb6r_c.zip , aeb6d_c.zip
Тексты тестовых примеров
taeb6r_c.zip , taeb6d_c.zip

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

Назначение

Вычисление нескольких собственных векторов, соответствующих заданным собственным значениям, для симметричной ленточной матрицы, заданной в компактной форме.

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

Подпрограмма aeb6r_c по заданным собственным значениям вычисляет соответствующие собственные векторы симметричной ленточной матрицы с помощью метода обратных итераций. Возникающие в методе обратных итераций системы

               ( A - λ I ) x  =  y , 

где А - симметричная ленточная матрица, решаются методом Гаусса с перестановками.

Уилкинсон, Райнш. Справочник алгоритмов на языке АЛГОЛ. Линейная алгебра. М.: "Машиностроение", 1976.

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

    int aeb6r_c (integer *nm, integer *n, integer *m, real *b,
            real *c, real *ev, integer *l, integer *l0, real *v, real *z, 
            real *w, logical *log, integer *ierr)

Параметры

nm - число строк двумерного массива b, указанное при описании этого массива в вызывающей подпрограмме (тип: целый);
n - порядок исходной матрицы, n ≤ nm (тип: целый);
m - число нижних ненулевых кодиагоналей исходной симметричной ленточной матрицы (включая главную диагональ) (тип: целый);
b - вещественный двумерный массив размерности nm * m, в первых n строках которого задана исходная симметричная ленточная матрица в компактной форме (см. Организация Библиотеки. Способы представления матриц специального вида);
c - вещественный рабочий двумерный массив размерности n * (2m - 1);
ev - вещественный вектор длины l, содержащий собственные значения, для которых должны быть вычислены собственные векторы, при l0 > 0 для первых l0 собственных значений собственные векторы задаются пользователем;
l - число заданных собственных значений (тип: целый);
l0 - число собственных значений, собственные векторы для которых уже известны и задаются на входе в подпрограмму, l0 < l (тип: целый);
v - вещественный двумерный массив размерности nm * l, содержащий на входе в подпрограмму в своих первых l0 столбцах ортонормированные собственные векторы, соответствующие собственным значениям, расположенным в первых l0 компонентах вектора ev, а на выходе из подпрограммы - l ортонормированных собственных векторов, соответствующих заданным собственным значениям;
z - вещественный рабочий вектор длины n;
w - вещественный рабочий двумерный массив размерности n * m;
log - логический рабочий двумерный массив размерности n * m;
ierr - целочисленная переменная, содержащая на входе признак задания пользователем начального приближения к искомым собственным векторам, при этом:
ierr=1 - если пользователь сам задает в соответствующих столбцах массива v начальные приближения к собственным вектоpам;
ierr=0 - ecли пользователь не задает начальных приближений;
  а при выходе из подпрограммы:
ierr=0 - если вычислены все требуемые собственные векторы;
ierr=k - если при вычислении собственного вектора с индексом k ни один из векторов, используемых в качестве начальных, не позволил получить приемлемого приближения; при этом компоненты k - ого столбца массива v полагаются равными нулю; если таких собственных векторов было несколько, то значение ierr полагается равным индексу последнего из них.

Версии

aeb6d_c - вычисление нескольких собственных векторов, соответствующих заданным собственным значениям, для симметричной ленточной матрицы, заданной в компактной форме и с двойной точностью.

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

       av04r_c -        av04d_c   вычисление скалярного произведения;
       av02r_c -        av02d_c   вычисление евклидовой нормы вектора.

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

  1. 

Подпpогpамма aeb6r_c сохpаняет исходный массив b;

  2. 

В подпpогpамме aeb6d_c паpаметpы b, c, ev, v, z, w имеют тип double;

  3. 

Если начальное приближение, заданное пользователем, окажется неудачным, то подпрограмма aeb6r_c продолжит работу с новым начальным вектором;

  4. 

При повторном обращении к подпрограмме можно задать уже вычисленные l0 собственных векторов в первых столбцах массива v, тогда подпрограмма aeb6r_c, вычисляя новые собственные векторы, обеспечит их ортогональность по отношению к заданным. Это важно, если среди новых и старых собственных значений имеются близкие, так как сам по себе метод обратных итераций не гарантирует ортогональность собственных векторов, соответствующих близким собственным значениям, и требуется дополнительная ортогонализация;

  5.  Собственные значения, задаваемые в компонентах вектора ev, могут не быть упорядочены.

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

int main(void)
{
    /* Initialized data */
    static float b[15] /* was [5][3] */ = { 0.f,0.f,4.f,0.f,4.f,0.f,3.f,3.f,
                                            3.f,3.f,5.f,3.25f,1.f,4.25f,6.f };
    static float ev[2] = { 1.f,2.f };

    /* Local variables */
    static int ierr;
    extern int aeb6r_c(int *, int *, int *, float *, float *, float *,
                       int *, int *, float *, float *, float *,
                       logical *, int *);
    static float c__[25] /* was [5][5] */;
    static int i__, l, m, n;
    static float v[10] /* was [5][2] */,
                 w[10] /* was [5][2] */, z__[5];
    static int l0, nm;
    static logical log__[10] /* was [5][2] */;
    int i__1;

#define v_ref(a_1,a_2) v[(a_2)*5 + a_1 - 6]

    n = 5;
    nm = 5;
    m = 3;
    l = 2;
    ierr = 0;
    l0 = 0;
    aeb6r_c(&nm, &n, &m, b, c__, ev, &l, &l0, v, z__, w, log__, &ierr);

    for (i__ = 1; i__ <= 5; ++i__) {
        printf("\n %15.7e %15.7e \n", v_ref(i__, 1), v_ref(i__, 2));
    }
    printf("\n %5i \n", ierr);
    return 0;
} /* main */


Результаты:

      ierr  =  0 ,

      | - 0.6              1.e - 11  |
      |   0.8              5.e - 12  |
      |   1.e - 11       8.e - 12  |
      |   2.e - 11     - 0.8         |
      | - 3.e - 11       0.6         |