00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "CoinHelperFunctions.hpp"
00012 #include "CouenneProblem.hpp"
00013
00014
00015 bool CouenneProblem::checkNLP (const double *solution, double &obj, bool recompute) const {
00016
00017 const int infeasible = 1;
00018 const int wrong_obj = 2;
00019
00020
00021
00022
00023
00024
00025
00026 for (int i=0; i < nOrigVars_; i++) {
00027
00028 CouNumber val = solution [i];
00029
00030
00031
00032 if ((variables_ [i] -> isInteger ()) &&
00033 (variables_ [i] -> Type () == VAR) &&
00034 (variables_ [i] -> Multiplicity () > 0) &&
00035 (fabs (val - COUENNE_round (val)) > feas_tolerance_)) {
00036
00037 Jnlst()->Printf(Ipopt::J_MOREVECTOR, J_PROBLEM,
00038 "checkNLP: integrality %d violated: %.6f [%g,%g]\n",
00039 i, val, domain_.lb (i), domain_.ub (i));
00040
00041 return false;
00042 }
00043 }
00044
00045 CouNumber *sol = new CouNumber [nVars ()];
00046
00047
00048
00049 CoinCopyN (solution, nOrigVars_, sol);
00050 getAuxs (sol);
00051 CoinCopyN (solution, nOrigVars_, sol);
00052
00053
00054 domain_.push (nVars (), sol, domain_.lb (), domain_.ub (), false);
00055
00056
00057
00058
00059
00060
00061 expression *objBody = Obj (0) -> Body ();
00062
00063
00064
00065
00066
00067
00068 CouNumber realobj = obj;
00069
00070 if (objBody)
00071 realobj =
00072 (objBody -> Index () >= 0) ?
00073 sol [objBody -> Index ()] :
00074 (*(objBody -> Image () ? objBody -> Image () : objBody)) ();
00075
00076
00077
00078
00079
00080 bool retval = true;
00081
00082 try {
00083
00084
00085
00086 if (fabs (realobj - obj) / (1. + fabs (realobj)) > feas_tolerance_) {
00087
00088 Jnlst()->Printf(Ipopt::J_MOREVECTOR, J_PROBLEM,
00089 "checkNLP: false objective. %g != %g (diff. %g)\n",
00090 realobj, obj, realobj - obj);
00091
00092 if (!recompute)
00093 throw wrong_obj;
00094 }
00095
00096 if (recompute)
00097 obj = realobj;
00098
00099
00100
00101 for (int i=0; i < nOrigVars_; i++) {
00102
00103 if (variables_ [i] -> Multiplicity () <= 0)
00104 continue;
00105
00106 CouNumber val = domain_.x (i);
00107
00108
00109
00110 if ((val > domain_.ub (i) + feas_tolerance_) ||
00111 (val < domain_.lb (i) - feas_tolerance_)) {
00112
00113 Jnlst()->Printf(Ipopt::J_MOREVECTOR, J_PROBLEM,
00114 "checkNLP: variable %d out of bounds: %.6f [%g,%g] (diff %g)\n",
00115 i, val, domain_.lb (i), domain_.ub (i),
00116 CoinMax (fabs (val - domain_.lb (i)),
00117 fabs (val - domain_.ub (i))));
00118 throw infeasible;
00119 }
00120
00121
00122
00123 if (variables_ [i] -> isInteger () &&
00124 (fabs (val - COUENNE_round (val)) > feas_tolerance_)) {
00125
00126 Jnlst()->Printf(Ipopt::J_MOREVECTOR, J_PROBLEM,
00127 "checkNLP: integrality %d violated: %.6f [%g,%g]\n",
00128 i, val, domain_.lb (i), domain_.ub (i));
00129
00130 throw infeasible;
00131 }
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 CouNumber delta;
00148
00149
00150
00151 if ((variables_ [i] -> Type () == AUX) &&
00152 (fabs (delta = (*(variables_ [i])) () -
00153 (*(variables_ [i] -> Image ())) ()) > feas_tolerance_)) {
00154
00155 Jnlst()->Printf(Ipopt::J_MOREVECTOR, J_PROBLEM,
00156 "checkNLP: auxiliarized %d violated (%g)\n", i, delta);
00157
00158 throw infeasible;
00159 }
00160 }
00161
00162
00163
00164 for (int i=0; i < nCons (); i++) {
00165
00166 CouenneConstraint *c = Con (i);
00167
00168 CouNumber
00169 body = (*(c -> Body ())) (),
00170 lhs = (*(c -> Lb ())) (),
00171 rhs = (*(c -> Ub ())) ();
00172
00173 if ((rhs < COUENNE_INFINITY) &&
00174 (body > rhs + feas_tolerance_ * (1 + CoinMax (fabs (body), fabs (rhs)))) ||
00175 (lhs > -COUENNE_INFINITY) &&
00176 (body < lhs - feas_tolerance_ * (1 + CoinMax (fabs (body), fabs (lhs))))) {
00177
00178 if (Jnlst()->ProduceOutput(Ipopt::J_MOREVECTOR, J_PROBLEM)) {
00179
00180 Jnlst()->Printf
00181 (Ipopt::J_MOREVECTOR, J_PROBLEM,
00182 "checkNLP: constraint %d violated (lhs=%+e body=%+e rhs=%+e, violation %g): ",
00183 i, lhs, body, rhs, CoinMax (lhs-body, body-rhs));
00184
00185 c -> print ();
00186 }
00187
00188 throw infeasible;
00189 }
00190 }
00191 }
00192
00193 catch (int exception) {
00194
00195 switch (exception) {
00196
00197 case wrong_obj:
00198 retval = false;
00199 break;
00200
00201 case infeasible:
00202 default:
00203 retval = false;
00204 break;
00205 }
00206 }
00207
00208 delete [] sol;
00209 domain_.pop ();
00210
00211 return retval;
00212 }