bool NLPDirectTester::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 { using std::setw; using std::endl; using std::right; using AbstractLinAlgPack::sum; using AbstractLinAlgPack::dot; using AbstractLinAlgPack::Vp_StV; using AbstractLinAlgPack::random_vector; using AbstractLinAlgPack::assert_print_nan_inf; using LinAlgOpPack::V_StV; using LinAlgOpPack::V_StMtV; using LinAlgOpPack::Vp_MtV; using LinAlgOpPack::M_StM; using LinAlgOpPack::M_StMtM; typedef VectorSpace::vec_mut_ptr_t vec_mut_ptr_t; // using AbstractLinAlgPack::TestingPack::CompareDenseVectors; // using AbstractLinAlgPack::TestingPack::CompareDenseSparseMatrices; using TestingHelperPack::update_success; bool success = true, preformed_fd; if(out) { *out << std::boolalpha << std::endl << "*********************************************************\n" << "*** NLPDirectTester::finite_diff_check(...) ***\n" << "*********************************************************\n"; } const Range1D var_dep = nlp->var_dep(), var_indep = nlp->var_indep(), con_decomp = nlp->con_decomp(), con_undecomp = nlp->con_undecomp(); NLP::vec_space_ptr_t space_x = nlp->space_x(), space_c = nlp->space_c(); // ////////////////////////////////////////////// // Validate the input TEST_FOR_EXCEPTION( py && !c, std::invalid_argument ,"NLPDirectTester::finite_diff_check(...) : " "Error, if py!=NULL then c!=NULL must also be true!" ); const CalcFiniteDiffProd &fd_deriv_prod = this->calc_fd_prod(); const value_type rand_y_l = -1.0, rand_y_u = 1.0, small_num = ::sqrt(std::numeric_limits<value_type>::epsilon()); try { // /////////////////////////////////////////////// // (1) Check Gf if(Gf) { switch( Gf_testing_method() ) { case FD_COMPUTE_ALL: { // Compute FDGf outright TEST_FOR_EXCEPT(true); // ToDo: update above! break; } case FD_DIRECTIONAL: { // Compute FDGF'*y using random y's if(out) *out << "\nComparing products Gf'*y with finite difference values FDGf'*y for " << "random y's ...\n"; vec_mut_ptr_t y = space_x->create_member(); value_type max_warning_viol = 0.0; int num_warning_viol = 0; const int num_fd_directions_used = ( num_fd_directions() > 0 ? num_fd_directions() : 1 ); for( int direc_i = 1; direc_i <= num_fd_directions_used; ++direc_i ) { if( num_fd_directions() > 0 ) { random_vector( rand_y_l, rand_y_u, y.get() ); if(out) *out << "\n****" << "\n**** Random directional vector " << direc_i << " ( ||y||_1 / n = " << (y->norm_1() / y->dim()) << " )" << "\n***\n"; } else { *y = 1.0; if(out) *out << "\n****" << "\n**** Ones vector y ( ||y||_1 / n = "<<(y->norm_1()/y->dim())<<" )" << "\n***\n"; } value_type Gf_y = dot( *Gf, *y ), FDGf_y; preformed_fd = fd_deriv_prod.calc_deriv_product( xo,xl,xu ,*y,NULL,NULL,true,nlp,&FDGf_y,NULL,out,dump_all(),dump_all() ); if( !preformed_fd ) goto FD_NOT_PREFORMED; assert_print_nan_inf(FDGf_y, "FDGf'*y",true,out); const value_type calc_err = ::fabs( ( Gf_y - FDGf_y )/( ::fabs(Gf_y) + ::fabs(FDGf_y) + small_num ) ); if( calc_err >= Gf_warning_tol() ) { max_warning_viol = my_max( max_warning_viol, calc_err ); ++num_warning_viol; } if(out) *out << "\nrel_err(Gf'*y,FDGf'*y) = " << "rel_err(" << Gf_y << "," << FDGf_y << ") = " << calc_err << endl; if( calc_err >= Gf_error_tol() ) { if(out) { *out << "Error, above relative error exceeded Gf_error_tol = " << Gf_error_tol() << endl; if(dump_all()) { *out << "\ny =\n" << *y; } } } } if(out && num_warning_viol) *out << "\nThere were " << num_warning_viol << " warning tolerance " << "violations out of num_fd_directions = " << num_fd_directions() << " computations of FDGf'*y\n" << "and the maximum violation was " << max_warning_viol << " > Gf_waring_tol = " << Gf_warning_tol() << endl; break; } default: TEST_FOR_EXCEPT(true); // Invalid value } } // ///////////////////////////////////////////// // (2) Check py = -inv(C)*c // // We want to check; // // FDC * (inv(C)*c) \approx c // \_________/ // -py // // We can compute this as: // // FDC * py = [ FDC, FDN ] * [ -py ; 0 ] // \__________/ // FDA' // // t1 = [ -py ; 0 ] // // t2 = FDA'*t1 // // Compare t2 \approx c // if(py) { if(out) *out << "\nComparing c with finite difference product FDA'*[ -py; 0 ] = -FDC*py ...\n"; // t1 = [ -py ; 0 ] VectorSpace::vec_mut_ptr_t t1 = space_x->create_member(); V_StV( t1->sub_view(var_dep).get(), -1.0, *py ); *t1->sub_view(var_indep) = 0.0; // t2 = FDA'*t1 VectorSpace::vec_mut_ptr_t t2 = nlp->space_c()->create_member(); preformed_fd = fd_deriv_prod.calc_deriv_product( xo,xl,xu ,*t1,NULL,NULL,true,nlp,NULL,t2.get(),out,dump_all(),dump_all() ); if( !preformed_fd ) goto FD_NOT_PREFORMED; const value_type sum_c = sum(*c), sum_t2 = sum(*t2); assert_print_nan_inf(sum_t2, "sum(-FDC*py)",true,out); const value_type calc_err = ::fabs( ( sum_c - sum_t2 )/( ::fabs(sum_c) + ::fabs(sum_t2) + small_num ) ); if(out) *out << "\nrel_err(sum(c),sum(-FDC*py)) = " << "rel_err(" << sum_c << "," << sum_t2 << ") = " << calc_err << endl; if( calc_err >= Gc_error_tol() ) { if(out) *out << "Error, above relative error exceeded Gc_error_tol = " << Gc_error_tol() << endl; if(print_all_warnings) *out << "\nt1 = [ -py; 0 ] =\n" << *t1 << "\nt2 = FDA'*t1 = -FDC*py =\n" << *t2; update_success( false, &success ); } if( calc_err >= Gc_warning_tol() ) { if(out) *out << "\nWarning, above relative error exceeded Gc_warning_tol = " << Gc_warning_tol() << endl; } } // ///////////////////////////////////////////// // (3) Check D = -inv(C)*N if(D) { switch( Gc_testing_method() ) { case FD_COMPUTE_ALL: { // // Compute FDN outright and check // -FDC * D \aprox FDN // // We want to compute: // // FDC * -D = [ FDC, FDN ] * [ -D; 0 ] // \__________/ // FDA' // // To compute the above we perform: // // T = FDA' * [ -D; 0 ] (one column at a time) // // Compare T \approx FDN // /* // FDN DMatrix FDN(m,n-m); fd_deriv_computer.calc_deriv( xo, xl, xu , Range1D(m+1,n), nlp, NULL , &FDN() ,BLAS_Cpp::trans, out ); // T = FDA' * [ -D; 0 ] (one column at a time) DMatrix T(m,n-m); DVector t(n); t(m+1,n) = 0.0; for( int s = 1; s <= n-m; ++s ) { // t = [ -D(:,s); 0 ] V_StV( &t(1,m), -1.0, D->col(s) ); // T(:,s) = FDA' * t fd_deriv_prod.calc_deriv_product( xo,xl,xu,t(),NULL,NULL,nlp,NULL,&T.col(s),out); } // Compare T \approx FDN if(out) *out << "\nChecking the computed D = -inv(C)*N\n" << "where D(i,j) = (-FDC*D)(i,j), dM(i,j) = FDN(i,j) ...\n"; result = comp_M.comp( T(), FDN, BLAS_Cpp::no_trans , CompareDenseSparseMatrices::FULL_MATRIX , CompareDenseSparseMatrices::REL_ERR_BY_COL , Gc_warning_tol(), Gc_error_tol() , print_all_warnings, out ); update_success( result, &success ); if(!result) return false; */ TEST_FOR_EXCEPT(true); // Todo: Implement above! break; } case FD_DIRECTIONAL: { // // Compute -FDC * D * v \aprox FDN * v // for random v's // // We will compute this as: // // t1 = [ 0; y ] <: R^(n) // // t2 = FDA' * t1 ( FDN * y ) <: R^(m) // // t1 = [ -D * y ; 0 ] <: R^(n) // // t3 = FDA' * t1 ( -FDC * D * y ) <: R^(m) // // Compare t2 \approx t3 // if(out) *out << "\nComparing finite difference products -FDC*D*y with FDN*y for " "random vectors y ...\n"; VectorSpace::vec_mut_ptr_t y = space_x->sub_space(var_indep)->create_member(), t1 = space_x->create_member(), t2 = space_c->create_member(), t3 = space_c->create_member(); value_type max_warning_viol = 0.0; int num_warning_viol = 0; const int num_fd_directions_used = ( num_fd_directions() > 0 ? num_fd_directions() : 1 ); for( int direc_i = 1; direc_i <= num_fd_directions_used; ++direc_i ) { if( num_fd_directions() > 0 ) { random_vector( rand_y_l, rand_y_u, y.get() ); if(out) *out << "\n****" << "\n**** Random directional vector " << direc_i << " ( ||y||_1 / n = " << (y->norm_1() / y->dim()) << " )" << "\n***\n"; } else { *y = 1.0; if(out) *out << "\n****" << "\n**** Ones vector y ( ||y||_1 / n = "<<(y->norm_1()/y->dim())<<" )" << "\n***\n"; } // t1 = [ 0; y ] <: R^(n) *t1->sub_view(var_dep) = 0.0; *t1->sub_view(var_indep) = *y; // t2 = FDA' * t1 ( FDN * y ) <: R^(m) preformed_fd = fd_deriv_prod.calc_deriv_product( xo,xl,xu ,*t1,NULL,NULL,true,nlp,NULL,t2.get(),out,dump_all(),dump_all() ); if( !preformed_fd ) goto FD_NOT_PREFORMED; // t1 = [ -D * y ; 0 ] <: R^(n) V_StMtV( t1->sub_view(var_dep).get(), -1.0, *D, BLAS_Cpp::no_trans, *y ); *t1->sub_view(var_indep) = 0.0; // t3 = FDA' * t1 ( -FDC * D * y ) <: R^(m) preformed_fd = fd_deriv_prod.calc_deriv_product( xo,xl,xu ,*t1,NULL,NULL,true,nlp,NULL,t3.get(),out,dump_all(),dump_all() ); // Compare t2 \approx t3 const value_type sum_t2 = sum(*t2), sum_t3 = sum(*t3); const value_type calc_err = ::fabs( ( sum_t2 - sum_t3 )/( ::fabs(sum_t2) + ::fabs(sum_t3) + small_num ) ); if(out) *out << "\nrel_err(sum(-FDC*D*y),sum(FDN*y)) = " << "rel_err(" << sum_t3 << "," << sum_t2 << ") = " << calc_err << endl; if( calc_err >= Gc_warning_tol() ) { max_warning_viol = my_max( max_warning_viol, calc_err ); ++num_warning_viol; } if( calc_err >= Gc_error_tol() ) { if(out) *out << "Error, above relative error exceeded Gc_error_tol = " << Gc_error_tol() << endl << "Stoping the tests!\n"; if(print_all_warnings) *out << "\ny =\n" << *y << "\nt1 = [ -D*y; 0 ] =\n" << *t1 << "\nt2 = FDA' * [ 0; y ] = FDN * y =\n" << *t2 << "\nt3 = FDA' * t1 = -FDC * D * y =\n" << *t3; update_success( false, &success ); } } if(out && num_warning_viol) *out << "\nThere were " << num_warning_viol << " warning tolerance " << "violations out of num_fd_directions = " << num_fd_directions() << " computations of sum(FDC*D*y) and sum(FDN*y)\n" << "and the maximum relative iolation was " << max_warning_viol << " > Gc_waring_tol = " << Gc_warning_tol() << endl; break; } default: TEST_FOR_EXCEPT(true); } } // /////////////////////////////////////////////// // (4) Check rGf = Gf(var_indep) + D'*Gf(var_dep) if(rGf) { if( Gf && D ) { if(out) *out << "\nComparing rGf_tmp = Gf(var_indep) - D'*Gf(var_dep) with rGf ...\n"; VectorSpace::vec_mut_ptr_t rGf_tmp = space_x->sub_space(var_indep)->create_member(); *rGf_tmp = *Gf->sub_view(var_indep); Vp_MtV( rGf_tmp.get(), *D, BLAS_Cpp::trans, *Gf->sub_view(var_dep) ); const value_type sum_rGf_tmp = sum(*rGf_tmp), sum_rGf = sum(*rGf); const value_type calc_err = ::fabs( ( sum_rGf_tmp - sum_rGf )/( ::fabs(sum_rGf_tmp) + ::fabs(sum_rGf) + small_num ) ); if(out) *out << "\nrel_err(sum(rGf_tmp),sum(rGf)) = " << "rel_err(" << sum_rGf_tmp << "," << sum_rGf << ") = " << calc_err << endl; if( calc_err >= Gc_error_tol() ) { if(out) *out << "Error, above relative error exceeded Gc_error_tol = " << Gc_error_tol() << endl; if(print_all_warnings) *out << "\nrGf_tmp =\n" << *rGf_tmp << "\nrGf =\n" << *rGf; update_success( false, &success ); } if( calc_err >= Gc_warning_tol() ) { if(out) *out << "\nWarning, above relative error exceeded Gc_warning_tol = " << Gc_warning_tol() << endl; } } else if( D ) { if(out) *out << "\nComparing rGf'*y with the finite difference product" << " fd_prod(f,[D*y;y]) for random vectors y ...\n"; VectorSpace::vec_mut_ptr_t y = space_x->sub_space(var_indep)->create_member(), t = space_x->create_member(); value_type max_warning_viol = 0.0; int num_warning_viol = 0; const int num_fd_directions_used = ( num_fd_directions() > 0 ? num_fd_directions() : 1 ); for( int direc_i = 1; direc_i <= num_fd_directions_used; ++direc_i ) { if( num_fd_directions() > 0 ) { random_vector( rand_y_l, rand_y_u, y.get() ); if(out) *out << "\n****" << "\n**** Random directional vector " << direc_i << " ( ||y||_1 / n = " << (y->norm_1() / y->dim()) << " )" << "\n***\n"; } else { *y = 1.0; if(out) *out << "\n****" << "\n**** Ones vector y ( ||y||_1 / n = "<<(y->norm_1()/y->dim())<<" )" << "\n***\n"; } // t = [ D*y; y ] LinAlgOpPack::V_MtV(&*t->sub_view(var_dep),*D,BLAS_Cpp::no_trans,*y); *t->sub_view(var_indep) = *y; value_type fd_rGf_y = 0.0; // fd_Gf_y preformed_fd = fd_deriv_prod.calc_deriv_product( xo,xl,xu ,*t,NULL,NULL,true,nlp,&fd_rGf_y,NULL,out,dump_all(),dump_all() ); if( !preformed_fd ) goto FD_NOT_PREFORMED; if(out) *out << "fd_prod(f,[D*y;y]) = " << fd_rGf_y << "\n"; // rGf_y = rGf'*y const value_type rGf_y = dot(*rGf,*y); if(out) *out << "rGf'*y = " << rGf_y << "\n"; // Compare fd_rGf_y and rGf*y const value_type calc_err = ::fabs( ( rGf_y - fd_rGf_y )/( ::fabs(rGf_y) + ::fabs(fd_rGf_y) + small_num ) ); if( calc_err >= Gc_warning_tol() ) { max_warning_viol = my_max( max_warning_viol, calc_err ); ++num_warning_viol; } if(out) *out << "\nrel_err(rGf'*y,fd_prod(f,[D*y;y])) = " << "rel_err(" << fd_rGf_y << "," << rGf_y << ") = " << calc_err << endl; if( calc_err >= Gf_error_tol() ) { if(out) *out << "Error, above relative error exceeded Gc_error_tol = " << Gc_error_tol() << endl; if(print_all_warnings) *out << "\ny =\n" << *y << "\nt = [ D*y; y ] =\n" << *t; update_success( false, &success ); } } } else { TEST_FOR_EXCEPT(true); // ToDo: Test rGf without D? (This is not going to be easy!) } } // /////////////////////////////////////////////////// // (5) Check GcU, and/or Uz (for undecomposed equalities) if(GcU || Uz) { TEST_FOR_EXCEPT(true); // ToDo: Implement! } FD_NOT_PREFORMED: if(!preformed_fd) { if(out) *out << "\nError, the finite difference computation was not preformed due to cramped bounds\n" << "Finite difference test failed!\n" << endl; return false; } } // end try catch( const AbstractLinAlgPack::NaNInfException& except ) { if(out) *out << "Error, found a NaN or Inf. Stoping tests\n"; success = false; } if( out ) { if( success ) *out << "\nCongradulations, all the finite difference errors where within the\n" "specified error tolerances!\n"; else *out << "\nOh no, at least one of the above finite difference tests failed!\n"; } return success; }
bool IterationPack::TestingPack::TestAlgorithmState(std::ostream* out) { using std::endl; using std::setw; using TestingHelperPack::update_success; try { bool success = true, result; // const int w = 15; if(out) *out << std::boolalpha; if(out) *out<< "\n\n******************************\n" << "*** Testing AlgorithmState ***\n" << "******************************\n" << "\nWarning: this interface is weakly typed and mistakes" << "can be very bad\n"; typedef double alpha_k_t; typedef std::vector<double> x_k_t; typedef B V_k_t; typedef IterQuantityAccessContiguous<alpha_k_t> alpha_t; typedef IterQuantityAccessContiguous<x_k_t> x_t; typedef IterQuantityAccessContiguous<V_k_t> V_t; if(out) *out << "\n*** Create state object ...\n"; AlgorithmState state(4); // Set three types of iteration quantity access objects. if(out) *out << "\n*** Set three types of iteration quantity access objects.\n"; if(out) *out << "set IterQuantityAccessContiguous<double>(2,\"alpha\")\n"; state.set_iter_quant( "alpha", Teuchos::rcp( new alpha_t( 2,"alpha" #ifdef _MIPS_CXX ,Teuchos::RCP<Teuchos::AbstractFactoryStd<alpha_k_t,alpha_k_t> >( new Teuchos::AbstractFactoryStd<alpha_k_t,alpha_k_t>()) #endif )) ); if(out) *out << "set IterQuantityAccessContiguous<std::vector<double> >(2,\"x\")\n"; state.set_iter_quant( "x", Teuchos::rcp( new x_t( 2,"x" #ifdef _MIPS_CXX ,Teuchos::RCP<Teuchos::AbstractFactoryStd<x_k_t,x_k_t> >( new Teuchos::AbstractFactoryStd<x_k_t,x_k_t>()) #endif )) ); if(out) *out << "set IterQuantityAccessDerivedToBase<B,D>(1,\"V\")\n"; state.set_iter_quant( "V" ,Teuchos::rcp( new V_t( 1 ,"V" ,Teuchos::rcp( new Teuchos::AbstractFactoryStd<V_k_t,D> ) ) ) ); // Try to add the same name again. if(out) *out << "\nTry to add \"x\" (should throw execption) : "; try { state.set_iter_quant( "x", Teuchos::rcp( new x_t( 2,"x" #ifdef _MIPS_CXX ,Teuchos::RCP<Teuchos::AbstractFactoryStd<x_k_t,x_k_t> >( new Teuchos::AbstractFactoryStd<x_k_t,x_k_t>()) #endif )) ); success = false; if(out) *out << "false\n"; } catch(const AlgorithmState::AlreadyExists& expt) { if(out) *out << "Caught a AlgorithmState::AlreadyExists execption : " << expt.what() << " : true\n" << endl; } // dump the iteration quantity names, ids, and concrete types. if(out) { *out << "\n*** dump iteration quantitys\n"; state.dump_iter_quant(*out); } update_success( result = state.k() == 0, &success ); if(out) *out << "\nstate.k() == 0 : " << result << endl; // Set the iteration quantities for the kth iteration and check them if(out) *out << "\n*** Set iteration quantities for the kth iteration\n"; if(out) *out << "\nSet alpha_k(0) = 5.0 then get alpha_k(0) == 5.0 : "; alpha_t *alpha = dynamic_cast<alpha_t*>( &state.iter_quant("alpha") ); alpha->set_k(0) = 5.0; alpha = dynamic_cast<alpha_t*>( &state.iter_quant("alpha") ); update_success( result = alpha->get_k(0) == 5.0, &success ); if(out) *out << result << endl; if(out) *out << "\nSet x_k(0)[0] = 2.0 then get x_k(0)[0] == 2.0 : "; x_t *x = dynamic_cast<x_t*>( &state.iter_quant("x") ); x->set_k(0).resize(1); x->set_k(0)[0] = 2.0; x = dynamic_cast<x_t*>( &state.iter_quant("x") ); update_success( result = x->get_k(0)[0] == 2.0, &success ); if(out) *out << result << endl; if(out) *out << "\nSet V_k(0).alpha() = 3.0 then get V_k(0).alpha() == 3.0 : "; V_t *V = dynamic_cast<V_t*>( &state.iter_quant("V") ); V->set_k(0).alpha(3.0); V = dynamic_cast<V_t*>( &state.iter_quant("V") ); update_success( result = V->get_k(0).alpha() == 3.0, &success ); if(out) *out << result << endl; // Use an id to get at an iteration quantity. if(out) *out << "\n*** Use an id to get at an iteration quantity\n"; if(out) *out << "\nid for \"x\" is : "; AlgorithmState::iq_id_type x_id = state.get_iter_quant_id("x"); if(out) *out << x_id << endl; if(out) *out << "\nAccess \"x\" using id and x_k(0)[0] == 2.0 : "; x = dynamic_cast<x_t*>( &state.iter_quant(x_id) ); update_success( result = x->get_k(0)[0] == 2.0, &success ); if(out) *out << result << endl; // use a nonexistant name if(out) *out << "\n*** Use a nonexistant name or id to access iteration quantity\n"; if(out) *out << "id for \"X\" is DOES_NOT_EXIST : "; update_success( result = state.get_iter_quant_id("X") == AlgorithmState::DOES_NOT_EXIST , & success ); if(out) *out << result << endl; if(out) *out << "\nAccess nonexistant iteration quantity by name \"X\" throws a AlgorithmState::DoesNotExist exception : "; try { state.iter_quant("X"); success = false; if(out) *out << false << endl; } catch(const AlgorithmState::DoesNotExist& expt) { if(out) *out << true << endl; } // use a nonexistant id if(out) *out << "\nUse of a nonexistant id = 100 throws a AlgorithmState::DoesNotExist exception : "; try { state.iter_quant(100); success = false; if(out) *out << false << endl; } catch(const AlgorithmState::DoesNotExist& expt) { if(out) *out << true << endl; } // update the iteration if(out) *out << "\n*** Update iteration quantities k+1 = k then check\n"; if(out) *out << "alpha_k(+1) = alpha_k(0)...\n"; alpha = dynamic_cast<alpha_t*>( &state.iter_quant("alpha") ); { alpha_k_t &alpha_k = alpha->get_k(0); alpha->set_k(+1) = alpha_k; } if(out) *out << "x_k(+1) = x_k(0)...\n"; x = dynamic_cast<x_t*>( &state.iter_quant("x") ); { x_k_t &x_k = x->get_k(0); x->set_k(+1) = x_k; } if(out) *out << "V_k(+1) = V_k(0)...\n"; V = dynamic_cast<V_t*>( &state.iter_quant("V") ); { V_k_t &V_k = V->get_k(0); V->set_k(+1) = V_k; } if(out) *out << "shift reference from k to k+1...\n"; state.next_iteration(); if(out) *out << "\nalpha_k(-1) == 5.0 : "; alpha = dynamic_cast<alpha_t*>( &state.iter_quant("alpha") ); update_success( result = alpha->get_k(-1) == 5.0, &success ); if(out) *out << result << endl; if(out) *out << "alpha_k(0) == 5.0 : "; update_success( result = alpha->get_k(0) == 5.0, &success ); if(out) *out << result << endl; if(out) *out << "\nx_k(-1)[0] == 2.0 : "; x = dynamic_cast<x_t*>( &state.iter_quant("x") ); update_success( result = x->get_k(-1)[0] == 2.0, &success ); if(out) *out << result << endl; if(out) *out << "x_k(0)[0] == 2.0 : "; update_success( result = x->get_k(0)[0] == 2.0, &success ); if(out) *out << result << endl; if(out) *out << "\nV_k(0).alpha() == 3.0 : "; V = dynamic_cast<V_t*>( &state.iter_quant("V") ); update_success( result = V->get_k(0).alpha() == 3.0, &success ); if(out) *out << result << endl; // erase an iteration quantity then try to access it if(out) *out << "\n*** Erasing iteration quantity \"x\" then trying to access it throws" " a AlgorithmState::DoesNotExist exception : "; state.erase_iter_quant("x"); try { state.iter_quant(x_id); if(out) *out << false << endl; update_success( false, &success ); } catch(const AlgorithmState::DoesNotExist& expt) { if(out) *out << true << endl; } // final printout. if(out) { if(success) { *out << "\n*** Congradulations, all of the tests for AlgorihtmState" " returned the expected results\n"; } else { *out << "\n*** Oops, at least one of the above tests for AlgorihtmState" " did not return the expected results ***\n"; } } return success; } // end try catch(const std::exception& excpt) { if(out) *out << "\nCaught a std::exception: " << typeName(excpt) << " : " << excpt.what() << endl; } catch(...) { if(out) *out << "\nCaught an unknown exception\n"; } if(out) *out << "\n*** Oops, If you read this some function throw an unexpected exception and the tests have failed!\n"; return false; }
bool NLPInterfacePack::test_nlp_direct( NLPDirect *nlp ,OptionsFromStreamPack::OptionsFromStream *options ,std::ostream *out ) { using TestingHelperPack::update_success; bool result; bool success = true; Teuchos::VerboseObjectTempState<NLP> nlpOutputTempState(Teuchos::rcp(nlp,false),Teuchos::getFancyOStream(Teuchos::rcp(out,false)),Teuchos::VERB_LOW); if(out) *out << "\n****************************" << "\n*** test_nlp_direct(...) ***" << "\n*****************************\n"; nlp->initialize(true); // Test the DVector spaces if(out) *out << "\nTesting the vector spaces ...\n"; VectorSpaceTester vec_space_tester; if(options) { VectorSpaceTesterSetOptions opt_setter(&vec_space_tester); opt_setter.set_options(*options); } if(out) *out << "\nTesting nlp->space_x() ...\n"; result = vec_space_tester.check_vector_space(*nlp->space_x(),out); if(out) { if(result) *out << "nlp->space_x() checks out!\n"; else *out << "nlp->space_x() check failed!\n"; } update_success( result, &success ); if(out) *out << "\nTesting nlp->space_x()->sub_space(nlp->var_dep()) ...\n"; result = vec_space_tester.check_vector_space( *nlp->space_x()->sub_space(nlp->var_dep()),out); if(out) { if(result) *out << "nlp->space_x()->sub_space(nlp->var_dep()) checks out!\n"; else *out << "nlp->space_x()->sub_space(nlp->var_dep()) check failed!\n"; } update_success( result, &success ); if(out) *out << "\nTesting nlp->space_x()->sub_space(nlp->var_indep()) ...\n"; result = vec_space_tester.check_vector_space( *nlp->space_x()->sub_space(nlp->var_indep()),out); if(out) { if(result) *out << "nlp->space_x()->sub_space(nlp->var_indep()) checks out!\n"; else *out << "nlp->space_x()->sub_space(nlp->var_indep()) check failed!\n"; } update_success( result, &success ); if(out) *out << "\nTesting nlp->space_c() ...\n"; result = vec_space_tester.check_vector_space(*nlp->space_c(),out); if(out) { if(result) *out << "nlp->space_c() checks out!\n"; else *out << "nlp->space_c() check failed!\n"; } update_success( result, &success ); if(out) *out << "\nTesting nlp->space_c()->sub_space(nlp->con_decomp()) ...\n"; result = vec_space_tester.check_vector_space( *nlp->space_c()->sub_space(nlp->con_decomp()),out); if(out) { if(result) *out << "nlp->space_c()->sub_space(nlp->con_decomp()) checks out!\n"; else *out << "nlp->space_c()->sub_space(nlp->con_decomp()) check failed!\n"; } update_success( result, &success ); if( nlp->con_decomp().size() < nlp->m() ) { if(out) *out << "\nTesting nlp->space_c()->sub_space(nlp->con_undecomp()) ...\n"; result = vec_space_tester.check_vector_space( *nlp->space_c()->sub_space(nlp->con_undecomp()),out); if(out) { if(result) *out << "nlp->space_c()->sub_space(nlp->con_undecomp()) checks out!\n"; else *out << "nlp->space_c()->sub_space(nlp->con_undecomp()) check failed!\n"; } update_success( result, &success ); } // Test the NLP interface first! NLPTester nlp_tester; if(options) { NLPTesterSetOptions nlp_tester_opt_setter(&nlp_tester); nlp_tester_opt_setter.set_options(*options); } const bool print_all_warnings = nlp_tester.print_all(); result = nlp_tester.test_interface( nlp, nlp->xinit(), print_all_warnings, out ); update_success( result, &success ); // Test the NLPDirect interface now! const bool supports_Gf = nlp->supports_Gf(); if(out) *out << "\nCalling nlp->calc_point(...) at nlp->xinit() ...\n"; const size_type n = nlp->n(), m = nlp->m(); const Range1D var_dep = nlp->var_dep(), var_indep = nlp->var_indep(), con_decomp = nlp->con_decomp(), con_undecomp = nlp->con_undecomp(); VectorSpace::vec_mut_ptr_t c = nlp->space_c()->create_member(), Gf = nlp->space_x()->create_member(), py = nlp->space_x()->sub_space(var_dep)->create_member(), rGf = nlp->space_x()->sub_space(var_indep)->create_member(); NLPDirect::mat_fcty_ptr_t::element_type::obj_ptr_t GcU = con_decomp.size() < m ? nlp->factory_GcU()->create() : Teuchos::null, D = nlp->factory_D()->create(), Uz = con_decomp.size() < m ? nlp->factory_Uz()->create() : Teuchos::null; nlp->calc_point( nlp->xinit(), NULL, c.get(), true, supports_Gf?Gf.get():NULL, py.get(), rGf.get() ,GcU.get(), D.get(), Uz.get() ); if(out) { if(supports_Gf) { *out << "\n||Gf||inf = " << Gf->norm_inf(); if(nlp_tester.print_all()) *out << "\nGf =\n" << *Gf; } *out << "\n||py||inf = " << py->norm_inf(); if(nlp_tester.print_all()) *out << "\npy =\n" << *py; *out << "\n||rGf||inf = " << rGf->norm_inf(); if(nlp_tester.print_all()) *out << "\nrGf =\n" << *rGf; if(nlp_tester.print_all()) *out << "\nD =\n" << *D; if( con_decomp.size() < m ) { TEST_FOR_EXCEPT(true); // ToDo: Print GcU and Uz } *out << "\n"; } CalcFiniteDiffProd calc_fd_prod; if(options) { CalcFiniteDiffProdSetOptions options_setter( &calc_fd_prod ); options_setter.set_options(*options); } NLPDirectTester nlp_first_order_direct_tester(Teuchos::rcp(&calc_fd_prod,false)); if(options) { NLPDirectTesterSetOptions nlp_tester_opt_setter(&nlp_first_order_direct_tester); nlp_tester_opt_setter.set_options(*options); } result = nlp_first_order_direct_tester.finite_diff_check( nlp, nlp->xinit() ,nlp->num_bounded_x() ? &nlp->xl() : NULL ,nlp->num_bounded_x() ? &nlp->xu() : NULL ,c.get() ,supports_Gf?Gf.get():NULL,py.get(),rGf.get(),GcU.get(),D.get(),Uz.get() ,print_all_warnings, out ); update_success( result, &success ); return success; }
bool NLPInterfacePack::test_nlp_first_order( NLPFirstOrder *nlp ,OptionsFromStreamPack::OptionsFromStream *options ,std::ostream *out ) { namespace rcp = MemMngPack; using TestingHelperPack::update_success; bool result; bool success = true; Teuchos::VerboseObjectTempState<NLP> nlpOutputTempState(Teuchos::rcp(nlp,false),Teuchos::getFancyOStream(Teuchos::rcp(out,false)),Teuchos::VERB_LOW); if(out) *out << "\n*********************************" << "\n*** test_nlp_first_order(...) ***" << "\n*********************************\n"; nlp->initialize(true); // Test the DVector spaces if(out) *out << "\nTesting the vector spaces ...\n"; VectorSpaceTester vec_space_tester; if(options) { VectorSpaceTesterSetOptions opt_setter(&vec_space_tester); opt_setter.set_options(*options); } if(out) *out << "\nTesting nlp->space_x() ...\n"; result = vec_space_tester.check_vector_space(*nlp->space_x(),out); if(out) { if(result) *out << "nlp->space_x() checks out!\n"; else *out << "nlp->space_x() check failed!\n"; } update_success( result, &success ); if( nlp->m() ) { if(out) *out << "\nTesting nlp->space_c() ...\n"; result = vec_space_tester.check_vector_space(*nlp->space_c(),out); if(out) { if(result) *out << "nlp->space_c() checks out!\n"; else *out << "nlp->space_c() check failed!\n"; } update_success( result, &success ); } // Test the NLP interface first! NLPTester nlp_tester; if(options) { NLPTesterSetOptions nlp_tester_opt_setter(&nlp_tester); nlp_tester_opt_setter.set_options(*options); } const bool print_all_warnings = nlp_tester.print_all(); result = nlp_tester.test_interface( nlp, nlp->xinit(), print_all_warnings, out ); update_success( result, &success ); // Test the NLPFirstOrder interface now! const size_type n = nlp->n(), m = nlp->m(); VectorSpace::vec_mut_ptr_t c = m ? nlp->space_c()->create_member() : Teuchos::null, Gf = nlp->space_x()->create_member(); NLPFirstOrder::mat_fcty_ptr_t::element_type::obj_ptr_t Gc = m ? nlp->factory_Gc()->create() : Teuchos::null; if(m) { if(out) *out << "\nCalling nlp->calc_Gc(...) at nlp->xinit() ...\n"; nlp->set_Gc( Gc.get() ); nlp->calc_Gc( nlp->xinit(), true ); if(nlp_tester.print_all()) { *out << "\nGc =\n" << *Gc; } } if(out) *out << "\nCalling nlp->calc_Gf(...) at nlp->xinit() ...\n"; nlp->set_Gf( Gf.get() ); nlp->calc_Gf( nlp->xinit(), m == 0 ); if(nlp_tester.print_all()) *out << "\nGf =\n" << *Gf; CalcFiniteDiffProd calc_fd_prod; if(options) { CalcFiniteDiffProdSetOptions options_setter( &calc_fd_prod ); options_setter.set_options(*options); } NLPFirstDerivTester nlp_first_derivatives_tester(Teuchos::rcp(&calc_fd_prod,false)); if(options) { NLPFirstDerivTesterSetOptions nlp_tester_opt_setter(&nlp_first_derivatives_tester); nlp_tester_opt_setter.set_options(*options); } result = nlp_first_derivatives_tester.finite_diff_check( nlp, nlp->xinit() ,nlp->num_bounded_x() ? &nlp->xl() : NULL ,nlp->num_bounded_x() ? &nlp->xu() : NULL ,Gc.get(), Gf.get() ,print_all_warnings, out ); update_success( result, &success ); return success; }