00001 #ifndef TOON_GOLDEN_SECTION_H
00002 #define TOON_GOLDEN_SECTION_H
00003 #include <TooN/TooN.h>
00004 #include <limits>
00005 #include <cmath>
00006 #include <cstdlib>
00007 #include <iomanip>
00008
00009 namespace TooN
00010 {
00011 using std::numeric_limits;
00012
00026 template<class Functor, class Precision> Vector<2, Precision> golden_section_search(Precision a, Precision b, Precision c, Precision fb, const Functor& func, int maxiterations, Precision tol = sqrt(numeric_limits<Precision>::epsilon()))
00027 {
00028 using std::abs;
00029
00030 const Precision g = (3.0 - sqrt(5))/2;
00031
00032 Precision x1, x2, fx1, fx2;
00033
00034
00035
00036
00037 if(abs(b-a) > abs(c-b))
00038 {
00039 x1 = b - g*(b-a);
00040 x2 = b;
00041
00042 fx1 = func(x1);
00043 fx2 = fb;
00044 }
00045 else
00046 {
00047 x2 = b + g * (c-b);
00048 x1 = b;
00049
00050 fx1 = fb;
00051 fx2 = func(x2);
00052 }
00053
00054
00055
00056
00057 int itnum = 1;
00058 while(abs(c-a) > tol * (abs(x2)+abs(x1)) && itnum < maxiterations)
00059 {
00060 if(fx1 > fx2)
00061 {
00062
00063
00064
00065 a = x1;
00066 x1 = x2;
00067 x2 = x1 + g * (c-x1);
00068
00069 fx1 = fx2;
00070 fx2 = func(x2);
00071 }
00072 else
00073 {
00074
00075
00076
00077 c = x2;
00078 x2 = x1;
00079 x1= x2 - g * (x2 - a);
00080
00081 fx2 = fx1;
00082 fx1 = func(x1);
00083 }
00084 }
00085
00086
00087 if(fx1 < fx2)
00088 return makeVector<Precision>(x1, fx1);
00089 else
00090 return makeVector<Precision>(x2, fx2);
00091 }
00092
00105 template<class Functor, class Precision> Vector<2, Precision> golden_section_search(Precision a, Precision b, Precision c, const Functor& func, int maxiterations, Precision tol = sqrt(numeric_limits<Precision>::epsilon()))
00106 {
00107 return golden_section_search(a, b, c, func(b), func, maxiterations, tol);
00108 }
00109
00110 }
00111 #endif