00001
00002
00008 #if !defined(__numerical_Opt_h__)
00009 #define __numerical_Opt_h__
00010
00011
00012 #if defined(DEBUG_numerical) && !defined(DEBUG_Opt)
00013 #define DEBUG_Opt
00014 #endif
00015
00016 #include "Exception.h"
00017
00018 #include "../derivative/centered_difference.h"
00019
00020 #include "../../ads/array/FixedArray.h"
00021
00022 BEGIN_NAMESPACE_NUMERICAL
00023
00025
00031 template<int N, class Function, typename T = typename Function::result_type,
00032 typename Point = typename Function::argument_type>
00033 class Opt {
00034 protected:
00035
00036
00037
00038
00039
00041 typedef Function function_type;
00042
00044 typedef T number_type;
00045
00047 typedef Point point_type;
00048
00049
00050
00051
00052
00053 protected:
00054
00056 const function_type& _function;
00057
00059 int _max_function_calls;
00060
00062 int _num_function_calls;
00063
00065 bool _are_checking_function_calls;
00066
00067
00068
00069
00070
00071 private:
00072
00073
00074 Opt();
00075
00076
00077 Opt(const Opt&);
00078
00079
00080 Opt&
00081 operator=(const Opt&);
00082
00083 protected:
00084
00085
00091
00092
00094 Opt(const function_type& function,
00095 const int max_function_calls = 10000,
00096 const bool are_checking_function_calls = true) :
00097 _function(function),
00098 _max_function_calls(max_function_calls),
00099
00100 _num_function_calls(std::numeric_limits<int>::max()),
00101 _are_checking_function_calls(are_checking_function_calls)
00102 {}
00103
00105 virtual
00106 ~Opt()
00107 {}
00108
00109
00110
00112
00113
00115
00118 number_type
00119 evaluate_function(const point_type& x) {
00120 increment_function_calls(x);
00121 return _function(x);
00122 }
00123
00125
00128 void
00129 evaluate_gradient(const point_type& x, point_type& gradient) {
00130 increment_function_calls(x);
00131 _function.gradient(x, gradient);
00132 }
00133
00135
00138 void
00139 evaluate_numeric_gradient(const point_type& x,
00140 point_type& gradient,
00141 const number_type delta = 0.0) {
00142 increment_function_calls(x, 2 * N);
00143 if (delta != 0.0) {
00144 numerical::gradient_centered_difference<N,function_type,number_type>
00145 (_function, x, gradient, delta);
00146 }
00147 else {
00148 numerical::gradient_centered_difference<N,function_type,number_type>
00149 (_function, x, gradient);
00150 }
00151 }
00152
00153
00154
00155 public:
00156
00157
00159
00160
00162 static
00163 int
00164 dimension() {
00165 return N;
00166 }
00167
00169 const function_type&
00170 function() const {
00171 return _function;
00172 }
00173
00175 int
00176 max_function_calls() {
00177 return _max_function_calls;
00178 }
00179
00181 int
00182 num_function_calls() const {
00183 return _num_function_calls;
00184 }
00185
00186
00187
00189
00190
00192 void
00193 set_max_function_calls(const int max_function_calls) {
00194 _max_function_calls = max_function_calls;
00195 }
00196
00198 void
00199 reset_num_function_calls() {
00200 _num_function_calls = 0;
00201 }
00202
00204 void
00205 set_are_checking_function_calls(const bool are_checking) {
00206 _are_checking_function_calls = are_checking;
00207 }
00208
00209
00210
00211 private:
00212
00213
00214 void
00215 increment_function_calls(const point_type& x, const int increment = 1) {
00216 _num_function_calls += increment;
00217 if (_are_checking_function_calls &&
00218 _num_function_calls > _max_function_calls) {
00219 OptimizationException<N,number_type,point_type>
00220 ex("In Opt: max function calls exceeded.",
00221 x, _function(x), _num_function_calls);
00222 ex.print();
00223 throw ex;
00224 }
00225 }
00226
00227 };
00228
00229 END_NAMESPACE_NUMERICAL
00230
00231 #endif