2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему
 
 Градиентный метод с дроблением шага
Сообщение09.04.2016, 23:31 


20/10/12
235
Я считаю, что он у меня не удался
+Считает правильные значения из некоторых начальных точек
-В процедуре дробления (partition), эпсилон нельзя брать больше половины, хотя в теории написано, что можно брать от 0 до 1.
-Даже если он считает правильно - слишком много итераций он на это тратит (больше 1000)
?Какой лучше брать критерий остановки?
?Какой лучше брать начальный лямбда?
Код (C):
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
#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;
}

Прошу специалистов взглянуть.
http://www.machinelearning.ru/wiki/inde ... 0%BA%D0%B0

 Профиль  
                  
 
 Re: Градиентный метод с дроблением шага
Сообщение19.04.2016, 13:55 


20/10/12
235
Эх, где же специалисты по градиентным методам?
Я, конечно, могу углубиться в чтение дополнительной литературы, но вопросы-то довольно простые:
Нормально ли для градиентного метода с дроблением шага для точности 0.01 делать пару тысяч итераций?
Эпсилон в процедуре дробления ведет себя странно (см. код и пред пост), в чем неточность?
В источнике берутся нормы градиента, но какие не сказано, возможно в этом все дело?

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 2 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group