MOOCHO (Single Doxygen Collection) Version of the Day
NLPInterfacePack_NLPTester.cpp
Go to the documentation of this file.
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 #include <ostream>
00033 
00034 #include "NLPInterfacePack_NLPTester.hpp"
00035 #include "NLPInterfacePack_NLP.hpp"
00036 #include "AbstractLinAlgPack_VectorSpace.hpp"
00037 #include "AbstractLinAlgPack_VectorMutable.hpp"
00038 #include "AbstractLinAlgPack_VectorOut.hpp"
00039 #include "AbstractLinAlgPack_VectorStdOps.hpp"
00040 #include "AbstractLinAlgPack_VectorAuxiliaryOps.hpp"
00041 #include "AbstractLinAlgPack_assert_print_nan_inf.hpp"
00042 #include "TestingHelperPack_update_success.hpp"
00043 
00044 namespace NLPInterfacePack {
00045 
00046 NLPTester::NLPTester(
00047   bool     print_all
00048   ,bool    throw_exception
00049   )
00050   :print_all_(print_all), throw_exception_(throw_exception)
00051 {}
00052 
00053 bool NLPTester::test_interface(
00054   NLP                     *nlp
00055   ,const Vector           &xo
00056   ,bool                   print_all_warnings
00057   ,std::ostream           *out
00058   )
00059 {
00060   using TestingHelperPack::update_success;
00061   using AbstractLinAlgPack::assert_print_nan_inf;
00062 
00063   bool result;
00064   bool success = true;
00065 
00066   if(out) {
00067     *out << std::boolalpha
00068        << std::endl
00069        << "**************************************\n"
00070        << "*** NLPTester::test_interface(...) ***\n"
00071        << "**************************************\n";
00072   }
00073 
00074   try {
00075 
00076     // Initialize the NLP if it has not been already and force in bounds
00077     if(out)
00078       *out << "\nnlp->force_xinit_in_bounds(true)";
00079     nlp->force_xinit_in_bounds();
00080     if(out)
00081       *out << "\nnlp->initialize(true)\n";
00082     nlp->initialize(true);
00083     
00084     const size_type
00085       n = nlp->n(),
00086       m = nlp->m();
00087     if(out)
00088       *out << "\n*** Dimensions of the NLP ...\n"
00089          << "\nnlp->n()  = " << n
00090          << "\nnlp->m()  = " << m
00091          << std::endl;
00092     if( n < m ) {
00093       if(*out)
00094         *out << "Error! n = " << n << " < m = " << m << " is not allowed!\n";
00095       TEST_FOR_EXCEPTION(
00096         throw_exception_, std::logic_error
00097         ,"NLPTester::test_interface(...): Error! n = " << n << " < m = " << m << " is not allowed!"
00098         );
00099     }
00100 
00101     // Validate the vector spaces
00102     if(out)
00103       *out << "\n*** Validate the dimensions of the vector spaces ...\n";
00104     
00105     result = nlp->space_x()->dim() == nlp->n();
00106     update_success( result, &success );
00107     if(out)
00108       *out << "\ncheck: nlp->space_x()->dim() = " << nlp->space_x()->dim()
00109            << " == nlp->n() = " << nlp->n() << ": " << result << std::endl;
00110 
00111     if( nlp->m() ) {
00112       result = nlp->space_c()->dim() == nlp->m();
00113       update_success( result, &success );
00114       if(out)
00115         *out << "\ncheck: nlp->space_c()->dim() = " << nlp->space_c()->dim()
00116              << " == nlp->m() = " << nlp->m() << ": " << result << std::endl;
00117     }
00118     else {
00119       result = nlp->space_c().get() == NULL;
00120       update_success( result, &success );
00121       if(out)
00122         *out << "\ncheck: nlp->space_c().get() = " << nlp->space_c().get()
00123              << " == NULL: " << result << std::endl;
00124     }
00125 
00126     // Validate the initial guess the bounds on the unknowns.
00127     if(out)
00128       *out << "\n*** Validate that the initial starting point is in bounds ...\n";
00129     const Vector &xinit = nlp->xinit();
00130     if(out) *out << "\n||nlp->xinit()||inf = " << xinit.norm_inf() << std::endl;
00131     if(out && print_all()) *out << "\nnlp->xinit() =\n" << xinit;
00132     assert_print_nan_inf(xinit,"xinit",true,out); 
00133     const Vector
00134       &xl = nlp->xl(),
00135       &xu = nlp->xu();
00136     if(out && print_all())
00137       *out << "\nnlp->xl() =\n" << xl
00138          << "\nnlp->xu() =\n" << xu;
00139     assert_print_nan_inf(xl,"xl",true,out); 
00140     assert_print_nan_inf(xu,"xu",true,out); 
00141 
00142     // Validate that xl <= xinit <= xu.
00143     VectorSpace::vec_mut_ptr_t
00144       d = nlp->space_x()->create_member();
00145     *d = 1.0;
00146     std::pair<value_type,value_type>
00147       u = AbstractLinAlgPack::max_near_feas_step(
00148         xinit, *d, nlp->xl(), nlp->xu(), 0.0
00149         );
00150     result = u.first >= 0.0;
00151     update_success( result, &success );
00152     if(out) {
00153       *out << "\ncheck: xl <= x <= xu : " << result;
00154       if(result)
00155         *out << "\nxinit is in bounds with { max |u| | xl <= x + u <= xu } -> "
00156            << ( u.first > -u.second ? u.first : u.second  ) << std::endl;
00157     }
00158     size_type 
00159       num_bounded_x = AbstractLinAlgPack::num_bounded(
00160         nlp->xl(), nlp->xu(), NLP::infinite_bound()
00161         );
00162     result = (num_bounded_x == nlp->num_bounded_x());
00163     update_success( result, &success );
00164     if(out)
00165       *out << "\ncheck: num_bounded(nlp->xl(),nlp->xu()) = " << num_bounded_x
00166          << " == nlp->num_bounded_x() = " << nlp->num_bounded_x()
00167          << ": " << result << std::endl;
00168 
00169     // Get the initial Lagrange multipliers
00170     if(out)
00171       *out << "\nGetting the initial estimates for the Lagrange mutipliers ...\n";
00172     VectorSpace::vec_mut_ptr_t  lambda, nu;
00173     nlp->get_init_lagrange_mult(
00174       (  nlp->m()
00175          ? (lambda  = nlp->space_c()->create_member()).get() 
00176          : (VectorMutable*)NULL )
00177       ,( nlp->num_bounded_x()
00178          ? (nu = nlp->space_x()->create_member()).get()
00179          : (VectorMutable*)NULL )
00180       );
00181 
00182     if(out) {
00183       if(lambda.get())
00184         *out << "\n||lambda||inf  = " << lambda->norm_inf();
00185       if(nu.get())
00186         *out << "\n||nu||inf      = " << nu->norm_inf()
00187            << "\nnu.nz()        = " << nu->nz();
00188       *out << std::endl;
00189       if(print_all()) {
00190         if(lambda.get())
00191           *out << "\nlambda =\n" << *lambda;
00192         if(nu.get())
00193           *out << "\nnu =\n" << *nu;
00194       }
00195     }
00196     if(lambda.get())
00197       assert_print_nan_inf(*lambda,"lambda",true,out); 
00198     if(nu.get())
00199       assert_print_nan_inf(*nu,"nu",true,out); 
00200 
00201     // Save the current reference that are set to be set back at the end
00202     value_type      *f_saved = NULL;
00203     VectorMutable   *c_saved = NULL;
00204     f_saved = nlp->get_f();
00205     if( nlp->m() )  c_saved = nlp->get_c();
00206 
00207     // Create calcualtion quantities
00208     value_type                   f;
00209     VectorSpace::vec_mut_ptr_t   c;
00210     if( nlp->m() )
00211       c = nlp->space_c()->create_member();
00212 
00213     // Set the calculation quantities
00214     nlp->set_f(&f);
00215     if( nlp->m() )  nlp->set_c(c.get());
00216 
00217     // Calculate the quantities at xo
00218 
00219     if(out)
00220       *out << "\n*** Evaluate the point xo ...\n";
00221 
00222     if(out) *out << "\n||xo||inf = " << xo.norm_inf() << std::endl;
00223     if(out && print_all()) *out << "\nxo =\n" << xo;
00224     assert_print_nan_inf(xo,"xo",true,out); 
00225 
00226     nlp->calc_f(xo,true);
00227     if(nlp->m())  nlp->calc_c(xo,false);
00228 
00229     if(out) {
00230       *out << "\nf(xo) = " << f;
00231       if(nlp->m())
00232         *out << "\n||c(xo)||inf = " << nlp->c().norm_inf();
00233       *out << std::endl;
00234       if(print_all()) {
00235         if(nlp->m())
00236           *out << "\nc(xo) =\n" << nlp->c();
00237       }
00238     }
00239 
00240     if(c.get())
00241       assert_print_nan_inf(*c,"c(xo)",true,out); 
00242 
00243     // Report the final solution!
00244     if(out)
00245       *out << "\n*** Report this point to the NLP as suboptimal ...\n";
00246     nlp->report_final_solution( xo, lambda.get(), nu.get(), false );
00247 
00248     // Print the number of evaluations!
00249     if(out) {
00250       *out << "\n*** Print the number of evaluations ...\n";
00251       *out << "\nnlp->num_f_evals() = " << nlp->num_f_evals();
00252       if(nlp->m())
00253         *out << "\nnlp->num_c_evals() = " << nlp->num_c_evals();
00254       *out << std::endl;
00255     }
00256 
00257     // Set the original quantities back
00258     nlp->set_f(f_saved);
00259     if(nlp->m())  nlp->set_c(c_saved);
00260 
00261   }
00262   catch(const std::exception& except) {
00263     if(out)
00264       *out << "Caught a std::exception: " << except.what() << std::endl;
00265     success = false;
00266     if(throw_exception())
00267       throw;
00268   }
00269   catch(...) {
00270     if(out)
00271       *out << "Caught an unknown exception!\n";
00272     success = false;
00273     if(throw_exception())
00274       throw;
00275   }
00276 
00277   return success;
00278 }
00279 
00280 } // namespace NLPInterfacePack
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines