Текст подпрограммы и версий
afp0r_c.zip , afp0c_c.zip , afp0d_c.zip
Тексты тестовых примеров
tafp0r_c.zip , tafp0c_c.zip , tafp0d_c.zip

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

Назначение

QR - разложение вещественной прямоугольной матрицы размера n*m (n ≥ m) методом отражений.

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

Выполняется факторизация мaтpицы А вида А = QR, где Q - унитарная, R - верхняя треугольная матрица. Матрица R получается в результате умножения матрицы А нa последовательность преобразований отражения Q1, Q2, ..., QМ тakиx, чтo QМQМ - 1...Q1А = R , при этом

     Q = Q1TQ2T ... QMT . 

В.В.Воеводин, Л.И.Карышева, Г.Д.Ким, Р.В.Петрина, Комплекс алгоритмов основанных на преобразованиях отражения, в пакете линейной алгебры, Сб. "Численный анализ на ФОРТРАНе", вып.3, Изд. МГУ, 1973.

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

    int afp0r_c (real *a, integer *n, integer *m, real *w)

Параметры

a - двумерный n*m массив, в котором задается исходная матрица (тип: real); в результате работы подпрограммы в массиве a на соответствующих местах запоминаются наддиагональные элементы матрицы R, в остальной части массива в последовательных столбцах запоминаются векторы, порождающие матрицы отражения Q1, Q2, ..., Qm ;
n, m - заданные размеры исходной матрицы, причем n ≥ m (тип: целый);
w - одномерный массив длины n, используемый подпрограммой как рабочий (тип: real); в результате работы подпрограммы в первых m компонентах w запоминаются диагональные элементы матрицы R.

Версии

afp0c_c - QR - разложение методом отражений для прямоугольной n*m (n ≥ m) комплексной матрицы;
afp0d_c - QR - разложение методом отражений для прямоугольной n*m (n ≥ m) вещественной матрицы, заданной с удвоенной точностью.

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

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

  1. 

В подпрограмме afp0c_c массивы a, w имеют тип complex.

  2.  В подпрограмме afp0d_c массивы a, w имеют тип double.

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

int main(void)
{
    /* Initialized data */
    static float a[15] /* was [5][3] */ = { 1.f,2.f,0.f,1.f,-1.f,0.f,1.f,1.f,
                                            2.f,1.f,1.f,3.f,1.f,0.f,0.f };
    /* Local variables */
    extern int afp0r_c(float *, int *, int *, float *);
    static int i__;
    static float v[5];

#define a_ref(a_1,a_2) a[(a_2)*5 + a_1 - 6]

    for (i__ = 1; i__ <= 5; ++i__) {
        printf("\n %12.4e %12.4e %12.4e \n",
            a_ref(i__, 1), a_ref(i__, 2), a_ref(i__, 3));
    }
    afp0r_c(a, &c__5, &c__3, v);

    for (i__ = 1; i__ <= 5; ++i__) {
        printf("\n %16.7e %16.7e %16.7e \n",
            a_ref(i__, 1), a_ref(i__, 2), a_ref(i__, 3));
    }
    printf("\n %16.7e %16.7e %16.7e \n", v[0], v[1], v[2]);
    return 0;
} /* main */


Результат:

                      |  1.174  -1.134  -2.646 |
                      |  0.644   1.076  -0.418 |
      a_ref  =    |  0.000   0.389    1.118 |
                      |  0.322   0.657  -0.853 |
                      | -0.322   0.510   0.150 |

       (v(i), i = 1, 3) =  -2.646, -2.390, -1.956.

Это означает, что

                 | -2.646  -1.134  -2.646 |
                 |  0.        -2.390  -0.418 |
      r  =     |  0.          0.        -1.956 |
                 |  0.         0.          0.       |
                 |  0.         0.          0.       |  , 

      qi  =  i - wi * wit,   i  =  1, 2, 3 ,
 где
      w1t  =   (1.174,  0.644,  0.,  0.322,  -0.322) , 

      w2t  =   (0.,  1.076,  0.389,  0.657,  0.510) , 

      w3t  =   (0.,  0.,  1.118,  -0.853,  0.150) .