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

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

Назначение

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

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

Для заданных вещественных матриц А и В размера N*N вычисляются такие ортогональные матрицы Q и Z размера N*N, что матрица QAZ является верхней почти треугольной, а матрица QВZ - верхней треугольной.

В результате работы подпрограммы afg3r_c матрица QAZ помещается на место матрицы А, матрица QВZ - на место матрицы В. Левостороннее преобразование Q не сохраняется, правостороннее преобразование Z по желанию пользователя может сохраняться.

С.В.Мoler_c and G.W.Stewart, Аn Аlgorithm for Generalized Mатrix Еigenvalue Рroblems, siam J. Numer.Аnal., 10, 1973.

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

    int afg3r_c (real *a, real *b, real *z, integer *n, integer *m)

Параметры

a, b - вещественные двумерные массивы размера n*n, в которых задаются исходные матрицы A и B; в результате работы подпрограммы в массивы a и b записываются соответственно верхняя почти треугольная матрица QAZ и верхняя треугольная матрица QBZ ;
z - вещественный двумерный массив размера n*n, который в результате работы подпрограммы по желанию пользователя может содержать матрицу Z правостороннего преобразования; если матрица Z не нужна, параметр z в подпрограмме не используется;
n - заданный порядок исходных матриц A и B (тип: целый);
m - задает режим работы подпрограммы (тип:целый); при этом
m = 0 - если преобразование Z сохраняется,
m = 1 - если преобразование Z не сохраняется.

Версии: нет

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

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

  1. 

Матрица преобразования Z необходима для вычисления соответственных векторов обобщенной проблемы AX = λBX по правилу X = ZY, где Y - собственные векторы обобщенной проблемы QAZY = λQBZY .

  2.  Если матрица преобразования Z не нужна, т.е. когда m = 1, то в качестве фактического параметра z можно использовать параметр a.

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

int main(void)
{
    /* Initialized data */
    static float a[9] /* was [3][3] */ = { 1.f,-10.f,5.f,.5f,2.f,1.f,0.f,
                                           0.f,.5f };
    static float b[9] /* was [3][3] */ = { .5f,3.f,4.f,0.f,3.f,.5f,0.f,0.f,
                                          1.f };
    /* Local variables */
    extern int afg3r_c(float *, float *, float *, int *, int *);
    static int i__, m, n;
    static float z__[9]  /* was [3][3] */;

#define a_ref(a_1,a_2) a[(a_2)*3 + a_1 - 4]
#define b_ref(a_1,a_2) b[(a_2)*3 + a_1 - 4]
#define z___ref(a_1,a_2) z__[(a_2)*3 + a_1 - 4]

    for (i__ = 1; i__ <= 3; ++i__) {
        printf("\n  %14.5f %14.5f %14.5f \n",
         a_ref(i__, 1), a_ref(i__, 2), a_ref(i__, 3));
    }
    for (i__ = 1; i__ <= 3; ++i__) {
        printf("\n  %14.5f %14.5f %14.5f \n",
         b_ref(i__, 1), b_ref(i__, 2), b_ref(i__, 3));
    }
    n = 3;
    m = 0;
    afg3r_c(a, b, z__, &n, &m);

    for (i__ = 1; i__ <= 3; ++i__) {
        printf("\n  %14.5f %14.5f %14.5f \n",
         a_ref(i__, 1), a_ref(i__, 2), a_ref(i__, 3));
    }
    for (i__ = 1; i__ <= 3; ++i__) {
        printf("\n  %14.5f %14.5f %14.5f \n",
         b_ref(i__, 1), b_ref(i__, 2), b_ref(i__, 3));
    }
    for (i__ = 1; i__ <= 3; ++i__) {
        printf("\n  %14.5f %14.5f %14.5f \n",
         z___ref(i__, 1), z___ref(i__, 2), z___ref(i__, 3));
    }
    return 0;
} /* main */


Результаты:

                      |   1.89057  -2.06068   0.27000 |
      a_ref  =    |-11.06462   0.94174   0.35338 |
                      |   0.00000  -0.39941  -0.09705 |

                      | -5.02494  -2.23447   0.65793 |
      b_ref  =    |  0.00000    2.07058   0.71846 |
                      |  0.00000    0.00000  -0.14417 |

                          |  1.00000   0.00000   0.00000 |
      z___ref  =    |  0.00000   0.99805    0.06238 |
                          |  0.00000   0.06238  -0.99805 |