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
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;
106 !m && Gc, std::invalid_argument
107 ,
"NLPFirstDerivTester::finite_diff_check(...) : "
108 "Error, Gc must be NULL if m == 0" );
118 switch(fd_testing_method_) {
120 return fd_check_all(nlp,xo,xl,xu,Gc,Gf,print_all_warnings,out);
131 <<
"Error: found a NaN or Inf. Stoping tests!\n";
147 ,
bool print_all_warnings
155 namespace rcp = MemMngPack;
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";
192 int num_Gf_warning_viol = 0;
194 int num_Gc_warning_viol = 0;
196 VectorSpace::vec_mut_ptr_t
197 e_i = space_x->create_member(),
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;
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;
262 sum_Gc_i =
sum(*Gc_i),
263 sum_FDGc_i =
sum(*FDGc_i);
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;
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";
332 ,
bool print_all_warnings
340 namespace rcp = MemMngPack;
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";
377 int num_Gf_warning_viol = 0;
379 VectorSpace::vec_mut_ptr_t
380 y = space_x->create_member(),
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;
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;
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);
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;
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";
AbstractLinAlgPack::size_type size_type
bool fd_directional_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
void pow(DVectorSlice *vs_lhs, const DVectorSlice &vs_rhs1, const DVectorSlice &vs_rhs2)
vs_lhs = pow(vs_rhs1,vs_rhs2)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
void Vp_StV(VectorMutable *v_lhs, const value_type &alpha, const Vector &v_rhs)
v_lhs = alpha * v_rhs + v_lhs
bool fd_check_all(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
void V_StV(VectorMutable *v_lhs, value_type alpha, const V &V_rhs)
v_lhs = alpha * V_rhs.
AbstractLinAlgPack::VectorSpace * space_c
AbstractLinAlgPack::VectorSpace * space_x
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 ...
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...
NLP interface class {abstract}.
value_type dot(const Vector &v_rhs1, const Vector &v_rhs2)
result = v_rhs1' * 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.
void V_MtV(VectorMutable *v_lhs, const MatrixOp &M_rhs1, BLAS_Cpp::Transp trans_rhs1, const V &V_rhs2)
v_lhs = op(M_rhs1) * V_rhs2.
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.
AbstractLinAlgPack::value_type value_type
value_type sum(const Vector &v_rhs)
result = sum( v_rhs(i), i = 1,,,dim )
bool update_success(bool result_check, bool *success)
Helper function for updating a flag for if an operation returned false.
virtual size_type m() const
Return the number of general equality constraints.
void random_vector(value_type l, value_type u, VectorMutable *v)
Generate a random vector with elements uniformly distrubuted elements.
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)