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

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

Назначение

Приближенное решение интегрального уравнения Фредгольма I рода в классе ограниченных кусочно - монотонных функций.

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

Приближенное решение интегрального уравнения Фредгольма I рода

            b
           ∫ k(x, y) u(y) dy  =  f(x)  ,  c ≤ x ≤ d ,
          a 

при априорно известной информации о качественном поведении искомого решения  u = u (y) осуществляется методом квазирешений В.К.Иванова путем сведения к решению задачи квадратичного программирования с линейными ограничениями

(1)     || K D u - f ||p2  =   inf   || K D v - f ||p2 ,
                                      vG 

где  K - известная матрица порядка  M * N с элементами  ki j , которая в зависимости от ядра  k (x, y) и способа его аппроксимации может быть матрицей общего вида, либо симметричной, циркулянтной, теплицевой и т.п.,

f = ( f1, ..., fM ) - известный  M -  мерный вектор ,

u = ( u1, ..., uN ) - искомый  N - мерный вектор приближенного решения,

D - диагональная матрица коэффициентов квадратурной формулы  dj ,  j = 1, ..., N,

                        M 
       || Z ||p2  =  ∑  pi zi2 ,      pi > 0  -  весовые коэффициенты.
                       i=1 

Линейные ограничения  G представляют собой одно из множеств  G1,  G2 или  G1 ∩ G2, где

 G1 = { v = (v1, ..., vN) :  aj ≤ vj ≤ bj ,  j = 1, ..., N } ,
 G2 = { v = (v1, ..., vN) :  mj (vj + 1 - vj) ≥ 0 ,  j = 1, ..., N - 1 } , 

a = (a1, ..., aN),  b = (b1, ..., bN) - заданные  N - мерные векторы нижних и верхних ограничений в  G1; параметры  mj определяются условиями кусочной монотонности и принимают значения 1, 0 или -1.

B случае отсутствия ограничений решается задача безусловной минимизации.

Численное решение задачи (1) основано на методе проекции сопряженных градиентов, который позволяет проводить итерационный процесс в конечномерном пространстве  W2, ρ1 с нормой

                                    N
 || v ||   =  ( || v || 2Q  +  ∑   ρj (vj - vj - 1)2 )1/2 ,
                                   j=2
                     N
 || v || Q  =  (  ∑   q j vj2 )1/2 ,
                    j=1 

q j > 0 и  ρj ≥ 0 - заданные числа. Если априори известно, что искомое решение достаточно гладкое, то задание параметров  ρj > 0, связанных с конкретной нормировкой  W2, ρ1 ( при  ρj≡0 эта ноpма  v  совпадает с  || v || Q ), позволяет увеличить точность и улучшить качество приближенного решения.

Итерационный процесс считается оконченным после выполнения заданного числа итераций или после достижения заданной точности.

B используемом алгоритме матрица  K участвует лишь в операциях умножения матрицы на вектоp и умножения транспонированной матрицы на вектоp. Эти операции выделены в отдельную подпрограмму, благодаря чему пользователь может максимально полно учесть специфику матрицы  K.

B самой подпрограмме ef01r_c матрица  K не используется, поэтому способ ее представления не регламентируется.

1.  А.Н.Тихонов, В.Я.Арсенин, Методы решения некорректных задач, M., "Hаука", 1974.
2.  В.А.Морозов, Н.Л.Гольдман, М.К.Самарин. Метод дескриптивной регуляризации и качество приближенных решений, ИФЖ, т. 33, N 6, 1977.
3.  Ф.П.Васильев, Лекции по медодам решения экстремальных задач. Изд - во МГУ, 1974.

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

    int ef01r_c (integer *m, integer *n, real *a, real *f,
            integer *ng, real *au, real *bu, integer *mu, real *p, real *q,
            real *d, real *r, real *e, integer *isp, real *u, real *fu,
            integer *kn, real *b, S_fp op)

Параметры

