PlayaDefaultOptConvergenceTest.cpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                 Playa: Programmable Linear Algebra
00005 //                 Copyright 2012 Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Kevin Long (kevin.long@ttu.edu)
00038 // 
00039 
00040 /* @HEADER@ */
00041 
00042 
00043 #include "PlayaDefaultOptConvergenceTest.hpp"
00044 #include "PlayaOptState.hpp"
00045 #include "PlayaTabs.hpp"
00046 #include "PlayaLinearCombinationImpl.hpp"
00047 
00048 namespace Playa
00049 {
00050 using std::endl;
00051 
00052 DefaultOptConvergenceTest::DefaultOptConvergenceTest(
00053   const ParameterList& params)
00054   : OptConvergenceTestBase(params),
00055     minIters_(params.get<int>("Min Iterations")), 
00056     maxIters_(params.get<int>("Max Iterations")),
00057     requiredPasses_(params.get<int>("Num Required Passes")),
00058     objTol_(params.get<double>("Objective Tolerance")), 
00059     gradTol_(params.get<double>("Gradient Tolerance")),
00060     stepTol_(params.get<double>("Step Tolerance")),
00061     xTyp_(1.0),
00062     fTyp_(1.0)
00063 {
00064   if (params.isParameter("Typical X Scale")) xTyp_ = params.get<double>("Typical X Scale");
00065   if (params.isParameter("Typical F Scale")) fTyp_ = params.get<double>("Typical F Scale");
00066 }
00067 
00068 
00069 OptStatus DefaultOptConvergenceTest::test(const OptState& state) const
00070 {
00071   Tabs tab(0);
00072   int i = state.iter();
00073   int conv = 0;
00074 
00075   PLAYA_MSG1(verb(), tab << "DefaultOptConvergenceTest testing iter #" << i);
00076   Tabs tab1;
00077 
00078   if (i < std::max(1, minIters_)) 
00079   {
00080     PLAYA_MSG2(verb(), tab1 << "iter #" << i 
00081       << " below minimum, skipping test");
00082     return Opt_Continue;
00083   }
00084 
00085   /* Get problem scale */
00086   double fCur = state.fCur();
00087   double fPrev = state.fPrev();
00088   double fScale = std::max( std::fabs(fPrev), std::fabs(fTyp_) );
00089   double xScale = std::max( state.xCur().normInf(), std::fabs(xTyp_) );
00090 
00091   /* check function value change */
00092   double objConv = std::fabs(fCur - fPrev)/fScale;
00093   if (objConv <= objTol_) conv++;
00094   PLAYA_MSG2(verb(), tab1 << "obj test: " << objConv << " tol=" << objTol_);
00095 
00096   /* check gradient */
00097   double gradConv = state.gradCur().normInf() * xScale / fScale ;
00098   PLAYA_MSG2(verb(), tab1 << "|grad|: " << gradConv << " tol=" << gradTol_);
00099   if (gradConv <= gradTol_) conv++;
00100 
00101   /* compute |xPrev_k - xCur_k| / xScale */
00102   double stepConv = (state.xCur() - state.xPrev()).normInf()/xScale;
00103   if (stepConv <= stepTol_) conv++;
00104   PLAYA_MSG2(verb(), tab1 << "step test " << stepConv << " tol=" << stepTol_);
00105   
00106   PLAYA_MSG2(verb(), tab1 << conv << " of " << requiredPasses_ << " criteria "
00107     "passed");
00108 
00109   if (conv >= requiredPasses_) 
00110   {
00111     PLAYA_MSG2(verb(), tab1 << "convergence detected!");
00112     return Opt_Converged;
00113   }
00114 
00115   if (i >= maxIters_) 
00116   {
00117     PLAYA_MSG2(verb(), "iter #" << i << " above maxiters, giving up");
00118     return Opt_ExceededMaxiters;
00119   }
00120 
00121   PLAYA_MSG2(verb(), tab1 << "not yet converged");
00122   return Opt_Continue;
00123 }
00124 
00125 void DefaultOptConvergenceTest::print(std::ostream& os) const
00126 {
00127   Tabs tab(0);
00128   os << tab << "DefaultOptConvergenceTest[" << endl;
00129   {
00130     Tabs tab1;
00131     os << tab1 << "min iterations " << minIters_ << endl;
00132     os << tab1 << "max iterations " << maxIters_ << endl;
00133     os << tab1 << "objective tol  " << objTol_ << endl;
00134     os << tab1 << "gradient tol   " << gradTol_ << endl;
00135     os << tab1 << "step tol       " << stepTol_ << endl;
00136   }
00137   os << tab << "]" << endl;
00138 }
00139 
00140 
00141 }

Site Contact