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
81 :calc_fd_prod_(calc_fd_prod)
82 ,Gf_testing_method_(Gf_testing_method)
83 ,Gc_testing_method_(Gc_testing_method)
84 ,Gf_warning_tol_(Gf_warning_tol)
85 ,Gf_error_tol_(Gf_error_tol)
86 ,Gc_warning_tol_(Gc_warning_tol)
87 ,Gc_error_tol_(Gc_error_tol)
88 ,num_fd_directions_(num_fd_directions)
107 ,
bool print_all_warnings
127 typedef VectorSpace::vec_mut_ptr_t vec_mut_ptr_t;
134 bool success =
true, preformed_fd;
136 *out << std::boolalpha
138 <<
"*********************************************************\n"
139 <<
"*** NLPDirectTester::finite_diff_check(...) ***\n"
140 <<
"*********************************************************\n";
156 py && !c, std::invalid_argument
157 ,
"NLPDirectTester::finite_diff_check(...) : "
158 "Error, if py!=NULL then c!=NULL must also be true!" );
161 &fd_deriv_prod = this->calc_fd_prod();
164 rand_y_l = -1.0, rand_y_u = 1.0,
165 small_num =
::sqrt(std::numeric_limits<value_type>::epsilon());
173 switch( Gf_testing_method() ) {
183 <<
"\nComparing products Gf'*y with finite difference values FDGf'*y for "
184 <<
"random y's ...\n";
185 vec_mut_ptr_t y = space_x->create_member();
187 int num_warning_viol = 0;
188 const int num_fd_directions_used = ( num_fd_directions() > 0 ? num_fd_directions() : 1 );
189 for(
int direc_i = 1; direc_i <= num_fd_directions_used; ++direc_i ) {
190 if( num_fd_directions() > 0 ) {
195 <<
"\n**** Random directional vector " << direc_i <<
" ( ||y||_1 / n = "
196 << (y->norm_1() / y->dim()) <<
" )"
204 <<
"\n**** Ones vector y ( ||y||_1 / n = "<<(y->norm_1()/y->dim())<<
" )"
208 Gf_y =
dot( *Gf, *y ),
212 ,*y,NULL,NULL,
true,nlp,&FDGf_y,NULL,out,dump_all(),dump_all()
215 goto FD_NOT_PREFORMED;
218 calc_err = ::fabs( ( Gf_y - FDGf_y )/( ::fabs(Gf_y) + ::fabs(FDGf_y) + small_num ) );
219 if( calc_err >= Gf_warning_tol() ) {
220 max_warning_viol = my_max( max_warning_viol, calc_err );
225 <<
"\nrel_err(Gf'*y,FDGf'*y) = "
226 <<
"rel_err(" << Gf_y <<
"," << FDGf_y <<
") = "
228 if( calc_err >= Gf_error_tol() ) {
231 <<
"Error, above relative error exceeded Gf_error_tol = " << Gf_error_tol() << endl;
233 *out <<
"\ny =\n" << *y;
238 if(out && num_warning_viol)
240 <<
"\nThere were " << num_warning_viol <<
" warning tolerance "
241 <<
"violations out of num_fd_directions = " << num_fd_directions()
242 <<
" computations of FDGf'*y\n"
243 <<
"and the maximum violation was " << max_warning_viol
244 <<
" > Gf_waring_tol = " << Gf_warning_tol() << endl;
276 <<
"\nComparing c with finite difference product FDA'*[ -py; 0 ] = -FDC*py ...\n";
278 VectorSpace::vec_mut_ptr_t
279 t1 = space_x->create_member();
280 V_StV( t1->sub_view(var_dep).get(), -1.0, *py );
281 *t1->sub_view(var_indep) = 0.0;
283 VectorSpace::vec_mut_ptr_t
284 t2 = nlp->
space_c()->create_member();
287 ,*t1,NULL,NULL,
true,nlp,NULL,t2.get(),
out,dump_all(),dump_all()
290 goto FD_NOT_PREFORMED;
296 calc_err = ::fabs( ( sum_c - sum_t2 )/( ::fabs(sum_c) + ::fabs(sum_t2) + small_num ) );
299 <<
"\nrel_err(sum(c),sum(-FDC*py)) = "
300 <<
"rel_err(" << sum_c <<
"," << sum_t2 <<
") = "
302 if( calc_err >= Gc_error_tol() ) {
305 <<
"Error, above relative error exceeded Gc_error_tol = " << Gc_error_tol() << endl;
306 if(print_all_warnings)
307 *out <<
"\nt1 = [ -py; 0 ] =\n" << *t1
308 <<
"\nt2 = FDA'*t1 = -FDC*py =\n" << *t2;
311 if( calc_err >= Gc_warning_tol() ) {
314 <<
"\nWarning, above relative error exceeded Gc_warning_tol = " << Gc_warning_tol() << endl;
322 switch( Gc_testing_method() ) {
395 <<
"\nComparing finite difference products -FDC*D*y with FDN*y for "
396 "random vectors y ...\n";
397 VectorSpace::vec_mut_ptr_t
398 y = space_x->sub_space(var_indep)->create_member(),
399 t1 = space_x->create_member(),
400 t2 = space_c->create_member(),
401 t3 = space_c->create_member();
403 int num_warning_viol = 0;
404 const int num_fd_directions_used = ( num_fd_directions() > 0 ? num_fd_directions() : 1 );
405 for(
int direc_i = 1; direc_i <= num_fd_directions_used; ++direc_i ) {
406 if( num_fd_directions() > 0 ) {
411 <<
"\n**** Random directional vector " << direc_i <<
" ( ||y||_1 / n = "
412 << (y->norm_1() / y->dim()) <<
" )"
420 <<
"\n**** Ones vector y ( ||y||_1 / n = "<<(y->norm_1()/y->dim())<<
" )"
424 *t1->sub_view(var_dep) = 0.0;
425 *t1->sub_view(var_indep) = *y;
429 ,*t1,NULL,NULL,
true,nlp,NULL,t2.get(),
out,dump_all(),dump_all()
432 goto FD_NOT_PREFORMED;
435 *t1->sub_view(var_indep) = 0.0;
439 ,*t1,NULL,NULL,
true,nlp,NULL,t3.get(),
out,dump_all(),dump_all()
446 calc_err = ::fabs( ( sum_t2 - sum_t3 )/( ::fabs(sum_t2) + ::fabs(sum_t3) + small_num ) );
449 <<
"\nrel_err(sum(-FDC*D*y),sum(FDN*y)) = "
450 <<
"rel_err(" << sum_t3 <<
"," << sum_t2 <<
") = "
452 if( calc_err >= Gc_warning_tol() ) {
453 max_warning_viol = my_max( max_warning_viol, calc_err );
456 if( calc_err >= Gc_error_tol() ) {
459 <<
"Error, above relative error exceeded Gc_error_tol = " << Gc_error_tol() << endl
460 <<
"Stoping the tests!\n";
461 if(print_all_warnings)
462 *out <<
"\ny =\n" << *y
463 <<
"\nt1 = [ -D*y; 0 ] =\n" << *t1
464 <<
"\nt2 = FDA' * [ 0; y ] = FDN * y =\n" << *t2
465 <<
"\nt3 = FDA' * t1 = -FDC * D * y =\n" << *t3;
469 if(out && num_warning_viol)
471 <<
"\nThere were " << num_warning_viol <<
" warning tolerance "
472 <<
"violations out of num_fd_directions = " << num_fd_directions()
473 <<
" computations of sum(FDC*D*y) and sum(FDN*y)\n"
474 <<
"and the maximum relative iolation was " << max_warning_viol
475 <<
" > Gc_waring_tol = " << Gc_warning_tol() << endl;
490 <<
"\nComparing rGf_tmp = Gf(var_indep) - D'*Gf(var_dep) with rGf ...\n";
491 VectorSpace::vec_mut_ptr_t
492 rGf_tmp = space_x->sub_space(var_indep)->create_member();
493 *rGf_tmp = *Gf->sub_view(var_indep);
496 sum_rGf_tmp =
sum(*rGf_tmp),
499 calc_err = ::fabs( ( sum_rGf_tmp - sum_rGf )/( ::fabs(sum_rGf_tmp) + ::fabs(sum_rGf) + small_num ) );
502 <<
"\nrel_err(sum(rGf_tmp),sum(rGf)) = "
503 <<
"rel_err(" << sum_rGf_tmp <<
"," << sum_rGf <<
") = "
505 if( calc_err >= Gc_error_tol() ) {
508 <<
"Error, above relative error exceeded Gc_error_tol = " << Gc_error_tol() << endl;
509 if(print_all_warnings)
510 *out <<
"\nrGf_tmp =\n" << *rGf_tmp
511 <<
"\nrGf =\n" << *rGf;
514 if( calc_err >= Gc_warning_tol() ) {
517 <<
"\nWarning, above relative error exceeded Gc_warning_tol = "
518 << Gc_warning_tol() << endl;
524 <<
"\nComparing rGf'*y with the finite difference product"
525 <<
" fd_prod(f,[D*y;y]) for random vectors y ...\n";
526 VectorSpace::vec_mut_ptr_t
527 y = space_x->sub_space(var_indep)->create_member(),
528 t = space_x->create_member();
530 int num_warning_viol = 0;
531 const int num_fd_directions_used = ( num_fd_directions() > 0 ? num_fd_directions() : 1 );
532 for(
int direc_i = 1; direc_i <= num_fd_directions_used; ++direc_i ) {
533 if( num_fd_directions() > 0 ) {
538 <<
"\n**** Random directional vector " << direc_i <<
" ( ||y||_1 / n = "
539 << (y->norm_1() / y->dim()) <<
" )"
547 <<
"\n**** Ones vector y ( ||y||_1 / n = "<<(y->norm_1()/y->dim())<<
" )"
552 *t->sub_view(var_indep) = *y;
557 ,*t,NULL,NULL,
true,nlp,&fd_rGf_y,NULL,out,dump_all(),dump_all()
560 goto FD_NOT_PREFORMED;
561 if(out) *out <<
"fd_prod(f,[D*y;y]) = " << fd_rGf_y <<
"\n";
564 if(out) *out <<
"rGf'*y = " << rGf_y <<
"\n";
567 calc_err = ::fabs( ( rGf_y - fd_rGf_y )/( ::fabs(rGf_y) + ::fabs(fd_rGf_y) + small_num ) );
568 if( calc_err >= Gc_warning_tol() ) {
569 max_warning_viol = my_max( max_warning_viol, calc_err );
574 <<
"\nrel_err(rGf'*y,fd_prod(f,[D*y;y])) = "
575 <<
"rel_err(" << fd_rGf_y <<
"," << rGf_y <<
") = "
577 if( calc_err >= Gf_error_tol() ) {
579 *out <<
"Error, above relative error exceeded Gc_error_tol = " << Gc_error_tol() << endl;
580 if(print_all_warnings)
581 *out <<
"\ny =\n" << *y
582 <<
"\nt = [ D*y; y ] =\n" << *t;
604 <<
"\nError, the finite difference computation was not preformed due to cramped bounds\n"
605 <<
"Finite difference test failed!\n" << endl;
613 <<
"Error, found a NaN or Inf. Stoping tests\n";
620 <<
"\nCongradulations, all the finite difference errors where within the\n"
621 "specified error tolerances!\n";
624 <<
"\nOh no, at least one of the above finite difference tests failed!\n";
void M_StMtM(MatrixOp *M_lhs, value_type alpha, const MatrixOp &M_rhs1, BLAS_Cpp::Transp trans_rhs1, const MatrixOp &M_rhs2, BLAS_Cpp::Transp trans_rhs2)
M_lhs = alpha * op(M_rhs1) * op(M_rhs2).
AbstractLinAlgPack::size_type size_type
NLPDirectTester(const calc_fd_prod_ptr_t &calc_fd_prod=Teuchos::null, ETestingMethod Gf_testing_method=FD_DIRECTIONAL, ETestingMethod Gc_testing_method=FD_DIRECTIONAL, value_type Gf_warning_tol=1e-6, value_type Gf_error_tol=1e-1, value_type Gc_warning_tol=1e-6, value_type Gc_error_tol=1e-1, size_type num_fd_directions=1, bool dump_all=false)
Constructor.
virtual Range1D con_decomp() const
Return the range of decomposed equality constraints.
virtual vec_space_ptr_t space_x() const =0
Vector space object for unknown variables x (dimension 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)
v_lhs = alpha * v_rhs + v_lhs
void V_StV(VectorMutable *v_lhs, value_type alpha, const V &V_rhs)
v_lhs = alpha * V_rhs.
void V_StMtV(VectorMutable *v_lhs, value_type alpha, const MatrixOp &M_rhs1, BLAS_Cpp::Transp trans_rhs1, const V &V_rhs2)
v_lhs = alpha * op(M_rhs1) * V_rhs2.
Interface providing only direct first order sensitivity information.
void Vp_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 Range1D con_undecomp() const
Return the range of undecomposed equality constraints.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
bool finite_diff_check(NLPDirect *nlp, const Vector &xo, const Vector *xl, const Vector *xu, const Vector *c, const Vector *Gf, const Vector *py, const Vector *rGf, const MatrixOp *GcU, const MatrixOp *D, const MatrixOp *Uz, bool print_all_warnings, std::ostream *out) const
This function takes an NLP object and its computed derivatives and function values and validates the ...
Strategy interface for computing the product of the derivatives of the functions of an NLP along give...
void M_StM(MatrixOp *M_lhs, value_type alpha, const MatrixOp &M_rhs, BLAS_Cpp::Transp trans_rhs)
gm_lhs = alpha * M_rhs.
virtual vec_space_ptr_t space_c() const =0
Vector space object for general equality constraints c(x) (dimension m).
virtual Range1D var_dep() const
Return the range of dependent (i.e. basic) variables.
virtual Range1D var_indep() const
Return the range of independent (i.e. nonbasic) variables.
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...
value_type dot(const Vector &v_rhs1, const Vector &v_rhs2)
result = v_rhs1' * v_rhs2
void sqrt(DVectorSlice *vs_lhs, const DVectorSlice &vs_rhs)
vs_lhs = sqrt(vs_rhs)
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.
RangePack::Range1D Range1D
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)