60 switch( solution_type ) {
62 case qpst::OPTIMAL_SOLUTION:
63 return "OPTIMAL_SOLUTION";
64 case qpst::PRIMAL_FEASIBLE_POINT:
65 return "PRIMAL_FEASIBLE_POINT";
66 case qpst::DUAL_FEASIBLE_POINT:
67 return "DUAL_FEASIBLE_POINT";
68 case qpst::SUBOPTIMAL_POINT:
69 return "SUBOPTIMAL_POINT";
123 ,
const char err_name[]
125 ,
const char error_tol_name[]
127 ,
const char warning_tol_name[]
131 if( err >= error_tol ) {
133 *out <<
"\n" << err_name <<
" = " << err <<
" >= " << error_tol_name <<
" = " << error_tol << std::endl;
136 else if( err >= warning_tol ) {
138 *out <<
"\n" << err_name <<
" = " << err <<
" >= " << warning_tol_name <<
" = " << warning_tol << std::endl;
144 namespace ConstrainedOptPack {
156 :opt_warning_tol_(opt_warning_tol)
157 ,opt_error_tol_(opt_error_tol)
158 ,feas_warning_tol_(feas_warning_tol)
159 ,feas_error_tol_(feas_error_tol)
160 ,comp_warning_tol_(comp_warning_tol)
161 ,comp_error_tol_(comp_error_tol)
167 ,std::ostream* out,
bool print_all_warnings,
bool print_vectors
168 ,
const Vector& g,
const MatrixSymOp& G
170 ,
const Vector& dL,
const Vector& dU
172 ,
const Vector& eL,
const Vector& eU
177 ,
const Vector* mu,
const Vector* Ed
178 ,
const Vector* lambda,
const Vector* Fd
182 solution_type,infinite_bound,out,print_all_warnings,print_vectors
183 ,g,G,etaL,&dL,&dU,&E,trans_E,&b,&eL,&eU,&F,trans_F,&f
184 ,obj_d,eta,d,nu,mu,Ed,lambda,Fd);
190 ,std::ostream* out,
bool print_all_warnings,
bool print_vectors
191 ,
const Vector& g,
const MatrixSymOp& G
193 ,
const Vector& dL,
const Vector& dU
195 ,
const Vector& eL,
const Vector& eU
199 ,
const Vector* mu,
const Vector* Ed
203 solution_type,infinite_bound,out,print_all_warnings,print_vectors
204 ,g,G,etaL,&dL,&dU,&E,trans_E,&b,&eL,&eU,NULL,
BLAS_Cpp::no_trans,NULL
205 ,obj_d,eta,d,nu,mu,Ed,NULL,NULL);
211 ,std::ostream* out,
bool print_all_warnings,
bool print_vectors
212 ,
const Vector& g,
const MatrixSymOp& G
214 ,
const Vector& dL,
const Vector& dU
219 ,
const Vector* lambda,
const Vector* Fd
223 solution_type,infinite_bound,out,print_all_warnings,print_vectors
224 ,g,G,etaL,&dL,&dU,NULL,
BLAS_Cpp::no_trans,NULL,NULL,NULL,&F,trans_F,&f
225 ,obj_d,eta,d,nu,NULL,NULL,lambda,Fd );
231 ,std::ostream* out,
bool print_all_warnings,
bool print_vectors
232 ,
const Vector& g,
const MatrixSymOp& G
233 ,
const Vector& dL,
const Vector& dU
240 solution_type,infinite_bound,out,print_all_warnings,print_vectors
241 ,g,G,0.0,&dL,&dU,NULL,
BLAS_Cpp::no_trans,NULL,NULL,NULL,NULL,
BLAS_Cpp::no_trans,NULL
242 ,obj_d,NULL,d,nu,NULL,NULL,NULL,NULL);
248 ,std::ostream* out,
bool print_all_warnings,
bool print_vectors
249 ,
const Vector& g,
const MatrixSymOp& G
251 ,
const Vector* dL,
const Vector* dU
253 ,
const Vector* eL,
const Vector* eU
258 ,
const Vector* mu,
const Vector* Ed
259 ,
const Vector* lambda,
const Vector* Fd
263 infinite_bound,g,G,etaL,dL,dU
264 ,E,trans_E,b,eL,eU,F,trans_F,f
265 ,obj_d,eta,d,nu,mu,Ed,lambda,Fd);
268 solution_type,infinite_bound
269 ,out,print_all_warnings,print_vectors,g,G,etaL,dL,dU
270 ,E,trans_E,b,eL,eU,F,trans_F,f
271 ,obj_d,eta,d,nu,mu,Ed,lambda,Fd);
279 ,std::ostream* out,
bool print_all_warnings,
bool print_vectors
280 ,
const Vector& g,
const MatrixSymOp& G
282 ,
const Vector* dL,
const Vector* dU
284 ,
const Vector* eL,
const Vector* eU
289 ,
const Vector* mu,
const Vector* Ed
290 ,
const Vector* lambda,
const Vector* Fd
311 bool test_failed =
false;
320 VectorSpace::vec_mut_ptr_t
321 t_d = d->space().create_member(),
322 u_d = d->space().create_member();
331 <<
"\n*** Begin checking QP optimality conditions ***\n"
332 <<
"\nThe solution type is " << solution_type_str(solution_type) << endl;
334 bool force_opt_error_check
335 = solution_type==qps_t::OPTIMAL_SOLUTION || solution_type==qps_t::DUAL_FEASIBLE_POINT;
336 const bool force_inequality_error_check
337 = solution_type==qps_t::OPTIMAL_SOLUTION || solution_type==qps_t::PRIMAL_FEASIBLE_POINT;
338 const bool force_equality_error_check
339 = solution_type!=qps_t::SUBOPTIMAL_POINT;
340 const bool force_complementarity_error_check
341 = solution_type!=qps_t::SUBOPTIMAL_POINT;
343 const char sep_line[] =
"\n--------------------------------------------------------------------------------\n";
350 <<
"\nChecking d(L)/d(d) = g + G*d + nu + op(E)'*mu - op(F)'*lambda == 0 ...\n";
352 if(out && !force_opt_error_check)
354 <<
"The optimality error tolerance will not be enforced ...\n";
359 opt_scale += g.norm_inf();
362 *out <<
"||g||inf = " << g.norm_inf() << endl;
366 Vp_V( u_d.get(), *t_d );
367 opt_scale += t_d->norm_inf();
370 *out <<
"||G*d||inf = " << t_d->norm_inf() << endl;
372 *out <<
"g + G*d =\n" << *u_d;
376 Vp_V( u_d.get(), *nu );
377 opt_scale += nu->norm_inf();
379 *out <<
"||nu||inf = " << nu->norm_inf() << endl;
384 Vp_V( u_d.get(), *t_d );
385 opt_scale += t_d->norm_inf();
387 *out <<
"||op(E)'*mu||inf = " << t_d->norm_inf() << endl;
389 *out <<
"op(E)'*mu =\n" << *t_d;
395 Vp_V( u_d.get(), *t_d );
396 opt_scale += t_d->norm_inf();
398 *out <<
"||op(F)'*lambda||inf = " << t_d->norm_inf() << endl;
400 *out <<
"op(F)'*lambda =\n" << *t_d;
406 term = ::fabs( (*eta - etaL) * (E ?
dot(*b,*mu) : 0.0) + (F ?
dot(*f,*lambda) : 0.0 ) );
408 *out <<
"|(eta - etaL) * (b'*mu + f'*lambda)| = " << term << endl;
413 if(out && print_vectors)
415 <<
"g + G*d + nu + op(E)'*mu - op(F)'*lambda =\n" << *u_d;
417 Vt_S( u_d.get(), 1.0/(1.0+opt_scale) );
423 <<
"\nopt_scale = " << opt_scale << endl
424 <<
"opt_err = sum( | g + G*d + nu + op(E)'*mu - op(F)'*lambda | / (1+opt_scale) ) / nd\n"
425 <<
" = " << err <<
" / " << nd <<
" = " << (err/nd) << endl;
429 if( force_opt_error_check ) {
430 if( err >= opt_error_tol() ) {
432 *out <<
"\nopt_err = " << err <<
" >= opt_error_tol = " << opt_error_tol() << endl;
435 else if( err >= opt_warning_tol() ) {
437 *out <<
"\nopt_err = " << err <<
" >= opt_error_tol = " << opt_error_tol() << endl;
444 <<
"\nTesting feasibility of the constraints and the complementarity conditions ...\n";
445 if(!force_inequality_error_check)
447 <<
"The inequality feasibility error tolerance will not be enforced ...\n";
448 if(!force_equality_error_check)
450 <<
"The equality feasibility error tolerance will not be enforced ...\n";
451 if(!force_complementarity_error_check)
453 <<
"The complementarity conditions error tolerance will not be enforced ...\n";
461 <<
"\nChecking etaL - eta <= 0 ...\n";
464 <<
"etaL - eta = " << (etaL - (*eta)) << endl;
465 if( etaL - (*eta) > feas_warning_tol() ) {
468 <<
"Warning, etaL - eta = " << etaL <<
" - " << (*eta)
469 <<
" = " << (etaL - (*eta)) <<
" > feas_warning_tol = "
470 << feas_warning_tol() << endl;
472 if( force_inequality_error_check && etaL - (*eta) > feas_error_tol() ) {
475 <<
"Error, etaL - eta = " << etaL <<
" - " << (*eta)
476 <<
" = " << (etaL - (*eta)) <<
" > feas_error_tol = "
477 << feas_error_tol() << endl;
481 d_norm_inf = d->norm_inf();
490 <<
"\nChecking dL - d <= 0 ...\n";
491 V_VmV( u_d.get(), *dL, *d );
492 if(out && print_vectors)
494 <<
"dL - d =\n" << *u_d;
495 Vt_S( u_d.get(), 1.0/(1.0+d_norm_inf) );
500 <<
"\nmax(dL-d) = " << err << endl;
501 if( force_inequality_error_check )
503 out,err,
"max(dU-d)",feas_error_tol(),
"feas_error_tol"
504 ,feas_warning_tol(),
"feas_error_tol",&test_failed
532 <<
"\nChecking d - dU <= 0 ...\n";
533 V_VmV( u_d.get(), *d, *dU );
534 if(out && print_vectors)
536 <<
"d - dU =\n" << *u_d;
537 Vt_S( u_d.get(), 1.0/(1.0+d_norm_inf) );
542 <<
"\nmax(d-dU) = " << err << endl;
543 if( force_inequality_error_check )
545 out,err,
"max(d-dU)",feas_error_tol(),
"feas_error_tol"
546 ,feas_warning_tol(),
"feas_error_tol",&test_failed
576 <<
"\nComputing e = op(E)*d - b*eta ...\n";
577 VectorSpace::vec_mut_ptr_t
578 e = ( trans_E == no_trans ? E->space_cols() : E->space_rows() ).create_member(),
579 t_e = e->space().create_member();
580 V_MtV( e.get(), *E, trans_E, *d );
581 Vp_StV( e.get(), -(*eta), *b );
582 e_norm_inf = e->norm_inf();
583 if(out && print_vectors)
585 <<
"e = op(E)*d - b*eta =\n" << *e;
592 <<
"\nChecking eL - e <= 0 ...\n";
593 V_VmV( t_e.get(), *eL, *e );
594 if(out && print_vectors)
596 <<
"eL - e =\n" << *t_e;
597 Vt_S( t_e.get(), 1.0/(1.0+e_norm_inf) );
602 <<
"\nmax(eL-e) = " << err << endl;
603 if( force_inequality_error_check )
605 out,err,
"max(eL-e)",feas_error_tol(),
"feas_error_tol"
606 ,feas_warning_tol(),
"feas_error_tol",&test_failed
633 <<
"\nChecking e - eU <= 0 ...\n";
634 V_VmV( t_e.get(), *e, *eU );
635 if(out && print_vectors)
637 <<
"\ne - eU =\n" << *t_e;
638 Vt_S( t_e.get(), 1.0/(1.0+e_norm_inf) );
643 <<
"\nmax(e-eU) = " << err << endl;
644 if( force_inequality_error_check )
646 out,err,
"max(e-eU)",feas_error_tol(),
"feas_error_tol"
647 ,feas_warning_tol(),
"feas_error_tol",&test_failed
704 if(solution_type != qps_t::SUBOPTIMAL_POINT) {
707 <<
"\nDarn it! At least one of the enforced QP optimality conditions were "
708 <<
"not within the specified error tolerances!\n";
712 <<
"\nCongradulations! All of the enforced QP optimality conditions were "
713 <<
"within the specified error tolerances!\n";
717 <<
"\n*** End checking QP optimality conditions ***\n";
AbstractLinAlgPack::size_type size_type
virtual bool imp_check_optimality_conditions(QPSolverStats::ESolutionType solution_type, const value_type infinite_bound, std::ostream *out, bool print_all_warnings, bool print_vectors, const Vector &g, const MatrixSymOp &G, value_type etaL, const Vector *dL, const Vector *dU, const MatrixOp *E, BLAS_Cpp::Transp trans_E, const Vector *b, const Vector *eL, const Vector *eU, const MatrixOp *F, BLAS_Cpp::Transp trans_F, const Vector *f, const value_type *obj_d, const value_type *eta, const Vector *d, const Vector *nu, const Vector *mu, const Vector *Ed, const Vector *lambda, const Vector *Fd)
Subclasses are to override this to implement the testing code.
void Vt_S(VectorMutable *v_lhs, const value_type &alpha)
v_lhs *= alpha
RTOp_value_type value_type
void Vp_StV(VectorMutable *v_lhs, const value_type &alpha, const Vector &v_rhs)
v_lhs = alpha * v_rhs + v_lhs
value_type max_element(const Vector &v)
Compute the maximum element in a vector.
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.
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 bool check_optimality_conditions(QPSolverStats::ESolutionType solution_type, const value_type infinite_bound, std::ostream *out, bool print_all_warnings, bool print_vectors, const Vector &g, const MatrixSymOp &G, value_type etaL, const Vector &dL, const Vector &dU, const MatrixOp &E, BLAS_Cpp::Transp trans_E, const Vector &b, const Vector &eL, const Vector &eU, const MatrixOp &F, BLAS_Cpp::Transp trans_F, const Vector &f, const value_type *obj_d, const value_type *eta, const Vector *d, const Vector *nu, const Vector *mu, const Vector *Ed, const Vector *lambda, const Vector *Fd)
Check the optimality conditions for the solved (or partially solved) QP.
Class for storing statistics about a run of a (active set?) QP solver.
value_type dot(const Vector &v_rhs1, const Vector &v_rhs2)
result = v_rhs1' * v_rhs2
Transp trans_not(Transp _trans)
Return the opposite of the transpose argument.
static void validate_input(const value_type infinite_bound, const Vector &g, const MatrixSymOp &G, value_type etaL, const Vector *dL, const Vector *dU, const MatrixOp *E, BLAS_Cpp::Transp trans_E, const Vector *b, const Vector *eL, const Vector *eU, const MatrixOp *F, BLAS_Cpp::Transp trans_F, const Vector *f, const value_type *obj_d, const value_type *eta, const Vector *d, const Vector *nu, const Vector *mu, const Vector *Ed, const Vector *lambda, const Vector *Fd)
This is a (static) function that is used as a utility to validate the input arguments to solve_qp()...
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.
AbstractLinAlgPack::value_type value_type
value_type sum(const Vector &v_rhs)
result = sum( v_rhs(i), i = 1,,,dim )
QPSolverRelaxedTester(value_type opt_warning_tol=1e-10, value_type opt_error_tol=1e-5, value_type feas_warning_tol=1e-10, value_type feas_error_tol=1e-5, value_type comp_warning_tol=1e-10, value_type comp_error_tol=1e-5)
void V_VmV(VectorMutable *v_lhs, const V1 &V1_rhs1, const V2 &V2_rhs2)
v_lhs = V_rhs1 - V_rhs2.
ESolutionType
Enumeration for the type of point returned from solve_qp(...).
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
void Vp_V(VectorMutable *v_lhs, const V &V_rhs)
v_lhs += V_rhs.