Текст подпрограммы и версий 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