Текст подпрограммы и версий mnb4r_c.zip , mnb4d_c.zip |
Тексты тестовых примеров tmnb4r_c.zip , tmnb4d_c.zip |
Решение задачи, безусловной минимизации диффеpенциpуемой функции многих переменных методом Дэвидона - Флетчеpа - Пауэлла.
Для решения задачи: min f (x) , x ∈ En используется квазиньютоновский метод Дэвидона - Флетчеpа - Пауэлла.
Некоторая вычисленная точка 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, 122 - 129.
int mnb4r_c (integer *n, integer *m, real *x, real *f, real *g, real *est, real *eps, integer *limit, integer *ierr, real *h, integer *kount, S_fp fun, S_fp grad)
Параметры
n - | размерность пространства переменных (тип: целый); |
m - | целая переменная, равная n * (n + 7)/2; |
x - | вещественный векто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ом направлении; |
h - | вещественный вектоp длины m, используемый в подпрограмме как рабочий; |
kount - | целая переменная, содержащая фактически выполненное число итераций метода (тип: целый); |
fun - | имя подпрограммы вычисления значения функции f (x) (см. замечания по использованию); |
grad - | имя подпрограммы вычисления градиента функции f (x) (см. замечания по использованию). |
Версии:
mnb4d_c - | Решение задачи безусловной минимизации диффеpенциpуемой функции многих переменных методом Дэвидона - Флетчеpа - Пауэлла, при этом вычисления проводятся с удвоенной точностью. Параметры x, f, g, est, eps, h, fe, ge подпрограммы mnb4d_c и подпрограмм fun, grad должны иметь тип double. Тип остальных параметров не изменяется. |
Вызываемые подпрограммы: нет
Замечания по использованию
Оценка est минимального значения функции f (x) используется в пpоцедуpе одномерной минимизации по направлению. Если приближение минимума можно указать, то это ускоpит процесс минимизации. В противном случае можно положить est = 0.0. Подпрограммы fun и grad составляются пользователем. Первый оператор подпрограммы вычисления функции должен иметь вид: int fun(float *x, float *f, float *fe) Параметры x - вещественный вектор длины n, задающий точку пространства, в которой вычисляется значение функции; f - вещественная переменная, содержащая вычисленное значение функции в точке x; fe - заданная точность вычисления значения функции в точке x (тип: вещественный); Параметр fe не должен переопределяться в теле подпрограммы fun и может не использоваться для вычисления f (x). Первый оператор подпрограммы вычисления градиента функции f (x) должен иметь вид: int grad(float *x, float *g, float *ge, int *i0) Параметры x - вещественный вектор длины n, задающий точку пространства, в которой вычисляется градиент; g - вещественный вектоp длины n, содержащий вычисленный градиент функции в точке x; ge - заданная точность вычисления компонент градиента (тип: вещественный); io - целочисленная переменная, используемая как рабочая. Параметры ge и io не должны переопределяться в теле подпрограммы grad и могут не использоваться для вычисления градиента. Имена подпрограмм вычисления значения функции f (x) и ее градиента должны быть определены в вызывающей программе оператором extern. |
min f(x) , x ∈ E3 .
f(x) = 100 (x3 - 0.25 (x1 + x2)2)2 + (1 - x1)2 + (1 - x2)2 .
Точка безусловного минимума x* = (1., 1., 1.) , f(x*) = 0.0 .
int main(void)
{
/* Initialized data */
static int n = 3;
static int limit = 100;
static float x[3] = { -1.2f,2.f,0.f };
/* Local variables */
extern int grad_c(), func_c();
static int ierr;
extern int mnb4r_c(int *, int *, float *, float *, float *, float *,
float *, int *, int *, float *, int *, U_fp, U_fp);
static float f, g[3], h__[15];
static int m, kount;
static float eps, est;
eps = 1e-5f;
est = 0.f;
printf("\n %5i \n", n);
printf("\n %5i \n", limit);
printf("\n %16.7e \n", est);
printf("\n %16.7e \n", eps);
printf("\n %16.7e %16.7e %16.7e \n", x[0], x[1], x[2]);
/* l100: */
m = n * (n + 7) / 2;
mnb4r_c(&n, &m, x, &f, g, &est, &eps, &limit, &ierr, h__, &kount,
(U_fp)func_c, (U_fp)grad_c);
printf("\n\n %5i \n", ierr);
printf("\n %5i \n", kount);
printf("\n %16.7e \n", f);
printf("\n %16.7e %16.7e %16.7e \n", x[0], x[1], x[2]);
/* l200: */
return 0;
} /* main */
int func_c(float *x, float *f, float *fe)
{
/* System generated locals */
float r__1, r__2, r__3, r__4;
/* Parameter adjustments */
--x;
/* Function Body */
/* Computing 2nd power */
r__2 = x[1] + x[2];
/* Computing 2nd power */
r__1 = x[3] - r__2 * r__2 * .25f;
/* Computing 2nd power */
r__3 = 1.f - x[1];
/* Computing 2nd power */
r__4 = 1.f - x[2];
*f = r__1 * r__1 * 100.f + r__3 * r__3 + r__4 * r__4;
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] + x[2];
g[1] = (x[1] + x[2]) * -100.f * (x[3] - r__1 * r__1 * .25f) -
(1.f - x[1]) * 2;
/* Computing 2nd power */
r__1 = x[1] + x[2];
g[2] = (x[1] + x[2]) * -100.f * (x[3] - r__1 * r__1 * .25f) -
(1.f - x[2]) * 2;
/* Computing 2nd power */
r__1 = x[1] + x[2];
g[3] = (x[3] - r__1 * r__1 * .25f) * 200.f;
return 0;
} /* grad_c */
Результаты:
ierr = 0
число итepaций = 18
значение функции = 0.0000000+00
значения независимых переменных
x(1) = 0.10000000+01
x(2) = 0.10000000+01
x(3) = 0.10000000+01