|
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_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
1.7.4