|
GlobiPack Package Browser (Single Doxygen Collection) Version of the Day
|
00001 /* 00002 // @HEADER 00003 // *********************************************************************** 00004 // 00005 // GlobiPack: Collection of Scalar 1D globalizaton utilities 00006 // Copyright (2009) Sandia Corporation 00007 // 00008 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00009 // license for use of this work by or on behalf of the U.S. Government. 00010 // 00011 // This library is free software; you can redistribute it and/or modify 00012 // it under the terms of the GNU Lesser General Public License as 00013 // published by the Free Software Foundation; either version 2.1 of the 00014 // License, or (at your option) any later version. 00015 // 00016 // This library is distributed in the hope that it will be useful, but 00017 // WITHOUT ANY WARRANTY; without even the implied warranty of 00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00019 // Lesser General Public License for more details. 00020 // 00021 // You should have received a copy of the GNU Lesser General Public 00022 // License along with this library; if not, write to the Free Software 00023 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00024 // USA 00025 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 00026 // 00027 // *********************************************************************** 00028 // @HEADER 00029 */ 00030 00031 00032 #include "GlobiPack_TestLagrPolyMeritFunc1D.hpp" 00033 #include "GlobiPack_ArmijoPolyInterpLineSearch.hpp" 00034 #include "Teuchos_Tuple.hpp" 00035 00036 #include "meritFuncsHelpers.hpp" 00037 00038 #include "Teuchos_UnitTestHarness.hpp" 00039 00040 00041 namespace { 00042 00043 00044 // 00045 // Helper code and declarations 00046 // 00047 00048 00049 using GlobiPack::TestLagrPolyMeritFunc1D; 00050 using GlobiPack::testLagrPolyMeritFunc1D; 00051 using GlobiPack::ArmijoPolyInterpLineSearch; 00052 using GlobiPack::armijoQuadraticLineSearch; 00053 using GlobiPack::computeValue; 00054 using Teuchos::as; 00055 using Teuchos::inOutArg; 00056 using Teuchos::outArg; 00057 using Teuchos::null; 00058 using Teuchos::RCP; 00059 using Teuchos::rcpFromRef; 00060 using Teuchos::Array; 00061 using Teuchos::tuple; 00062 using Teuchos::ParameterList; 00063 using Teuchos::parameterList; 00064 00065 00066 double g_tol = Teuchos::ScalarTraits<double>::eps()*100.0; 00067 00068 00069 TEUCHOS_STATIC_SETUP() 00070 { 00071 Teuchos::UnitTestRepository::getCLP().setOption( 00072 "tol", &g_tol, "Floating point tolerance" ); 00073 } 00074 00075 00076 // 00077 // Unit tests for ArmijoPolyInterpLineSearch 00078 // 00079 00080 00081 // 00082 // Check that internal default parameters are set correctly 00083 // 00084 00085 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArmijoPolyInterpLineSearch, defaultParams, Scalar ) 00086 { 00087 typedef Teuchos::ScalarTraits<Scalar> ST; 00088 typedef typename ST::magnitudeType ScalarMag; 00089 namespace AQLSU = GlobiPack::ArmijoPolyInterpLineSearchUtils; 00090 RCP<ArmijoPolyInterpLineSearch<Scalar> > linesearch = 00091 armijoQuadraticLineSearch<Scalar>(); 00092 TEST_EQUALITY(linesearch->eta(), as<ScalarMag>(AQLSU::eta_default)); 00093 TEST_EQUALITY(linesearch->minFrac(), as<ScalarMag>(AQLSU::minFrac_default)); 00094 TEST_EQUALITY(linesearch->maxFrac(), as<ScalarMag>(AQLSU::maxFrac_default)); 00095 TEST_EQUALITY(linesearch->doMaxIters(), as<ScalarMag>(AQLSU::doMaxIters_default)); 00096 TEST_EQUALITY(linesearch->maxIters(), as<ScalarMag>(AQLSU::maxIters_default)); 00097 } 00098 00099 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT_REAL_SCALAR_TYPES( ArmijoPolyInterpLineSearch, defaultParams ) 00100 00101 00102 // 00103 // Check that parameter list is parsed correctly 00104 // 00105 00106 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArmijoPolyInterpLineSearch, parseParams, Scalar ) 00107 { 00108 typedef Teuchos::ScalarTraits<Scalar> ST; 00109 namespace AQLSU = GlobiPack::ArmijoPolyInterpLineSearchUtils; 00110 ECHO(RCP<ArmijoPolyInterpLineSearch<Scalar> > linesearch = 00111 armijoQuadraticLineSearch<Scalar>()); 00112 const double eta = 0.99999; 00113 const double minFrac = 4.0; 00114 const double maxFrac = 5.0; 00115 const int minIters = 5; 00116 const int maxIters = 100; 00117 const bool doMaxIters = true; 00118 ECHO(const RCP<ParameterList> pl = parameterList()); 00119 ECHO(pl->set("Armijo Slope Fraction", eta)); 00120 ECHO(pl->set("Min Backtrack Fraction", minFrac)); 00121 ECHO(pl->set("Max Backtrack Fraction", maxFrac)); 00122 ECHO(pl->set("Min Num Iterations", minIters)); 00123 ECHO(pl->set("Max Num Iterations", maxIters)); 00124 ECHO(pl->set("Do Max Iterations", doMaxIters)); 00125 ECHO(linesearch->setParameterList(pl)); 00126 const Scalar tol = ST::eps(); 00127 TEST_FLOATING_EQUALITY(linesearch->eta(), as<Scalar>(eta), tol); 00128 TEST_FLOATING_EQUALITY(linesearch->minFrac(), as<Scalar>(minFrac), tol); 00129 TEST_FLOATING_EQUALITY(linesearch->maxFrac(), as<Scalar>(maxFrac), tol); 00130 TEST_EQUALITY(linesearch->minIters(), minIters); 00131 TEST_EQUALITY(linesearch->maxIters(), maxIters); 00132 TEST_EQUALITY(linesearch->doMaxIters(), doMaxIters); 00133 } 00134 00135 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT_REAL_SCALAR_TYPES( ArmijoPolyInterpLineSearch, parseParams ) 00136 00137 00138 // 00139 // Check that the ArmijoPolyInterpLineSearch object validates its parameters 00140 // and their values correctly. 00141 // 00142 00143 /* 00144 00145 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArmijoPolyInterpLineSearch, validateParams, Scalar ) 00146 { 00147 TEST_FOR_EXCEPT(true); 00148 } 00149 00150 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT_REAL_SCALAR_TYPES( ArmijoPolyInterpLineSearch, validateParams ) 00151 00152 */ 00153 00154 00155 // 00156 // Check that object can exactly interplate a quadratic merit function at the 00157 // very first iteration 00158 // 00159 00160 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArmijoPolyInterpLineSearch, quadExact, Scalar ) 00161 { 00162 00163 typedef Teuchos::ScalarTraits<Scalar> ST; 00164 typedef typename ST::magnitudeType ScalarMag; 00165 00166 const RCP<TestLagrPolyMeritFunc1D<Scalar> > phi = quadPhi<Scalar>(); 00167 00168 RCP<ArmijoPolyInterpLineSearch<Scalar> > linesearch = 00169 armijoQuadraticLineSearch<Scalar>(); 00170 00171 linesearch->setOStream(rcpFromRef(out)); 00172 00173 const PointEval1D<Scalar> point_k = computePoint(*phi, ST::zero(), true, true); 00174 PointEval1D<Scalar> point_kp1 = computePoint(*phi, as<Scalar>(5.0)); 00175 00176 int numIters = -1; 00177 const bool linesearchResult = linesearch->doLineSearch( 00178 *phi, point_k, inOutArg(point_kp1), outArg(numIters) ); 00179 00180 TEST_ASSERT(linesearchResult); 00181 TEST_EQUALITY(numIters, 1); 00182 TEST_FLOATING_EQUALITY(point_kp1.alpha, as<Scalar>(2.0), g_tol); 00183 TEST_FLOATING_EQUALITY(point_kp1.phi, as<ScalarMag>(3.0), g_tol); 00184 00185 } 00186 00187 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT_REAL_SCALAR_TYPES( ArmijoPolyInterpLineSearch, quadExact ) 00188 00189 00190 // 00191 // Check that object will accept the inital point passed in without doing any 00192 // evaluations. 00193 // 00194 00195 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArmijoPolyInterpLineSearch, noEval, Scalar ) 00196 { 00197 00198 typedef Teuchos::ScalarTraits<Scalar> ST; 00199 typedef typename ST::magnitudeType ScalarMag; 00200 00201 const RCP<TestLagrPolyMeritFunc1D<Scalar> > phi = quadPhi<Scalar>(); 00202 00203 RCP<ArmijoPolyInterpLineSearch<Scalar> > linesearch = 00204 armijoQuadraticLineSearch<Scalar>(); 00205 00206 linesearch->setOStream(rcpFromRef(out)); 00207 00208 const Scalar alpha_k_init = as<Scalar>(2.1); 00209 const PointEval1D<Scalar> point_k = computePoint(*phi, ST::zero(), true, true); 00210 PointEval1D<Scalar> point_kp1 = computePoint(*phi, alpha_k_init); 00211 00212 int numIters = -1; 00213 const bool linesearchResult = linesearch->doLineSearch( 00214 *phi, point_k, inOutArg(point_kp1), outArg(numIters) ); 00215 00216 TEST_ASSERT(linesearchResult); 00217 TEST_EQUALITY(numIters, 0); 00218 TEST_FLOATING_EQUALITY(point_kp1.alpha, alpha_k_init, g_tol); 00219 TEST_FLOATING_EQUALITY(point_kp1.phi, computeValue(*phi, alpha_k_init), g_tol); 00220 00221 } 00222 00223 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT_REAL_SCALAR_TYPES( ArmijoPolyInterpLineSearch, noEval ) 00224 00225 00226 // 00227 // Check that object will force a minimum number of iterations if asked. 00228 // 00229 00230 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( ArmijoPolyInterpLineSearch, minIters, Scalar ) 00231 { 00232 00233 typedef Teuchos::ScalarTraits<Scalar> ST; 00234 typedef typename ST::magnitudeType ScalarMag; 00235 00236 const RCP<TestLagrPolyMeritFunc1D<Scalar> > phi = quadPhi<Scalar>(); 00237 00238 RCP<ArmijoPolyInterpLineSearch<Scalar> > linesearch = 00239 armijoQuadraticLineSearch<Scalar>(); 00240 00241 const RCP<ParameterList> pl = parameterList(); 00242 pl->set("Max Backtrack Fraction", 1.0); 00243 pl->set("Min Num Iterations", 1); 00244 linesearch->setParameterList(pl); 00245 00246 linesearch->setOStream(rcpFromRef(out)); 00247 00248 const Scalar alpha_k_init = as<Scalar>(2.1); 00249 const PointEval1D<Scalar> point_k = computePoint(*phi, ST::zero(), true, true); 00250 PointEval1D<Scalar> point_kp1 = computePoint(*phi, alpha_k_init); 00251 00252 int numIters = -1; 00253 const bool linesearchResult = linesearch->doLineSearch( 00254 *phi, point_k, inOutArg(point_kp1), outArg(numIters) ); 00255 00256 TEST_ASSERT(linesearchResult); 00257 TEST_EQUALITY(numIters, 1); 00258 TEST_FLOATING_EQUALITY(point_kp1.alpha, as<Scalar>(2.0), g_tol); 00259 TEST_FLOATING_EQUALITY(point_kp1.phi, as<ScalarMag>(3.0), g_tol); 00260 00261 } 00262 00263 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT_REAL_SCALAR_TYPES( ArmijoPolyInterpLineSearch, minIters ) 00264 00265 00266 // 00267 // ToDo: 00268 // 00269 // (*) Check that the object performs min bracketing correctly. 00270 // 00271 // (*) Check that the object performs max bracketing correctly. 00272 // 00273 // (*) Check that the ArmijoPolyInterpLineSearch object deals with NaN returns 00274 // currectly. 00275 // 00276 // (*) Check that the ArmijoPolyInterpLineSearch object will throw the right 00277 // exception if a positive initial derivative is presented. 00278 // 00279 // (*) Check that the ArmijoPolyInterpLineSearch object will deal with line search 00280 // failure correctly. 00281 // 00282 // (*) Check that the ArmijoPolyInterpLineSearch object deals with invalid input 00283 // correctly (i.e. check preconditions and throws). 00284 // 00285 00286 00287 } // namespace
1.7.4