uminstep.hh

Go to the documentation of this file.
00001 // conoptstep.H
00002 // created by ADP 5/27/04
00003 
00004 /*************************************************************************
00005 
00006 Copyright Rice University, 2004.
00007 All rights reserved.
00008 
00009 Permission is hereby granted, free of charge, to any person obtaining a
00010 copy of this software and associated documentation files (the "Software"),
00011 to deal in the Software without restriction, including without limitation
00012 the rights to use, copy, modify, merge, publish, distribute, and/or sell
00013 copies of the Software, and to permit persons to whom the Software is
00014 furnished to do so, provided that the above copyright notice(s) and this
00015 permission notice appear in all copies of the Software and that both the
00016 above copyright notice(s) and this permission notice appear in supporting
00017 documentation.
00018 
00019 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00020 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00021 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
00022 RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
00023 NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
00024 DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
00025 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
00026 ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
00027 THIS SOFTWARE.
00028 
00029 Except as contained in this notice, the name of a copyright holder shall
00030 not be used in advertising or otherwise to promote the sale, use or other
00031 dealings in this Software without prior written authorization of the
00032 copyright holder.
00033 
00034 **************************************************************************/
00035 
00036 #ifndef __ALG_UMINSTEP_H_
00037 #define __ALG_UMINSTEP_H_
00038 
00039 #include "lnsrch.hh"
00040 #include "alg.hh"
00041 #include "functional.hh"
00042 
00043 namespace RVLUmin {
00044 
00045   using namespace RVLAlg;
00046   using RVL::Functional;
00047   using RVL::Vector;
00048   using RVL::Vector;
00049   using RVL::FunctionalEvaluation;
00050 
00056   template<typename Scalar>
00057   class UMinDir: public Terminator {
00058   public:
00059     UMinDir() {}
00060     UMinDir(UMinDir<Scalar> const &) {}
00061     virtual ~UMinDir() {}
00062 
00063     // note that Terminator::query must be defined by instantiable subclass 
00064 
00066     virtual void calcDir(Vector<Scalar> & dir,
00067              FunctionalEvaluation<Scalar> & fx) = 0;
00068 
00070     virtual void updateDir(LineSearchAlg<Scalar> const & ls) = 0;
00071 
00073     virtual void resetDir() = 0;
00074 
00076     virtual ostream & write(ostream & str) const = 0;
00077   };
00078 
00098   template<class Scalar>
00099   class UMinStepLS: public Algorithm, public Terminator {
00100   private:
00101     
00102     FunctionalEvaluation<Scalar> & fx; 
00103     UMinDir<Scalar> & dc;
00104     LineSearchAlg<Scalar> & ls;
00105     bool ans;
00106     ostream & str;
00107 
00117     virtual void calcStep(Vector<Scalar> & dir) {
00118       try {
00119     //Line Search
00120     bool tried_steepest_descent = false;
00121     // set up and run line search
00122     ls.initialize(fx,dir);
00123         ls.run();
00124     bool res = ls.query();
00125     if (!res) { 
00126       dc.updateDir(ls);
00127       ans = ans || dc.query(); 
00128     }
00129     // line search failed, try steepest descent
00130     else {
00131       if (!tried_steepest_descent) {
00132         str<<"UMinStep: attempting steepest descent restart\n";
00133         // This resets the evaluation point
00134         Vector<Scalar> & x = fx.getPoint();
00135         x.copy(ls.getBasePoint());
00136         dir.copy(ls.getBaseGradient());
00137         dir.negate();
00138         dc.resetDir();
00139         // this costs a redundant gradient computation!!
00140         ls.initialize(fx,dir);
00141         ls.run();
00142         if (!ls.query()) { 
00143           dc.updateDir(ls);
00144           ans= ans || dc.query();
00145         }
00146         else {
00147           ans = true;
00148         }
00149         tried_steepest_descent=true;
00150       }
00151       else {
00152         ans = true;
00153       }
00154     }
00155 
00156       } catch(RVLException & e) {
00157     e << "\ncalled from UMinStepLS::calcStep()\n";
00158     throw e;
00159       }
00160     }
00161 
00162   public:
00163 
00167     UMinStepLS(FunctionalEvaluation<Scalar> & _fx, 
00168            UMinDir<Scalar> & _dc,
00169            LineSearchAlg<Scalar> & _ls,
00170            ostream & _str = cout)
00171       : fx(_fx), dc(_dc), ls(_ls), ans(false), str(_str) {}
00172 
00173     UMinStepLS(const UMinStepLS<Scalar> & cos)
00174       : fx(cos.fx), dc(cos.dc), ls(cos.ls), ans(cos.ans), str(cos.str) {}
00175 
00176     virtual ~UMinStepLS() {}
00177 
00179     Vector<Scalar> const & getBasePoint() { return ls.getBasePoint(); }
00180 
00182     Vector<Scalar> const & getBaseGradient() { return ls.getBaseGradient(); }
00183 
00185     FunctionalEvaluation<Scalar> & getFunctionalEvaluation() { return fx; }
00186     
00187     void run() {
00188       try {
00189     Vector<Scalar> dir(fx.getDomain(), true);
00190     dc.calcDir(dir,fx);
00191     calcStep(dir);
00192       } 
00193       catch(RVLException & e) {
00194     e << "called from UMinStepLS::run()\n";
00195     throw e;
00196       } 
00197       catch( std::exception & e) {
00198     RVLException es;
00199     es << "Exception caught in UMinStepLS::run() with error message";
00200     es << e.what(); 
00201     throw e;
00202       }
00203     }
00204 
00205     bool query() { return ans; }
00206 
00207   };
00208 
00209 }
00210 
00211 
00212 #endif

Generated on 5 Jan 2017 for RvlUmin by  doxygen 1.4.7