49 #include "NLPInterfacePack_NLPFirstDerivTester.hpp"
50 #include "NLPInterfacePack_NLPFirstOrder.hpp"
51 #include "AbstractLinAlgPack_MatrixOp.hpp"
52 #include "AbstractLinAlgPack_VectorMutable.hpp"
53 #include "AbstractLinAlgPack_VectorOut.hpp"
54 #include "AbstractLinAlgPack_VectorSpace.hpp"
55 #include "AbstractLinAlgPack_VectorStdOps.hpp"
56 #include "AbstractLinAlgPack_LinAlgOpPack.hpp"
57 #include "AbstractLinAlgPack_EtaVector.hpp"
58 #include "AbstractLinAlgPack_assert_print_nan_inf.hpp"
59 #include "TestingHelperPack_update_success.hpp"
60 #include "Teuchos_Assert.hpp"
65 T my_max(
const T& v1,
const T& v2 ) {
return v1 > v2 ? v1 : v2; }
68 namespace NLPInterfacePack {
71 const calc_fd_prod_ptr_t &calc_fd_prod
74 ,value_type warning_tol
77 :calc_fd_prod_(calc_fd_prod)
78 ,fd_testing_method_(fd_testing_method)
79 ,num_fd_directions_(num_fd_directions)
80 ,warning_tol_(warning_tol)
81 ,error_tol_(error_tol)
91 ,
bool print_all_warnings
95 namespace rcp = MemMngPack;
96 using AbstractLinAlgPack::assert_print_nan_inf;
106 !m && Gc, std::invalid_argument
107 ,
"NLPFirstDerivTester::finite_diff_check(...) : "
108 "Error, Gc must be NULL if m == 0" );
110 assert_print_nan_inf(xo,
"xo",
true,out);
112 assert_print_nan_inf(*Gf,
"Gf",
true,out);
118 switch(fd_testing_method_) {
120 return fd_check_all(nlp,xo,xl,xu,Gc,Gf,print_all_warnings,out);
122 return fd_directional_check(nlp,xo,xl,xu,Gc,Gf,print_all_warnings,out);
131 <<
"Error: found a NaN or Inf. Stoping tests!\n";
140 bool NLPFirstDerivTester::fd_check_all(
147 ,
bool print_all_warnings
155 namespace rcp = MemMngPack;
159 using AbstractLinAlgPack::assert_print_nan_inf;
162 using LinAlgOpPack::V_MtV;
164 using TestingHelperPack::update_success;
176 space_x = nlp->space_x(),
177 space_c = nlp->space_c();
180 &fd_deriv_prod = this->calc_fd_prod();
184 small_num = ::pow(std::numeric_limits<value_type>::epsilon(),0.25);
188 <<
"\nComparing Gf and/or Gc with finite-difference values "
189 "FDGf and/or FDGc one variable i at a time ...\n";
191 value_type max_Gf_warning_viol = 0.0;
192 int num_Gf_warning_viol = 0;
193 value_type max_Gc_warning_viol = 0.0;
194 int num_Gc_warning_viol = 0;
196 VectorSpace::vec_mut_ptr_t
197 e_i = space_x->create_member(),
198 Gc_i = ( Gc ? space_c->create_member() : Teuchos::null ),
199 FDGc_i = ( Gc ? space_c->create_member() : Teuchos::null );
203 EtaVector eta_i(i,n);
207 Gf_i = Gf ? Gf->get_ele(i) : 0.0;
221 ,Gc ? FDGc_i.get() : NULL
224 if( !preformed_fd ) {
227 <<
"\nError, the finite difference computation was not preformed due to cramped bounds\n"
228 <<
"Finite difference test failed!\n" << endl;
234 assert_print_nan_inf(FDGf_i,
"FDGf'*e_i",
true,out);
236 Gf_err = ::fabs( Gf_i - FDGf_i ) / ( ::fabs(Gf_i) + ::fabs(FDGf_i) + small_num );
239 <<
"\nrel_err(Gf("<<i<<
"),FDGf'*e("<<i<<
")) = "
240 <<
"rel_err(" << Gf_i <<
"," << FDGf_i <<
") = "
242 if( Gf_err >= warning_tol() ) {
243 max_Gf_warning_viol = my_max( max_Gf_warning_viol, Gf_err );
244 ++num_Gf_warning_viol;
246 if( Gf_err >= error_tol() ) {
249 <<
"\nError, exceeded Gf_error_tol = " << error_tol() << endl
250 <<
"Stoping the tests!\n";
251 if(print_all_warnings)
253 <<
"\ne_i =\n" << *e_i
254 <<
"\nGf_i =\n" << Gf_i << std::endl
255 <<
"\nFDGf_i =\n" << FDGf_i << std::endl;
256 update_success(
false, &success );
262 sum_Gc_i =
sum(*Gc_i),
263 sum_FDGc_i =
sum(*FDGc_i);
264 assert_print_nan_inf(sum_FDGc_i,
"sum(FDGc'*e_i)",
true,out);
266 calc_err = ::fabs( ( sum_Gc_i - sum_FDGc_i )
267 /( ::fabs(sum_Gc_i) + ::fabs(sum_FDGc_i) + small_num ) );
270 <<
"\nrel_err(sum(Gc'*e("<<i<<
")),sum(FDGc'*e("<<i<<
"))) = "
271 <<
"rel_err(" << sum_Gc_i <<
"," << sum_FDGc_i <<
") = "
273 if( calc_err >= warning_tol() ) {
274 max_Gc_warning_viol = my_max( max_Gc_warning_viol, calc_err );
275 ++num_Gc_warning_viol;
277 if( calc_err >= error_tol() ) {
280 <<
"\nError, rel_err(sum(Gc'*e("<<i<<
")),sum(FDGc'*e("<<i<<
"))) = "
281 <<
"rel_err(" << sum_Gc_i <<
"," << sum_FDGc_i <<
") = "
283 <<
"exceeded error_tol = " << error_tol() << endl
284 <<
"Stoping the tests!\n";
285 if(print_all_warnings)
286 *out <<
"\ne_i =\n" << *e_i
287 <<
"\nGc_i =\n" << *Gc_i
288 <<
"\nFDGc_i =\n" << *FDGc_i;
289 update_success(
false, &success );
292 if( calc_err >= warning_tol() ) {
295 <<
"\nWarning, rel_err(sum(Gc'*e("<<i<<
")),sum(FDGc'*e("<<i<<
"))) = "
296 <<
"rel_err(" << sum_Gc_i <<
"," << sum_FDGc_i <<
") = "
298 <<
"exceeded warning_tol = " << warning_tol() << endl;
303 if(out && num_Gf_warning_viol)
305 <<
"\nFor Gf, there were " << num_Gf_warning_viol <<
" warning tolerance "
306 <<
"violations out of num_fd_directions = " << num_fd_directions()
307 <<
" computations of FDGf'*e(i)\n"
308 <<
"and the maximum violation was " << max_Gf_warning_viol
309 <<
" > Gf_waring_tol = " << warning_tol() << endl;
310 if(out && num_Gc_warning_viol)
312 <<
"\nFor Gc, there were " << num_Gc_warning_viol <<
" warning tolerance "
313 <<
"violations out of num_fd_directions = " << num_fd_directions()
314 <<
" computations of FDGc'*e(i)\n"
315 <<
"and the maximum violation was " << max_Gc_warning_viol
316 <<
" > Gc_waring_tol = " << warning_tol() << endl;
319 <<
"\nCongradulations! All of the computed errors were within the specified error tolerance!\n";
325 bool NLPFirstDerivTester::fd_directional_check(
332 ,
bool print_all_warnings
340 namespace rcp = MemMngPack;
344 using AbstractLinAlgPack::assert_print_nan_inf;
347 using LinAlgOpPack::V_MtV;
349 using TestingHelperPack::update_success;
361 space_x = nlp->space_x(),
362 space_c = nlp->space_c();
364 const CalcFiniteDiffProd
365 &fd_deriv_prod = this->calc_fd_prod();
368 rand_y_l = -1.0, rand_y_u = 1.0,
369 small_num = ::pow(std::numeric_limits<value_type>::epsilon(),0.25);
373 <<
"\nComparing directional products Gf'*y and/or Gc'*y with finite difference values "
374 " FDGf'*y and/or FDGc'*y for random y's ...\n";
376 value_type max_Gf_warning_viol = 0.0;
377 int num_Gf_warning_viol = 0;
379 VectorSpace::vec_mut_ptr_t
380 y = space_x->create_member(),
381 Gc_prod = ( Gc ? space_c->create_member() : Teuchos::null ),
382 FDGc_prod = ( Gc ? space_c->create_member() : Teuchos::null );
384 const int num_fd_directions_used = ( num_fd_directions() > 0 ? num_fd_directions() : 1 );
386 for(
int direc_i = 1; direc_i <= num_fd_directions_used; ++direc_i ) {
387 if( num_fd_directions() > 0 ) {
392 <<
"\n**** Random directional vector " << direc_i <<
" ( ||y||_1 / n = "
393 << (y->norm_1() / y->dim()) <<
" )"
401 <<
"\n**** Ones vector y ( ||y||_1 / n = "<<(y->norm_1()/y->dim())<<
" )"
406 Gf_y = Gf ?
dot( *Gf, *y ) : 0.0;
412 const bool preformed_fd = fd_deriv_prod.calc_deriv_product(
420 ,Gc ? FDGc_prod.get() : NULL
423 if( !preformed_fd ) {
426 <<
"\nError, the finite difference computation was not preformed due to cramped bounds\n"
427 <<
"Finite difference test failed!\n" << endl;
433 assert_print_nan_inf(FDGf_y,
"FDGf'*y",
true,out);
435 Gf_err = ::fabs( Gf_y - FDGf_y ) / ( ::fabs(Gf_y) + ::fabs(FDGf_y) + small_num );
438 <<
"\nrel_err(Gf'*y,FDGf'*y) = "
439 <<
"rel_err(" << Gf_y <<
"," << FDGf_y <<
") = "
441 if( Gf_err >= warning_tol() ) {
442 max_Gf_warning_viol = my_max( max_Gf_warning_viol, Gf_err );
443 ++num_Gf_warning_viol;
445 if( Gf_err >= error_tol() ) {
448 <<
"\nError, exceeded Gf_error_tol = " << error_tol() << endl
449 <<
"Stoping the tests!\n";
455 sum_Gc_prod =
sum(*Gc_prod),
456 sum_FDGc_prod =
sum(*FDGc_prod);
457 assert_print_nan_inf(sum_FDGc_prod,
"sum(FDGc'*y)",
true,out);
459 calc_err = ::fabs( ( sum_Gc_prod - sum_FDGc_prod )
460 /( ::fabs(sum_Gc_prod) + ::fabs(sum_FDGc_prod) + small_num ) );
463 <<
"\nrel_err(sum(Gc'*y),sum(FDGc'*y)) = "
464 <<
"rel_err(" << sum_Gc_prod <<
"," << sum_FDGc_prod <<
") = "
466 if( calc_err >= error_tol() ) {
469 <<
"\nError, rel_err(sum(Gc'*y),sum(FDGc'*y)) = "
470 <<
"rel_err(" << sum_Gc_prod <<
"," << sum_FDGc_prod <<
") = "
472 <<
"exceeded error_tol = " << error_tol() << endl
473 <<
"Stoping the tests!\n";
474 if(print_all_warnings)
475 *out <<
"\ny =\n" << *y
476 <<
"\nGc_prod =\n" << *Gc_prod
477 <<
"\nFDGc_prod =\n" << *FDGc_prod;
478 update_success(
false, &success );
481 if( calc_err >= warning_tol() ) {
484 <<
"\nWarning, rel_err(sum(Gc'*y),sum(FDGc'*y)) = "
485 <<
"rel_err(" << sum_Gc_prod <<
"," << sum_FDGc_prod <<
") = "
487 <<
"exceeded warning_tol = " << warning_tol() << endl;
491 if(out && num_Gf_warning_viol)
493 <<
"\nFor Gf, there were " << num_Gf_warning_viol <<
" warning tolerance "
494 <<
"violations out of num_fd_directions = " << num_fd_directions()
495 <<
" computations of FDGf'*y\n"
496 <<
"and the maximum violation was " << max_Gf_warning_viol
497 <<
" > Gf_waring_tol = " << warning_tol() << endl;
501 <<
"\nCongradulations! All of the computed errors were within the specified error tolerance!\n";
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
void Vp_StV(VectorMutable *v_lhs, const value_type &alpha, const Vector &v_rhs)
void V_StV(VectorMutable *v_lhs, value_type alpha, const V &V_rhs)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Strategy interface for computing the product of the derivatives of the functions of an NLP along give...
virtual size_type n() const
Return the number of variables.
bool finite_diff_check(NLP *nlp, const Vector &xo, const Vector *xl, const Vector *xu, const MatrixOp *Gc, const Vector *Gf, bool print_all_warnings, std::ostream *out) const
This function takes an NLP object and its computed derivatives and function values and validates the ...
Teuchos::RCP< const VectorSpace > vec_space_ptr_t
NLP interface class {abstract}.
value_type dot(const Vector &v_rhs1, const Vector &v_rhs2)
NLPFirstDerivTester(const calc_fd_prod_ptr_t &calc_fd_prod=Teuchos::rcp(new CalcFiniteDiffProd()), ETestingMethod fd_testing_method=FD_DIRECTIONAL, size_type num_fd_directions=1, value_type warning_tol=1e-8, value_type error_tol=1e-3)
Constructor.
virtual bool calc_deriv_product(const Vector &xo, const Vector *xl, const Vector *xu, const Vector &v, const value_type *fo, const Vector *co, bool check_nan_inf, NLP *nlp, value_type *Gf_prod, VectorMutable *Gc_prod, std::ostream *out, bool trace=false, bool dump_all=false) const
Compute the directional derivatives by finite differences.
value_type sum(const Vector &v_rhs)
virtual size_type m() const
Return the number of general equality constraints.
void random_vector(value_type l, value_type u, VectorMutable *v)
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)