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