m - заданная размерность вектоpа правой части  f (тип: целый);
n - заданная размерность вектоpа искомого решения  u (тип: целый);
a - заданный вещественный массив, содержащий информацию о матрице  K; параметр  a используется только в подпрограмме пользователя  op (см. дальше), и поэтому в данной подпрограмме его размерность не фиксируется;
f - вещественный вектоp длины  m, содержащий компоненты вектоpа правой части  f;
ng - заданный признак наличия ограничений на искомое решение (тип: целый):
ng = 0 - если ограничения отсутствуют,
ng = 1 - если требуется найти  u  g1,
ng = 2 - если требуется найти  u  g2,
ng = 3 - если требуется найти  u  g1 ∩ g2;
au - вещественный вектоp длины  n, содержащий компоненты вектоpа нижних ограничений  a;
bu - вещественный вектоp длины  n, содержащий компоненты вектоpа верхних ограничений  b;
mu - целый вектоp длины  n, первые  n - 1 компоненты которого содержат параметры  mj, определяемые условиями кусочной монотонности;
p - вещественный вектоp длины  m, содержащий весовые коэффициенты  pi > 0;
q - вещественный вектоp длины  n, содержащий весовые коэффициенты  q j > 0;
d - вещественный вектоp длины  n, содержащий коэффициенты квадратурной формулы  d j > 0;
r - вещественный вектоp длины  n + 1 значений параметров  ρj :  r (1) = 0.,  r (j) = ρj ≥ 0 ,  j = 2, ..., n ,  r (n + 1) = 0 ;
e - заданная точность вычисления по градиенту (тип: вещественный);
isp - заданное максимально допустимое число итераций (тип: целый);
u - вещественный вектоp длины  n, задающий произвольное начальное приближение; в результате работы подпрограммы содержит вычисленное решение  u;
fu - вещественная переменная, содержащая вычисленное значение функционала невязки  || K D u - f ||p2;
kn - целая переменная, указывающая причину выхода из подпрограммы:
kn = 0 - если выполнено заданное число итераций,
kn = 1 - если достигнута точность по градиенту,
kn = 2 - если достигнута точность по функционалу,
kn = 3 - если достигнута точность по аргументу;
b - вещественный вектоp длины  m + 7n + 2, используемый как рабочий;
op - имя подпрограммы пользователя, вычисляющей векторы  w = K v и  w = K' v (см. замечания по использованию);

первый оператор подпрограммы должен иметь вид:
int op (integer *m, integer *n, real *a, real *v, real *w, integer *nop)

Здесь:
m, n - параметры, описанные выше;
a - заданный вещественный массив, содержащий информацию о матрице  K; способ представления матрицы  K в массиве  a определяется пользователем;
v - вещественный вектоp длины  max (m, n), содержащий компоненты вектоpа  v;
w - вещественный вектоp длины  max (m, n), содержащий компоненты вычисленного вектоpа  w;
nop - управляющий параметр (тип: целый);

при  nop = 1 должен быть вычислен вектоp  w с компонентами

                n
      wi  =  ∑   ki j vj ,    i = 1, ..., m ,
               j=1 

при  nop = 2 должен быть вычислен вектоp  w с компонентами

                m
      wj  =  ∑   kj i vi ,    j = 1, ..., n .
               i=1 

Версии: нет

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

ia01r_c - среднеквадратичная аппроксимация одномерной дискретной функции на множестве кусочно - монотонных функций.

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

  1. 

Различные способы аппроксимации интегрального уpавнения приводят к различному определению элементов  ki j и  d j.

Например, при гладком ядре  ki j = k (xi, yj),  xi:  c = x1 < x2 < ... < xm = d,  xi + 1 = xi + hix - узлы на отрезке  [c, d],  yj:  a = y1 < y2 < ... < yn = b,  yj + 1= yj + hjy - узлы на отрезке  [a, b],  dj - коэффициенты выбранной квадратурной формулы, а при негладком ядре

                             xi+1    yj+1
      ki j  =  1/h1x       ∫       ∫     k (x, y)  dx dy ,   dj ≡ 1 .
                              xi      yj 
  2. 

При обращении к данной подпрограмме в качестве фактического параметра, соответствующего параметру  op, можно указывать имена следующих имеющихся в библиотеке служебных подпрограмм :

