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

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

Назначение

Решение интегрального уравнения Вольтерра со стационарным ядром методом рягуляризации первого порядка без выбора параметра регуляризации.

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

Данная подпрограмма реализyeт aлгоритм, изложенный в [1].

Численное решение интегрального уравнения Вольтерра 1 рода вида

                T
(1)           ∫   k (t - x)  u (x)  dx  =  f (t)
              t
                t
           (   ∫   k (t - x)  u (x)  dx  =  f (t) )
              0

         t  [ 0, T ] 

на равномерной сетке  ti = i H,  i = 1, 2, ..., n,  H = Т/n, сводится к задаче минимизации

(2)           || K u - f || E - min u , 

где K - верхняя (нижняя) треугольная теплицева матрица размера  n на n, полученная при дискретизации (1):   Ki j  =  H * k (H ( i - j )).

Используя метод регуляризации А.Н.Тихонова [2], приходим к следующей задаче

(3)           || K u - f || E2  +  α || D u || E2  -  min u , 

где α > 0 - заданный параметр регуляризации, D - дискретный аналог оператора дифференцирования   d /dx.

Задача (3) эквивалентна задаче

                ||     |    K      |           |  f   |     ||  
(4)           ||     |             |  u   -   |      |     ||      -   min u ,                 
                ||     | α1/2 D |           |  0  |     || E 

для решения которой при помощи метода вращений [3] определим ортогональную матрицу Q, такую, что

              |     K    |            |  Kα  |                             |   f    |            |   f1    |
    QT     | α1/2 D |     =     |   0    |  ,               QT     |   0   |     =     |   f2    | 

где Kα - верхняя (нижняя) треугольная матрица. Тогда решение задачи (4) сводится к решению системы линейных алгебраических уравнений с треугольной матрицей:

(5)           Kα u  =  f1 , 

котоpое осуществляется методом обратной подстановки.

1.  L.Elden. An efficient algorithm for the regularization of ill - conditioned least squares problems with triangular toeplitz matrix. - REPORT  LITH - MAT - R - 1981 - 25, Sweden, 1981.
2.  А.Н.Тихонов, В.Я.Арсенин. Методы решения некорректных задач. - М., Наука, 1979.
3.  В.В.Воеводин. Численные методы алгебры. - M., Hаука, 1966.

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

    int ev01r_c(real *a, real *f, integer *n, integer *l,
        real *alfa, real *h, real *b, real *c, real *u, integer *ierr)

Параметры

a - вещественный вектоp длины n, содержащий первую стpоку (первый столбец) теплицевой матрицы K;
f - вещественный вектоp длины 2n, содержащий в первых n ячейках компоненты заданного вектоpа правой части; последующие n ячеек используются как рабочие;
n - заданная размерность вектоpов f и u и число узлов сетки разбиения (тип: целый);
l - заданный параметр - указатель типа матрицы K:
 

l = 0, если матрица верхняя треугольная,

l = 1, если матрица нижняя треугольная (тип: целый);

alfa - заданный параметр регуляризации (тип: вещественный);
h - заданный шаг разбиения сетки (тип: вещественный);
b - вещественный вектоp длины n (n + 1)/2, используемый как рабочий;
c - вещественный вектоp длины n, используемый как рабочий;
u - вещественный вектоp длины n, содержащий на выходе из подпрограммы вычисленное решение интегрального уравнения в узлах заданной сетки;
ierr - целая переменная, сообщающая об ошибках, обнаруженных в ходе вычислений;
ierr= 0 - если ошибок не было обнаружено;
ierr=65 - в случае, если при заданном значении alfa матрица системы вырождается.

Версии: нет

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

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

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

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

 Решается интегральное уравнение
                      t
                     ∫   K (t - s)  f (s)  ds  =  g (t)   ,      0 ≤ t ≤ 1
                   0
с ядром
                              
      K(t)  =  0.5 π   ∑    (- 1)n (2nh )  exp (-(2n + 1)2 π2 t /8) .
                             n=0 

Точное значение функции  f (s) задано таблицей. Используя формулу трапеции, вычисляем приближенное значение правой части  g (t), затем по  g (t) восстанавливаем значение функции  f (s) = u с помощью программы ev01r_c.

Параметр регуляризации  α = 10 - 8

int main(void)
{
    /* Initialized data */
    static float f[50] = { .025f,.215f,.405f,.595f,.785f,.975f,1.f,.92f,.71f,
            .5f,.29f,.08f,0.f,.08f,.29f,.5f,.71f,.92f,1.f,.975f,.785f,.595f,
            .405f,.215f,.025f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,
            0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f };

    /* Builtin functions */
    double exp(double);
    int pow_ii(int *, int *);

    /* Local variables */
    static float alfa;
    extern int ev01r_c(float *, float *, int *, int *,
                       float *, float *, float *, float *, float *, int *);
    static int ierr;
    static float work[1325], g[100], h__;
    static int i__, j;
    static float k[50];
    static int l, n;
    static float r__[50], s, u[50];
    static int n1;
    static float pi, rab;
    int i__1, i__2;

    n = 50;
    alfa = 1e-8f;
    h__ = .02f;
    pi = 3.14159265f;
    n1 = n - 1;
    i__1 = n;
    for (i__ = 1; i__ <= i__1; ++i__) {
        g[n + i__ - 1] = 0.f;
        s = (float)exp((float)(-(pi * pi * i__ * h__ / 8)));
        for (j = 1; j <= 15; ++j) {
/* Computing 2nd power */
            i__2 = (j << 1) + 1;
            rab = (float)exp((float)(-(i__2 * i__2) * pi * pi * i__ * h__ / 8));
/* l12: */
            s += pow_ii(&c_n1, &j) * ((j << 1) + 1) * rab;
        }
/* l11: */
        r__[i__ - 1] = pi * .5f * s;
    }
    k[0] = r__[0] * h__ / 2;
    k[n - 1] = r__[n - 1] * h__ / 2;
    i__1 = n1;
    for (i__ = 2; i__ <= i__1; ++i__) {
/* l13: */
        k[i__ - 1] = r__[i__ - 1] * h__;
    }
    i__1 = n;
    for (i__ = 1; i__ <= i__1; ++i__) {
        s = 0.f;
        i__2 = i__;
        for (j = 1; j <= i__2; ++j) {
/* l15: */
            s += f[j - 1] * k[i__ - j];
        }
/* l14: */
        g[i__ - 1] = s;
    }
    l = 1;
    ev01r_c(r__, g, &n, &l, &alfa, &h__, &work[n], work, u, &ierr);

    i__1 = n;
    for (i__ = 1; i__ <= 21; i__ += 20) {
         printf("\n %16.7e %16.7e %16.7e %16.7e ",
                 u[i__-1], u[i__+4], u[i__+9], u[i__+14]);
    }
    printf("\n %16.7e %16.7e \n",u[40], u[45]);
    printf("\n %16.7e \n",alfa);
    return 0;
} /* main */


Результаты:

          alfa  =  1.00000000-08

               |  4.18939426-02   9.47262731-01   2.69209987-01    4.94652786-01
      u  =  |  8.07735236-01   9.34217208-04   8.94488047-03   -2.22705150-03
               | -3.81489539-04   5.87342988-03