PlayaDefaultOptConvergenceTest.cpp

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   /* Get problem scale */
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   /* check function value change */
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   /* check gradient */
00055   double gradConv = state.gradCur().normInf() * xScale / fScale ;
00056   PLAYA_MSG2(verb(), tab1 << "|grad|: " << gradConv << " tol=" << gradTol_);
00057   if (gradConv <= gradTol_) conv++;
00058 
00059   /* compute |xPrev_k - xCur_k| / xScale */
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 }

doxygen