PlayaLineSearchBasedOptBase.cpp

00001 #include "PlayaLineSearchBasedOptBase.hpp"
00002 #include "PlayaOut.hpp"
00003 #include "PlayaTabs.hpp"
00004 #include "PlayaLinearCombinationImpl.hpp"
00005 #include "PlayaLineSearchBuilder.hpp"
00006 #include "PlayaOptConvergenceTestBuilder.hpp"
00007 
00008 
00009 namespace Playa
00010 {
00011 using std::endl;
00012 using std::setw;
00013 
00014 LineSearchBasedOptBase::LineSearchBasedOptBase(
00015   const ParameterList& params
00016   )
00017   : lineSearch_(),
00018     convTest_()
00019 {
00020   const ParameterList& lsParams = params.sublist("Line Search");
00021   lineSearch_ = LineSearchBuilder::createLineSearch(lsParams);
00022 
00023   const ParameterList& ctParams = params.sublist("Convergence Test");
00024   convTest_ = OptConvergenceTestBuilder::createConvTest(ctParams);
00025 }
00026 
00027 
00028 OptState LineSearchBasedOptBase::run(const RCP<ObjectiveBase>& obj,
00029   const Vector<double>& xInit,
00030   const RCP<ConvergenceMonitor>& convMonitor) const
00031 {
00032   Tabs tab0(0);
00033   PLAYA_MSG1(verb(), tab0 << "in " << description() << "::run()");
00034 
00035   RCP<DirectionGeneratorBase> dirGen = makeDirectionGenerator();
00036 
00037   VectorSpace<double> vs = xInit.space();
00038 
00039   Vector<double> xCur = xInit.copy();
00040   Vector<double> gradCur =vs.createMember();
00041   double fCur;
00042 
00043   obj->evalGrad(xCur, fCur, gradCur);
00044 
00045   OptState state(xCur, fCur, gradCur);
00046 
00047   Vector<double> xNew = vs.createMember();
00048   Vector<double> gradNew = vs.createMember();
00049   Vector<double> p = vs.createMember();
00050   double fNew;
00051 
00052   /* -------- Main optimization loop ------------- */
00053   while (state.status()==Opt_Continue)
00054   {
00055     Tabs tab1;
00056     PLAYA_MSG2(verb(), 
00057       tab1 << "--------------------------------------------------------------");
00058     PLAYA_MSG2(verb(), tab1 << description() << " iter " 
00059       << setw(5) << state.iter() 
00060       << " f=" << setw(14) << state.fCur() << " |grad|=" << setw(14)
00061       << state.gradCur().norm2());
00062       
00063 
00064     Tabs tab2;
00065     Tabs tab3;
00066     PLAYA_MSG4(verb(), tab2 << "current x " << endl << tab3 << state.xCur());
00067 
00068     obj->iterationCallback(state.xCur(), state.iter());
00069 
00070     if (convMonitor.ptr()!=null) 
00071     {
00072       convMonitor->addRecord(state.iter(), tuple(state.fCur()));
00073     }
00074 
00075 
00076     /* Find a direction for the line search */
00077     bool dirOK = dirGen->generateDirection(obj, state.xCur(), 
00078       state.gradCur(), state.fCur(), p);
00079 
00080     if (!dirOK)
00081     {
00082       state.setStatus(Opt_DirectionFailure);
00083       return state;
00084     }
00085 
00086     /* Perform the line search */
00087     LineSearchStatus info = lineSearch_->search(obj, 
00088       state.xCur(), state.fCur(), p,
00089       1.0, xNew, gradNew, fNew);
00090 
00091     if (info != LS_Success)
00092     {
00093       state.setStatus(Opt_LineSearchFailed);
00094       return state;
00095     }
00096 
00097     PLAYA_MSG4(verb(), tab2 << "new x " << endl << tab3 << xNew);
00098 
00099     /* Update the state to know about the new approximation to the min */
00100     state.update(xNew, gradNew, fNew);
00101 
00102     /* Check for convergence */
00103     OptStatus iterStatus = convTest_->test(state);
00104     state.setStatus(iterStatus);
00105   }
00106 
00107   /* -------- End main optimization loop ------------- */
00108   if (convMonitor.ptr()!=null) 
00109   {
00110     convMonitor->addRecord(state.iter(), tuple(state.fCur()));
00111   }
00112 
00113   return state;
00114 }
00115 
00116 void LineSearchBasedOptBase::print(std::ostream& os) const 
00117 {
00118   Tabs tab(0);
00119   os << tab << description() << "[" << endl;
00120   Tabs tab1;
00121   os << tab1 << "Line search=" << endl;
00122   lineSearch_->print(os);
00123   os << tab1 << "Convergence test=" << endl;
00124   convTest_->print(os);
00125   os << tab << "]";
00126   
00127 }
00128 
00129 
00130 }

doxygen