Текст подпрограммы и версий
adb1r_c.zip , adb1d_c.zip , adb1c_c.zip
Тексты тестовых примеров
tadb1r_c.zip , tadb1d_c.zip , tadb1c_c.zip

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

Назначение

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

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

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

           rcond = 1/( || A ||1 * || A-1 ||1 ) ,

 где   || A ||1 = maxj = 1, ..., N { | a1 j | + | a2 j | + ...+ | aN j | } ,

а затем вычисляется определитель матрицы А как произведение диагональных элементов матрицы U, умноженное на (-1)I, где I - число выполненных в процессе факторизации перестановок.

Определитель записывается в виде:

     det A = D1*10D2 ,   где 1.0 ≤ D1 < 10.0 

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

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

    int adb1r_c(real *a, integer *ma, integer *n, integer *ml,
        integer *mu, integer *nlead, real *det1, real *det2, real *rcond, 
        real *z__, integer *ierr)

Параметры

a - вещественный двумерный массив размера ma на n, в первых ml+mu+1 столбцах которого задается в компактном виде исходная ленточная матрица порядка n; на выходе в первых ml столбцах массива находятся нижние кодиагонали ленточной матрицы l1* ... *ln - 1 ( li ,  i = 1, ..., n - 1 суть элементарные матрицы исключения метода Гаусса ), в следующих ml+mu+1 столбцах содержится в компактном виде матрица u (см. замечания по использованию);
ma - первая размерность массива a в вызывающей программе (тип: целый);
n - порядок матрицы a (тип: целый);
ml - число нижних кодиагоналей матрицы a (тип: целый);
mu - число верхних кодиагоналей матрицы a (тип: целый);
nlead - целый вектор длины n, содержащий на выходе информацию о выполненных в ходе факторизации перестановках (см. замечания по использованию);
det1 - вещественная переменная, содержащая на выходе мантиссу определителя;
det2 - вещественная переменная, содержащая на выходе десятичный порядок определителя;
rcond - вещественная переменная, содержащая на выходе вычисленное значение величины, обратной числу обусловленности матрицы a;
z - вещественный рабочий вектор длины n;
ierr - целая переменная, содержащая на выходе информацию о прохождении счета, при этом:
ierr=65 - если ma ≤ 0 или n ≤ 0;
ierr=66 - если в процессе работы произошло переполнение (это говорит о том, что либо ||a||1, либо некоторые элементы матрицы u превосходят по абсолютной величине максимальное представимое на данной машине число);
ierr=-k - если в результате факторизации в k-ой строке матрицы u диагональный элемент равен нулю (свидетельствует о вырожденности матрицы a). Если таких строк у матрицы u несколько, то значение k полагается равным номеру последней из них.

Версии

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

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

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

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

  1. 

В подпрограмме adb1d_c массивы a, z и переменные rcond, det1 и det2 имеют тип double, для треугольного разложения и оценки числа обусловленности ленточной матрицы a вызывается подпрограмма afb2d_c.

  2. 

В подпрограмме adb1c_c массивы a и z и переменная det1 имеют тип complex, для треугольного разложения и оценки числа обусловленности ленточной матрицы a вызывается подпрограмма afb2c_c.

  3. 

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

  4. 

Так как в результате выполненных в ходе факторизации перестановок число верхних кодиагоналей матрицы u равно ml+mu, а также в силу некоторых конструктивных особенностей подпрограммы, для правильной ее работы необходимо выполнение условия ma ≥ n > mu+2*ml+1.

   

Если же mu+2*ml+1 ≥ n, то имеет смысл, задав матрицу a не в компактной, а в полной форме, обратиться к подпрограмме adg2r_c.

  5. 

Если вырабатывается значение переменной ierr, отличное от нуля, то выдается соответствующее диагностическое сообщение, полагается rcond = 0.0, det1 = 0.0, det2 = 0.0 и происходит выход из подпрограммы.

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

int main(void)
{
    /* Local variables */
    static int ierr;
    extern int adb1r_c(float *, int *, int *, int *, int *, int *,
                       float *, float *, float *, float *, int *);
    static float a[25]   /* was [5][5] */;
    static int i__, j, k, n, nlead[5];
    static float z__[5], rcond;
    static int j0, j1, ma, ml, mu;
    static float det1, det2;
    int i__1, i__2, i__3;

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

    ma = 5;
    n = 5;
    i__1 = ma;
    for (i__ = 1; i__ <= i__1; ++i__) {
        i__2 = n;
        for (j = 1; j <= i__2; ++j) {
            a_ref(i__, j) = 0.f;
/* l2: */
        }
/* l1: */
    }
    ml = 1;
    mu = 1;
    i__1 = ma;
    for (i__ = 1; i__ <= i__1; ++i__) {
/* Computing max */
        i__2 = 1, i__3 = i__ - ml;
        j0 = max(i__2,i__3);
/* Computing min */
        i__2 = n, i__3 = i__ + mu;
        j1 = min(i__2,i__3);
        i__2 = j1;
        for (j = j0; j <= i__2; ++j) {
            k = j - i__ + ml + 1;
            a_ref(i__, k) = (float) (i__ * 10 + j);
/* l3: */
        }
/* l4: */
    }
    for (j = 1; j <= 5; ++j) {
        printf("\n  %12.4e %12.4e %12.4e %12.4e %12.4e \n",
               a_ref(j, 1), a_ref(j, 2), a_ref(j, 3),
               a_ref(j, 4), a_ref(j, 5));
    }
    adb1r_c(a, &ma, &n, &ml, &mu, nlead, &det1, &det2, &rcond, z__, &ierr);

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


Результаты:

           |    0         21.0     22.0     23.0     0 |
           | -0.524    32.0     33.0     34.0     0 |
    a = | -0.015    43.0     44.0     45.0     0 |
           |  0.292    54.0     55.0        0       0 |
           | -0.228    0.569      0         0       0 |

       nlead = (2, 3, 4, 5, 5)
       rcond = 1.47362E-03
       det1 = 8.88360
       det2 = 5.0