|
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 // 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_MoochoTrackerSummaryStd.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 "AbstractLinAlgPack_MatrixSymOp.hpp" 00052 #include "Teuchos_dyn_cast.hpp" 00053 00054 using std::endl; 00055 using std::setw; 00056 00057 namespace MoochoPack { 00058 00059 MoochoTrackerSummaryStd::MoochoTrackerSummaryStd( 00060 const ostream_ptr_t &o 00061 ,const ostream_ptr_t &journal_out 00062 ,EOptError opt_error 00063 ) 00064 :AlgorithmTracker(journal_out) 00065 ,o_(o) 00066 ,opt_error_(opt_error) 00067 ,num_total_qp_iter_(0) 00068 {} 00069 00070 void MoochoTrackerSummaryStd::set_output_stream(const ostream_ptr_t& o) 00071 { 00072 o_ = o; 00073 } 00074 00075 const MoochoTrackerSummaryStd::ostream_ptr_t& 00076 MoochoTrackerSummaryStd::get_output_stream() const 00077 { 00078 return o_; 00079 } 00080 00081 void MoochoTrackerSummaryStd::output_iteration(const Algorithm& algo) const 00082 { 00083 00084 const NLPAlgo &_algo = rsqp_algo(algo); 00085 const NLPAlgoState &s =_algo.rsqp_state(); 00086 const NLP &nlp = _algo.nlp(); 00087 00088 const size_type 00089 m = nlp.m(); 00090 00091 std::ostream& o = this->o(); 00092 00093 int w = 15; 00094 int prec = 6; 00095 o.precision(prec); 00096 00097 // Output the table's header for the first iteration 00098 if(s.k() == 0) { 00099 print_header(s); 00100 } 00101 00102 // /////////////////////////////// 00103 // Output a row for the iteration 00104 00105 // Get active set and QP solver statistics. 00106 const ActSetStats *act_stats = 00107 ( act_set_stats_.exists_in(s) && act_set_stats_(s).updated_k(0) 00108 ? &act_set_stats_(s).get_k(0) 00109 : NULL ); 00110 const QPSolverStats *qp_stats = 00111 ( qp_solver_stats_.exists_in(s) && qp_solver_stats_(s).updated_k(0) 00112 ? &qp_solver_stats_(s).get_k(0) 00113 : NULL ); 00114 const QuasiNewtonStats *quasi_newt_stats = 00115 ( quasi_newton_stats_.exists_in(s) && quasi_newton_stats_(s).updated_k(0) 00116 ? &quasi_newton_stats_(s).get_k(0) 00117 : NULL ); 00118 00119 // Get the norms of Ypy and Zpz 00120 value_type norm_2_Ypy = -1.0, norm_2_Zpz = -1.0; 00121 bool Ypy_exists, Zpz_exists; 00122 if( m && ( Ypy_exists = s.Ypy().updated_k(0) ) ) 00123 norm_2_Ypy = s.Ypy().get_k(0).norm_2(); 00124 if( Zpz_exists = s.Zpz().updated_k(0) ) 00125 norm_2_Zpz = s.Zpz().get_k(0).norm_2(); 00126 00127 o << std::right 00128 << setw(5) << s.k(); 00129 00130 if( s.f().updated_k(0) ) 00131 o << setw(w) << s.f().get_k(0); 00132 else 00133 o << setw(w) << "-"; 00134 00135 if( s.Gf().updated_k(0) ) 00136 o << setw(w) << s.Gf().get_k(0).norm_inf(); 00137 else 00138 o << setw(w) << "-"; 00139 00140 if( m && s.c().updated_k(0) ) 00141 o << setw(w) 00142 << s.c().get_k(0).norm_inf(); 00143 else 00144 o << setw(w) << "-"; 00145 00146 { 00147 const IterQuantityAccess<VectorMutable> 00148 &rGL_GL = ( opt_error_ == OPT_ERROR_REDUCED_GRADIENT_LAGR 00149 ? s.rGL() : s.GL() ); 00150 if( rGL_GL.updated_k(0) ) 00151 o << setw(w) << rGL_GL.get_k(0).norm_inf(); 00152 else 00153 o << setw(w) << "-"; 00154 } 00155 00156 if( quasi_newt_stats ) { 00157 o << setw(w); 00158 switch( quasi_newt_stats->updated() ) { 00159 case QuasiNewtonStats::UNKNOWN: 00160 o << "-"; 00161 break; 00162 case QuasiNewtonStats:: REINITIALIZED: 00163 o << "initialized"; 00164 break; 00165 case QuasiNewtonStats::DAMPENED_UPDATED: 00166 o << "damp.updated"; 00167 break; 00168 case QuasiNewtonStats::UPDATED: 00169 o << "updated"; 00170 break; 00171 case QuasiNewtonStats::SKIPED: 00172 o << "skiped"; 00173 break; 00174 case QuasiNewtonStats::INDEF_SKIPED: 00175 o << "indef skiped"; 00176 break; 00177 default: 00178 TEUCHOS_TEST_FOR_EXCEPT(true); 00179 } 00180 } 00181 else { 00182 o << setw(w) << "-"; 00183 } 00184 00185 if( act_stats ) { 00186 o << setw(7) << act_stats->num_active(); 00187 // don't know num_add and num_drops on first iteration. 00188 if( act_stats->num_adds() == ActSetStats::NOT_KNOWN ) { 00189 o << setw(7) << "-"; 00190 } 00191 else { 00192 o << setw(7) << act_stats->num_adds(); 00193 } 00194 if( act_stats->num_drops() == ActSetStats::NOT_KNOWN ) { 00195 o << setw(7) << "-"; 00196 } 00197 else { 00198 o << setw(7) << act_stats->num_drops(); 00199 } 00200 } 00201 else if( s.nu().updated_k(0) ) { 00202 o << setw(7) << s.nu().get_k(0).nz() 00203 << setw(7) << "-" 00204 << setw(7) << "-"; 00205 } 00206 else { 00207 o << setw(7) << "-" 00208 << setw(7) << "-" 00209 << setw(7) << "-"; 00210 } 00211 00212 if( qp_stats ) { 00213 o << setw(7) << qp_stats->num_qp_iter() 00214 << setw(3) << ( qp_stats->warm_start() ? 'w' : 'c') 00215 << setw(2) << ( qp_stats->infeasible_qp() ? 'i' : 'f'); 00216 num_total_qp_iter_ += qp_stats->num_qp_iter(); 00217 } 00218 else { 00219 o << setw(7) << "-" 00220 << setw(3) << "-" 00221 << setw(2) << "-"; 00222 } 00223 00224 if(m && Ypy_exists) 00225 o << setw(w) << norm_2_Ypy; 00226 else 00227 o << setw(w) << "-"; 00228 00229 if(Zpz_exists) 00230 o << setw(w) << norm_2_Zpz; 00231 else 00232 o << setw(w) << "-"; 00233 00234 if( s.d().updated_k(0) ) 00235 o << setw(w) 00236 << s.d().get_k(0).norm_inf(); 00237 else 00238 o << setw(w) << "-"; 00239 00240 if( s.alpha().updated_k(0) ) 00241 o << setw(w) << s.alpha().get_k(0); 00242 else 00243 o << setw(w) << "-"; 00244 00245 o << std::endl; 00246 } 00247 00248 void MoochoTrackerSummaryStd::output_final(const Algorithm& algo 00249 , EAlgoReturn algo_return) const 00250 { 00251 using Teuchos::dyn_cast; 00252 00253 const NLPAlgo &_algo = rsqp_algo(algo); 00254 const NLPAlgoState &s =_algo.rsqp_state(); 00255 const NLPObjGrad &nlp = dyn_cast<const NLPObjGrad>(_algo.nlp()); 00256 const NLPFirstOrder *nlp_foi = dynamic_cast<const NLPFirstOrder*>(&nlp); 00257 00258 const size_type 00259 m = nlp.m(); 00260 00261 std::ostream& o = this->o(); 00262 00263 int w = 15; 00264 int prec = 6; 00265 o.precision(prec); 00266 00267 // Get active set, QP solver and quasi-newton statistics. 00268 const ActSetStats *act_stats = 00269 ( act_set_stats_.exists_in(s) && act_set_stats_(s).updated_k(0) 00270 ? &act_set_stats_(s).get_k(0) 00271 : NULL ); 00272 const QPSolverStats *qp_stats = 00273 ( qp_solver_stats_.exists_in(s) && qp_solver_stats_(s).updated_k(0) 00274 ? &qp_solver_stats_(s).get_k(0) 00275 : NULL ); 00276 const QuasiNewtonStats *quasi_newt_stats = 00277 ( quasi_newton_stats_.exists_in(s) && quasi_newton_stats_(s).updated_k(0) 00278 ? &quasi_newton_stats_(s).get_k(0) 00279 : NULL ); 00280 00281 // Output the table's header for the first iteration 00282 if(s.k() == 0) { 00283 print_header(s); 00284 } 00285 else { 00286 o << " ----" 00287 << " ------------" 00288 << " ------------" 00289 << " ------------" 00290 << " ------------" 00291 << " ------------" 00292 << " ------" 00293 << " ------" 00294 << " ------" 00295 << " ------" 00296 << " ----\n"; 00297 } 00298 00299 o << std::right 00300 << setw(5) << s.k(); 00301 00302 if( s.f().updated_k(0) ) 00303 o << setw(w) << s.f().get_k(0); 00304 else 00305 o << setw(w) << "-"; 00306 00307 if( s.Gf().updated_k(0) ) 00308 o << setw(w) << s.Gf().get_k(0).norm_inf(); 00309 else 00310 o << setw(w) << "-"; 00311 00312 if( m && s.c().updated_k(0) ) 00313 o << setw(w) 00314 << s.c().get_k(0).norm_inf(); 00315 else 00316 o << setw(w) << "-"; 00317 00318 { 00319 const IterQuantityAccess<VectorMutable> 00320 &rGL_GL = ( opt_error_ == OPT_ERROR_REDUCED_GRADIENT_LAGR 00321 ? s.rGL() : s.GL() ); 00322 if( rGL_GL.updated_k(0) ) 00323 o << setw(w) << rGL_GL.get_k(0).norm_inf(); 00324 else 00325 o << setw(w) << "-"; 00326 } 00327 00328 o << setw(w); 00329 if( quasi_newt_stats ) { 00330 switch( quasi_newt_stats->updated() ) { 00331 case QuasiNewtonStats::UNKNOWN: 00332 o << "-"; 00333 break; 00334 case QuasiNewtonStats:: REINITIALIZED: 00335 o << "initialized"; 00336 break; 00337 case QuasiNewtonStats::DAMPENED_UPDATED: 00338 o << "damp.updated"; 00339 break; 00340 case QuasiNewtonStats::UPDATED: 00341 o << "updated"; 00342 break; 00343 case QuasiNewtonStats::SKIPED: 00344 o << "skiped"; 00345 break; 00346 case QuasiNewtonStats::INDEF_SKIPED: 00347 o << "indef skiped"; 00348 break; 00349 default: 00350 TEUCHOS_TEST_FOR_EXCEPT(true); 00351 } 00352 } 00353 else { 00354 o << setw(w) << "-";; 00355 } 00356 00357 if( act_stats ) { 00358 o << setw(7) << act_stats->num_active() 00359 << setw(7) << act_stats->num_adds() 00360 << setw(7) << act_stats->num_drops(); 00361 } 00362 else if( s.nu().updated_k(0) ) { 00363 o << setw(7) << s.nu().get_k(0).nz() 00364 << setw(7) << "-" 00365 << setw(7) << "-"; 00366 } 00367 else { 00368 o << setw(7) << "-" 00369 << setw(7) << "-" 00370 << setw(7) << "-"; 00371 } 00372 00373 if( qp_stats ) { 00374 o << setw(7) << qp_stats->num_qp_iter() 00375 << setw(3) << ( qp_stats->warm_start() ? 'w' : 'c') 00376 << setw(2) << ( qp_stats->infeasible_qp() ? 'i' : 'f'); 00377 num_total_qp_iter_ += qp_stats->num_qp_iter(); 00378 } 00379 else { 00380 o << setw(7) << "-" 00381 << setw(3) << "-" 00382 << setw(2) << "-"; 00383 } 00384 00385 if(m && s.Ypy().updated_k(0)) 00386 o << setw(w) 00387 << s.Ypy().get_k(0).norm_2(); 00388 else 00389 o << setw(w) << "-"; 00390 00391 if(s.Zpz().updated_k(0)) 00392 o << setw(w) 00393 << s.Zpz().get_k(0).norm_2(); 00394 else 00395 o << setw(w) << "-"; 00396 00397 if( s.d().updated_k(0) ) 00398 o << setw(w) 00399 << s.d().get_k(0).norm_inf(); 00400 else 00401 o << setw(w) << "-"; 00402 00403 o << endl; 00404 00405 o << "\nNumber of function evaluations:\n" 00406 << "-------------------------------\n" 00407 << "f(x) : " << nlp.num_f_evals() << endl 00408 << "c(x) : " << ( m ? nlp.num_c_evals() : 0 ) << endl 00409 << "Gf(x) : " << nlp.num_Gf_evals() << endl 00410 << "Gc(x) : "; 00411 if(m){ 00412 if( nlp_foi ) 00413 o << nlp_foi->num_Gc_evals(); 00414 else 00415 o << "?"; 00416 } 00417 else { 00418 o << 0; 00419 } 00420 o << endl; 00421 00422 } 00423 00424 void MoochoTrackerSummaryStd::print_header(const NLPAlgoState &s) const 00425 { 00426 // Reset the count of total QP iterations 00427 num_total_qp_iter_ = 0; 00428 00429 std::ostream& o = this->o(); 00430 00431 NLPAlgoState::space_c_ptr_t 00432 space_c = s.get_space_c(); 00433 00434 o << "\n\n********************************\n" 00435 << "*** Start of rSQP Iterations ***\n" 00436 << "n = " << s.space_x().dim() 00437 << ", m = " << ( space_c.get() ? space_c->dim() : 0 ) 00438 << ", nz = "; 00439 try { 00440 if(space_c.get()) { 00441 if( s.Gc().updated_k(0) ) 00442 o << s.Gc().get_k(0).nz() << endl; 00443 else 00444 o << "?\n"; 00445 } 00446 else { 00447 o << 0 << endl; 00448 } 00449 } 00450 catch( const AlgorithmState::DoesNotExist& ) { 00451 o << "?\n"; 00452 } 00453 o 00454 << "\n k " 00455 << " f " 00456 << " ||Gf||inf " 00457 << " ||c||inf "; 00458 switch(opt_error_) { 00459 case OPT_ERROR_REDUCED_GRADIENT_LAGR: 00460 o << " ||rGL||inf "; 00461 break; 00462 case OPT_ERROR_GRADIENT_LAGR: 00463 o << " ||GL||inf "; 00464 break; 00465 default: 00466 TEUCHOS_TEST_FOR_EXCEPT(true); 00467 } 00468 o << " quasi-Newton" 00469 << " #act " 00470 << " #adds " 00471 << " #drops" 00472 << " #qpitr" 00473 << " wcfi " 00474 << " ||Ypy||2 " 00475 << " ||Zpz||2 " 00476 << " ||d||inf " 00477 << " alpha\n" 00478 << " ----" 00479 << " ------------" 00480 << " ------------" 00481 << " ------------" 00482 << " ------------" 00483 << " ------------" 00484 << " ------" 00485 << " ------" 00486 << " ------" 00487 << " ------" 00488 << " ----" 00489 << " ------------" 00490 << " ------------" 00491 << " ------------" 00492 << " ------------\n"; 00493 } 00494 00495 } // end namespace MoochoPack
1.7.6.1