MoochoPack_MoochoTrackerSummaryStd.cpp

00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization
00005 //                  Copyright (2003) Sandia Corporation
00006 // 
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 // 
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //  
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //  
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 
00025 // 
00026 // ***********************************************************************
00027 // @HEADER
00028 
00029 #include <assert.h>
00030 
00031 #include <iomanip>
00032 
00033 #include "MoochoPack_MoochoTrackerSummaryStd.hpp"
00034 #include "MoochoPack_NLPAlgoState.hpp"
00035 #include "MoochoPack_moocho_algo_conversion.hpp"
00036 #include "NLPInterfacePack_NLPFirstOrder.hpp"
00037 #include "AbstractLinAlgPack_Vector.hpp"
00038 #include "AbstractLinAlgPack_MatrixSymOp.hpp"
00039 #include "Teuchos_dyn_cast.hpp"
00040 
00041 using std::endl;
00042 using std::setw;
00043 
00044 namespace MoochoPack {
00045 
00046 MoochoTrackerSummaryStd::MoochoTrackerSummaryStd(
00047   const ostream_ptr_t      &o
00048   ,const ostream_ptr_t     &journal_out
00049   ,EOptError               opt_error
00050   )
00051   :AlgorithmTracker(journal_out)
00052   ,o_(o)
00053   ,opt_error_(opt_error)
00054   ,num_total_qp_iter_(0)
00055 {}  
00056 
00057 void MoochoTrackerSummaryStd::set_output_stream(const ostream_ptr_t& o)
00058 { 
00059   o_ = o;
00060 }
00061 
00062 const MoochoTrackerSummaryStd::ostream_ptr_t&
00063 MoochoTrackerSummaryStd::get_output_stream() const
00064 {
00065   return o_;
00066 }
00067 
00068 void MoochoTrackerSummaryStd::output_iteration(const Algorithm& algo) const
00069 {
00070 
00071   const NLPAlgo            &_algo  = rsqp_algo(algo);
00072   const NLPAlgoState           &s      =_algo.rsqp_state();
00073   const NLP                 &nlp    = _algo.nlp(); 
00074 
00075   const size_type
00076     m = nlp.m();
00077 
00078   std::ostream& o = this->o();
00079   
00080   int w = 15;
00081   int prec = 6;
00082   o.precision(prec);
00083 
00084   // Output the table's header for the first iteration
00085   if(s.k() == 0) {
00086     print_header(s);
00087   }
00088 
00089   // ///////////////////////////////
00090   // Output a row for the iteration
00091   
00092   // Get active set and QP solver statistics.
00093   const ActSetStats   *act_stats =
00094     ( act_set_stats_.exists_in(s) && act_set_stats_(s).updated_k(0)
00095       ? &act_set_stats_(s).get_k(0)
00096       : NULL );
00097   const QPSolverStats   *qp_stats =
00098     ( qp_solver_stats_.exists_in(s) && qp_solver_stats_(s).updated_k(0)
00099       ? &qp_solver_stats_(s).get_k(0)
00100       : NULL );
00101   const QuasiNewtonStats  *quasi_newt_stats =
00102     ( quasi_newton_stats_.exists_in(s) && quasi_newton_stats_(s).updated_k(0)
00103       ? &quasi_newton_stats_(s).get_k(0)
00104       : NULL );
00105 
00106   // Get the norms of Ypy and Zpz
00107   value_type norm_2_Ypy = -1.0, norm_2_Zpz = -1.0;
00108   bool Ypy_exists, Zpz_exists;
00109   if( m && ( Ypy_exists = s.Ypy().updated_k(0) ) )
00110     norm_2_Ypy = s.Ypy().get_k(0).norm_2();
00111   if( Zpz_exists = s.Zpz().updated_k(0) )
00112     norm_2_Zpz = s.Zpz().get_k(0).norm_2();
00113 
00114   o << std::right
00115     << setw(5) << s.k();
00116 
00117   if( s.f().updated_k(0) )
00118     o << setw(w) << s.f().get_k(0);
00119   else
00120     o << setw(w) << "-";
00121 
00122   if( s.Gf().updated_k(0) )
00123     o << setw(w) << s.Gf().get_k(0).norm_inf();
00124   else
00125     o << setw(w) << "-";
00126 
00127   if( m && s.c().updated_k(0) )
00128     o << setw(w)
00129       << s.c().get_k(0).norm_inf();
00130   else
00131     o << setw(w) << "-";
00132 
00133   {
00134     const IterQuantityAccess<VectorMutable>
00135       &rGL_GL = ( opt_error_ == OPT_ERROR_REDUCED_GRADIENT_LAGR
00136               ? s.rGL() : s.GL()  );
00137     if( rGL_GL.updated_k(0) )
00138       o << setw(w) << rGL_GL.get_k(0).norm_inf();
00139     else
00140       o << setw(w) << "-";
00141   }
00142 
00143   if( quasi_newt_stats ) {
00144     o << setw(w);
00145     switch( quasi_newt_stats->updated() ) {
00146       case QuasiNewtonStats::UNKNOWN:
00147         o << "-";
00148         break;
00149       case QuasiNewtonStats:: REINITIALIZED:
00150         o << "initialized";
00151         break;
00152       case QuasiNewtonStats::DAMPENED_UPDATED:
00153         o << "damp.updated";
00154         break;
00155       case QuasiNewtonStats::UPDATED:
00156         o << "updated";
00157         break;
00158       case QuasiNewtonStats::SKIPED:
00159         o << "skiped";
00160         break;
00161       case QuasiNewtonStats::INDEF_SKIPED:
00162         o << "indef skiped";
00163         break;
00164       default:
00165         TEST_FOR_EXCEPT(true);
00166     }
00167   }
00168   else {
00169     o << setw(w) << "-";
00170   }
00171 
00172   if( act_stats ) {
00173     o << setw(7) << act_stats->num_active();
00174     // don't know num_add and num_drops on first iteration.
00175     if( act_stats->num_adds() == ActSetStats::NOT_KNOWN ) { 
00176       o << setw(7) << "-";
00177     }
00178     else {    
00179       o << setw(7) << act_stats->num_adds();
00180     }
00181     if( act_stats->num_drops() == ActSetStats::NOT_KNOWN ) {
00182       o << setw(7) << "-";
00183     }
00184     else {    
00185       o << setw(7) << act_stats->num_drops();
00186     }
00187   }
00188   else if( s.nu().updated_k(0) ) {
00189     o << setw(7) << s.nu().get_k(0).nz()
00190       << setw(7) << "-"
00191       << setw(7) << "-";
00192   }
00193   else {
00194     o << setw(7) << "-"
00195       << setw(7) << "-"
00196       << setw(7) << "-";
00197   }
00198 
00199   if( qp_stats ) {
00200     o << setw(7) << qp_stats->num_qp_iter()
00201       << setw(3) << ( qp_stats->warm_start() ? 'w' : 'c')
00202       << setw(2) << ( qp_stats->infeasible_qp() ? 'i' : 'f');
00203     num_total_qp_iter_ += qp_stats->num_qp_iter();
00204   }
00205   else {
00206   o << setw(7) << "-"
00207     << setw(3) << "-"
00208     << setw(2) << "-";
00209   }
00210 
00211   if(m && Ypy_exists)
00212     o << setw(w) << norm_2_Ypy;
00213   else
00214     o << setw(w) << "-";
00215 
00216   if(Zpz_exists)
00217     o << setw(w) << norm_2_Zpz;
00218   else
00219     o << setw(w) << "-";
00220 
00221   if( s.d().updated_k(0) )
00222     o << setw(w)
00223       << s.d().get_k(0).norm_inf();
00224   else
00225     o << setw(w) << "-";
00226 
00227   if( s.alpha().updated_k(0) )
00228     o << setw(w) << s.alpha().get_k(0);
00229   else
00230     o << setw(w) << "-";
00231 
00232   o << std::endl;
00233 }
00234 
00235 void MoochoTrackerSummaryStd::output_final(const Algorithm& algo
00236   , EAlgoReturn algo_return) const
00237 {
00238   using Teuchos::dyn_cast;
00239 
00240   const NLPAlgo            &_algo  = rsqp_algo(algo);
00241   const NLPAlgoState           &s      =_algo.rsqp_state();
00242   const NLPObjGrad      &nlp    = dyn_cast<const NLPObjGrad>(_algo.nlp()); 
00243   const NLPFirstOrder  *nlp_foi = dynamic_cast<const NLPFirstOrder*>(&nlp); 
00244 
00245   const size_type
00246     m = nlp.m();
00247 
00248   std::ostream& o = this->o();
00249 
00250   int w = 15;
00251   int prec = 6;
00252   o.precision(prec);
00253 
00254   // Get active set, QP solver and quasi-newton statistics.
00255   const ActSetStats   *act_stats =
00256     ( act_set_stats_.exists_in(s) && act_set_stats_(s).updated_k(0)
00257       ? &act_set_stats_(s).get_k(0)
00258       : NULL );
00259   const QPSolverStats   *qp_stats =
00260     ( qp_solver_stats_.exists_in(s) && qp_solver_stats_(s).updated_k(0)
00261       ? &qp_solver_stats_(s).get_k(0)
00262       : NULL );
00263   const QuasiNewtonStats  *quasi_newt_stats =
00264     ( quasi_newton_stats_.exists_in(s) && quasi_newton_stats_(s).updated_k(0)
00265       ? &quasi_newton_stats_(s).get_k(0)
00266       : NULL );
00267 
00268   // Output the table's header for the first iteration
00269   if(s.k() == 0) {
00270     print_header(s);
00271   }
00272   else {
00273     o << " ----"
00274       << "   ------------"
00275       << "   ------------"
00276       << "   ------------"
00277       << "   ------------"
00278       << "   ------------"
00279       << " ------"
00280       << " ------"
00281       << " ------"
00282       << " ------"
00283       << " ----\n";
00284   }
00285 
00286   o << std::right
00287     << setw(5) << s.k();
00288 
00289   if( s.f().updated_k(0) )
00290     o << setw(w) << s.f().get_k(0);
00291   else
00292     o << setw(w) << "-";
00293 
00294   if( s.Gf().updated_k(0) )
00295     o << setw(w) << s.Gf().get_k(0).norm_inf();
00296   else
00297     o << setw(w) << "-";
00298 
00299   if( m && s.c().updated_k(0) )
00300     o << setw(w)
00301       << s.c().get_k(0).norm_inf();
00302   else
00303     o << setw(w) << "-";
00304 
00305   {
00306     const IterQuantityAccess<VectorMutable>
00307       &rGL_GL = ( opt_error_ == OPT_ERROR_REDUCED_GRADIENT_LAGR
00308               ? s.rGL() : s.GL()  );
00309     if( rGL_GL.updated_k(0) )
00310       o << setw(w) << rGL_GL.get_k(0).norm_inf();
00311     else
00312       o << setw(w) << "-";
00313   }
00314 
00315   o << setw(w);
00316   if( quasi_newt_stats ) {
00317     switch( quasi_newt_stats->updated() ) {
00318       case QuasiNewtonStats::UNKNOWN:
00319         o << "-";
00320         break;
00321       case QuasiNewtonStats:: REINITIALIZED:
00322         o << "initialized";
00323         break;
00324       case QuasiNewtonStats::DAMPENED_UPDATED:
00325         o << "damp.updated";
00326         break;
00327       case QuasiNewtonStats::UPDATED:
00328         o << "updated";
00329         break;
00330       case QuasiNewtonStats::SKIPED:
00331         o << "skiped";
00332         break;
00333       case QuasiNewtonStats::INDEF_SKIPED:
00334         o << "indef skiped";
00335         break;
00336       default:
00337         TEST_FOR_EXCEPT(true);
00338     }
00339   }
00340   else {
00341     o << setw(w) << "-";;
00342   }
00343 
00344   if( act_stats ) {
00345     o << setw(7) << act_stats->num_active()
00346       << setw(7) << act_stats->num_adds()
00347       << setw(7) << act_stats->num_drops();
00348   }
00349   else if( s.nu().updated_k(0) ) {
00350     o << setw(7) << s.nu().get_k(0).nz()
00351       << setw(7) << "-"
00352       << setw(7) << "-";
00353   }
00354   else {
00355     o << setw(7) << "-"
00356       << setw(7) << "-"
00357       << setw(7) << "-";
00358   }
00359   
00360   if( qp_stats ) {
00361     o << setw(7) << qp_stats->num_qp_iter()
00362       << setw(3) << ( qp_stats->warm_start() ? 'w' : 'c')
00363       << setw(2) << ( qp_stats->infeasible_qp() ? 'i' : 'f');
00364     num_total_qp_iter_ += qp_stats->num_qp_iter();
00365   }
00366   else {
00367     o << setw(7) << "-"
00368       << setw(3) << "-"
00369       << setw(2) << "-";
00370   }
00371   
00372   if(m && s.Ypy().updated_k(0))
00373     o << setw(w) 
00374       << s.Ypy().get_k(0).norm_2();
00375   else
00376     o << setw(w) << "-";
00377   
00378   if(s.Zpz().updated_k(0))
00379     o << setw(w)
00380       << s.Zpz().get_k(0).norm_2();
00381   else
00382     o << setw(w) << "-";
00383   
00384   if( s.d().updated_k(0) )
00385     o << setw(w)
00386       << s.d().get_k(0).norm_inf();
00387   else
00388     o << setw(w) << "-";
00389 
00390   o << endl;
00391   
00392   o << "\nNumber of function evaluations:\n"
00393     <<     "-------------------------------\n"
00394     << "f(x)  : " << nlp.num_f_evals() << endl
00395     << "c(x)  : " << ( m ? nlp.num_c_evals() : 0 ) << endl
00396     << "Gf(x) : " << nlp.num_Gf_evals() << endl
00397     << "Gc(x) : ";
00398   if(m){
00399     if( nlp_foi )
00400       o << nlp_foi->num_Gc_evals();
00401     else
00402       o << "?";
00403   }
00404   else {
00405     o << 0;
00406   }
00407   o << endl;
00408 
00409 }
00410 
00411 void MoochoTrackerSummaryStd::print_header(const NLPAlgoState &s) const
00412 {
00413   // Reset the count of total QP iterations
00414   num_total_qp_iter_ = 0;
00415 
00416   std::ostream& o = this->o();
00417 
00418   NLPAlgoState::space_c_ptr_t
00419     space_c = s.get_space_c();
00420 
00421   o << "\n\n********************************\n"
00422     << "*** Start of rSQP Iterations ***\n"
00423     << "n = " << s.space_x().dim()
00424     << ", m = " << ( space_c.get() ? space_c->dim() : 0 )
00425     << ", nz = ";
00426   try {
00427     if(space_c.get()) {
00428       if( s.Gc().updated_k(0) )
00429         o << s.Gc().get_k(0).nz() << endl;
00430       else
00431         o << "?\n";
00432     }
00433     else {
00434       o << 0 << endl;
00435     }
00436   }
00437   catch( const AlgorithmState::DoesNotExist& ) {
00438       o << "?\n";
00439   }
00440   o
00441     << "\n k   "
00442     << "   f           "
00443     << "   ||Gf||inf   "
00444     << "   ||c||inf    ";
00445   switch(opt_error_) {
00446     case OPT_ERROR_REDUCED_GRADIENT_LAGR:
00447       o << "   ||rGL||inf  ";
00448       break;
00449     case OPT_ERROR_GRADIENT_LAGR:
00450       o << "   ||GL||inf  ";
00451       break;
00452     default:
00453       TEST_FOR_EXCEPT(true);
00454   }
00455   o   << "   quasi-Newton"
00456     << " #act  "
00457     << " #adds "
00458     << " #drops"
00459     << " #qpitr"
00460     << " wcfi  "
00461     << "   ||Ypy||2    "
00462     << "   ||Zpz||2    "
00463     << "   ||d||inf    "
00464     << "   alpha\n"
00465     << " ----"
00466     << "   ------------"
00467     << "   ------------"
00468     << "   ------------"
00469     << "   ------------"
00470     << "   ------------"
00471     << " ------"
00472     << " ------"
00473     << " ------"
00474     << " ------"
00475     << " ----"
00476     << "   ------------"
00477     << "   ------------"
00478     << "   ------------"
00479     << "   ------------\n";
00480 }
00481 
00482 } // end namespace MoochoPack

Generated on Tue Jul 13 09:29:32 2010 for MoochoPack : Framework for Large-Scale Optimization Algorithms by  doxygen 1.4.7