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
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
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
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
00100 state.update(xNew, gradNew, fNew);
00101
00102
00103 OptStatus iterStatus = convTest_->test(state);
00104 state.setStatus(iterStatus);
00105 }
00106
00107
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 }