SIMLIB/C++  3.07
opt-hooke.cc
Go to the documentation of this file.
1 /////////////////////////////////////////////////////////////////////////////
2 //! \file opt-hooke.cc Optimization algorithm - Hooke-Jeves
3 //
4 // Copyright (c) 2000-2004 Petr Peringer
5 //
6 // This library is licensed under GNU Library GPL. See the file COPYING.
7 //
8 
9 // EXPERIMENTAL
10 // Hooke-Jeves optimization method
11 
12 #include "simlib.h"
13 #include "internal.h"
14 #include "optimize.h"
15 
16 #define debug 1 // print values
17 
18 //## repair
19 #include <math.h>
20 
21 namespace simlib3 {
22 
24 
25 //////////////////////////////////////////////////////////////////////////////
26 // optimization method
27 //
28 // look for a better minimum, change one coord at a time
29 static double hooke_step(double *delta, opt_function_t f, ParameterVector & p,
30  double min0)
31 {
32  int n = p.size();
33  double fmin = min0;
34  for (int i = 0; i < n; i++) {
35  if (delta[i] == 0.0)
36  continue; // ignore zero delta
37  double old = p[i];
38  p[i] = old + delta[i];
39  double ftmp = (p[i] == old) ? fmin : f(p);
40  if (ftmp < fmin)
41  fmin = ftmp;
42  else {
43  delta[i] = -delta[i]; // opposite direction
44  p[i] = old + delta[i];
45  ftmp = (p[i] == old) ? fmin : f(p);
46  if (ftmp < fmin)
47  fmin = ftmp;
48  else
49  p[i] = old; // no change
50  }
51  }
52  return fmin;
53 }
54 
55 //////////////////////////////////////////////////////////////////////////////
56 
58  double rho, double epsilon, int itermax)
59 {
60 // assert(rho>0.01 && rho <1.0);
61 // assert(epsilon>1e-12 && epsilon < rho); // 1e-12 > 100*DBL_EPS
62 // assert(itermax>0);
63  int n = parameter.size(); // number of parameters
64 // assert(n>0);
65  double *delta = new double[n];
66  ParameterVector oldx(parameter);
67  ParameterVector newx(parameter);
68  for (int i = 0; i < n; i++)
69  delta[i] = fabs(parameter[i].Range() / 10); // initial step 10==MPARAMETER-???
70  int iteration = 0;
71  double steplength = rho; // 1.0 ???
72  double newf = f(newx);
73 #if debug
74  newx.PrintValues();
75  Print("%g\n", newf);
76 #endif
77  double oldf = newf;
78  while (iteration < itermax && steplength > epsilon) {
79  iteration++;
80  newx = oldx;
81  newf = hooke_step(delta, f, newx, oldf);
82  // if we made some improvements, continue that direction
83  while (newf < oldf) {
84 #if debug
85  newx.PrintValues();
86  Print("%g\n", newf);
87 #endif
88  for (int i = 0; i < n; i++) {
89  double dxi = newx[i] - oldx[i]; // actual difference
90  // arrange the sign of delta[]
91  delta[i] = (dxi <= 0.0) ? -fabs(delta[i]) : fabs(delta[i]);
92  // move further in this direction
93  oldx[i] = newx[i];
94  newx[i] = newx[i] + dxi;
95  }
96  oldf = newf;
97  newf = hooke_step(delta, f, newx, oldf);
98  /* if the further (optimistic) move was bad.... */
99  if (newf >= oldf) // worse
100  break; ///////////////////// break
101  /* !!!! make sure that the differences between the new and the old
102  * points are due to actual displacements; beware of roundoff
103  * errors that might cause newf < oldf
104  */
105  int i;
106  for (i = 0; i < n; i++)
107  if (fabs(newx[i] - oldx[i]) > (0.5 * fabs(delta[i])))
108  break;
109  // if there is NOT actual change in at least one axis
110  if (i == n)
111  break; ///////////////////// break
112  }
113  if (steplength >= epsilon && newf >= oldf) {
114  steplength *= rho;
115  for (int i = 0; i < n; i++)
116  delta[i] *= rho; // decrease delta
117  }
118  }
119  delete[]delta; //
120  parameter = oldx; // copy result
121 // iterations = iteration; // number of iterations
122  return oldf; // return last minimum value
123 }
124 
125 }
126 // end
int Print(const char *fmt,...)
for Output methods, can be redirected
Definition: print.cc:92
double Optimize_hooke(opt_function_t f, ParameterVector &parameter, double rho, double epsilon, int itermax)
Definition: opt-hooke.cc:57
Implementation of class CalendarList interface is static - using global functions in SQS namespace...
Definition: algloop.cc:32
Basic optimization framework + methods.
static double hooke_step(double *delta, opt_function_t f, ParameterVector &p, double min0)
Definition: opt-hooke.cc:29
double(* opt_function_t)(const ParameterVector &p)
Definition: optimize.h:83
Internal header file for SIMLIB/C++.
Main SIMLIB/C++ interface.
SIMLIB_IMPLEMENTATION
Definition: algloop.cc:34
void PrintValues() const
Definition: opt-param.cc:97