00001 #include "PlayaDefaultOptConvergenceTest.hpp"
00002 #include "PlayaOptState.hpp"
00003 #include "PlayaTabs.hpp"
00004 #include "PlayaLinearCombinationImpl.hpp"
00005
00006 namespace Playa
00007 {
00008 using std::endl;
00009
00010 DefaultOptConvergenceTest::DefaultOptConvergenceTest(
00011 const ParameterList& params)
00012 : OptConvergenceTestBase(params),
00013 minIters_(params.get<int>("Min Iterations")),
00014 maxIters_(params.get<int>("Max Iterations")),
00015 requiredPasses_(params.get<int>("Num Required Passes")),
00016 objTol_(params.get<double>("Objective Tolerance")),
00017 gradTol_(params.get<double>("Gradient Tolerance")),
00018 stepTol_(params.get<double>("Step Tolerance")),
00019 xTyp_(1.0),
00020 fTyp_(1.0)
00021 {
00022 if (params.isParameter("Typical X Scale")) xTyp_ = params.get<double>("Typical X Scale");
00023 if (params.isParameter("Typical F Scale")) fTyp_ = params.get<double>("Typical F Scale");
00024 }
00025
00026
00027 OptStatus DefaultOptConvergenceTest::test(const OptState& state) const
00028 {
00029 Tabs tab(0);
00030 int i = state.iter();
00031 int conv = 0;
00032
00033 PLAYA_MSG1(verb(), tab << "DefaultOptConvergenceTest testing iter #" << i);
00034 Tabs tab1;
00035
00036 if (i < std::max(1, minIters_))
00037 {
00038 PLAYA_MSG2(verb(), tab1 << "iter #" << i
00039 << " below minimum, skipping test");
00040 return Opt_Continue;
00041 }
00042
00043
00044 double fCur = state.fCur();
00045 double fPrev = state.fPrev();
00046 double fScale = std::max( std::fabs(fPrev), std::fabs(fTyp_) );
00047 double xScale = std::max( state.xCur().normInf(), std::fabs(xTyp_) );
00048
00049
00050 double objConv = std::fabs(fCur - fPrev)/fScale;
00051 if (objConv <= objTol_) conv++;
00052 PLAYA_MSG2(verb(), tab1 << "obj test: " << objConv << " tol=" << objTol_);
00053
00054
00055 double gradConv = state.gradCur().normInf() * xScale / fScale ;
00056 PLAYA_MSG2(verb(), tab1 << "|grad|: " << gradConv << " tol=" << gradTol_);
00057 if (gradConv <= gradTol_) conv++;
00058
00059
00060 double stepConv = (state.xCur() - state.xPrev()).normInf()/xScale;
00061 if (stepConv <= stepTol_) conv++;
00062 PLAYA_MSG2(verb(), tab1 << "step test " << stepConv << " tol=" << stepTol_);
00063
00064 PLAYA_MSG2(verb(), tab1 << conv << " of " << requiredPasses_ << " criteria "
00065 "passed");
00066
00067 if (conv >= requiredPasses_)
00068 {
00069 PLAYA_MSG2(verb(), tab1 << "convergence detected!");
00070 return Opt_Converged;
00071 }
00072
00073 if (i >= maxIters_)
00074 {
00075 PLAYA_MSG2(verb(), "iter #" << i << " above maxiters, giving up");
00076 return Opt_ExceededMaxiters;
00077 }
00078
00079 PLAYA_MSG2(verb(), tab1 << "not yet converged");
00080 return Opt_Continue;
00081 }
00082
00083 void DefaultOptConvergenceTest::print(std::ostream& os) const
00084 {
00085 Tabs tab(0);
00086 os << tab << "DefaultOptConvergenceTest[" << endl;
00087 {
00088 Tabs tab1;
00089 os << tab1 << "min iterations " << minIters_ << endl;
00090 os << tab1 << "max iterations " << maxIters_ << endl;
00091 os << tab1 << "objective tol " << objTol_ << endl;
00092 os << tab1 << "gradient tol " << gradTol_ << endl;
00093 os << tab1 << "step tol " << stepTol_ << endl;
00094 }
00095 os << tab << "]" << endl;
00096 }
00097
00098
00099 }