|
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 #include <math.h> 00031 00032 #include <ostream> 00033 #include <iomanip> 00034 #include <sstream> 00035 #include <limits> 00036 00037 #include "NLPInterfacePack_NLPDirectTester.hpp" 00038 #include "NLPInterfacePack_NLPDirect.hpp" 00039 #include "AbstractLinAlgPack_VectorMutable.hpp" 00040 #include "AbstractLinAlgPack_VectorOut.hpp" 00041 #include "AbstractLinAlgPack_VectorSpace.hpp" 00042 #include "AbstractLinAlgPack_VectorStdOps.hpp" 00043 #include "AbstractLinAlgPack_LinAlgOpPack.hpp" 00044 #include "AbstractLinAlgPack_LinAlgOpPack.hpp" 00045 #include "AbstractLinAlgPack_assert_print_nan_inf.hpp" 00046 #include "TestingHelperPack_update_success.hpp" 00047 #include "Teuchos_TestForException.hpp" 00048 00049 namespace { 00050 template< class T > 00051 inline 00052 T my_max( const T& v1, const T& v2 ) { return v1 > v2 ? v1 : v2; } 00053 } // end namespace 00054 00055 namespace NLPInterfacePack { 00056 00057 NLPDirectTester::NLPDirectTester( 00058 const calc_fd_prod_ptr_t &calc_fd_prod 00059 ,ETestingMethod Gf_testing_method 00060 ,ETestingMethod Gc_testing_method 00061 ,value_type Gf_warning_tol 00062 ,value_type Gf_error_tol 00063 ,value_type Gc_warning_tol 00064 ,value_type Gc_error_tol 00065 ,size_type num_fd_directions 00066 ,bool dump_all 00067 ) 00068 :calc_fd_prod_(calc_fd_prod) 00069 ,Gf_testing_method_(Gf_testing_method) 00070 ,Gc_testing_method_(Gc_testing_method) 00071 ,Gf_warning_tol_(Gf_warning_tol) 00072 ,Gf_error_tol_(Gf_error_tol) 00073 ,Gc_warning_tol_(Gc_warning_tol) 00074 ,Gc_error_tol_(Gc_error_tol) 00075 ,num_fd_directions_(num_fd_directions) 00076 ,dump_all_(dump_all) 00077 { 00078 if(calc_fd_prod_ == Teuchos::null) 00079 calc_fd_prod_ = Teuchos::rcp(new CalcFiniteDiffProd()); 00080 } 00081 00082 bool NLPDirectTester::finite_diff_check( 00083 NLPDirect *nlp 00084 ,const Vector &xo 00085 ,const Vector *xl 00086 ,const Vector *xu 00087 ,const Vector *c 00088 ,const Vector *Gf 00089 ,const Vector *py 00090 ,const Vector *rGf 00091 ,const MatrixOp *GcU 00092 ,const MatrixOp *D 00093 ,const MatrixOp *Uz 00094 ,bool print_all_warnings 00095 ,std::ostream *out 00096 ) const 00097 { 00098 00099 using std::setw; 00100 using std::endl; 00101 using std::right; 00102 00103 using AbstractLinAlgPack::sum; 00104 using AbstractLinAlgPack::dot; 00105 using AbstractLinAlgPack::Vp_StV; 00106 using AbstractLinAlgPack::random_vector; 00107 using AbstractLinAlgPack::assert_print_nan_inf; 00108 using LinAlgOpPack::V_StV; 00109 using LinAlgOpPack::V_StMtV; 00110 using LinAlgOpPack::Vp_MtV; 00111 using LinAlgOpPack::M_StM; 00112 using LinAlgOpPack::M_StMtM; 00113 00114 typedef VectorSpace::vec_mut_ptr_t vec_mut_ptr_t; 00115 00116 // using AbstractLinAlgPack::TestingPack::CompareDenseVectors; 00117 // using AbstractLinAlgPack::TestingPack::CompareDenseSparseMatrices; 00118 00119 using TestingHelperPack::update_success; 00120 00121 bool success = true, preformed_fd; 00122 if(out) { 00123 *out << std::boolalpha 00124 << std::endl 00125 << "*********************************************************\n" 00126 << "*** NLPDirectTester::finite_diff_check(...) ***\n" 00127 << "*********************************************************\n"; 00128 } 00129 00130 const Range1D 00131 var_dep = nlp->var_dep(), 00132 var_indep = nlp->var_indep(), 00133 con_decomp = nlp->con_decomp(), 00134 con_undecomp = nlp->con_undecomp(); 00135 NLP::vec_space_ptr_t 00136 space_x = nlp->space_x(), 00137 space_c = nlp->space_c(); 00138 00139 // ////////////////////////////////////////////// 00140 // Validate the input 00141 00142 TEST_FOR_EXCEPTION( 00143 py && !c, std::invalid_argument 00144 ,"NLPDirectTester::finite_diff_check(...) : " 00145 "Error, if py!=NULL then c!=NULL must also be true!" ); 00146 00147 const CalcFiniteDiffProd 00148 &fd_deriv_prod = this->calc_fd_prod(); 00149 00150 const value_type 00151 rand_y_l = -1.0, rand_y_u = 1.0, 00152 small_num = ::sqrt(std::numeric_limits<value_type>::epsilon()); 00153 00154 try { 00155 00156 // /////////////////////////////////////////////// 00157 // (1) Check Gf 00158 00159 if(Gf) { 00160 switch( Gf_testing_method() ) { 00161 case FD_COMPUTE_ALL: { 00162 // Compute FDGf outright 00163 TEST_FOR_EXCEPT(true); // ToDo: update above! 00164 break; 00165 } 00166 case FD_DIRECTIONAL: { 00167 // Compute FDGF'*y using random y's 00168 if(out) 00169 *out 00170 << "\nComparing products Gf'*y with finite difference values FDGf'*y for " 00171 << "random y's ...\n"; 00172 vec_mut_ptr_t y = space_x->create_member(); 00173 value_type max_warning_viol = 0.0; 00174 int num_warning_viol = 0; 00175 const int num_fd_directions_used = ( num_fd_directions() > 0 ? num_fd_directions() : 1 ); 00176 for( int direc_i = 1; direc_i <= num_fd_directions_used; ++direc_i ) { 00177 if( num_fd_directions() > 0 ) { 00178 random_vector( rand_y_l, rand_y_u, y.get() ); 00179 if(out) 00180 *out 00181 << "\n****" 00182 << "\n**** Random directional vector " << direc_i << " ( ||y||_1 / n = " 00183 << (y->norm_1() / y->dim()) << " )" 00184 << "\n***\n"; 00185 } 00186 else { 00187 *y = 1.0; 00188 if(out) 00189 *out 00190 << "\n****" 00191 << "\n**** Ones vector y ( ||y||_1 / n = "<<(y->norm_1()/y->dim())<<" )" 00192 << "\n***\n"; 00193 } 00194 value_type 00195 Gf_y = dot( *Gf, *y ), 00196 FDGf_y; 00197 preformed_fd = fd_deriv_prod.calc_deriv_product( 00198 xo,xl,xu 00199 ,*y,NULL,NULL,true,nlp,&FDGf_y,NULL,out,dump_all(),dump_all() 00200 ); 00201 if( !preformed_fd ) 00202 goto FD_NOT_PREFORMED; 00203 assert_print_nan_inf(FDGf_y, "FDGf'*y",true,out); 00204 const value_type 00205 calc_err = ::fabs( ( Gf_y - FDGf_y )/( ::fabs(Gf_y) + ::fabs(FDGf_y) + small_num ) ); 00206 if( calc_err >= Gf_warning_tol() ) { 00207 max_warning_viol = my_max( max_warning_viol, calc_err ); 00208 ++num_warning_viol; 00209 } 00210 if(out) 00211 *out 00212 << "\nrel_err(Gf'*y,FDGf'*y) = " 00213 << "rel_err(" << Gf_y << "," << FDGf_y << ") = " 00214 << calc_err << endl; 00215 if( calc_err >= Gf_error_tol() ) { 00216 if(out) { 00217 *out 00218 << "Error, above relative error exceeded Gf_error_tol = " << Gf_error_tol() << endl; 00219 if(dump_all()) { 00220 *out << "\ny =\n" << *y; 00221 } 00222 } 00223 } 00224 } 00225 if(out && num_warning_viol) 00226 *out 00227 << "\nThere were " << num_warning_viol << " warning tolerance " 00228 << "violations out of num_fd_directions = " << num_fd_directions() 00229 << " computations of FDGf'*y\n" 00230 << "and the maximum violation was " << max_warning_viol 00231 << " > Gf_waring_tol = " << Gf_warning_tol() << endl; 00232 break; 00233 } 00234 default: 00235 TEST_FOR_EXCEPT(true); // Invalid value 00236 } 00237 } 00238 00239 // ///////////////////////////////////////////// 00240 // (2) Check py = -inv(C)*c 00241 // 00242 // We want to check; 00243 // 00244 // FDC * (inv(C)*c) \approx c 00245 // \_________/ 00246 // -py 00247 // 00248 // We can compute this as: 00249 // 00250 // FDC * py = [ FDC, FDN ] * [ -py ; 0 ] 00251 // \__________/ 00252 // FDA' 00253 // 00254 // t1 = [ -py ; 0 ] 00255 // 00256 // t2 = FDA'*t1 00257 // 00258 // Compare t2 \approx c 00259 // 00260 if(py) { 00261 if(out) 00262 *out 00263 << "\nComparing c with finite difference product FDA'*[ -py; 0 ] = -FDC*py ...\n"; 00264 // t1 = [ -py ; 0 ] 00265 VectorSpace::vec_mut_ptr_t 00266 t1 = space_x->create_member(); 00267 V_StV( t1->sub_view(var_dep).get(), -1.0, *py ); 00268 *t1->sub_view(var_indep) = 0.0; 00269 // t2 = FDA'*t1 00270 VectorSpace::vec_mut_ptr_t 00271 t2 = nlp->space_c()->create_member(); 00272 preformed_fd = fd_deriv_prod.calc_deriv_product( 00273 xo,xl,xu 00274 ,*t1,NULL,NULL,true,nlp,NULL,t2.get(),out,dump_all(),dump_all() 00275 ); 00276 if( !preformed_fd ) 00277 goto FD_NOT_PREFORMED; 00278 const value_type 00279 sum_c = sum(*c), 00280 sum_t2 = sum(*t2); 00281 assert_print_nan_inf(sum_t2, "sum(-FDC*py)",true,out); 00282 const value_type 00283 calc_err = ::fabs( ( sum_c - sum_t2 )/( ::fabs(sum_c) + ::fabs(sum_t2) + small_num ) ); 00284 if(out) 00285 *out 00286 << "\nrel_err(sum(c),sum(-FDC*py)) = " 00287 << "rel_err(" << sum_c << "," << sum_t2 << ") = " 00288 << calc_err << endl; 00289 if( calc_err >= Gc_error_tol() ) { 00290 if(out) 00291 *out 00292 << "Error, above relative error exceeded Gc_error_tol = " << Gc_error_tol() << endl; 00293 if(print_all_warnings) 00294 *out << "\nt1 = [ -py; 0 ] =\n" << *t1 00295 << "\nt2 = FDA'*t1 = -FDC*py =\n" << *t2; 00296 update_success( false, &success ); 00297 } 00298 if( calc_err >= Gc_warning_tol() ) { 00299 if(out) 00300 *out 00301 << "\nWarning, above relative error exceeded Gc_warning_tol = " << Gc_warning_tol() << endl; 00302 } 00303 } 00304 00305 // ///////////////////////////////////////////// 00306 // (3) Check D = -inv(C)*N 00307 00308 if(D) { 00309 switch( Gc_testing_method() ) { 00310 case FD_COMPUTE_ALL: { 00311 // 00312 // Compute FDN outright and check 00313 // -FDC * D \aprox FDN 00314 // 00315 // We want to compute: 00316 // 00317 // FDC * -D = [ FDC, FDN ] * [ -D; 0 ] 00318 // \__________/ 00319 // FDA' 00320 // 00321 // To compute the above we perform: 00322 // 00323 // T = FDA' * [ -D; 0 ] (one column at a time) 00324 // 00325 // Compare T \approx FDN 00326 // 00327 /* 00328 // FDN 00329 DMatrix FDN(m,n-m); 00330 fd_deriv_computer.calc_deriv( xo, xl, xu 00331 , Range1D(m+1,n), nlp, NULL 00332 , &FDN() ,BLAS_Cpp::trans, out ); 00333 00334 // T = FDA' * [ -D; 0 ] (one column at a time) 00335 DMatrix T(m,n-m); 00336 DVector t(n); 00337 t(m+1,n) = 0.0; 00338 for( int s = 1; s <= n-m; ++s ) { 00339 // t = [ -D(:,s); 0 ] 00340 V_StV( &t(1,m), -1.0, D->col(s) ); 00341 // T(:,s) = FDA' * t 00342 fd_deriv_prod.calc_deriv_product( 00343 xo,xl,xu,t(),NULL,NULL,nlp,NULL,&T.col(s),out); 00344 } 00345 00346 // Compare T \approx FDN 00347 if(out) 00348 *out 00349 << "\nChecking the computed D = -inv(C)*N\n" 00350 << "where D(i,j) = (-FDC*D)(i,j), dM(i,j) = FDN(i,j) ...\n"; 00351 result = comp_M.comp( 00352 T(), FDN, BLAS_Cpp::no_trans 00353 , CompareDenseSparseMatrices::FULL_MATRIX 00354 , CompareDenseSparseMatrices::REL_ERR_BY_COL 00355 , Gc_warning_tol(), Gc_error_tol() 00356 , print_all_warnings, out ); 00357 update_success( result, &success ); 00358 if(!result) return false; 00359 */ 00360 TEST_FOR_EXCEPT(true); // Todo: Implement above! 00361 break; 00362 } 00363 case FD_DIRECTIONAL: { 00364 // 00365 // Compute -FDC * D * v \aprox FDN * v 00366 // for random v's 00367 // 00368 // We will compute this as: 00369 // 00370 // t1 = [ 0; y ] <: R^(n) 00371 // 00372 // t2 = FDA' * t1 ( FDN * y ) <: R^(m) 00373 // 00374 // t1 = [ -D * y ; 0 ] <: R^(n) 00375 // 00376 // t3 = FDA' * t1 ( -FDC * D * y ) <: R^(m) 00377 // 00378 // Compare t2 \approx t3 00379 // 00380 if(out) 00381 *out 00382 << "\nComparing finite difference products -FDC*D*y with FDN*y for " 00383 "random vectors y ...\n"; 00384 VectorSpace::vec_mut_ptr_t 00385 y = space_x->sub_space(var_indep)->create_member(), 00386 t1 = space_x->create_member(), 00387 t2 = space_c->create_member(), 00388 t3 = space_c->create_member(); 00389 value_type max_warning_viol = 0.0; 00390 int num_warning_viol = 0; 00391 const int num_fd_directions_used = ( num_fd_directions() > 0 ? num_fd_directions() : 1 ); 00392 for( int direc_i = 1; direc_i <= num_fd_directions_used; ++direc_i ) { 00393 if( num_fd_directions() > 0 ) { 00394 random_vector( rand_y_l, rand_y_u, y.get() ); 00395 if(out) 00396 *out 00397 << "\n****" 00398 << "\n**** Random directional vector " << direc_i << " ( ||y||_1 / n = " 00399 << (y->norm_1() / y->dim()) << " )" 00400 << "\n***\n"; 00401 } 00402 else { 00403 *y = 1.0; 00404 if(out) 00405 *out 00406 << "\n****" 00407 << "\n**** Ones vector y ( ||y||_1 / n = "<<(y->norm_1()/y->dim())<<" )" 00408 << "\n***\n"; 00409 } 00410 // t1 = [ 0; y ] <: R^(n) 00411 *t1->sub_view(var_dep) = 0.0; 00412 *t1->sub_view(var_indep) = *y; 00413 // t2 = FDA' * t1 ( FDN * y ) <: R^(m) 00414 preformed_fd = fd_deriv_prod.calc_deriv_product( 00415 xo,xl,xu 00416 ,*t1,NULL,NULL,true,nlp,NULL,t2.get(),out,dump_all(),dump_all() 00417 ); 00418 if( !preformed_fd ) 00419 goto FD_NOT_PREFORMED; 00420 // t1 = [ -D * y ; 0 ] <: R^(n) 00421 V_StMtV( t1->sub_view(var_dep).get(), -1.0, *D, BLAS_Cpp::no_trans, *y ); 00422 *t1->sub_view(var_indep) = 0.0; 00423 // t3 = FDA' * t1 ( -FDC * D * y ) <: R^(m) 00424 preformed_fd = fd_deriv_prod.calc_deriv_product( 00425 xo,xl,xu 00426 ,*t1,NULL,NULL,true,nlp,NULL,t3.get(),out,dump_all(),dump_all() 00427 ); 00428 // Compare t2 \approx t3 00429 const value_type 00430 sum_t2 = sum(*t2), 00431 sum_t3 = sum(*t3); 00432 const value_type 00433 calc_err = ::fabs( ( sum_t2 - sum_t3 )/( ::fabs(sum_t2) + ::fabs(sum_t3) + small_num ) ); 00434 if(out) 00435 *out 00436 << "\nrel_err(sum(-FDC*D*y),sum(FDN*y)) = " 00437 << "rel_err(" << sum_t3 << "," << sum_t2 << ") = " 00438 << calc_err << endl; 00439 if( calc_err >= Gc_warning_tol() ) { 00440 max_warning_viol = my_max( max_warning_viol, calc_err ); 00441 ++num_warning_viol; 00442 } 00443 if( calc_err >= Gc_error_tol() ) { 00444 if(out) 00445 *out 00446 << "Error, above relative error exceeded Gc_error_tol = " << Gc_error_tol() << endl 00447 << "Stoping the tests!\n"; 00448 if(print_all_warnings) 00449 *out << "\ny =\n" << *y 00450 << "\nt1 = [ -D*y; 0 ] =\n" << *t1 00451 << "\nt2 = FDA' * [ 0; y ] = FDN * y =\n" << *t2 00452 << "\nt3 = FDA' * t1 = -FDC * D * y =\n" << *t3; 00453 update_success( false, &success ); 00454 } 00455 } 00456 if(out && num_warning_viol) 00457 *out 00458 << "\nThere were " << num_warning_viol << " warning tolerance " 00459 << "violations out of num_fd_directions = " << num_fd_directions() 00460 << " computations of sum(FDC*D*y) and sum(FDN*y)\n" 00461 << "and the maximum relative iolation was " << max_warning_viol 00462 << " > Gc_waring_tol = " << Gc_warning_tol() << endl; 00463 break; 00464 } 00465 default: 00466 TEST_FOR_EXCEPT(true); 00467 } 00468 } 00469 00470 // /////////////////////////////////////////////// 00471 // (4) Check rGf = Gf(var_indep) + D'*Gf(var_dep) 00472 00473 if(rGf) { 00474 if( Gf && D ) { 00475 if(out) 00476 *out 00477 << "\nComparing rGf_tmp = Gf(var_indep) - D'*Gf(var_dep) with rGf ...\n"; 00478 VectorSpace::vec_mut_ptr_t 00479 rGf_tmp = space_x->sub_space(var_indep)->create_member(); 00480 *rGf_tmp = *Gf->sub_view(var_indep); 00481 Vp_MtV( rGf_tmp.get(), *D, BLAS_Cpp::trans, *Gf->sub_view(var_dep) ); 00482 const value_type 00483 sum_rGf_tmp = sum(*rGf_tmp), 00484 sum_rGf = sum(*rGf); 00485 const value_type 00486 calc_err = ::fabs( ( sum_rGf_tmp - sum_rGf )/( ::fabs(sum_rGf_tmp) + ::fabs(sum_rGf) + small_num ) ); 00487 if(out) 00488 *out 00489 << "\nrel_err(sum(rGf_tmp),sum(rGf)) = " 00490 << "rel_err(" << sum_rGf_tmp << "," << sum_rGf << ") = " 00491 << calc_err << endl; 00492 if( calc_err >= Gc_error_tol() ) { 00493 if(out) 00494 *out 00495 << "Error, above relative error exceeded Gc_error_tol = " << Gc_error_tol() << endl; 00496 if(print_all_warnings) 00497 *out << "\nrGf_tmp =\n" << *rGf_tmp 00498 << "\nrGf =\n" << *rGf; 00499 update_success( false, &success ); 00500 } 00501 if( calc_err >= Gc_warning_tol() ) { 00502 if(out) 00503 *out 00504 << "\nWarning, above relative error exceeded Gc_warning_tol = " 00505 << Gc_warning_tol() << endl; 00506 } 00507 } 00508 else if( D ) { 00509 if(out) 00510 *out 00511 << "\nComparing rGf'*y with the finite difference product" 00512 << " fd_prod(f,[D*y;y]) for random vectors y ...\n"; 00513 VectorSpace::vec_mut_ptr_t 00514 y = space_x->sub_space(var_indep)->create_member(), 00515 t = space_x->create_member(); 00516 value_type max_warning_viol = 0.0; 00517 int num_warning_viol = 0; 00518 const int num_fd_directions_used = ( num_fd_directions() > 0 ? num_fd_directions() : 1 ); 00519 for( int direc_i = 1; direc_i <= num_fd_directions_used; ++direc_i ) { 00520 if( num_fd_directions() > 0 ) { 00521 random_vector( rand_y_l, rand_y_u, y.get() ); 00522 if(out) 00523 *out 00524 << "\n****" 00525 << "\n**** Random directional vector " << direc_i << " ( ||y||_1 / n = " 00526 << (y->norm_1() / y->dim()) << " )" 00527 << "\n***\n"; 00528 } 00529 else { 00530 *y = 1.0; 00531 if(out) 00532 *out 00533 << "\n****" 00534 << "\n**** Ones vector y ( ||y||_1 / n = "<<(y->norm_1()/y->dim())<<" )" 00535 << "\n***\n"; 00536 } 00537 // t = [ D*y; y ] 00538 LinAlgOpPack::V_MtV(&*t->sub_view(var_dep),*D,BLAS_Cpp::no_trans,*y); 00539 *t->sub_view(var_indep) = *y; 00540 value_type fd_rGf_y = 0.0; 00541 // fd_Gf_y 00542 preformed_fd = fd_deriv_prod.calc_deriv_product( 00543 xo,xl,xu 00544 ,*t,NULL,NULL,true,nlp,&fd_rGf_y,NULL,out,dump_all(),dump_all() 00545 ); 00546 if( !preformed_fd ) 00547 goto FD_NOT_PREFORMED; 00548 if(out) *out << "fd_prod(f,[D*y;y]) = " << fd_rGf_y << "\n"; 00549 // rGf_y = rGf'*y 00550 const value_type rGf_y = dot(*rGf,*y); 00551 if(out) *out << "rGf'*y = " << rGf_y << "\n"; 00552 // Compare fd_rGf_y and rGf*y 00553 const value_type 00554 calc_err = ::fabs( ( rGf_y - fd_rGf_y )/( ::fabs(rGf_y) + ::fabs(fd_rGf_y) + small_num ) ); 00555 if( calc_err >= Gc_warning_tol() ) { 00556 max_warning_viol = my_max( max_warning_viol, calc_err ); 00557 ++num_warning_viol; 00558 } 00559 if(out) 00560 *out 00561 << "\nrel_err(rGf'*y,fd_prod(f,[D*y;y])) = " 00562 << "rel_err(" << fd_rGf_y << "," << rGf_y << ") = " 00563 << calc_err << endl; 00564 if( calc_err >= Gf_error_tol() ) { 00565 if(out) 00566 *out << "Error, above relative error exceeded Gc_error_tol = " << Gc_error_tol() << endl; 00567 if(print_all_warnings) 00568 *out << "\ny =\n" << *y 00569 << "\nt = [ D*y; y ] =\n" << *t; 00570 update_success( false, &success ); 00571 } 00572 } 00573 } 00574 else { 00575 TEST_FOR_EXCEPT(true); // ToDo: Test rGf without D? (This is not going to be easy!) 00576 } 00577 } 00578 00579 // /////////////////////////////////////////////////// 00580 // (5) Check GcU, and/or Uz (for undecomposed equalities) 00581 00582 if(GcU || Uz) { 00583 TEST_FOR_EXCEPT(true); // ToDo: Implement! 00584 } 00585 00586 FD_NOT_PREFORMED: 00587 00588 if(!preformed_fd) { 00589 if(out) 00590 *out 00591 << "\nError, the finite difference computation was not preformed due to cramped bounds\n" 00592 << "Finite difference test failed!\n" << endl; 00593 return false; 00594 } 00595 00596 } // end try 00597 catch( const AbstractLinAlgPack::NaNInfException& except ) { 00598 if(out) 00599 *out 00600 << "Error, found a NaN or Inf. Stoping tests\n"; 00601 success = false; 00602 } 00603 00604 if( out ) { 00605 if( success ) 00606 *out 00607 << "\nCongradulations, all the finite difference errors where within the\n" 00608 "specified error tolerances!\n"; 00609 else 00610 *out 00611 << "\nOh no, at least one of the above finite difference tests failed!\n"; 00612 } 00613 00614 return success; 00615 00616 } 00617 00618 } // end namespace NLPInterfacePack
1.7.4