00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef _criteria_h
00014 #define _criteria_h
00015
00016
00017 #include <iostream>
00018 #include <iomanip>
00019
00020 #include <portability.h>
00021
00029 class OptimizationEndCriteria {
00030 public:
00031 enum EndCriteria { maxIter=1, statPt=2, statGd=3};
00032 protected:
00034 int maxIteration_;
00036 double functionEpsilon_, gradientEpsilon_;
00038 int maxIterStatPt_, statState_;
00039 int endCriteria_;
00040 bool positiveOptimization_;
00041 public:
00043 inline OptimizationEndCriteria();
00045 inline OptimizationEndCriteria(int maxIteration, double epsilon);
00047 inline OptimizationEndCriteria(const OptimizationEndCriteria& oec);
00049 inline ~OptimizationEndCriteria() {}
00050
00052 inline OptimizationEndCriteria& operator=(const OptimizationEndCriteria& oec);
00053
00054 inline void setPositiveOptimization() {
00055 positiveOptimization_ = true;
00056 #ifdef DISPLAY_OPTI
00057 std::cout << "--> Assuming positivity of the optimization problem" << std::endl;
00058 #endif
00059 }
00060
00061 inline bool checkIterationNumber(int iteration) {
00062
00063 bool test = (iteration >= maxIteration_);
00064 if (test) {
00065 endCriteria_ = maxIter;
00066 #ifdef DISPLAY_OPTI
00067 std::cout << "maxIteration" << std::endl;
00068 #endif
00069 }
00070 return test;
00071 }
00072 inline bool checkStationnaryValue(double fold, double fnew) {
00073
00074 bool test = (ABS(fold-fnew) < functionEpsilon_);
00075 if (test){
00076 statState_++;
00077 if (statState_ > maxIterStatPt_) {
00078 endCriteria_ = statPt;
00079 #ifdef DISPLAY_OPTI
00080 std::cout << "stationnary point, number of stationnary evaluation : " << statState_ << std::endl;
00081 #endif
00082 }
00083 }
00084 else { if (statState_!=0) statState_=0;}
00085 return (test&&(statState_ > maxIterStatPt_));
00086 }
00087 inline bool checkAccuracyValue(double f) {
00088
00089 bool test = ((f < functionEpsilon_) && positiveOptimization_);
00090 if (test) {
00091 endCriteria_ = statPt;
00092 #ifdef DISPLAY_OPTI
00093 std::cout << "Function accuracy satisfied : f = " << f << ", functionEpsilon_ = " << functionEpsilon_ << std::endl;
00094 #endif
00095 }
00096 return test;
00097 }
00098 inline bool checkStationnaryGradientNorm(double normDiff) {
00099
00100 bool test = (normDiff < gradientEpsilon_);
00101 if (test) {
00102 endCriteria_ = statGd;
00103 #ifdef DISPLAY_OPTI
00104 std::cout << "stationnary gradient" << std::endl;
00105 #endif
00106 }
00107 return test;
00108 }
00109 inline bool checkAccuracyGradientNorm(double norm) {
00110
00111 bool test = (norm < gradientEpsilon_);
00112 if (test) {
00113 endCriteria_ = statGd;
00114 #ifdef DISPLAY_OPTI
00115 std::cout << "new local minima" << std::endl;
00116 #endif
00117 }
00118 return test;
00119 }
00120
00122 inline
00123 bool operator() (int iteration,
00124 double fold, double normgold,
00125 double fnew, double normgnew,
00126 double normdiff);
00127
00129 inline int criteria() const { return endCriteria_;}
00130 };
00131
00132 inline
00133 OptimizationEndCriteria::OptimizationEndCriteria()
00134 : maxIteration_(100), functionEpsilon_(1e-8), gradientEpsilon_(1e-8),
00135 maxIterStatPt_(10), statState_(0), endCriteria_(0),
00136 positiveOptimization_(false)
00137 {
00138
00139 }
00140
00141 inline
00142 OptimizationEndCriteria::OptimizationEndCriteria(int maxIteration, double epsilon)
00143 : maxIteration_(maxIteration), functionEpsilon_(epsilon), gradientEpsilon_(epsilon),
00144 maxIterStatPt_(maxIteration/10), statState_(0), endCriteria_(0),
00145 positiveOptimization_(false)
00146 {
00147
00148 }
00149
00150 inline
00151 OptimizationEndCriteria::OptimizationEndCriteria(const OptimizationEndCriteria& oec)
00152 : maxIteration_(oec.maxIteration_),
00153 functionEpsilon_(oec.functionEpsilon_),
00154 gradientEpsilon_(oec.gradientEpsilon_),
00155 maxIterStatPt_(oec.maxIterStatPt_),
00156 statState_(oec.statState_),
00157 endCriteria_(oec.endCriteria_),
00158 positiveOptimization_(oec.positiveOptimization_)
00159 {
00160
00161 }
00162
00163 inline OptimizationEndCriteria&
00164 OptimizationEndCriteria::operator=(const OptimizationEndCriteria& oec)
00165 {
00166 maxIteration_ = oec.maxIteration_;
00167 functionEpsilon_ = oec.functionEpsilon_;
00168 gradientEpsilon_ = oec.gradientEpsilon_;
00169 maxIterStatPt_ = oec.maxIterStatPt_;
00170 statState_ = oec.statState_;
00171 endCriteria_ = oec.endCriteria_;
00172 positiveOptimization_ = oec.positiveOptimization_;
00173
00174
00175
00176 return (*this);
00177 }
00178
00179
00180 inline
00181 bool OptimizationEndCriteria::operator() (int iteration,
00182 double fold, double normgold,
00183 double fnew, double normgnew,
00184 double normdiff)
00185 {
00186
00187
00188
00189
00190
00191 return ( checkIterationNumber(iteration) ||
00192 checkStationnaryValue(fold,fnew) || checkAccuracyValue(fnew) || checkAccuracyValue(fold) ||
00193 checkAccuracyGradientNorm(normgnew) || checkAccuracyGradientNorm(normgold) );
00194 }
00195
00196
00197
00198 #endif