#include <stdio.h>
#include <math.h>
#define M 10000
double a = 1.0, b = 1.0, c = 1.0;
double abs(double x)
{
return x < 0 ? -x : x;
}
double f(double x1, double x2)
{
return a*x1 + x2 + 4*sqrt(1 + b*x1*x1 + c*x2*x2);
}
double df_dx1(double x1, double x2)
{
return a + 4 * b * x1 / sqrt(1 + b*x1*x1 + c*x2*x2);
}
double df_dx2(double x1, double x2)
{
return 1 + 4 * c * x2 / sqrt(1 + b*x1*x1 + c*x2*x2);
}
double partition(double lambda, double (*f)(double, double), double x1, double x2)
{
double delta = 0.5, eps = 0.25;//константа дробления и оценки
double dx1 = df_dx1(x1, x2), dx2 = df_dx2(x1, x2);
double a = abs(dx1 + dx2);
while(f(x1 - lambda * dx1, x2 - lambda * dx2) > f(x1, x2) - eps * lambda * a * a )
lambda *= delta;
return lambda;
}
double GradientWithPartitions(double (*f)(double, double), double x01, double x02, double eps)
{
FILE *out;
double x1 = x01, x2 = x02, lambda, xp1, xp2;
int it = 0;
lambda = 0.001; //magic, начальный шаг, взят с потолка
out = fopen("out.txt", "w");
do
{
lambda = partition(lambda, f, x1, x2);
++it;
xp1 = x1;
xp2 = x2;
x1 -= lambda * df_dx1(x1, x2);
x2 -= lambda * df_dx2(x1, x2);
}while(sqrt( df_dx1(x1, x2)*df_dx1(x1, x2) + df_dx2(x1, x2)*df_dx2(x1, x2) ) > eps && it < M);
printf("# %i iterations \n", it);
printf("Optimum achieved on (%lf, %lf)\n", x1, x2);
printf("Optimum achieved on (%lf, %lf)\n", -1/sqrt(14.0), -1/sqrt(14.0));
return f(x1, x2);
}
int main(void)
{
double opt = GradientWithPartitions(f, 0, 0, 0.1);
printf("%.10lf : %.10lf \n", opt, sqrt(14.0));
return 0;
}