Текст подпрограммы и версий
afg5r_c.zip , afg5d_c.zip , afg5c_c.zip
Тексты тестовых примеров
tafg5r_c.zip , tafg5d_c.zip , tafg5c_c.zip

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

Назначение

Треугольное разложение вещественной матрицы общего вида методом Гаусса с выбором ведущего элемента по столбцу.

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

Для заданной квадратной вeщecтвeнной матрицы А порядка N выполняется треугольная факторизация А = LU , где U - верхняя треугольная матрица, причем матрица L- 1 имеет вид:

     L-1  =  LN-1 * PN-1 *...* L1 * P1 , 

где Рi,  i = 1, ..., N - 1, суть матрицы перестановок, обеспечивающие стратегию выбора ведущего элемента по столбцам; Li,  i = 1, ..., N - 1, суть элементарные матрицы исключения в методе Гаусса.

Все матрицы Li,  i = 1, ..., N - 1, имеют нижне - треугольный вид с единичными диагональными элементами.

Дж. Форсайт, М. Малькольм, К. Моулер. Машинные методы математических вычислений. М.: Мир, 1980.

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

    int afg5r_c(real *a, integer *m, integer *n, integer *nlead,
        integer *ierr)

Параметры

a - вещественный двумерный массив размера m*n, в котором задается исходная квадратная матрица порядка n; на выходе на соответствующих местах массива находятся элементы матрицы U и поддиагональные элементы матриц Li,  i = 1, ..., n - 1;
m - первая размерность массива a в вызывающей программе (тип: целый);
n - порядок матрицы A (тип: целый);
nlead - целый вектор длины n, содержащий на выходе информацию о выполненных в процессе исключения перестановках (см. замечания по использованию);
ierr - целая переменная, содержащая на выходе информацию о прохождении счета, при этом:
ierr=65 - если m ≤ 0 или n ≤ 0;
ierr=66 - если в процессе работы подпрограммы произошло переполнение (это говорит о том, что некоторые элементы матрицы U превосходят по абсолютной величине максимально представимое на данной машине число);
ierr=-k - если в результате факторизации диагональный элемент в K - ой строке матрицы U равен нулю (это свидетельствует о вырожденности матрицы A). Если таких строк у матрицы U несколько, то значение k полагается равным номеру последней из них.

Версии

afg5d_c - треугольное разложение вещественной матрицы, заданной с удвоенной точностью методом Гаусса с выбором ведущего элемента по столбцу.
afg5c_c - треугольное разложение комплексной матрицы методом Гаусса с выбором ведущего элемента по столбцу.

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

utafsi_c - подпрограмма выдачи диагностических сообщений.

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

  1. 

В подпрограмме afg5c_c массив a имеет тип complex.

  2. 

В подпрограмме afg5d_c массив a имеет тип double.

  3. 

На выходе K - ый элемент вектора nlead равен номеру строки, переставленной на K - ом шаге факторизации с K - ой строкой матрицы A. Поскольку факторизация Гаусса требует n - 1 шагов, то nlead (n) = n.

  4. 

В отличие от подпрограммы afg1r_c, матрицы Li,  i = 1, ..., n - 1 состоят из множителей, используемых в методе Гаусса, взятых со знаком минус, а исключение производится с использованием сложения, а не вычитания.

Кроме того, элементы матриц Li,  i = 1, ..., n - 1 не подвергаются выполняемым в процессе исключения перестановкам, как это происходит в подпрограмме afg1r_c.

  5.  Диагностическое сообщение выдается, если переменной ierr присвоено значение, отличное от нуля. При этом, если ierr = 65 или 66, то выполнение факторизации прекращается, если же ierr < 0, то не прекращается.

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

int main(void)
{
    /* Initialized data */
    static float a[16]   /* was [4][4] */ = { 7.9f,8.5f,4.3f,3.2f,5.6f,-4.8f,
                       4.2f,-1.4f,5.7f,.8f,-3.2f,-8.9f,-7.2f,3.5f,9.3f,3.3f };
    /* Local variables */
    static int ierr;
    extern int afg5r_c(float *, int *, int *, int *, int *);
    static int i__, m, n, nlead[4];

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

    m = 4;
    n = m;
    afg5r_c(a, &m, &n, nlead, &ierr);

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


Результаты:

               |  8.500     -4.800       0.800         3.500 |
               | -0.929     10.061      4.956      -10.453 |
      a  =  | -0.506     -0.659     -9.402          2.405 |
               | -0.376     -0.040     -0.731        12.658 |

      nlead  =   (2, 2, 4, 4)
   
 Это означает, что

                          |  1             0            0          0 |
                          | -0.929      1           0          0 |
      l1*l2*l3 =  | -0.506    -0.659     1          0 |
                          | -0.376    -0.040    -0.731   1 |

               | 8.500    -4.800      0.800        3.500 |
               |   0        10.061      4.956     -10.453 |
      u  =  |   0          0           -9.402         2.405 |
               |   0          0             0              12.658 |