MOOCHO (Single Doxygen Collection) Version of the Day
MoochoPack_MoochoTrackerStatsStd.cpp
Go to the documentation of this file.
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 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 
00038 // 
00039 // ***********************************************************************
00040 // @HEADER
00041 
00042 #include <assert.h>
00043 
00044 #include <iomanip>
00045 
00046 #include "MoochoPack_MoochoTrackerStatsStd.hpp"
00047 #include "MoochoPack_NLPAlgoState.hpp"
00048 #include "MoochoPack_moocho_algo_conversion.hpp"
00049 #include "NLPInterfacePack_NLPFirstOrder.hpp"
00050 #include "AbstractLinAlgPack_Vector.hpp"
00051 #include "Teuchos_dyn_cast.hpp"
00052 
00053 namespace {
00054 template< class T >
00055 inline
00056 T my_max( const T& v1, const T& v2 ) { return v1 > v2 ? v1 : v2; }
00057 } // end namespace
00058 
00059 namespace MoochoPack {
00060 
00061 using std::endl;
00062 using std::setw;
00063 using std::left;
00064 using std::right;
00065 using std::setprecision;
00066 
00067 MoochoTrackerStatsStd::MoochoTrackerStatsStd(
00068   const ostream_ptr_t& o, const ostream_ptr_t& journal_out
00069   )
00070   :AlgorithmTracker(journal_out)
00071 {
00072   set_output_stream(o);
00073 }
00074 
00075 void MoochoTrackerStatsStd::set_output_stream(const ostream_ptr_t& o)
00076 {
00077   o_ = o;
00078 }
00079 
00080 const MoochoTrackerStatsStd::ostream_ptr_t&
00081 MoochoTrackerStatsStd::get_output_stream() const
00082 {
00083   return o_;
00084 }
00085 
00086 void MoochoTrackerStatsStd::initialize()
00087 {
00088   num_QN_updates_ = 0;
00089   timer_.reset();
00090   timer_.start();
00091 }
00092 
00093 void MoochoTrackerStatsStd::output_iteration(const Algorithm& p_algo) const
00094 {
00095   const NLPAlgo  &algo = rsqp_algo(p_algo);
00096   const NLPAlgoState &s    = algo.rsqp_state();
00097 
00098   // All we have to do here is to just to count the number of quasi-newton updates
00099   const QuasiNewtonStats  *quasi_newt_stats =
00100     ( quasi_newton_stats_.exists_in(s) && quasi_newton_stats_(s).updated_k(0)
00101       ? &quasi_newton_stats_(s).get_k(0)
00102       : NULL );
00103   if( quasi_newt_stats ) {
00104     QuasiNewtonStats::EUpdate updated = quasi_newt_stats->updated();
00105     if( updated == QuasiNewtonStats::DAMPENED_UPDATED || updated == QuasiNewtonStats::UPDATED )
00106       num_QN_updates_++;
00107   }
00108 }
00109 
00110 void MoochoTrackerStatsStd::output_final( const Algorithm& p_algo
00111   , EAlgoReturn algo_return ) const
00112 {
00113   using Teuchos::dyn_cast;
00114 
00115   const NLPAlgo           &algo    = rsqp_algo(p_algo);
00116   const NLPAlgoState          &s       = algo.rsqp_state();
00117   const NLPObjGrad     &nlp     = dyn_cast<const NLPObjGrad>(algo.nlp()); 
00118   const NLPFirstOrder  *nlp_foi = dynamic_cast<const NLPFirstOrder*>(&nlp); 
00119 
00120   const size_type
00121     m = nlp.m();
00122 
00123   std::ostream& o = this->o();
00124 
00125   // Stop the timer
00126   timer_.stop();
00127 
00128   // Formating info
00129   const int
00130     p      = 18,
00131     stat_w = 15,
00132     val_w  = p + 10;
00133 
00134   // Get a Quasi-Newton statistics.
00135   const QuasiNewtonStats  *quasi_newt_stats =
00136     ( quasi_newton_stats_.exists_in(s) && quasi_newton_stats_(s).updated_k(0)
00137       ? &quasi_newton_stats_(s).get_k(0)
00138       : NULL );
00139   if( quasi_newt_stats ) {
00140     QuasiNewtonStats::EUpdate updated = quasi_newt_stats->updated();
00141     if( updated == QuasiNewtonStats::DAMPENED_UPDATED || updated == QuasiNewtonStats::UPDATED )
00142       num_QN_updates_++;
00143   }
00144 
00145   // status
00146   o << left << setw(stat_w) << "status" << "= "
00147     << right << setw(val_w);
00148   switch( algo_return ) {
00149     case IterationPack::TERMINATE_TRUE:
00150       o << "solved";
00151       break;
00152     case IterationPack::TERMINATE_FALSE:
00153       o << "except";
00154       break;
00155     case IterationPack::MAX_ITER_EXCEEDED:
00156       o << "max_iter";
00157       break;
00158     case IterationPack::MAX_RUN_TIME_EXCEEDED:
00159       o << "max_run_time";
00160       break;
00161     case IterationPack::INTERRUPTED_TERMINATE_TRUE:
00162       o << "interrupted_solved";
00163       break;
00164     case IterationPack::INTERRUPTED_TERMINATE_FALSE:
00165       o << "interrupted_not_solved";
00166       break;
00167     default:
00168       TEUCHOS_TEST_FOR_EXCEPT(true);
00169   }
00170   o << "; # solved, except, max_iter, max_run_time\n";
00171   // niter
00172   o << left << setw(stat_w) << "niter" << "= "
00173     << right << setw(val_w) << s.k()
00174     << "; # Number of rSQP iterations (plus 1?)\n";
00175   // nfunc
00176   o << left << setw(stat_w) << "nfunc" << "= "
00177     << right << setw(val_w) << my_max(nlp.num_f_evals(),(m? nlp.num_c_evals():0) )
00178     << "; # max( number f(x) evals, number c(x) evals )\n";
00179   // ngrad
00180   o << left << setw(stat_w) << "ngrad" << "= "
00181     << right << setw(val_w) << my_max(nlp.num_Gf_evals(),(m?(nlp_foi?nlp_foi->num_Gc_evals():s.k()+1):0))
00182     << "; # max( number Gf(x) evals, number Gc(x) evals )\n";
00183   // CPU
00184   o << left << setw(stat_w) << "CPU" << "= "
00185     << right << setw(val_w) << timer_.read()
00186     << "; # Number of CPU seconds total\n";
00187   // obj_func
00188   o << left << setw(stat_w) << "obj_func" << "= "
00189     << right << setw(val_w);
00190   if(s.f().updated_k(0))
00191     o << s.f().get_k(0);
00192   else
00193     o << "-";
00194   o << "; # Objective function value f(x) at final point\n";
00195   // feas_kkt_err
00196   o << left << setw(stat_w) << "feas_kkt_err" << "= "
00197     << right << setw(val_w);
00198   if(s.feas_kkt_err().updated_k(0))
00199     o << s.feas_kkt_err().get_k(0);
00200   else if(s.c().updated_k(0))
00201     o << s.c().get_k(0).norm_inf();
00202   else
00203     o << "-";
00204   o << "; # Feasibility error at final point (scaled ||c(x)||inf, feas_err_k)\n";
00205   // opt_kkt_err
00206   o << left << setw(stat_w) << "opt_kkt_err" << "= "
00207     << right << setw(val_w);
00208   if(s.opt_kkt_err().updated_k(0))
00209     o << s.opt_kkt_err().get_k(0);
00210   else if(s.rGL().updated_k(0))
00211     o << s.rGL().get_k(0).norm_inf();
00212   else if(s.rGL().updated_k(-1))
00213     o << s.rGL().get_k(-1).norm_inf();
00214   else
00215     o << "-";
00216   o << "; # Optimality error at final point (scaled ||rGL||inf, opt_err_k)\n";
00217   // nact
00218   o << left << setw(stat_w) << "nact" << "= "
00219     << right << setw(val_w);
00220   if(s.nu().updated_k(0))
00221     o << s.nu().get_k(0).nz();
00222   else if(s.nu().updated_k(-1))
00223     o << s.nu().get_k(-1).nz();
00224   else
00225     o << "-";
00226   o << "; # Number of total active constraints at the final point\n";
00227   // nbasis_change
00228   const IterQuantityAccess<index_type> &num_basis = s.num_basis();
00229   const int lu_k = num_basis.last_updated();
00230   o << left << setw(stat_w) << "nbasis_change" << "= "
00231     << right << setw(val_w) << ( lu_k != IterQuantity::NONE_UPDATED
00232                    ? num_basis.get_k(lu_k)
00233                    : 0 ) 
00234     << "; # Number of basis changes\n";
00235   // nquasi_newton
00236   o << left << setw(stat_w) << "nquasi_newton" << "= "
00237     << right << setw(val_w) << num_QN_updates_
00238     << "; # Number of quasi-newton updates\n";
00239 
00240 }
00241 
00242 } // end namespace MoochoPack
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines