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

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

Назначение

Поиск отрезка, содержащего минимум функции многих переменных на заданном направлении.

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

Для заданной функции  φ (x) и заданного направления  s (x, s  En) тpебуется найти отрезок [a, b] такой, что  x* = argmin φ (x0 + λ s),  λ  E1 принадлежит отpезку [x0 + a s, x0 + b s], где  x0 - заданная начальная точка поиска.

Для решения задачи используется метод удвоения шага.

Функция  φ (x) предполагается строго квазивыпуклой по направлению  S.

В.Г.Kаpманов. Математическое программирование. M., "Hаука", 1980.

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

    int mnb9r_c (integer *n, real *x, real *s, real *xx, real *eps,
             real *h, real *a, real *b, real *fa, real *fb, integer *k,
         S_fp fun, integer *ierr)

Параметры

n - размерность пространства переменных (тип: целый);
x - вещественный вектоp длины  n, задающий начальную точку поиска;
s - вещественный вектоp длины  n, задающий направление поиска;
xx - вещественный вектоp длины  n, используемый в подпрограмме как рабочий;
eps - вещественная переменная, задающая длину начального шага по направлению (см. замечания по использованию);
h - вещественная переменная, задающая максимальное смещение от  x по направлению  s (см. замечания по по использованию);
a - вещественная переменная, содержащая на выходе нижнюю гpаницу найденного отрезка;
b - вещественная переменная, содержащая на выходе верхнюю гpаницу найденного отрезка;
fa - вещественная переменная, содержащая значение функции в точке x + a * s;
fb - вещественная переменная, содержащая значение функции в точке x + b * s;
k - целая переменная, содержащая на выходе выполненное число вычислений функции;
fun - имя подпрограммы вычисления функции (см. замечания по использованию);
ierr - целая переменная, указывающая пpичину окончания процесса вычислений:
ierr= 0 - локализован отрезок, содержащий точку минимума;
ierr=65 - функция монотонно убывает на отрезке [x, x + h * s] или [x - h * s, x];
ierr=66 - функция постоянна на отрезке [x - eps * s, x + eps * s].

Версии: нет

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

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

  1. 

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

  2. 

Значение параметра  h выбирается достаточно большим положительным числом, однако таким, чтобы значения функции в точках x + h * s и x - h * s были определены при вычислениях на данной ЭВМ.

  3. 

Подпрограмма fun составляется пользователем. Первый оператор подпрограммы должен иметь вид:

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

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

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

        φ (x)  =  log(-x) ,   если  x ≤ -1 ,
        φ (x)  =  x3 + 1 ,   если  x > -1

               x0  =  -3

int main(void)
{
    /* Initialized data */
    static int n = 1;
    static float eps = 1e-4f;
    static float h__ = 1e3f;
    static float x[1] = { -3.f };
    static float s[1] = { 1.f };

    /* Local variables */
    extern int func_c();
    static int ierr;
    extern int mnb9r_c(int *, float *, float *, float *, float *, float *,
                       float *, float *, float *, float *, int *, U_fp, int *);
    static float a, b;
    static int kount;
    static float fa, fb, xx[1];

    mnb9r_c(&n, x, s, xx, &eps, &h__, &a, &b, &fa, &fb, &kount, (U_fp)func_c,
            &ierr);

    printf("\n %5i \n", ierr);
    if (ierr == 66) { goto l10; }

    printf("\n %16.7e %16.7e \n", a, b);
    printf("\n %16.7e %16.7e \n", fa, fb);
l10:
    return 0;
} /* main */

int func_c(float *x, float *f, float *fe)
{
    /* System generated locals */
    float r__1;

    /* Builtin functions */
    double r_lg10(float *);

    /* Parameter adjustments */
    --x;

    /* Function Body */
    if (x[1] + 1.f <= 0.f) {
        goto l10;
    } else {
        goto l20;
    }
l10:
    r__1 = -x[1];
    *f = (float)r_lg10(&r__1);
    goto l30;
l20:
/* Computing 3rd power */
    r__1 = x[1];
    *f = r__1 * (r__1 * r__1) + 1.f;
l30:
    return 0;
} /* func_c */


Результаты:
      
      ierr  =  0

      a  =  0.8191000
      b  =  3.2767000

      fa  =  0.33863580
      fb  =  1.0211850