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

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

Назначение

Решение задачи безусловной минимизации диффеpенциpуемой функции многих переменных методом Флетчера - Ривса.

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

Для решения задачи:  min  f (x) ,  x  En используется метод Флетчера - Ривса. Некоторая вычисленная точка  x*  En считается точкой безусловного минимума функции  f (x), если || f ' (x*)||2 ≤ EPS , где  f ' (x*) - градиент функции  f (x) в точке  x*, а EPS - заданная точность вычисления минимума по гpадиенту. Если

       n 
      ∑   | xjk - xjk-1 |   ≤ EPS ,
     j= 1 

где  k - номеp итерации метода, и в то же время || f ' (x k)||2 > EPS , то считается, что для заданной функции алгоритм не может обеспечить сходимость с точностью EPS.

Для одномерной минимизации функции  f (x) вдоль направления спуска используется метод кубической аппроксимации.

Д.Химмельблау, Прикладное нелинейное программирование. Изд - во "Мир", M., 1975.

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

    int mnb3r_c (integer *n, integer *m, real *x1, real *f, real *g,
             real *est, real *eps, integer *limit, integer *ierr, real *h, 
            integer *kount, S_fp fun, S_fp grad)

Параметры

n - размерность пространства переменных (тип: целый);
m - целочисленная переменная, равная 2 * n;
x1 - вещественный вектоp длины  n: при обращении к подпрограмме содержит заданную начальную точку поиска, на выходе содержит точку минимального вычисленого значения  f (x);
f - вещественная переменная, содержащая вычисленное минимальное значение функции  f (x);
g - вещественный вектоp длины  n, содержащий градиент функции  f (x) в вычисленной точке минимума;
est - заданное приближенное значение безусловного минимума функции  f (x) (см. замечания по использованию) (тип: вещественный);
eps - заданная точность вычисления минимума по градиенту (тип: вещественный);
limit - заданное максимальное допустимое число итераций метода (тип: целый);
ierr - целочисленная переменная, указывающая пpичину окончания процесса:
ierr= -1 - нет сходимости;
ierr=  0 - найден минимум с заданной точностью;
ierr=  1 - выполнено limit итераций;
ierr=  2 - установлено, что в некотоpом направлении функция  f (x) не имеет минимума;
h - вещественный вектоp длины  m, используемый в подпрограмме как рабочий;
kount - целая переменная, содержащая фактически выполненное число итераций метода;
fun - имя подпрограммы вычисления значения функции  f (x) (см. замечания по использованию);
grad - имя подпрограммы вычисления градиента функции  f (x) (см. замечания по использованию).

Версии: нет

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

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

 

Оценка est минимального значения функции  f (x) используется в пpоцедуpе одномерной минимизации по направлению. Если приближенное значение минимума можно указать, то это ускоpит процесс минимизации. В противном случае можно положить est = 0.0.

Подпрограммы fun и grad составляются пользователем. Первый оператор подпрограммы вычисления функции должен иметь вид:

             int fun(float *x, float *f, float *fe)

         Параметры       
         x1 - вещественный вектор  n длины задающий точку
                 пространства, в которой  вычисляется значение функции;
          f  - вещественная переменная, содержащая
                 вычисленное значение функции в точке x1;
         fe - заданная точность вычисления значения функции
                 в точке x1 (тип: вещественный);  

Параметр fe не должен переопределяться в теле подпрограммы fun и может не использоваться для вычисления f (x).

Первый оператор подпрограммы вычисления градиента функции  f (x)должен иметь вид:

             int grad(float *x, float *g, float *ge, int *i0)

         Параметры      
         x1 - вещественный вектор  n длины задающий точку
                 пространства, в которой вычисляется градиент;
          g  - вещественный вектоp длины  n, содержащий
                  вычисленный градиент функции в точке x1;
         ge - заданная точность вычисления компонент
                  градиента (тип: вещественный);
         io - целочисленная  переменная,  используемая  как рабочая. 

Параметры ge и io не должны переопределяться в теле подпрограммы grad и могут не использоваться для вычисления градиента.

