|
NLPInterfacePack: C++ Interfaces and Implementation for Non-Linear Programs 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 #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
1.7.4