| Текст подпрограммы и версий mna6r_c.zip , mna6d_c.zip | Тексты тестовых примеров tmna6r_c.zip , tmna6d_c.zip | 
Поиск локального минимума функции многих переменных методом Пауэлла.
Пусть задана функция N переменных F (x1, x2, ..., xN) и пусть известны координаты начальной точки X = (x*1, x*2, ..., x*N) поиска локального минимума (N ≤ 50).
Подпрограмма mna6r_c выполняет итерационный процесс, состоящий в проведении последовательных одномерных поисков минимумов, начиная с точки X, вдоль системы определяемых в самой подпрограмме сопряженных направлений. В качестве начальных направлений поиска выбираются направления координатных осей в пространстве En.
Итерационный процесс продолжаетася до тех пор, пока модуль разности между значениями функции F в точках приближения к минимуму на двух последних итерациях не станет меньше EPS.
Предполагается, что составляемая пользователем подпрограмма - функция вычисления F в текущей точке XTEC всегда имеет имя FUNC и оформляется с двумя формальными параметрами:
XTEC - вещественный вектор длины N, содержащий координаты точки, в которой вычисляется значение функции F;
N - количество переменных (тип: целый).
Д.Химмельбау. Прикладное нелинейное программирование. Изд - во "Мир", 1975.
    int mna6r_c (integer *n, real *x, real *y, real *p, real *eps,
            integer *iflag, integer *itmax)
Параметры
| n - | количество переменных; n ≤ 50 (тип: целый); | 
| x - | вещественный вектор длины n, содержащий на входе координаты начальной точки поиска локального минимума, а на выходе - координаты этого минимума; | 
| y - | вещественная переменная, содержащая на выходе значение функции F в полученной точке минимума; | 
| p - | вещественный двумерный массив размеров n на n, используемый в подпрограмме в качестве рабочего; | 
| eps - | заданное допустимое отклонение между значениями функции F на двух последовательных итерациях (тип: вещественный); | 
| iflag - | целая переменная, служащая для сообщения о том, удалось ли найти локальный минимум за itmax итераций; при этом: | 
| iflag=0 - | когда минимум функции F не найден; тогда вектор x содержит приближение к минимуму на последней итерации, а y - значение F в этой точке; | 
| iflag=1 - | когда точка минимум найдена; | 
| itmax - | заданное максимальное число итераций (тип: целый). | 
Версии
| mna6d_c - | поиск локального минимума функции многих переменных методом Пауэлла в режиме удвоенной точности; при этом параметры x, y, p и eps должны иметь тип double, а подпрограмма - функция FUNC должна быть описана как double. | 
Вызываемые подпрограммы
| mna1r_c - mna1d_c | локализация минимума функции одной переменной в режимах одинарной и удвоенной точности; используются в подпрограммах mna6r_c и mna6d_c соответственно; | 
| mna3r_c - mna3d_c | поиск локального минимума функции одной переменной методом Брента (методом обратной параболической интерполяции) в режимах одинарной и удвоенной точности; используются в подпрограммах mna6r_c и mna6d_c соответственно. | 
Замечания по использованию
| В подпрограммах mna6r_c и mna6d_c имеется внешняя структура с именем mna6rr_ , содержащая элемент целого типа с именем iter. Переменная iter полагается равной количеству итераций, выполненных при поиске минимума функции. Если iflag = 0, то iter = itmax. В этом случае следует либо увеличить itmax, либо увеличить eps.В качестве рабочих используются подпрограммы mna6r1_c (mna6d1_c) и mna6r2_c (mna6d2_c), в которых имеется внешняя структура с именем mna6rc_ . | 
struct {
    int ntest;
} _BLNK__;
#define _BLNK__1 _BLNK__
struct {
    int iter;
} mna6rr_;
#define mna6rr_1 mna6rr_
int main(void)
{
    /* Local variables */
    extern int mna6r_c(int *, float *, float *, float *, float *, int *,
                       int *);
    static int n, iflag;
    static float y;
    static int itmax;
    static float p1[4] /* was [2][2] */,
                 p2[4] /* was [2][2] */, x1[2], x2[2], eps;
    _BLNK__1.ntest = 1;
    n = 2;
    x1[0] = 8.f;
    x1[1] = 9.f;
    eps = 1e-6f;
    itmax = 500;
    mna6r_c(&n, x1, &y, p1, &eps, &iflag, &itmax);
    printf("\n %16.7e %16.7e \n", x1[0], x1[1]);
    printf("\n %16.7e \n", y);
    printf("\n %5i \n", iflag);
    printf("\n %5i \n", mna6rr_1.iter);
    _BLNK__1.ntest = 2;
    x2[0] = 1.2f;
    x2[1] = 1.f;
    mna6r_c(&n, x2, &y, p2, &eps, &iflag, &itmax);
    printf("\n %16.7e %16.7e \n", x2[0], x2[1]);
    printf("\n %16.7e \n", y);
    printf("\n %5i \n", iflag);
    printf("\n %5i \n", mna6rr_1.iter);
    return 0;
} /* main */
float func_c(float *x, int *n)
{
    /* System generated locals */
    float ret_val, r__1, r__2, r__3;
    /* Parameter adjustments */
    --x;
    /* Function Body */
    if (_BLNK__1.ntest != 1) {
        goto l1;
    }
/* Computing 2nd power */
    r__1 = x[1] - .5f;
/* Computing 2nd power */
    r__2 = x[2] - 6.f;
    ret_val = r__1 * r__1 * 4.f + r__2 * r__2;
    return ret_val;
l1:
/* 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];
    ret_val = r__1 * r__1 * 100.f + r__3 * r__3;
    return ret_val;
} /* func_c */
Результаты: 
      x1(1) = 0.5 ;            x1(2) = 6.0 ;   y = 0.0 
      iflag = 1 ;             mna6rr_1.iter = 3 
      x2(1) = 1.00001 ;     x2(2) = 1.0 ;   y = 0.295415e - 7 
      iflag = 1 ;              mna6rr_1.iter = 2