TooN: optimization/golden_section.h Source File

TooN 2.0.0-beta8

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List

optimization/golden_section.h

    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