MOOCHO (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NLPInterfacePack_NLPTester.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 #include <ostream>
46 
48 #include "NLPInterfacePack_NLP.hpp"
56 
57 namespace NLPInterfacePack {
58 
60  bool print_all
61  ,bool throw_exception
62  )
63  :print_all_(print_all), throw_exception_(throw_exception)
64 {}
65 
67  NLP *nlp
68  ,const Vector &xo
69  ,bool print_all_warnings
70  ,std::ostream *out
71  )
72 {
75 
76  bool result;
77  bool success = true;
78 
79  if(out) {
80  *out << std::boolalpha
81  << std::endl
82  << "**************************************\n"
83  << "*** NLPTester::test_interface(...) ***\n"
84  << "**************************************\n";
85  }
86 
87  try {
88 
89  // Initialize the NLP if it has not been already and force in bounds
90  if(out)
91  *out << "\nnlp->force_xinit_in_bounds(true)";
92  nlp->force_xinit_in_bounds();
93  if(out)
94  *out << "\nnlp->initialize(true)\n";
95  nlp->initialize(true);
96 
97  const size_type
98  n = nlp->n(),
99  m = nlp->m();
100  if(out)
101  *out << "\n*** Dimensions of the NLP ...\n"
102  << "\nnlp->n() = " << n
103  << "\nnlp->m() = " << m
104  << std::endl;
105  if( n < m ) {
106  if(*out)
107  *out << "Error! n = " << n << " < m = " << m << " is not allowed!\n";
109  throw_exception_, std::logic_error
110  ,"NLPTester::test_interface(...): Error! n = " << n << " < m = " << m << " is not allowed!"
111  );
112  }
113 
114  // Validate the vector spaces
115  if(out)
116  *out << "\n*** Validate the dimensions of the vector spaces ...\n";
117 
118  result = nlp->space_x()->dim() == nlp->n();
119  update_success( result, &success );
120  if(out)
121  *out << "\ncheck: nlp->space_x()->dim() = " << nlp->space_x()->dim()
122  << " == nlp->n() = " << nlp->n() << ": " << result << std::endl;
123 
124  if( nlp->m() ) {
125  result = nlp->space_c()->dim() == nlp->m();
126  update_success( result, &success );
127  if(out)
128  *out << "\ncheck: nlp->space_c()->dim() = " << nlp->space_c()->dim()
129  << " == nlp->m() = " << nlp->m() << ": " << result << std::endl;
130  }
131  else {
132  result = nlp->space_c().get() == NULL;
133  update_success( result, &success );
134  if(out)
135  *out << "\ncheck: nlp->space_c().get() = " << nlp->space_c().get()
136  << " == NULL: " << result << std::endl;
137  }
138 
139  // Validate the initial guess the bounds on the unknowns.
140  if(out)
141  *out << "\n*** Validate that the initial starting point is in bounds ...\n";
142  const Vector &xinit = nlp->xinit();
143  if(out) *out << "\n||nlp->xinit()||inf = " << xinit.norm_inf() << std::endl;
144  if(out && print_all()) *out << "\nnlp->xinit() =\n" << xinit;
145  assert_print_nan_inf(xinit,"xinit",true,out);
146  const Vector
147  &xl = nlp->xl(),
148  &xu = nlp->xu();
149  if(out && print_all())
150  *out << "\nnlp->xl() =\n" << xl
151  << "\nnlp->xu() =\n" << xu;
152  assert_print_nan_inf(xl,"xl",true,out);
153  assert_print_nan_inf(xu,"xu",true,out);
154 
155  // Validate that xl <= xinit <= xu.
156  VectorSpace::vec_mut_ptr_t
157  d = nlp->space_x()->create_member();
158  *d = 1.0;
159  std::pair<value_type,value_type>
161  xinit, *d, nlp->xl(), nlp->xu(), 0.0
162  );
163  result = u.first >= 0.0;
164  update_success( result, &success );
165  if(out) {
166  *out << "\ncheck: xl <= x <= xu : " << result;
167  if(result)
168  *out << "\nxinit is in bounds with { max |u| | xl <= x + u <= xu } -> "
169  << ( u.first > -u.second ? u.first : u.second ) << std::endl;
170  }
171  size_type
172  num_bounded_x = AbstractLinAlgPack::num_bounded(
173  nlp->xl(), nlp->xu(), NLP::infinite_bound()
174  );
175  result = (num_bounded_x == nlp->num_bounded_x());
176  update_success( result, &success );
177  if(out)
178  *out << "\ncheck: num_bounded(nlp->xl(),nlp->xu()) = " << num_bounded_x
179  << " == nlp->num_bounded_x() = " << nlp->num_bounded_x()
180  << ": " << result << std::endl;
181 
182  // Get the initial Lagrange multipliers
183  if(out)
184  *out << "\nGetting the initial estimates for the Lagrange mutipliers ...\n";
185  VectorSpace::vec_mut_ptr_t lambda, nu;
187  ( nlp->m()
188  ? (lambda = nlp->space_c()->create_member()).get()
189  : (VectorMutable*)NULL )
190  ,( nlp->num_bounded_x()
191  ? (nu = nlp->space_x()->create_member()).get()
192  : (VectorMutable*)NULL )
193  );
194 
195  if(out) {
196  if(lambda.get())
197  *out << "\n||lambda||inf = " << lambda->norm_inf();
198  if(nu.get())
199  *out << "\n||nu||inf = " << nu->norm_inf()
200  << "\nnu.nz() = " << nu->nz();
201  *out << std::endl;
202  if(print_all()) {
203  if(lambda.get())
204  *out << "\nlambda =\n" << *lambda;
205  if(nu.get())
206  *out << "\nnu =\n" << *nu;
207  }
208  }
209  if(lambda.get())
210  assert_print_nan_inf(*lambda,"lambda",true,out);
211  if(nu.get())
212  assert_print_nan_inf(*nu,"nu",true,out);
213 
214  // Save the current reference that are set to be set back at the end
215  value_type *f_saved = NULL;
216  VectorMutable *c_saved = NULL;
217  f_saved = nlp->get_f();
218  if( nlp->m() ) c_saved = nlp->get_c();
219 
220  // Create calcualtion quantities
221  value_type f;
222  VectorSpace::vec_mut_ptr_t c;
223  if( nlp->m() )
224  c = nlp->space_c()->create_member();
225 
226  // Set the calculation quantities
227  nlp->set_f(&f);
228  if( nlp->m() ) nlp->set_c(c.get());
229 
230  // Calculate the quantities at xo
231 
232  if(out)
233  *out << "\n*** Evaluate the point xo ...\n";
234 
235  if(out) *out << "\n||xo||inf = " << xo.norm_inf() << std::endl;
236  if(out && print_all()) *out << "\nxo =\n" << xo;
237  assert_print_nan_inf(xo,"xo",true,out);
238 
239  nlp->calc_f(xo,true);
240  if(nlp->m()) nlp->calc_c(xo,false);
241 
242  if(out) {
243  *out << "\nf(xo) = " << f;
244  if(nlp->m())
245  *out << "\n||c(xo)||inf = " << nlp->c().norm_inf();
246  *out << std::endl;
247  if(print_all()) {
248  if(nlp->m())
249  *out << "\nc(xo) =\n" << nlp->c();
250  }
251  }
252 
253  if(c.get())
254  assert_print_nan_inf(*c,"c(xo)",true,out);
255 
256  // Report the final solution!
257  if(out)
258  *out << "\n*** Report this point to the NLP as suboptimal ...\n";
259  nlp->report_final_solution( xo, lambda.get(), nu.get(), false );
260 
261  // Print the number of evaluations!
262  if(out) {
263  *out << "\n*** Print the number of evaluations ...\n";
264  *out << "\nnlp->num_f_evals() = " << nlp->num_f_evals();
265  if(nlp->m())
266  *out << "\nnlp->num_c_evals() = " << nlp->num_c_evals();
267  *out << std::endl;
268  }
269 
270  // Set the original quantities back
271  nlp->set_f(f_saved);
272  if(nlp->m()) nlp->set_c(c_saved);
273 
274  }
275  catch(const std::exception& except) {
276  if(out)
277  *out << "Caught a std::exception: " << except.what() << std::endl;
278  success = false;
279  if(throw_exception())
280  throw;
281  }
282  catch(...) {
283  if(out)
284  *out << "Caught an unknown exception!\n";
285  success = false;
286  if(throw_exception())
287  throw;
288  }
289 
290  return success;
291 }
292 
293 } // namespace NLPInterfacePack
AbstractLinAlgPack::size_type size_type
virtual void calc_c(const Vector &x, bool newx=true) const
Update the constraint residual vector for c at the point x and put it in the stored reference...
void f()
virtual void report_final_solution(const Vector &x, const Vector *lambda, const Vector *nu, bool is_optimal)
Used by the solver to report the final solution and multipliers.
bool test_interface(NLP *nlp, const Vector &xo, bool print_all_warnings, std::ostream *out)
Test the NLP interface as the given base point xo.
virtual size_type num_c_evals() const
Gives the number of constraint function c(x) evaluations called by the solver since initialize() was ...
virtual value_type norm_inf() const
Infinity norm. ||v||_inf = max( |v(i)|, i = 1,,,this->dim() )
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
virtual void get_init_lagrange_mult(VectorMutable *lambda, VectorMutable *nu) const
Get the initial value of the Lagrange multipliers lambda.
AbstractLinAlgPack::VectorSpace * space_c
AbstractLinAlgPack::VectorSpace * space_x
virtual void calc_f(const Vector &x, bool newx=true) const
Update the value for the objective f at the point x and put it in the stored reference.
virtual size_type n() const
Return the number of variables.
virtual const Vector & xl() const =0
Returns the lower bounds on the variables x.
std::ostream * out
virtual size_type num_bounded_x() const =0
Returns the number of variables in x(i) for which xl(i)> -infinite_bound() or xu(i) < +infinite_bound...
virtual void set_c(VectorMutable *c)
Set a pointer to a vector to be updated when this->calc_c() is called.
virtual const Vector & xu() const =0
Returns a reference to the vector of upper bounds on the variables x.
virtual value_type * get_f()
Return pointer passed to this->set_f().
size_type num_bounded(const Vector &xl, const Vector &xu, value_type inf_bound)
Count the number of finitly bounded elements in xl <= x <= xu.
bool assert_print_nan_inf(const value_type &val, const char name[], bool throw_excpt, std::ostream *out)
This function asserts if a value_type scalare is a NaN or Inf and optionally prints out these entires...
virtual void force_xinit_in_bounds(bool force_xinit_in_bounds)=0
Set if the initial point must be within the bounds.
NLP interface class {abstract}.
NLPTester(bool print_all=false, bool throw_exception=true)
Constructor (default options)
virtual index_type dim() const =0
Return the dimmension of the vector space.
std::pair< value_type, value_type > max_near_feas_step(const Vector &x, const Vector &d, const Vector &xl, const Vector &xu, value_type max_bnd_viol)
Computes the maximum positive and negative step that can be taken that are within the relaxed bounds...
AbstractLinAlgPack::value_type value_type
bool update_success(bool result_check, bool *success)
Helper function for updating a flag for if an operation returned false.
virtual vec_mut_ptr_t create_member() const =0
Create a vector member from the vector space.
virtual const Vector & xinit() const =0
Returns a reference to the vector of the initial guess for the solution x.
virtual size_type m() const
Return the number of general equality constraints.
virtual void initialize(bool test_setup=false)
Initialize the NLP before it is used.
virtual size_type num_f_evals() const
Gives the number of object function f(x) evaluations called by the solver since initialize() was call...
static value_type infinite_bound()
Value for an infinite bound.
int n
virtual VectorMutable * get_c()
Return pointer passed to this->set_c().
virtual void set_f(value_type *f)
Set a pointer to an value to be updated when this->calc_f() is called.
const f_int f_dbl_prec const f_int f_int const f_int f_int const f_dbl_prec & u
virtual VectorMutable & c()
Returns non-const *this->get_c().