00001
00002
00008 #if !defined(__numerical_QuasiNewton_h__)
00009 #define __numerical_QuasiNewton_h__
00010
00011
00012 #if defined(DEBUG_numerical) && !defined(DEBUG_QuasiNewton)
00013 #define DEBUG_QuasiNewton
00014 #endif
00015
00016 #ifdef DEBUG_QuasiNewton
00017
00018 #ifndef DEBUG_OptGrad
00019 #define DEBUG_OptGrad
00020 #endif
00021 #endif
00022
00023 #include "Opt.h"
00024
00025 #include "../../ads/tensor/SquareMatrix.h"
00026
00027 #include "../../geom/kernel/Point.h"
00028
00029 #include <cmath>
00030
00031 BEGIN_NAMESPACE_NUMERICAL
00032
00034
00040 template <int N,
00041 class Function,
00042 typename T = typename Function::result_type,
00043 typename Point = typename Function::argument_type>
00044 class QuasiNewton :
00045 public Opt<N,Function,T,Point>
00046 {
00047 private:
00048
00049
00050
00051
00052
00053 typedef Opt<N,Function,T,Point> base_type;
00054
00055 typedef ads::SquareMatrix<N,T> matrix_type;
00056
00057 public:
00058
00059
00060
00061
00062
00064 typedef typename base_type::function_type function_type;
00065
00067 typedef typename base_type::number_type number_type;
00068
00070 typedef typename base_type::point_type point_type;
00071
00072 private:
00073
00074
00075
00076
00077
00078 number_type _x_tolerance;
00079
00080 number_type _gradient_tolerance;
00081
00082
00083
00084
00085
00086
00087 QuasiNewton();
00088
00089
00090 QuasiNewton( const QuasiNewton& );
00091
00092
00093 QuasiNewton&
00094 operator=( const QuasiNewton& );
00095
00096 public:
00097
00098
00103
00104
00106 QuasiNewton( const function_type& function,
00107 const number_type x_tolerance
00108 = 4 * std::numeric_limits<number_type>::epsilon(),
00109 const number_type gradient_tolerance
00110 = 4 * std::numeric_limits<number_type>::epsilon(),
00111 const int max_function_calls = 10000 ) :
00112 base_type( function, max_function_calls ),
00113 _x_tolerance( x_tolerance ),
00114 _gradient_tolerance( gradient_tolerance )
00115 {}
00116
00118 virtual
00119 ~QuasiNewton()
00120 {}
00121
00122
00123
00125
00126
00128
00140 void
00141 find_minimum( point_type& x, number_type& value, int& num_iterations,
00142 number_type max_step = 0,
00143 const number_type x_tolerance = 0,
00144 const number_type gradient_tolerance = 0 );
00145
00147
00151 void
00152 find_minimum( point_type& x )
00153 {
00154 number_type value;
00155 int num_iterations;
00156 find_minimum( x, value, num_iterations );
00157 }
00158
00159
00160
00162
00163
00164
00165
00166
00167
00169 static
00170 int
00171 dimension()
00172 {
00173 return base_type::dimension();
00174 }
00175
00177 const function_type&
00178 function() const
00179 {
00180 return base_type::function();
00181 }
00182
00184 int
00185 num_function_calls() const
00186 {
00187 return base_type::num_function_calls();
00188 }
00189
00190
00191
00192
00193
00195 number_type
00196 x_tolerance() const
00197 {
00198 return _x_tolerance;
00199 }
00200
00202 number_type
00203 gradient_tolerance() const
00204 {
00205 return _gradient_tolerance;
00206 }
00207
00208
00209
00211
00212
00213
00214
00215
00216
00218 void
00219 set_max_function_calls( const int max_function_calls )
00220 {
00221 base_type::set_max_function_calls( max_function_calls );
00222 }
00223
00225 void
00226 reset_num_function_calls()
00227 {
00228 base_type::reset_num_function_calls();
00229 }
00230
00231
00232
00233
00234
00236 void
00237 set_x_tolerance( const number_type x_tolerance )
00238 {
00239 _x_tolerance = x_tolerance;
00240 }
00241
00243 void
00244 set_gradient_tolerance( const number_type gradient_tolerance )
00245 {
00246 _gradient_tolerance = gradient_tolerance;
00247 }
00248
00249
00250
00251 protected:
00252
00253
00257
00258
00260
00263 number_type
00264 evaluate_function( const point_type& x )
00265 {
00266 return base_type::evaluate_function( x );
00267 }
00268
00270
00273 void
00274 evaluate_gradient( const point_type& x, point_type& gradient )
00275 {
00276 base_type::evaluate_gradient( x, gradient );
00277 }
00278
00280
00283 void
00284 evaluate_numeric_gradient( const point_type& x,
00285 point_type& gradient,
00286 const number_type delta = 0.0 )
00287 {
00288 base_type::evaluate_numeric_gradient( x, gradient, delta );
00289 }
00290
00291
00292
00293 private:
00294
00295 void
00296 line_search( const point_type& x_old, const number_type f_old,
00297 point_type& gradient, point_type& direction, point_type& x,
00298 number_type& f, const number_type max_step );
00299
00300 };
00301
00302 END_NAMESPACE_NUMERICAL
00303
00304 #define __QuasiNewton_ipp__
00305 #include "QuasiNewton.ipp"
00306 #undef __QuasiNewton_ipp__
00307
00308 #endif