15 #include "CoinHelperFunctions.hpp"
16 #include "CoinFinite.hpp"
20 using namespace Couenne;
27 printf (
"Checking solution: %.12e (", obj);
30 printf (
"%g ", solution [i]);
47 if ((v -> Type () ==
VAR) &&
48 (v -> isDefinedInteger ()) &&
49 (v -> Multiplicity () > 0) &&
53 "checkNLP: integrality %d violated: %.6f [%g,%g]\n",
63 const int wrong_obj = 2;
69 CoinCopyN (solution,
nOrigVars_ - ndefined_, sol);
71 CoinCopyN (solution,
nOrigVars_ - ndefined_, sol);
77 printf (
" checkNLP: %d vars -------------------\n ",
domain_.
current () -> Dimension ());
79 if (i && !(i%5)) printf (
"\n ");
95 (objBody -> Index () >= 0) ?
96 sol [objBody -> Index ()] :
97 (*(objBody -> Image () ? objBody -> Image () : objBody)) ();
99 Jnlst () -> Printf (Ipopt::J_ALL,
J_PROBLEM,
" Objective: %.12e %.12e %.12e\n",
100 realobj, objBody -> Index () >= 0 ? sol [objBody -> Index ()] : objBody -> Value (),
101 (*(objBody -> Image () ? objBody -> Image () : objBody)) ());
112 " checkNLP, false objective: computed %g != %g xQ (diff. %g)\n",
113 realobj, obj, realobj - obj);
122 Jnlst () -> Printf (Ipopt::J_ALL,
J_PROBLEM,
" recomputed: %.12e\n", obj);
137 " checkNLP: variable %d out of bounds: %.6f [%g,%g] (diff %g)\n",
150 " checkNLP: integrality %d violated: %.6f [%g,%g]\n",
159 for (
int i=0; i <
nVars (); i++) {
163 if ((v -> Type () !=
AUX) ||
164 (v -> Multiplicity () <= 0))
168 printf (
" "); v ->
print ();
171 img = (*(v -> Image ())) (),
172 diff = fabs (val - img);
173 printf (
": val = %15g; img = %-15g ", val, img);
175 printf (
"[diff %12e] ",
diff);
177 v -> Image () ->
print ();
187 fval = (*(v -> Image ())) (),
188 denom = CoinMax (1., v -> Image () -> gradientNorm (
X ()));
191 if (CoinIsnan (fval)) {
204 ratio = (CoinMax (1., fabs (vval)) /
205 CoinMax (1., fabs (fval)));
221 " checkNLP: auxiliary %d violates tolerance %g by %g/%g = %g\n",
230 for (
int i=0; i <
nCons (); i++) {
235 body = (*(c -> Body ())) (),
236 lhs = (*(c ->
Lb ())) (),
237 rhs = (*(c ->
Ub ())) ();
244 printf (
" checkNLP: constraint %d violated (lhs=%+e body=%+e rhs=%+e, violation %g): ",
245 i, lhs, body, rhs, CoinMax (lhs-body, body-rhs));
255 catch (
int exception) {
273 Jnlst () -> Printf (Ipopt::J_ALL,
J_PROBLEM,
"Done: %d\n", retval);
294 (objBody ->
Index() >= 0) ?
295 sol[objBody->
Index()] :
296 (*(objBody->
Image() ? objBody->
Image() : objBody)) ();
299 "%.12e %.12e %.12e ------------------------------\n",
300 realObj, objBody -> Index () >= 0 ? sol[objBody -> Index ()] : 0.,
301 (*(objBody -> Image () ? objBody -> Image () : objBody)) ());
304 printf(
"### ERROR: CouenneProblem::checkObj(): no objective body\n");
314 const int from,
const int upto,
315 const std::vector<int> listInt,
316 const bool origVarOnly,
317 const bool stopAtFirstViol,
318 const double precision,
double &maxViol)
const {
322 for(
unsigned int i=0; i<listInt.size(); i++) {
324 int ind = listInt[i];
326 if((ind < from) || (
variables_ [ind] -> Multiplicity () <= 0))
335 if ((!origVarOnly) || (v -> Type () ==
VAR)) {
338 if (viol > maxViol) maxViol = viol;
339 if (viol > precision) {
342 "checkInt(): integrality %d violated: %.6f [%g,%g]: integer distance %e > %e (by %e)\n",
347 Jnlst () -> Printf (Ipopt::J_ALL,
J_PROBLEM,
"CouenneProblem::checkInt(): integrality %d violated: %.6f [%g,%g]\n", ind, val,
domain_.
lb (ind),
domain_.
ub (ind));
362 const bool stopAtFirstViol,
363 const double precision,
double &maxViol)
const {
376 if (viol < violUb) viol = violUb;
377 if (viol < violLb) viol = violLb;
379 maxViol = (maxViol > viol ? maxViol : viol);
381 if (viol > precision) {
383 Jnlst()->Printf(Ipopt::J_MOREVECTOR,
J_PROBLEM,
"checkBounds(): variable %d out of bounds: %.6f [%g,%g] (diff %g)\n",
388 Jnlst () -> Printf (Ipopt::J_ALL,
J_PROBLEM,
"CouenneProblem::checkBounds: variable %d out of bounds: %.6f [%g,%g] (diff %g)\n",
404 const bool stopAtFirstViol,
405 const double precision,
double &maxViol)
const {
408 for (
int i=0; i<
nVars(); i++) {
412 if ((v -> Type () !=
AUX) ||
413 (v -> Multiplicity () <= 0))
418 printf (
"before check\n");
430 printf (
"[%g,%g]\n", vdb, fdb);
432 printf (
"checking aux -- %+.12e = %+.12e [%+.12e] ", vdb, fdb, del);
442 fval = (*(v -> Image ())) (),
443 denom = CoinMax (1., v -> Image () -> gradientNorm (
X ()));
446 if (CoinIsnan (fval)) {
459 ratio = (CoinMax (1., fabs (vval)) /
460 CoinMax (1., fabs (fval)));
464 double deldenom = delta/denom;
465 if (maxViol <= deldenom) maxViol = deldenom;
472 Jnlst () -> Printf (Ipopt::J_MOREVECTOR,
J_PROBLEM,
"checkAux(): auxiliary %d violates tolerance %g by %g (deldenom: %g ratio %g)\n", i,
feas_tolerance_, delta, deldenom,
ratio);
476 Jnlst () -> Printf (Ipopt::J_ALL,
J_PROBLEM,
"CouenneProblem::checkAux(): auxiliary %d violates tolerance %g by %g (deldenom: %g ratio %g COUENNE_EPS: %g)\n",
490 const bool stopAtFirstViol,
491 const double precision,
double &maxViol)
const {
494 for (
int i=0; i<
nCons(); i++) {
499 body = (*(c -> Body ())) (),
500 lhs = (*(c ->
Lb ())) (),
501 rhs = (*(c ->
Ub ())) ();
503 double denomUb = 1 + CoinMax (fabs (body), fabs (rhs));
504 double denomLb = 1 + CoinMax (fabs (body), fabs (lhs));
505 double violUb = 0, violRelUb = 0, violAbsUb = 0;
507 violAbsUb = body - rhs;
508 violRelUb = violAbsUb / denomUb;
509 violUb = violAbsUb - precision * denomUb;
511 #ifdef FM_USE_ABS_VIOL_CONS
512 if (maxViol <= violAbsUb) maxViol = violAbsUb;
514 if (maxViol <= violRelUb) maxViol = violRelUb;
517 Jnlst () -> Printf (Ipopt::J_ALL,
J_PROBLEM,
"violAbsUb: %12.10f violRelUb: %12.10f violUb: %12.10f maxViol: %12.10f\n", violAbsUb, violRelUb, violUb, maxViol);
520 double violLb = 0, violRelLb = 0, violAbsLb = 0;
522 violAbsLb = - body + lhs;
523 violRelLb = violAbsLb / denomLb;
524 violLb = violAbsLb - precision * denomLb;
526 #ifdef FM_USE_ABS_VIOL_CONS
527 if (maxViol <= violAbsLb) maxViol = violAbsLb;
529 if (maxViol <= violRelLb) maxViol = violRelLb;
532 Jnlst () -> Printf (Ipopt::J_ALL,
J_PROBLEM,
"violAbsLb: %12.10f violRelLb: %12.10f violLb: %12.10f maxViol: %12.10f\n", violAbsLb, violRelLb, violLb, maxViol);
535 #ifdef FM_USE_ABS_VIOL_CONS
536 if((violAbsUb > precision) || (violAbsLb > precision)) {
539 printf (
"CouenneProblem::checkCons(): constraint %d violated (lhs=%+e body=%+e rhs=%+e, absolute violation: %g)\n", i, lhs, body, rhs, CoinMax(violAbsUb, violAbsLb));
543 Jnlst () -> Printf (Ipopt::J_ALL,
J_PROBLEM,
"CouenneProblem::checkCons(): constraint %d violated (lhs=%+e body=%+e rhs=%+e, absolute violation: %g)\n", i, lhs, body, rhs, CoinMax (violAbsUb, violAbsLb));
546 if(stopAtFirstViol) {
551 if((violUb > 0) || (violLb > 0)) {
554 printf (
"CouenneProblem::checkCons(): constraint %d violated (lhs=%+e body=%+e rhs=%+e, relative violation: %g)\n", i, lhs, body, rhs, CoinMax(violRelUb, violRelLb));
558 Jnlst () -> Printf (Ipopt::J_ALL,
J_PROBLEM,
"CouenneProblem::checkCons(): constraint %d violated (lhs=%+e body=%+e rhs=%+e, relative violation: %g)\n", i, lhs, body, rhs, CoinMax (violRelUb, violRelLb));
561 if(stopAtFirstViol) {
572 const double obj,
const bool careAboutObj,
573 const bool stopAtFirstViol,
575 const double precision)
const {
577 if (careAboutObj && stopAtFirstViol) {
578 printf(
"CouenneProblem::checkNLP2(): ### ERROR: careAboutObj: true and stopAtFirstViol: true are incompatible\n");
584 double maxViolCouSol = 0;
585 double maxViolRecSol = 0;
590 printf(
"Integrality:\n");
591 for (
register int i=0; i<
nVars(); i++) {
603 for (
register int i=0; i<
nVars(); i++) {
608 if( (v -> Type () ==
VAR)) {
615 for (
register int i=0; i<
nVars(); i++) {
620 if( (v -> Type () ==
AUX)) {
627 for (
register int i=0; i<
nVars(); i++) {
637 printf (
"checking solution:\n");
639 printf (
"%.12e ", solution [i]);
640 printf (
"\nCouenneProblem::checkNLP2(): Start checking recomputed_solution\n");
647 false, stopAtFirstViol,
648 precision, maxViolRecSol);
649 bool isFeasCou = isFeasRec;
650 maxViolCouSol = maxViolRecSol;
652 if (stopAtFirstViol && !isFeasRec &&
Jnlst () -> ProduceOutput (Ipopt::J_ALL,
J_PROBLEM))
653 printf(
"CouenneProblem::checkNLP2(): recomputed_solution is infeasible (some orig vars not integer feasible; violation: %12.10g)\n", maxViolRecSol);
657 printf(
"CouenneProblem::checkNLP2(): ### ERROR: cardInitDom: %d nVars: %d\n",
getRecordBestSol()->getCardInitDom(),
nVars());
660 if(getInitDomLb() == NULL) {
661 printf(
"CouenneProblem::checkNLP2(): ### WARNING: initDomLb == NULL\n");
663 if(getInitDomUb() == NULL) {
664 printf(
"CouenneProblem::checkNLP2(): ### WARNING: initDomUb == NULL\n");
686 printf (
"checkNLP2(): recomputed_solution: %d vars -------------------\n",
domain_.
current () -> Dimension ());
688 for (
int i=0; i<
nVars (); i++) {
690 if (v -> Multiplicity () <= 0)
693 double soli = solution[i];
698 if (maxDelta < fabs(solution[i] -
domain_.
x(i))) maxDelta = fabs (solution[i] -
domain_.
x(i));
701 if(v -> Type() ==
AUX) {
705 printf (
"maxDelta: %.12g\n", maxDelta);
710 if(!stopAtFirstViol || isFeasRec) {
712 false, stopAtFirstViol,
713 precision, maxViolRecSol);
716 Jnlst () -> Printf (Ipopt::J_ALL,
J_PROBLEM,
"CouenneProblem::checkNLP2(): recomputed_solution is infeasible (some aux vars not integer feasible; violation: %12.10g)\n", maxViolRecSol);
723 double objRecSol =
checkObj(couRecSol, precision);
724 double objCouSol = 0;
727 if(!stopAtFirstViol || isFeasRec) {
728 bool isFeasBnd =
checkBounds(couRecSol, stopAtFirstViol,
729 precision, maxViolRecSol);
733 Jnlst () -> Printf (Ipopt::J_ALL,
J_PROBLEM,
"CouenneProblem::checkNLP2(): recomputed_solution is infeasible (violated bounds; violation: %12.10g)\n", maxViolRecSol);
739 if(!stopAtFirstViol || isFeasRec) {
740 bool isFeasAux =
checkAux(couRecSol, stopAtFirstViol,
741 precision, maxViolRecSol);
745 Jnlst () -> Printf (Ipopt::J_ALL,
J_PROBLEM,
"CouenneProblem::checkNLP2(): recomputed_solution is infeasible (violated Aux; violation: %12.10g)\n", maxViolRecSol);
752 if(!stopAtFirstViol || isFeasRec) {
753 bool isFeasCons =
checkCons(couRecSol, stopAtFirstViol,
754 precision, maxViolRecSol);
758 Jnlst () -> Printf (Ipopt::J_ALL,
J_PROBLEM,
"CouenneProblem::checkNLP2(): recomputed_solution is infeasible (violated constraint; violation: %12.10g)\n", maxViolRecSol);
764 Jnlst () -> Printf (Ipopt::J_ALL,
J_PROBLEM,
"CouenneProblem::checkNLP2(): end check recomputed_solution (maxViol: %12.10g)\n", maxViolRecSol);
766 double objErrorRecSol = objRecSol - obj;
771 bool useRecSol =
false;
772 if(isFeasRec && (objErrorRecSol < precision)) {
780 Jnlst () -> Printf (Ipopt::J_ALL,
J_PROBLEM,
"CouenneProblem::checkNLP2(): Start checking solution (maxViol: %g)\n", maxViolCouSol);
782 CoinCopyN(solution,
nVars(), couSol);
788 printf (
"checkNLP2(): solution: %d vars -------------------\n",
domain_.
current () -> Dimension ());
793 if (fabs (solution[i] -
domain_.
x(i)) > maxDelta)
794 maxDelta = fabs(solution[i] -
domain_.
x(i));
796 printf(
"maxDelta: %.12g\n", maxDelta);
799 if(!stopAtFirstViol || isFeasCou) {
801 false, stopAtFirstViol,
802 precision, maxViolCouSol);
805 Jnlst () -> Printf (Ipopt::J_ALL,
J_PROBLEM,
"CouenneProblem::checkNLP2(): solution is infeasible (some aux vars not integer feasible; violation: %12.10g)\n", maxViolCouSol);
811 objCouSol =
checkObj(couSol, precision);
813 if(!stopAtFirstViol || isFeasCou) {
814 bool isFeasCouBnd =
checkBounds(couSol, stopAtFirstViol,
815 precision, maxViolCouSol);
818 Jnlst () -> Printf (Ipopt::J_ALL,
J_PROBLEM,
"CouenneProblem::checkNLP2(): solution is infeasible (some bounds are violated; violation: %12.10g)\n", maxViolCouSol);
824 if(!stopAtFirstViol || isFeasCou) {
825 bool isFeasCouAux =
checkAux(couSol, stopAtFirstViol,
826 precision, maxViolCouSol);
829 Jnlst () -> Printf (Ipopt::J_ALL,
J_PROBLEM,
"CouenneProblem::checkNLP2(): solution is infeasible (violated Aux; violation: %12.10g)\n", maxViolCouSol);
835 if(!stopAtFirstViol || isFeasCou) {
836 bool isFeasCouCons =
checkCons(couSol, stopAtFirstViol,
837 precision, maxViolCouSol);
840 Jnlst () -> Printf (Ipopt::J_ALL,
J_PROBLEM,
"CouenneProblem::checkNLP2(): solution is infeasible (violated constraint; violation: %12.10g)\n", maxViolCouSol);
846 Jnlst () -> Printf (Ipopt::J_ALL,
J_PROBLEM,
"CouenneProblem::checkNLP2(): end check solution (maxViol: %12.10g)\n", maxViolCouSol);
848 double objErrorCouSol = objCouSol - obj;
852 double delObj = objErrorCouSol - objErrorRecSol;
853 double delViol = maxViolCouSol - maxViolRecSol;
879 if(fabs(delViol) < 10 * precision) {
880 useRecSol = (delObj <= 0 ?
false :
true);
883 if(fabs(delObj) < 10 * precision) {
884 useRecSol = (delViol > 0 ?
false :
true);
887 double ratObj = fabs(delObj)/(1+fabs(obj));
888 if(ratObj < fabs(delViol)) {
889 useRecSol = (delViol > 0 ?
false :
true);
892 useRecSol = (delObj > 0 ?
false :
true);
914 if(!stopAtFirstViol || isFeas) {
917 maxViol = maxViolRecSol;
919 Jnlst () -> Printf (Ipopt::J_ALL,
J_PROBLEM,
"CouenneProblem::checkNLP2(): select recomputed_solution (maxViol: %12.10g)\n", maxViol);
922 recBSol -> setModSol(couSol,
nVars(), objCouSol, maxViolCouSol);
923 maxViol = maxViolCouSol;
925 Jnlst () -> Printf (Ipopt::J_ALL,
J_PROBLEM,
"CouenneProblem::checkNLP2(): select solution (maxViol: %12.10g)\n", maxViol);
937 printf (
"checkNLP2(): RETURN: feasible (maxViol: %g)\n", maxViol);
940 printf (
"checkNLP2(): RETURN: recomputed_solution and solution are infeasible\n");
941 if(!stopAtFirstViol) {
942 printf(
"(maxViol: %g)\n", maxViol);
962 const bool careAboutObj,
963 const bool stopAtFirstViol,
965 const double precision)
const {
983 retval = checkNLP1 (solution, obj, recompute_obj);
bool checkInt(const CouNumber *sol, const int from, const int upto, const std::vector< int > listInt, const bool origVarOnly, const bool stopAtFirstViol, const double precision, double &maxViol) const
check integrality of vars in sol with index between from and upto (original vars only if origVarOnly ...
int nVars() const
Total number of variables.
static Bigint * diff(Bigint *a, Bigint *b)
CouNumber & ub(register int index)
current upper bound
CouNumber & lb(register int index)
current lower bound
void print(std::ostream &=std::cout)
Display current representation of problem: objective, linear and nonlinear constraints, and auxiliary variables.
expression * Body() const
get body
bool checkNLP0(const double *solution, double &obj, bool recompute_obj=false, const bool careAboutObj=false, const bool stopAtFirstViol=true, const bool checkAll=false, const double precision=-1) const
And finally a method to get both.
bool checkAux(const CouNumber *sol, const bool stopAtFirstViol, const double precision, double &maxViol) const
returns true iff value of all auxiliaries are within bounds
bool checkNLP2(const double *solution, const double obj, const bool careAboutObj, const bool stopAtFirstViol, const bool checkAll, const double precision) const
Return true if either solution or recomputed_solution obtained using getAuxs() from the original vari...
double checkObj(const CouNumber *sol, const double &precision) const
Recompute objective value for sol.
int Dimension()
return dimension_
bool * getInitIsInt() const
virtual expression * Image() const
return pointer to corresponding expression (for auxiliary variables only)
void fint fint fint real fint real real real real real real real real real * e
Class to represent nonlinear constraints.
void restoreUnusedOriginals(CouNumber *=NULL) const
Some originals may be unused due to their zero multiplicity (that happens when they are duplicates)...
bool checkBounds(const CouNumber *sol, const bool stopAtFirstViol, const double precision, double &maxViol) const
Check bounds; returns true iff feasible for given precision.
std::vector< int > getListInt() const
static double ratio(Bigint *a, Bigint *b)
void getAuxs(CouNumber *) const
Get auxiliary variables from original variables.
int ndefined_
Number of "defined variables" (aka "common expressions")
virtual int Index() const
Return index of variable (only valid for exprVar and exprAux)
CouenneRecordBestSol * getRecordBestSol() const
returns recorded best solution
ConstJnlstPtr Jnlst() const
Provide Journalist.
CouenneConstraint * Con(int i) const
i-th constraint
void pop()
restore previous point
std::vector< exprVar * > variables_
Variables (original, auxiliary, and defined)
CouenneRecordBestSol * recBSol
Domain domain_
current point and bounds;
CouNumber * Ub() const
Return vector of upper bounds.
static const int infeasible
double CouNumber
main number type in Couenne
int nOrigVars_
Number of original variables.
CouNumber feas_tolerance_
feasibility tolerance (to be used in checkNLP)
CouNumber * X() const
Return vector of variables.
CouNumber & x(register int index)
current variable
virtual enum auxSign sign() const
return its sign in the definition constraint
void push(int dim, CouNumber *x, CouNumber *lb, CouNumber *ub, bool copy=true)
save current point and start using another
int nCons() const
Get number of constraints.
bool checkCons(const CouNumber *sol, const bool stopAtFirstViol, const double precision, double &maxViol) const
returns true iff value of all auxiliaries are within bounds
void setModSol(const double *givenModSol, const int givenModCard, const double givenModVal, const double givenModMaxViol)
bool checkNLP(const double *solution, double &obj, bool recompute=false) const
Check if solution is MINLP feasible.
CouenneObjective * Obj(int i) const
i-th objective
DomainPoint * current()
return current point
const Ipopt::EJournalCategory J_PROBLEM(Ipopt::J_USER4)
CouNumber * Lb() const
Return vector of lower bounds.