|
MoochoPack : Framework for Large-Scale Optimization Algorithms Version of the Day
|
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_MoochoTrackerStatsStd.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 "Teuchos_dyn_cast.hpp" 00039 00040 namespace { 00041 template< class T > 00042 inline 00043 T my_max( const T& v1, const T& v2 ) { return v1 > v2 ? v1 : v2; } 00044 } // end namespace 00045 00046 namespace MoochoPack { 00047 00048 using std::endl; 00049 using std::setw; 00050 using std::left; 00051 using std::right; 00052 using std::setprecision; 00053 00054 MoochoTrackerStatsStd::MoochoTrackerStatsStd( 00055 const ostream_ptr_t& o, const ostream_ptr_t& journal_out 00056 ) 00057 :AlgorithmTracker(journal_out) 00058 { 00059 set_output_stream(o); 00060 } 00061 00062 void MoochoTrackerStatsStd::set_output_stream(const ostream_ptr_t& o) 00063 { 00064 o_ = o; 00065 } 00066 00067 const MoochoTrackerStatsStd::ostream_ptr_t& 00068 MoochoTrackerStatsStd::get_output_stream() const 00069 { 00070 return o_; 00071 } 00072 00073 void MoochoTrackerStatsStd::initialize() 00074 { 00075 num_QN_updates_ = 0; 00076 timer_.reset(); 00077 timer_.start(); 00078 } 00079 00080 void MoochoTrackerStatsStd::output_iteration(const Algorithm& p_algo) const 00081 { 00082 const NLPAlgo &algo = rsqp_algo(p_algo); 00083 const NLPAlgoState &s = algo.rsqp_state(); 00084 00085 // All we have to do here is to just to count the number of quasi-newton updates 00086 const QuasiNewtonStats *quasi_newt_stats = 00087 ( quasi_newton_stats_.exists_in(s) && quasi_newton_stats_(s).updated_k(0) 00088 ? &quasi_newton_stats_(s).get_k(0) 00089 : NULL ); 00090 if( quasi_newt_stats ) { 00091 QuasiNewtonStats::EUpdate updated = quasi_newt_stats->updated(); 00092 if( updated == QuasiNewtonStats::DAMPENED_UPDATED || updated == QuasiNewtonStats::UPDATED ) 00093 num_QN_updates_++; 00094 } 00095 } 00096 00097 void MoochoTrackerStatsStd::output_final( const Algorithm& p_algo 00098 , EAlgoReturn algo_return ) const 00099 { 00100 using Teuchos::dyn_cast; 00101 00102 const NLPAlgo &algo = rsqp_algo(p_algo); 00103 const NLPAlgoState &s = algo.rsqp_state(); 00104 const NLPObjGrad &nlp = dyn_cast<const NLPObjGrad>(algo.nlp()); 00105 const NLPFirstOrder *nlp_foi = dynamic_cast<const NLPFirstOrder*>(&nlp); 00106 00107 const size_type 00108 m = nlp.m(); 00109 00110 std::ostream& o = this->o(); 00111 00112 // Stop the timer 00113 timer_.stop(); 00114 00115 // Formating info 00116 const int 00117 p = 18, 00118 stat_w = 15, 00119 val_w = p + 10; 00120 00121 // Get a Quasi-Newton statistics. 00122 const QuasiNewtonStats *quasi_newt_stats = 00123 ( quasi_newton_stats_.exists_in(s) && quasi_newton_stats_(s).updated_k(0) 00124 ? &quasi_newton_stats_(s).get_k(0) 00125 : NULL ); 00126 if( quasi_newt_stats ) { 00127 QuasiNewtonStats::EUpdate updated = quasi_newt_stats->updated(); 00128 if( updated == QuasiNewtonStats::DAMPENED_UPDATED || updated == QuasiNewtonStats::UPDATED ) 00129 num_QN_updates_++; 00130 } 00131 00132 // status 00133 o << left << setw(stat_w) << "status" << "= " 00134 << right << setw(val_w); 00135 switch( algo_return ) { 00136 case IterationPack::TERMINATE_TRUE: 00137 o << "solved"; 00138 break; 00139 case IterationPack::TERMINATE_FALSE: 00140 o << "except"; 00141 break; 00142 case IterationPack::MAX_ITER_EXCEEDED: 00143 o << "max_iter"; 00144 break; 00145 case IterationPack::MAX_RUN_TIME_EXCEEDED: 00146 o << "max_run_time"; 00147 break; 00148 case IterationPack::INTERRUPTED_TERMINATE_TRUE: 00149 o << "interrupted_solved"; 00150 break; 00151 case IterationPack::INTERRUPTED_TERMINATE_FALSE: 00152 o << "interrupted_not_solved"; 00153 break; 00154 default: 00155 TEST_FOR_EXCEPT(true); 00156 } 00157 o << "; # solved, except, max_iter, max_run_time\n"; 00158 // niter 00159 o << left << setw(stat_w) << "niter" << "= " 00160 << right << setw(val_w) << s.k() 00161 << "; # Number of rSQP iterations (plus 1?)\n"; 00162 // nfunc 00163 o << left << setw(stat_w) << "nfunc" << "= " 00164 << right << setw(val_w) << my_max(nlp.num_f_evals(),(m? nlp.num_c_evals():0) ) 00165 << "; # max( number f(x) evals, number c(x) evals )\n"; 00166 // ngrad 00167 o << left << setw(stat_w) << "ngrad" << "= " 00168 << right << setw(val_w) << my_max(nlp.num_Gf_evals(),(m?(nlp_foi?nlp_foi->num_Gc_evals():s.k()+1):0)) 00169 << "; # max( number Gf(x) evals, number Gc(x) evals )\n"; 00170 // CPU 00171 o << left << setw(stat_w) << "CPU" << "= " 00172 << right << setw(val_w) << timer_.read() 00173 << "; # Number of CPU seconds total\n"; 00174 // obj_func 00175 o << left << setw(stat_w) << "obj_func" << "= " 00176 << right << setw(val_w); 00177 if(s.f().updated_k(0)) 00178 o << s.f().get_k(0); 00179 else 00180 o << "-"; 00181 o << "; # Objective function value f(x) at final point\n"; 00182 // feas_kkt_err 00183 o << left << setw(stat_w) << "feas_kkt_err" << "= " 00184 << right << setw(val_w); 00185 if(s.feas_kkt_err().updated_k(0)) 00186 o << s.feas_kkt_err().get_k(0); 00187 else if(s.c().updated_k(0)) 00188 o << s.c().get_k(0).norm_inf(); 00189 else 00190 o << "-"; 00191 o << "; # Feasibility error at final point (scaled ||c(x)||inf, feas_err_k)\n"; 00192 // opt_kkt_err 00193 o << left << setw(stat_w) << "opt_kkt_err" << "= " 00194 << right << setw(val_w); 00195 if(s.opt_kkt_err().updated_k(0)) 00196 o << s.opt_kkt_err().get_k(0); 00197 else if(s.rGL().updated_k(0)) 00198 o << s.rGL().get_k(0).norm_inf(); 00199 else if(s.rGL().updated_k(-1)) 00200 o << s.rGL().get_k(-1).norm_inf(); 00201 else 00202 o << "-"; 00203 o << "; # Optimality error at final point (scaled ||rGL||inf, opt_err_k)\n"; 00204 // nact 00205 o << left << setw(stat_w) << "nact" << "= " 00206 << right << setw(val_w); 00207 if(s.nu().updated_k(0)) 00208 o << s.nu().get_k(0).nz(); 00209 else if(s.nu().updated_k(-1)) 00210 o << s.nu().get_k(-1).nz(); 00211 else 00212 o << "-"; 00213 o << "; # Number of total active constraints at the final point\n"; 00214 // nbasis_change 00215 const IterQuantityAccess<index_type> &num_basis = s.num_basis(); 00216 const int lu_k = num_basis.last_updated(); 00217 o << left << setw(stat_w) << "nbasis_change" << "= " 00218 << right << setw(val_w) << ( lu_k != IterQuantity::NONE_UPDATED 00219 ? num_basis.get_k(lu_k) 00220 : 0 ) 00221 << "; # Number of basis changes\n"; 00222 // nquasi_newton 00223 o << left << setw(stat_w) << "nquasi_newton" << "= " 00224 << right << setw(val_w) << num_QN_updates_ 00225 << "; # Number of quasi-newton updates\n"; 00226 00227 } 00228 00229 } // end namespace MoochoPack
1.7.4