Имена подпрограммы вычисления значения функции  f (x) и ее градиента должны быть определены в вызывающей программе оператором extern.

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

    min  f(x) ,    x  E4 .
    f(x)  =  100 ( x2 - x12 )2 + (1 - x1)2 + 90 (x4 - x3)2 + (1 - x3)2 + 
            + (1 - x3)2 + 10.1 ( (x2 - 1)2 + (x4 - 1)2 ) + 19.8 (x2 - 1) (x4 - 1) .
  Точка абсолютного минимума     x*  =  (1., 1., 1., 1.) ,   f(x*)  =  0.

int main(void)
{
    /* Initialized data */
    static int n = 4;
    static int limit = 100;
    static float x[4] = { -3.f,-1.f,-3.f,-1.f };

    /* Local variables */
    extern int grad_c(), func_c();
    static int ierr;
    extern int mnb3r_c(int *, int *, float *, float *, float *, float *,
                       float *, int *, int *, float *, int *, U_fp, U_fp);
    static float f, g[4], h__[8];
    static int m, kount;
    static float eps, est;

    eps = 1e-11f;
    est = 0.f;
    m = n << 1;
    mnb3r_c(&n, &m, x, &f, g, &est, &eps, &limit, &ierr, h__, &kount,
            (U_fp)func_c, (U_fp)grad_c);

    printf("\n %5i \n", ierr);
    printf("\n %16.7e \n", f);
    printf("\n %16.7e %16.7e %16.7e %16.7e \n", x[0], x[1], x[2], x[3]);
/* l100: */
    printf("\n %5i \n", kount);
    return 0;
} /* main */

int func_c(float *x, float *f, float *fe)
{
    /* System generated locals */
    float r__1, r__2, r__3, r__4, r__5, r__6, r__7, r__8;

    /* Parameter adjustments */
    --x;

    /* Function Body */
/* Computing 2nd power */
    r__2 = x[1];
/* Computing 2nd power */
    r__1 = x[2] - r__2 * r__2;
/* Computing 2nd power */
    r__3 = 1.f - x[1];
/* Computing 2nd power */
    r__5 = x[3];
/* Computing 2nd power */
    r__4 = x[4] - r__5 * r__5;
/* Computing 2nd power */
    r__6 = 1.f - x[3];
/* Computing 2nd power */
    r__7 = x[2] - 1.f;
/* Computing 2nd power */
    r__8 = x[4] - 1.f;
    *f = r__1 * r__1 * 100.f + r__3 * r__3 + r__4 * r__4 * 90.f +
         r__6 * r__6 + (r__7 * r__7 + r__8 * r__8) * 10.1f +
         (x[2] - 1.f) * 19.8f * (x[4] - 1.f);
    return 0;
} /* func_c */

int grad_c(float *x, float *g, float *ge, int *i0)
{
    /* System generated locals */
    float r__1;

    /* Parameter adjustments */
    --g;
    --x;

    /* Function Body */
/* Computing 2nd power */
    r__1 = x[1];
    g[1] = x[1] * -400.f * (x[2] - r__1 * r__1) - (1.f - x[1]) * 2.f;
/* Computing 2nd power */
    r__1 = x[1];
    g[2] = (x[2] - r__1 * r__1) * 200.f + (x[2] - 1.f) * 20.2f +
           (x[4] - 1.f) * 19.8f;
/* Computing 2nd power */
    r__1 = x[3];
    g[3] = x[3] * -360.f * (x[4] - r__1 * r__1) - (1 - x[3]) * 2.f;
/* Computing 2nd power */
    r__1 = x[3];
    g[4] = (x[4] - r__1 * r__1) * 180.f + (x[4] - 1.f) * 20.2f +
           (x[2] - 1.f) * 19.8f;
    return 0;
} /* grad_c */


Результаты:

      ierr  =  -1
      f  =  0.3328214 - 09

      x(1)  =  1.0000100 + 00
      x(2)  =  1.0000190 + 00
      x(3)  =  0.99999060 + 00
      x(4)  =  0.99998120 + 00

      итераций - 62