GeneralFunctionMinimizer.h

00001 //===========================================================================
00002 // GoTools - SINTEF Geometry Tools version 1.1
00003 //
00004 // GoTools module: CORE
00005 //
00006 // Copyright (C) 2000-2007 SINTEF ICT, Applied Mathematics, Norway.
00007 //
00008 // This program is free software; you can redistribute it and/or          
00009 // modify it under the terms of the GNU General Public License            
00010 // as published by the Free Software Foundation version 2 of the License. 
00011 //
00012 // This program is distributed in the hope that it will be useful,        
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of         
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          
00015 // GNU General Public License for more details.                           
00016 //
00017 // You should have received a copy of the GNU General Public License      
00018 // along with this program; if not, write to the Free Software            
00019 // Foundation, Inc.,                                                      
00020 // 59 Temple Place - Suite 330,                                           
00021 // Boston, MA  02111-1307, USA.                                           
00022 //
00023 // Contact information: E-mail: tor.dokken@sintef.no                      
00024 // SINTEF ICT, Department of Applied Mathematics,                         
00025 // P.O. Box 124 Blindern,                                                 
00026 // 0314 Oslo, Norway.                                                     
00027 //
00028 // Other licenses are also available for this software, notably licenses
00029 // for:
00030 // - Building commercial software.                                        
00031 // - Building software whose source code you wish to keep private.        
00032 //===========================================================================
00033 #ifndef _GENERAL_FUNCTIONMINIMIZER_H
00034 #define _GENERAL_FUNCTIONMINIMIZER_H
00035 
00036 #include "Point.h"
00037 #include <vector>
00038 #include <limits>
00039 
00040 namespace Go {
00043 
00044 
00045 template<class Functor> class FunctionMinimizer;
00046 
00047 
00051 //===========================================================================
00052 template<class Functor>
00053 void minimise_conjugated_gradient(FunctionMinimizer<Functor>& dfmin);
00054 //===========================================================================
00055 
00110 template<class Functor>
00111 class FunctionMinimizer
00112 {
00113  public:
00117     FunctionMinimizer(int num_param, const Functor& fun, 
00118                       const double* const seed, 
00119                       double tol = std::sqrt(std::numeric_limits<double>::epsilon()));
00120 
00121     ~FunctionMinimizer() 
00122     {}
00123     
00130     double minimize(const Point& dir, bool& hit_domain_edge); 
00131 
00132 
00147     double linminBrent(const Point& dir,
00148                        const double* bracket,
00149                        const double* fval_brak);
00150 
00151 
00153     inline double fval() const; 
00154 
00157     inline double fval(const Point& param) const;
00158 
00161     inline void grad(Point& result) const;
00162 
00165     inline void grad(const Point& param, Point& result) const;
00166 
00169     inline void moveUV(const Point& dir, double multiplier);
00170 
00173     bool atMin(int param_ix) const {return at_min_[param_ix];}
00174     bool atMax(int param_ix) const {return at_max_[param_ix];}
00175 
00177     double getPar(int param_ix) const {return par_[param_ix];}
00178 
00180     const double* getPar() const {return par_.begin();}
00181 
00183     int numPars() const {return par_.size();}
00184                               
00185  private:
00186     const Functor fun_;
00187 
00188     Point par_;
00189     std::vector<bool> at_min_;
00190     std::vector<bool> at_max_;
00191 
00192     mutable bool cached_value_updated_;
00193     mutable bool cached_grad_updated_;
00194 
00195     mutable double cached_value_;
00196     mutable Point cached_grad_;
00197 
00198     const double minimization_tol_;
00199     std::vector<double> param_tol_;
00200 
00201     static const double root_machine_precision_;
00202     static const double rel_tol_;
00203     static const double perturbation_;
00204     static const double golden_ratio_;
00205     static const double default_partition_;
00206     static const double tiny_;
00207     static const int max_iter_;
00208 
00209 
00210     // update at_umin_, at_umax_, at_vmin_ and at_vmax_.  Should be called whenever the
00211     // current parameters ('cur_uv_') are changed.
00212     inline void checkBorder();
00213 
00214     // clear cached values.  Should be called whenever the current parameters ('cur_uv_') 
00215     // are changed.
00216     inline void resetCache() const;
00217 
00218     // determine how far we are allowed to step from the current parameter point in a certain
00219     // direction ('dir') before going out of the valid parameter domain.
00220     double determineMaxSteplength(const Point& dir) const;
00221 
00222     // Bracket the function minimum from the current parameter point along a certain 
00223     // direction ('dir'). The maximum allowed steplength is given in 'max_step'.  
00224     // Upon completion, two things might happen:
00225     // Possibility 1 : the function was able to bracket a minimum.  The position of the 
00226     //                 bracketing points (from current parameters, along 'dir') is 
00227     //                 returned in 'bracket' (3 values), and the corresponding distance
00228     //                 function values are returned in fval_brak.  The function returns 'true'.
00229     // Possibility 2 : the function hit the 'max_step' before it was able to bracket any
00230     //                 minimum.  The function returns 'false'.
00231     bool bracketInterval(const Point& dir,  
00232                          const double max_step,
00233                          //const double working_tolerance,
00234                          double* bracket,    // points to 3-array
00235                          double* fval_brak); // points to 3-array
00236 
00237     // given a direction 'dir', this function generates a direction 'result' that is a scaled
00238     // version of 'dir', with a possible sign change to make sure that the direction is 
00239     // "downhill" (negative scalar product with function gradient).  Returns 'true' on success,
00240     // and 'false' if the direction was practically perpendicular to the function gradient.
00241     bool orientDirection(const Point& dir, Point& result);
00242 
00243     // Returns -1 if the scalar product of p1 and p2 is negative, +1 if the scalar product
00244     // is positive and 0 if it close to 0.  In this case, 'close to 0' means that it is 
00245     // impossible to judge the derivatives sign when taking into account the numerical
00246     // noise associated with the magnitude of the points' components.
00247     int scalarProductSign(const Point& p1, const Point& p2);
00248 
00249     // Estimate the minimum of a parabola where two points and one tangent is known.  The 
00250     // two points are the current parameter point and the point obtained by marching from this
00251     // point a distance of 'dir' multiplied by 'p2'.  The function value in this second point
00252     // must also be given by 'fp2'.  The tangent known is the one for the current parameter 
00253     // point.  The abscissa for the minimum point of the parabola is returned.
00254     double parabolicEstimate(double p2, double fp2, const Point& dir);
00255 
00256     // Estimate the minimum of a parabola where three points are known.  If the minimum is found
00257     // to lie within the distance 'max_from_b' from b, the point is returned as 'u', and the
00258     // function returns 'true'.  Otherwise, it returns 'false', and 'u' is not calculated.
00259     static bool parabolicFit(double a, double fa, 
00260                              double b, double fb, 
00261                              double c, double fc, 
00262                              double max_from_b, double&u);
00263 
00264     // determine the smallest detectable change around the value 'c'
00265     static double numerical_tolerance(double c);
00266 
00267     // Determine the numerical tolerance around a given point in a given direction
00268     static double numerical_tolerance(const Point& x, const Point& dir);
00269 
00270     // Determine the numerical tolerance around a given point in a given direction, also
00271     // considering the change in function value (fx is the function at x, dfx is the derivative)
00272     static double numerical_tolerance(const Point& x, const Point& dir,
00273                                       const double fx, const double dfx);
00274 
00275 
00276     // A helper function for linminBrent.  A new point has been evaluated (u, fu), and we must
00277     // update the other points used by the algorithm.
00278     static void adjustBrackets(double& a, double& fa,
00279                                double& b, double& fb,
00280                                double& c, double& fc,
00281                                double& b2, double& fb2,
00282                                double& b3, double& fb3,
00283                                double u, double fu);
00284 
00285     static void shift3(double& a, double& b, double& c, double d) 
00286         { a = b; b = c; c = d;}
00287     static void shift2(double& a, double& b, double c) 
00288         { a = b; b = c;}
00289 };
00290 
00292 }; // end namespace Go
00293 
00294 #include "GeneralFunctionMinimizer_implementation.h"
00295 
00296 #endif // _GENERAL_FUNCTIONMINIMIZER_H
00297 
00298 

Generated on Mon Jun 11 14:48:18 2007 for GoTools Core Library by  doxygen 1.5.1