gradient.cpp 2.71 KB
Newer Older
Sergi Hernandez's avatar
Sergi Hernandez committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include "gradient.h"
#include <math.h>

CGradient::CGradient()
{ 
  this->max_coord_inc=DEFAULT_MAX_INC;	
  this->max_coord=std::numeric_limits<double>::max();
  this->min_coord=-std::numeric_limits<double>::max();
}

CGradient::CGradient(double max_coord_inc)
{
  this->set_max_coord_inc(max_coord_inc);
  this->max_coord=std::numeric_limits<double>::max();
  this->min_coord=-std::numeric_limits<double>::max();
}

void CGradient::set_max_coord_inc(double max_inc)
{
  this->max_coord_inc=max_inc;
}

double CGradient::get_max_coord_inc(void)
{
  return this->max_coord_inc;
}

void CGradient::set_coord_constraints(double max,double min)
{
  this->max_coord=max;
  this->min_coord=min;
}

void CGradient::get_coord_constraints(double &max,double &min)
{
  max=this->max_coord;
  min=this->min_coord;
}

void CGradient::set_function(boost::function<double (double)> p_function)
{
  this->p_function=p_function;
}

void CGradient::set_function_der(boost::function<double (double)> p_function)
{
  this->p_function_der=p_function;
}

50
bool CGradient::compute(double max_func_error,unsigned int max_iter,double start_point,bool &beyond_limits,bool max)
Sergi Hernandez's avatar
Sergi Hernandez committed
51
52
53
54
55
{
  unsigned int iteration=0;
  double gamma=1.0,func_value,func_der_value,prev_func_value,prev_func_der_value;
  double coord,prev_coord,coord_inc;

56
  beyond_limits=false;
Sergi Hernandez's avatar
Sergi Hernandez committed
57
58
59
60
61
62
63
64
65
66
67
68
69
70
  coord=start_point;
  func_value=this->p_function(coord);
  func_der_value=this->p_function_der(coord);
  do{
    coord_inc=gamma*func_der_value;  
    if(coord_inc>this->max_coord_inc)
      coord_inc=this->max_coord_inc;
    else if(coord_inc<-this->max_coord_inc)
      coord_inc=-this->max_coord_inc;
    prev_coord=coord;
    if(max)
      coord+=coord_inc;
    else
      coord-=coord_inc;
71
    if((coord-this->max_coord)>max_func_error)
Sergi Hernandez's avatar
Sergi Hernandez committed
72
73
74
75
    {
      coord=this->max_coord;
      this->coordinate=coord;
      this->value=this->p_function(coord);
76
      beyond_limits=true;
Sergi Hernandez's avatar
Sergi Hernandez committed
77
78
      break;
    }
79
    else if((coord-this->min_coord)<-max_func_error)
Sergi Hernandez's avatar
Sergi Hernandez committed
80
81
82
83
    {
      coord=this->min_coord;
      this->coordinate=coord;
      this->value=this->p_function(coord);
84
      beyond_limits=true;
Sergi Hernandez's avatar
Sergi Hernandez committed
85
86
87
88
89
90
91
92
93
94
95
      break;
    }
    prev_func_value=func_value;
    func_value=this->p_function(coord);
    prev_func_der_value=func_der_value;
    func_der_value=this->p_function_der(coord);
    gamma=fabs((coord-prev_coord)/(func_der_value-prev_func_der_value));
    iteration++;
  }while((fabs(func_value-prev_func_value)>max_func_error || fabs(coord-prev_coord)>0.001) && iteration<max_iter);
  this->coordinate=coord;
  this->value=func_value;
96
  if(iteration==max_iter)
Sergi Hernandez's avatar
Sergi Hernandez committed
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
    return false;
  else
    return true;
}

double CGradient::get_value(void)
{
  return this->value;
}

double CGradient::get_coordinate(void)
{
  return this->coordinate;
}

CGradient::~CGradient()
{


}