00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
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');     
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 ) { 
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 { 
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 ) { 
00353       out_ << setw(10) << getCount() << ' '; 
00354       out_ << setw(17) << setprecision(8) << val_ << endl;
00355     }
00356     else { 
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     
00404     for (size_t i=0;i<names.size();i++) {
00405       out  << " |  "<< setw(names[i].size()) << names[i];
00406       
00407     }
00408     out << endl;
00409     
00410   }
00411 
00412   bool query() {
00413     
00414     bool stop = CountTerminator::query();
00415 
00416     if( !stop ) { 
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 { 
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 ) { 
00480     out << setw(10) << getCount() << ' '; 
00481     out << setw(13) << setprecision(8) << nx << endl;
00482       }
00483       else { 
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