MOOCHO (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MoochoPack_MoochoTrackerConsoleStd.cpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization
5 // Copyright (2003) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #include <assert.h>
43 
44 #include <iomanip>
45 
51 #include "Teuchos_dyn_cast.hpp"
52 
53 namespace MoochoPack {
54 
55 using std::endl;
56 using std::setw;
57 using std::left;
58 using std::right;
59 using std::setprecision;
60 
61 // Static members
65 char MoochoTrackerConsoleStd::ul_i4_[] = "----";
68 char MoochoTrackerConsoleStd::ul_p2_[] = "--------";
71 char MoochoTrackerConsoleStd::ul_p3_[] = "---------";
72 
74  const ostream_ptr_t& o
75  ,const ostream_ptr_t& journal_out
76  )
77  :AlgorithmTracker(journal_out)
78  ,o_(o)
79  ,printed_lines_(NUM_PRINT_LINES)
80 {}
81 
82 void MoochoTrackerConsoleStd::set_output_stream(const ostream_ptr_t& o)
83 {
84  o_ = o;
85 }
86 
89 {
90  return o_;
91 }
92 
94 {
95  timer_.reset();
96  timer_.start();
97 }
98 
100 {
101  const NLPAlgo &algo = rsqp_algo(p_algo);
102  const NLPAlgoState &s = algo.rsqp_state();
103  const NLP &nlp = algo.nlp();
104 
105  const size_type
106  m = nlp.m();
107 
108  const int
109  nb = nlp.num_bounded_x();
110 
111  if(s.k() == 0) {
112  print_top_header(s,algo);
114  }
115 
116  // Output the table's header
118  printed_lines_ = 0;
119  print_header(s,algo);
120  }
121 
122  // ///////////////////////////////
123  // Output a row for the iteration
124 
125  // Get a Quasi-Newton statistics.
126  const QuasiNewtonStats *quasi_newt_stats =
127  ( quasi_newton_stats_.exists_in(s) && quasi_newton_stats_(s).updated_k(0)
128  ? &quasi_newton_stats_(s).get_k(0)
129  : NULL );
130 
131  std::ostream& o = this->o();
132 
133  // k
134  o << " " << right << setw(w_i4_) << s.k();
135  // f
136  if( s.f().updated_k(0) )
137  o << " " << setprecision(p3_) << right << setw(w_p3_) << s.f().get_k(0);
138  else
139  o << " " << right << setw(w_p3_) << "-";
140  // ||c||s
141  if( m && s.feas_kkt_err().updated_k(0) )
142  o << " " << setprecision(p3_) << right << setw(w_p3_) << s.feas_kkt_err().get_k(0);
143  else
144  o << " " << right << setw(w_p3_) << "-";
145  // ||rGL||s
146  if( s.opt_kkt_err().updated_k(0) )
147  o << " " << setprecision(p3_) << right << setw(w_p3_) << s.opt_kkt_err().get_k(0);
148  else
149  o << " " << right << setw(w_p3_) << "-";
150  // QN
151  if( quasi_newt_stats ) {
152  o << " " << right << setw(w_i2_);
153  switch( quasi_newt_stats->updated() ) {
155  o << "-";
156  break;
158  o << "IN";
159  break;
161  o << "DU";
162  break;
164  o << "UP";
165  break;
167  o << "SK";
168  break;
170  o << "IS";
171  break;
172  default:
174  }
175  }
176  else {
177  o << " " << right << setw(w_i2_) << "-";
178  }
179  // #act
180  if(nb) {
181  if( s.nu().updated_k(0) )
182  o << " " << right << setw(w_i4_) << s.nu().get_k(0).nz();
183  else
184  o << " " << right << setw(w_i4_) << "-";
185  }
186  // ||Ypy||2
187  if( m && s.Ypy().updated_k(0) )
188  o << " "<< setprecision(p2_) << right << setw(w_p2_) << s.Ypy().get_k(0).norm_2();
189  else
190  o << " " << right << setw(w_p2_) << "-";
191  // ||Zpz||2
192  if( s.Zpz().updated_k(0) )
193  o << " " << setprecision(p2_) << right << setw(w_p2_) << s.Zpz().get_k(0).norm_2();
194  else
195  o << " " << right << setw(w_p2_) << "-";
196  // ||d||inf
197  if( s.d().updated_k(0) )
198  o << " " << setprecision(p2_) << right << setw(w_p2_) << s.d().get_k(0).norm_inf();
199  else
200  o << " " << right << setw(w_p2_) << "-";
201  // alpha
202  if( s.alpha().updated_k(0) )
203  o << " " << setprecision(p2_) << right << setw(w_p2_) << s.alpha().get_k(0);
204  else
205  o << " " << right << setw(w_p2_) << "-";
206  // time(sec)
207  o << " " << setprecision(7) << right << setw(w_p3_) << timer_.read();
208 
209  o << std::endl;
210 
211  ++printed_lines_;
212 }
213 
215  , EAlgoReturn algo_return ) const
216 {
217  using Teuchos::dyn_cast;
218 
219  const NLPAlgo &algo = rsqp_algo(p_algo);
220  const NLPAlgoState &s = algo.rsqp_state();
221  const NLPObjGrad &nlp = dyn_cast<const NLPObjGrad>(algo.nlp());
222  const NLPFirstOrder *nlp_foi = dynamic_cast<const NLPFirstOrder*>(&nlp);
223 
224  const size_type
225  m = nlp.m();
226 
227  const int
228  nb = nlp.num_bounded_x();
229 
230  std::ostream& o = this->o();
231 
232  // Output the table's header for the first iteration
233  if(s.k() == 0) {
234  print_top_header(s,algo);
235  print_header(s,algo);
236  }
237  else {
238  o
239  << " " << right << ul_i4_ // "k"
240  << " " << right << ul_p3_ // "f"
241  << " " << right << ul_p3_ // "||c||s"
242  << " " << right << ul_p3_ // "||rGL||s"
243  << " " << right << ul_i2_ // "QN"
244  ;
245  if(nb)
246  o << " " << right << ul_i4_; // "#act"
247  o << endl;
248  }
249 
250  // //////////////////////////////////////////
251  // Output a row for the final iteration
252 
253  // Get a Quasi-Newton statistics.
254  const QuasiNewtonStats *quasi_newt_stats =
255  ( quasi_newton_stats_.exists_in(s) && quasi_newton_stats_(s).updated_k(0)
256  ? &quasi_newton_stats_(s).get_k(0)
257  : NULL );
258 
259  // k
260  o << " " << right << setw(w_i4_) << s.k();
261  // f
262  if( s.f().updated_k(0) )
263  o << " " << setprecision(p3_) << right << setw(w_p3_) << s.f().get_k(0);
264  else
265  o << " " << right << setw(w_p3_) << "-";
266  // ||c||s
267  if( m && s.feas_kkt_err().updated_k(0) )
268  o << " " << setprecision(p3_) << right << setw(w_p3_) << s.feas_kkt_err().get_k(0);
269  else
270  o << " " << right << setw(w_p3_) << "-";
271  // ||rGL||s
272  if( s.opt_kkt_err().updated_k(0) )
273  o << " " << setprecision(p3_) << right << setw(w_p3_) << s.opt_kkt_err().get_k(0);
274  else
275  o << " " << right << setw(w_p3_) << "-";
276  // QN
277  if( quasi_newt_stats ) {
278  o << " " << right << setw(w_i2_);
279  switch( quasi_newt_stats->updated() ) {
281  o << "-";
282  break;
284  o << "IN";
285  break;
287  o << "DU";
288  break;
290  o << "UP";
291  break;
293  o << "SK";
294  break;
296  o << "IS";
297  break;
298  default:
300  }
301  }
302  else {
303  o << " " << right << setw(w_i2_) << "-";
304  }
305  // #act
306  if(nb) {
307  if( s.nu().updated_k(0) )
308  o << " " << right << setw(w_i4_) << s.nu().get_k(0).nz();
309  else
310  o << " " << right << setw(w_i4_) << "-";
311  }
312  // ||Ypy||2
313  if( m && s.Ypy().updated_k(0) )
314  o << " "<< setprecision(p2_) << right << setw(w_p2_) << s.Ypy().get_k(0).norm_2();
315  else
316  o << " " << right << setw(w_p2_) << "-";
317  // ||Zpz||2
318  if( s.Zpz().updated_k(0) )
319  o << " " << setprecision(p2_) << right << setw(w_p2_) << s.Zpz().get_k(0).norm_2();
320  else
321  o << " " << right << setw(w_p2_) << "-";
322  // ||d||inf
323  if( s.d().updated_k(0) )
324  o << " " << setprecision(p2_) << right << setw(w_p2_) << s.d().get_k(0).norm_inf();
325  else
326  o << " " << right << setw(w_p2_) << "-";
327  // alpha
328  if( s.alpha().updated_k(0) )
329  o << " " << setprecision(p2_) << right << setw(w_p2_) << s.alpha().get_k(0);
330  else
331  o << " " << right << setw(w_p2_) << "-";
332  // time(sec)
333  o << " " << setprecision(7) << right << setw(w_p3_) << timer_.read();
334 
335  o << endl;
336 
337  // Print total time
338  o << setprecision(5) << "\nTotal time = " << timer_.read() << " sec\n";
339 
340  switch( algo_return ) {
342  o << "\nJackpot! You have found the solution!!!!!!\n";
343  break;
345  o << "\nOops! Not the solution. Some error has occured!\n";
346  break;
348  o << "\nOops! Not the solution. Maximum number of SQP iteration exceeded!\n";
349  break;
351  o << "\nOops! Not the solution. Maximum runtime exceeded!\n";
352  break;
354  o << "\nJackpot? The user terminated the algorithm but said to return optimal!!!!!!\n";
355  break;
357  o << "\nOops! Not the solution. The user terminated the algorithm and said to return non-optimal!\n";
358  break;
359  default:
361  }
362 
363  o << "\nNumber of function evaluations:\n"
364  << "-------------------------------\n"
365  << "f(x) : " << nlp.num_f_evals() << endl
366  << "c(x) : " << ( m ? nlp.num_c_evals() : 0 ) << endl
367  << "Gf(x) : " << nlp.num_Gf_evals() << endl
368  << "Gc(x) : ";
369  if(m){
370  if( nlp_foi )
371  o << nlp_foi->num_Gc_evals();
372  else
373  o << "?";
374  }
375  else {
376  o << 0;
377  }
378  o << endl;
379 }
380 
382  , const NLPAlgo &algo) const
383 {
384  std::ostream& o = this->o();
385 
386  NLPAlgoState::space_c_ptr_t
387  space_c = s.get_space_c();
388 
389  o << "\n\n********************************\n"
390  << "*** Start of rSQP Iterations ***\n"
391  << "n = " << s.space_x().dim()
392  << ", m = " << ( space_c.get() ? space_c->dim() : 0 )
393  << ", nz = ";
394  try {
395  if(space_c.get()) {
396  if( s.Gc().updated_k(0) )
397  o << s.Gc().get_k(0).nz() << endl;
398  else
399  o << "?\n";
400  }
401  else {
402  o << 0 << endl;
403  }
404  }
405  catch( const AlgorithmState::DoesNotExist& ) {
406  o << "?\n";
407  }
408  if( algo.nlp().scale_f() != 1.0 ) {
409  o << "f(x) is scaled by : " << algo.nlp().scale_f() << endl;
410  }
411 }
412 
414  , const NLPAlgo &algo) const
415 {
416  std::ostream& o = this->o();
417 
418  const NLP &nlp = algo.nlp();
419 
420  const int
421  nb = nlp.num_bounded_x();
422 
423  o
424  << endl
425  << " " << left << setw(w_i4_) << "k"
426  << " " << left << setw(w_p3_) << "f"
427  << " " << left << setw(w_p3_) << "||c||s"
428  << " " << left << setw(w_p3_) << "||rGL||s"
429  << " " << left << setw(w_i2_) << "QN";
430  if(nb)
431  o << " " << left << setw(w_i4_) << "#act";
432  o
433  << " " << left << setw(w_p2_) << "||Ypy||2"
434  << " " << left << setw(w_p2_) << "||Zpz||2"
435  << " " << left << setw(w_p2_) << "||d||inf"
436  << " " << left << setw(w_p2_) << "alpha"
437  << " " << left << setw(w_p3_) << "time(sec)"
438  << endl
439  << " " << right << ul_i4_ // "k"
440  << " " << right << ul_p3_ // "f"
441  << " " << right << ul_p3_ // "||c||s"
442  << " " << right << ul_p3_ // "||rGL||s"
443  << " " << right << ul_i2_; // "QN"
444  if(nb)
445  o << " " << right << ul_i4_; // "#act"
446  o
447  << " " << right << ul_p2_ // "||Ypy||2"
448  << " " << right << ul_p2_ // "||Zpz||2"
449  << " " << right << ul_p2_ // "||d||inf"
450  << " " << right << ul_p2_ // "alpha"
451  << " " << right << ul_p3_ // "time(s)"
452  << endl;
453 }
454 
455 } // end namespace MoochoPack
void output_iteration(const Algorithm &algo) const
AbstractLinAlgPack::size_type size_type
Class for storing statistics about the Quasi-Newton updating.
void print_top_header(const NLPAlgoState &s, const NLPAlgo &algo) const
Print the top header to the output.
const ostream_ptr_t & get_output_stream() const
Get the output stream for console outputting.
void reset()
Stops and resets the clock if it is running.
rSQP Algorithm control class.
void print_header(const NLPAlgoState &s, const NLPAlgo &algo) const
Print the header to the output.
T_To & dyn_cast(T_From &from)
Reduced space SQP state encapsulation interface.
void start()
Starts timing if it has already not been started.
Acts as the central hub for an iterative algorithm.
NLPAlgoState & rsqp_state()
<<std aggr>="">> members for algo_cntr
void set_output_stream(const ostream_ptr_t &o)
Set the output stream for console outputting.
void output_final(const Algorithm &algo, EAlgoReturn algo_return) const
double read()
Reads the elapsed time (sec.) and leaves the clock running.
NLPAlgo & rsqp_algo(Algorithm &algo)
Convert from a Algorithm to a NLPAlgo.
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)