TooN 2.1
|
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 00013 /// golden_section_search performs a golden section search line minimization 00014 /// on the functor provided. The inputs a, b, c must bracket the minimum, and 00015 /// must be in order, so that \f$ a < b < c \f$ and \f$ f(a) > f(b) < f(c) \f$. 00016 /// @param a The most negative point along the line. 00017 /// @param b The central point. 00018 /// @param fb The value of the function at the central point (\f$b\f$). 00019 /// @param c The most positive point along the line. 00020 /// @param func The functor to minimize 00021 /// @param maxiterations Maximum number of iterations 00022 /// @param tol Tolerance at which the search should be stopped. 00023 /// @return The minima position is returned as the first element of the vector, 00024 /// and the minimal value as the second element. 00025 /// @ingroup gOptimize 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 //The golden ratio: 00030 const Precision g = (3.0 - sqrt(5))/2; 00031 00032 Precision x1, x2, fx1, fx2; 00033 00034 //Perform an initial iteration, to get a 4 point 00035 //bracketing. This is rather more convenient than 00036 //a 3 point bracketing. 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 //We now have an ordered list of points a x1 x2 c 00055 00056 //Termination condition from NR in C 00057 int itnum = 1; //We've already done one iteration. 00058 while(abs(c-a) > tol * (abs(x2)+abs(x1)) && itnum < maxiterations) 00059 { 00060 if(fx1 > fx2) 00061 { 00062 // Bracketing does: 00063 // a x1 x2 c 00064 // a x1 x2 c 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 // Bracketing does: 00075 // a x1 x2 c 00076 // a x1 x2 c 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 00093 /// golden_section_search performs a golden section search line minimization 00094 /// on the functor provided. The inputs a, b, c must bracket the minimum, and 00095 /// must be in order, so that \f$ a < b < c \f$ and \f$ f(a) > f(b) < f(c) \f$. 00096 /// @param a The most negative point along the line. 00097 /// @param b The central point. 00098 /// @param c The most positive point along the line. 00099 /// @param func The functor to minimize 00100 /// @param maxiterations Maximum number of iterations 00101 /// @param tol Tolerance at which the search should be stopped. 00102 /// @return The minima position is returned as the first element of the vector, 00103 /// and the minimal value as the second element. 00104 /// @ingroup gOptimize 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