ef01r1_c - если матрица  K имеет общий вид и задается двумерным массивом  a размерности  m * n :  a [i, J] = ki j ,  i = 1, 2, ..., m,  j = 1, 2, ..., n ;

ef01r2_c - если матрица  K симметричная ( т.е. если ядро симметрично,  k (x, y) = k (y, x) и  a = c,  b = d,  hix = hjy = h ,  m = n ) и задается одномерным массивом  a в компактной форме; при работе подпрограммы ef01r2_c вызывается подпрограмма am16r_c - вычисление произведения вещественной симметричной матрицы на вещественный вектоp;

ef01r3_c - если матрица  K теплицева ( т.е. если  k (x, y) = k (x - y) ,  a = c,  b = d,  hix = hjy = h,  m = n ) и задается одномерным массивом  a длины 2n - 1, содержащим элементы первого столбца и первой строки матрицы  K в следующем порядке :  kn1, ..., k21, k11, k12, ..., k1n ;

ef01r4_c - если матрица  K циркулянтная ( т.е.  k (x, y) = k (x - y),  a = c,  b = d,  hix = hjy = h,  m = n и, кpоме того, ядро  k (t) периодично с периодом  t = b - a ) и задается одномерным массивом  a длины  n, содержащим элементы первого столбца матрицы  K :  k11, k21, ..., kn1.

  3. 

Наименование подпрограммы, соответствующей формальному параметру  op, должно быть указано в операторе extern в программе пользователя.

  4. 

B случае  ng = 0 или  ng = 2 массивы  au и  bu в вычислениях не используются и для них не следует резервировать память. Соответствующим фактическим параметpом может быть произвольный идентификатор. Это замечание относится и к массиву  mu в случае  ng = 0 или  ng = 1.

  5. 

Весовые коэффициенты  pi ( i = 1, ..., m ) и  qj ( j = 1, ..., n ), задаваемые векторами  p и  q, могут быть коэффициентами квадратурных формул или задаваться из других соображений, в частности, можно положить  pi ≡ 1,  qj ≡ 1.

Если  f (xi) = fi + ξi, где  fi = f (xi) - точное значение правой части,  ξi - нормально распределенная случайная величина с дисперсией  d ξi = σi2 и  m ξi = 0, то можно положить  pi = 1 / σi2.

  6. 

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

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

Матрица  K имеет общий вид

int main(void)
{
    /* Initialized data */
    static float a[9] /* was [3][3] */ = { 3.f,1.f,5.f,1.f,-3.f,2.f,1.f,2.f,
            1.f };
    static float bu[3] = { 10.f,10.f,10.f };
    static float f[3] = { 4.f,3.f,4.f };
    static int mu[3] = { 1,1,0 };
    static float p[3] = { 1.f,1.f,1.f };
    static float q[3] = { 1.f,1.f,1.f };
    static float d__[3] = { 1.f,1.f,1.f };
    static float r__[4] = { 0.f,0.f,0.f,0.f };
    static float u[3] = { 0.f,0.f,0.f };
    static float au[3] = { -10.f,-10.f,-10.f };

    /* Local variables */
    extern int ef01r_c(int *, int *, float *, float *, int *, float *,
            float *, int *, float *, float *, float *, float *, float *,
            int *, float *, float *, int *, float *, U_fp);
    extern int ef01r1_c();
    static float b[26], e;
    static int m, n, ng, kn;
    static float fu;
    static int isp;

    m = 3;
    n = 3;
    ng = 2;
    e = 1e-7f;
    isp = 20;
l1:
    ef01r_c(&m, &n, a, f, &ng, au, bu, mu, p, q, d__, r__, &e, &isp, u, &fu,
            &kn, b, (U_fp)ef01r1_c);

        printf("\n %13.2e %13.2e %13.2e \n", u[0], u[1], u[2]);
        printf("\n %17.6e \n", fu);
    if (kn != 0) { goto l2;}
       else { goto l1;}
l2:
    return 0;
} /* main */


Результат:    u  =  (-1., 2., 5.)