ioterm.hh

Go to the documentation of this file.
00001 /*************************************************************************
00002 
00003 Copyright Rice University, 2004.
00004 All rights reserved.
00005 
00006 Permission is hereby granted, free of charge, to any person obtaining a
00007 copy of this software and associated documentation files (the "Software"),
00008 to deal in the Software without restriction, including without limitation
00009 the rights to use, copy, modify, merge, publish, distribute, and/or sell
00010 copies of the Software, and to permit persons to whom the Software is
00011 furnished to do so, provided that the above copyright notice(s) and this
00012 permission notice appear in all copies of the Software and that both the
00013 above copyright notice(s) and this permission notice appear in supporting
00014 documentation.
00015 
00016 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00017 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00018 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
00019 RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
00020 NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
00021 DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
00022 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
00023 ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
00024 THIS SOFTWARE.
00025 
00026 Except as contained in this notice, the name of a copyright holder shall
00027 not be used in advertising or otherwise to promote the sale, use or other
00028 dealings in this Software without prior written authorization of the
00029 copyright holder.
00030 
00031 **************************************************************************/
00032 
00033 #ifndef __RVLALG_IO_TERMINATOR
00034 #define __RVLALG_IO_TERMINATOR
00035 
00036 #include "std_cpp_includes.hh"
00037 #include "alg.hh"
00038 #include "scalarterm.hh"
00039 #include "functional.hh"
00040 
00047 namespace RVLAlg {
00048   using namespace RVL;
00057 class IOTerminator: public Terminator {
00058 public:
00059   
00060   IOTerminator() : ins(cin), outs(cout) { 
00061     s = new char[30];  
00062     strncpy(s, "Do you wish to stop?", 30); 
00063   }
00064 
00065   IOTerminator(char t[]) : ins(cin), outs(cout) { 
00066     int l = strlen(t);
00067     s = new char[l];  
00068     strncpy(s, t, l);
00069   }
00070 
00071   IOTerminator(istream & in_, ostream & out_) : ins(in_), outs(out_) 
00072   {  
00073     s = new char[30];  
00074     strncpy(s, "Do you wish to stop iterating?", 30); 
00075   }
00076 
00077   IOTerminator(char t[], istream & in_, ostream & out_) : ins(in_), outs(out_) 
00078   { 
00079     int l = strlen(t);
00080     s = new char[l];  
00081     strncpy(s, t, l);
00082   }
00083 
00084   virtual ~IOTerminator() {
00085     if( s != NULL )
00086       delete [] s;
00087   }
00088     
00089   virtual bool query() {
00090     char response;
00091     outs << s << " y/n : ";
00092     ins >> response;
00093     ins.ignore(10, '\n');     // Clear buffer? 
00094 
00095     if ((response == 'y')||(response == 'Y'))
00096       return 1;
00097     else
00098       return 0;
00099   }
00100 
00101 protected:
00102   char * s;
00103   istream & ins;
00104   ostream & outs;
00105 
00106 };
00107 
00114 template< class Scalar>
00115 class VecWatchTerminator: public Terminator {
00116 public:
00117   VecWatchTerminator( Vector<Scalar> & x ) 
00118     : x_(x), outs_(cout){}
00119 
00120   VecWatchTerminator( Vector<Scalar> & x, ostream & outs ) 
00121     : x_(x), outs_(outs){}
00122 
00123   virtual bool query() {
00124     x_.write(outs_);
00125     return 0;
00126   }
00127 
00128 private: 
00129   Vector<Scalar> & x_;
00130   ostream & outs_;
00131 };
00132 
00136 template< class Scalar >
00137 class IterationTable: public Terminator {
00138 public:
00139   IterationTable( FunctionalEvaluation<Scalar> & _fx, 
00140           ostream & _out = cout) 
00141     : count(0), fx(_fx), out(_out)
00142   {
00143     out << setw(10) << "Iteration " << "|" 
00144      << setw(13) <<"f(x)" << endl;
00145   }
00146 
00147   bool query() {
00148     out << setw(10) << count << ' '; 
00149     out << setw(13) << setprecision(8) << fx.getValue() << endl;
00150     count++;
00151     return false;
00152   }
00153     
00154 protected:
00155   int count;
00156   FunctionalEvaluation<Scalar> & fx;
00157   ostream & out;
00158 
00159 };
00160 
00165 template< class Scalar >
00166 class SteppedIterationTable: public Terminator {
00167 public:
00168   SteppedIterationTable(FunctionalEvaluation<Scalar> & _fx,
00169             Scalar & _step,
00170             ostream & _out = cout) 
00171     : count(0), fx(_fx), step(_step), out(_out)
00172   {
00173     out << setw(10) << "Iteration " << "|" 
00174      << setw(13) <<"f(x)" << "|"
00175      << setw(13) << "Delta" << endl;
00176   }
00177 
00178   bool query() {
00179     
00180     Scalar fxval;
00181 
00182     fxval = fx.getValue();
00183 
00184     out << setw(10) << count << ' '; 
00185     out << setw(13) << setprecision(8) << fxval << ' ';
00186     out << setw(13) << setprecision(8) << step << endl;
00187     count++;
00188     return false;
00189   }
00190     
00191 protected:
00192   int count;
00193   FunctionalEvaluation<Scalar> & fx;
00194   Scalar & step;
00195   ostream & out;
00196 
00197 };
00198 
00219 template< class Scalar >
00220 class GradientThresholdIterationTable: public CountTerminator {
00221   
00222     typedef typename ScalarFieldTraits<Scalar>::AbsType atype;
00223   
00224 public:
00225   GradientThresholdIterationTable(FunctionalEvaluation<Scalar> & _fx, 
00226                   int maxcount = 1, 
00227                   atype _atol = numeric_limits<atype>::max(),
00228                   atype _rtol = ScalarFieldTraits<atype>::One(),
00229                   ostream & _out = cout,
00230                   bool _doit = true) 
00231       : CountTerminator(maxcount), atol(_atol), rtol(_rtol), init(true), ngfx0(ScalarFieldTraits<atype>::Zero()), ingfx(ScalarFieldTraits<atype>::One()), doit(_doit),  fx(_fx), out(_out) {
00232     if (doit) {
00233       out << setw(10) << "Iteration " << "|" 
00234       << setw(13) <<"f(x)   " << "|" 
00235       << setw(13) << "||gradf(x)||" << endl;
00236     }
00237   }
00238 
00239   bool query() {
00240     
00241     Scalar fxval;
00242     atype ngfx;
00243     bool stop = CountTerminator::query();
00244     
00245     fxval = fx.getValue();
00246     ngfx  = fx.getGradient().norm();
00247 
00248     if (init) {
00249       if (ProtectedDivision<atype>(ScalarFieldTraits<atype>::One(),ngfx,ingfx)) {
00250     out<<"Initial gradient below roundoff - success!! (?)\n";
00251     return true;
00252       }
00253       ngfx0=ngfx;
00254       fxval0=fxval;
00255       init=false;
00256     }
00257     
00258     bool astop = (ngfx <= atol);
00259     bool rstop = (ngfx*ingfx <= rtol );
00260     stop = (stop || astop || rstop );
00261     
00262     if (doit) {
00263       if( !stop ) { //print out current results
00264     out << scientific << setw(10) << getCount() << ' '; 
00265     out << scientific << setw(13) << setprecision(8) << fxval << ' '
00266         << scientific << setw(13) << setprecision(8) << ngfx << endl;
00267       }
00268       else { // print out hline, then final results 
00269     out << "-----------------------------------------------" << endl;
00270     if (astop || rstop) {
00271       out << "Convergence: gradient norm below tolerance after "<< setw(10) << getCount() << " iterations" <<endl;
00272     }
00273     else {
00274       out <<"Termination: maximum number of iterations exceeded"<<endl;
00275     }
00276     out << "Function Value           = " << scientific << setw(13) << setprecision(8) << fxval <<endl;
00277     out << "Initial Function Value   = " << scientific << setw(13) << setprecision(8) << fxval0 <<endl;
00278     atype frat;
00279     if ((fxval >= ScalarFieldTraits<atype>::Zero()) && 
00280         (fxval0 > ScalarFieldTraits<atype>::Zero()) &&
00281         (!(ProtectedDivision<atype>(fxval,fxval0,frat)))) {
00282       out << "Function Value Reduction = " << scientific << setw(13) << setprecision(8) << frat <<endl;
00283     }
00284     out << "Gradient Norm            = " << scientific << setw(13) << setprecision(8) << ngfx << endl;
00285     out << "Initial Gradient Norm    = " << scientific << setw(13) << setprecision(8) << ngfx0 << endl;
00286     atype grat;
00287     if ((ngfx >= ScalarFieldTraits<atype>::Zero()) && 
00288         (ngfx0 > ScalarFieldTraits<atype>::Zero()) &&
00289         (!(ProtectedDivision<atype>(ngfx,ngfx0,grat)))) {
00290       out << "Gradient Norm Reduction  = " << scientific << setw(13) << setprecision(8) << grat <<endl;
00291     }
00292     out << "Absolute Tolerance       = " << scientific << setw(13) << setprecision(8) << atol << endl;
00293     out << "Relative Tolerance       = " << scientific << setw(13) << setprecision(8) << rtol << endl;
00294       }
00295     }
00296 
00297     return stop;
00298   } 
00299       
00300 protected:
00301   atype atol;
00302   atype rtol;
00303   mutable bool init;
00304   mutable atype fxval0;
00305   mutable atype ngfx0;
00306   mutable atype ingfx;
00307   
00308   bool doit;
00309   FunctionalEvaluation<Scalar> & fx;
00310   ostream & out;
00311   
00312 };
00313 
00322 template< class Scalar >
00323 class CountingThresholdIterationTable: public CountTerminator {
00324 public:
00325 
00326   typedef typename ScalarFieldTraits<Scalar>::AbsType atype;
00327 
00328   CountingThresholdIterationTable(int maxcount,
00329                                   const atype & val,
00330                                   atype tol,
00331                                   string & scalarname,
00332                                   ostream & out = cout) 
00333     : tol_(tol), val_(val), out_(out), CountTerminator(maxcount)  
00334   {
00335     out_ << setw(10) << "Iteration " << " | " 
00336          << setw(scalarname.size()+5) << scalarname << endl;
00337   }
00338 
00339   CountingThresholdIterationTable(int maxcount,
00340                                   const atype & val,
00341                                   atype tol,
00342                                   ostream & out = cout) 
00343     : tol_(tol), val_(val), out_(out), CountTerminator(maxcount)  
00344   {
00345     out_ << setw(10) << "Iteration " << "|" 
00346          << setw(17) << "Scalar Value" << endl;
00347   }
00348 
00349   bool query() {
00350     
00351     bool stop = CountTerminator::query();
00352     if( !stop ) { //print out current results
00353       out_ << setw(10) << getCount() << ' '; 
00354       out_ << setw(17) << setprecision(8) << val_ << endl;
00355     }
00356     else { // print out hline, then final results 
00357       out_ << "-----------------------------------------------" << endl;
00358       out_ << setw(10) << getCount() << ' ' 
00359            << setw(17) << setprecision(8) << val_ << endl;
00360     }
00361     return (stop || (val_ <= tol_ ));
00362   }
00363     
00364     
00365 protected:
00366   atype tol_;
00367   const atype & val_;
00368   ostream & out_;
00369 
00370 };
00371 
00372 
00373 
00379 template< class Scalar >
00380 class VectorCountingThresholdIterationTable: public CountTerminator {
00381 public:
00382 
00383   typedef typename ScalarFieldTraits<Scalar>::AbsType atype;
00384 
00385   VectorCountingThresholdIterationTable(int maxcount,
00386                     vector<string> const & _names,
00387                     vector<atype *> const & _nums,
00388                     vector<atype> const & _tols,
00389                     ostream & _out = cout) 
00390     :  CountTerminator(maxcount), tols(_tols), nums(_nums), names(_names), out(_out)
00391   {
00392     if ((nums.size() != names.size()) ||
00393     (tols.size() != names.size())) {
00394       RVLException e;
00395       e<<"Error: VectorCountingThresholdIterationTable constructor\n";
00396       e<<"input name, value, and tol arrays must have same length\n";
00397       throw e;
00398     }
00399   }
00400 
00401   void init() {
00402     out << setw(10) << "Iteration  ";
00403     //    cerr << setw(10) << "Iteration  ";
00404     for (size_t i=0;i<names.size();i++) {
00405       out  << " |  "<< setw(names[i].size()) << names[i];
00406       //      cerr  << " |  "<< setw(names[i].size()+1) << names[i];
00407     }
00408     out << endl;
00409     //    cerr << endl;
00410   }
00411 
00412   bool query() {
00413     
00414     bool stop = CountTerminator::query();
00415 
00416     if( !stop ) { //print out current results
00417       out << setw(10) << getCount() << ' ';
00418       for (size_t i=0;i<names.size();i++)  
00419     out << setw(4+names[i].size()) << setprecision(8) << *(nums[i]);
00420       out << endl;
00421     }
00422     else { // print out hline, then final results 
00423       out << "-----------------------------------------------" << endl;
00424       out << setw(10) << getCount() << ' ' ;
00425       for (size_t i=0;i<names.size();i++)  
00426     out << setw(4+names[i].size()) << setprecision(8) << *(nums[i]);
00427       out << endl;
00428     }
00429     for (size_t i=0; i<names.size();i++) {
00430       if (*(nums[i]) < tols[i]) out<<names[i]<<" = "<<*(nums[i])<<" below tol = "<<tols[i]<<endl;
00431       stop = stop || (*(nums[i]) < tols[i] );
00432     }
00433     return stop;
00434   }
00435     
00436     
00437 protected:
00438   vector<atype> tols;
00439   vector<atype *> nums;
00440   vector<string> names;
00441   ostream & out;
00442 
00443 private:
00444 
00445   VectorCountingThresholdIterationTable();
00446   VectorCountingThresholdIterationTable( VectorCountingThresholdIterationTable const & );
00447 };
00448 
00454 template< class Scalar >
00455 class CountingNormTable: public CountTerminator {
00456 public:
00457   typedef typename ScalarFieldTraits<Scalar>::AbsType NormRetType;
00458 
00459   CountingNormTable(int maxcount, 
00460             const Vector<Scalar> & _x, 
00461             NormRetType _tol,
00462             bool _doit = true,
00463             ostream & _out = cout) 
00464     : x(_x), tol(_tol), doit(_doit), out(_out), CountTerminator(maxcount) {
00465     if (doit) {
00466       out << setw(10) << "Iteration " << "|" 
00467       << setw(13) << "||x||" << endl;
00468     }
00469   }
00470 
00471   bool query() {
00472     
00473     NormRetType nx;
00474     bool stop = CountTerminator::query();
00475 
00476     nx = x.norm();
00477 
00478     if (doit) {
00479       if( !stop ) { //print out current results
00480     out << setw(10) << getCount() << ' '; 
00481     out << setw(13) << setprecision(8) << nx << endl;
00482       }
00483       else { // print out hline, then final results 
00484     out << "-----------------------------------------------" << endl;
00485     out << setw(10) << getCount() << ' '; 
00486     out << setw(13) << setprecision(8) << nx << endl;
00487       }
00488     }
00489     return (stop || (nx <= tol ));
00490   }
00491     
00492     
00493 protected:
00494   bool doit;
00495   ostream & out;
00496   const Vector<Scalar> & x;
00497   NormRetType tol;
00498 };
00499 
00500 }
00501 
00502 #endif

Generated on 5 Jan 2017 for RvlAlg by  doxygen 1.4.7