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

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

Назначение

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

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

Для решения задачи: min  f (x),  x  En , используется квазиньютоновский метод, основанный на приближенном вычислении на каждой итерации матрицы  H, обратной к матрице Гессе функции  f (x). Приведение матрицы  H к диагональному виду осуществляется с использованием метода вращений.

Вычисленная точка  x k  En (k - номеp итерации метода) считается точкой минимума функции  f (x), если  | f (x k) - f (x k - 1) | ≤ EPS , где EPS > 0 - заданная точность вычисления минимума по функционалу.

Пшеничный Б.Н., Редковский H.H., Об одном численном методе минимизации без вычисления производных, ЖВМ и МФ, т.16, 1976.

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

    int mni2r_c (integer *n, real *f, real *eps, integer *lim,
            real *r1, real *r2, real *r3, real *r4, real *r5, real *r6,
            real *r7, real *r8, real *x, real *step, S_fp fun)

Параметры

n - размерность пространства переменных (тип: целый);
f - вещественная переменная, содержащая минимальное значение функции  f (x);
eps - заданная точность вычисления минимума по функционалу (тип: вещественный);
lim - заданное максимально допустимое число итераций метода (см. замечания по использованию) (тип: целый);
r1, r2 - вещественные векторы длины  n * n, используемые в подпрограмме как рабочие;
r3, r4 -
r5, r6  
r7, r8  
вещественные векторы длины  n, используемые в подпрограмме как рабочие;
x - вещественный вектоp длины  n; при обращении к подпрограмме содержит заданную начальную точку поиска, на выходе содержит точку минимального вычисленного значения  f (x);
step - заданное значение начального шага поиска (тип: вещественный);
fun - имя подпрограммы вычисления значения функции  f (x) (см. замечания по использованию).

Версии: нет

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

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

 

Используется служебная подпрограмма mni01_c.

Если eps > 0, то подпрограмма выполнит такое количество итераций метода, котоpое необходимо для достижения заданной точности решения, даже если оно больше lim.

Чтобы число фактически выполненных итераций было не больше lim, следует задавать eps = 0.0.

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

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

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

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

В общем случае, значения точности по функционалу eps и величины начального шага step pекомендуется задавать в следующих диапазонах: 1.e - 15 ≤ eps ≤ 1.e - 4,  0.01 ≤ step ≤ 0.2.

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

    min  f(x) ,   x  E2 .
    f(x)  =  100 ( x12 - x2 )2 + (x1 - 1)2.
    тoчкa бeзycлoвнoгo минимyмa     x*  =  (1.0, 1.0) ,   f(x*)  =  0.0 .

int main(void)
{
    /* Initialized data */
    static float x[2] = { -1.2f,1.f };

    /* Local variables */
    static float step;
    extern int mni2r_c(int *, float *, float *, int *, float *, float *,
                       float *, float *, float *, float *, float *, float *,
                       float *, float *, U_fp);
    static float e, f;
    static int k, n;
    static float r1[4] /* was [2][2] */,
                 r2[4] /* was [2][2] */, r3[2], r4[2],
                 r5[2], r6[2], r7[2], r8[2];
    extern int fun_c();

    n = 2;
    e = 1e-12f;
    step = .1f;
    mni2r_c(&n, &f, &e, &k, r1, r2, r3, r4, r5, r6, r7, r8, x, &step,
            (U_fp)fun_c);

    printf("\n %16.7e %16.7e \n", x[0], x[1]);
    printf("\n %16.7e \n", f);
    return 0;
} /* main */

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

    /* Parameter adjustments */
    --x;

    /* Function Body */
/* Computing 2nd power */
    r__2 = x[1];
/* Computing 2nd power */
    r__1 = r__2 * r__2 - x[2];
/* Computing 2nd power */
    r__3 = x[1] - 1;
    *f = r__1 * r__1 * 100.f + r__3 * r__3;
    return 0;
} /* fun_c */


Результаты:

      f  =  0.355e-15
      x  =  ( 0.9999999, 0.9999999 )