15 #include "CoinHelperFunctions.hpp"
25 using namespace Couenne;
40 code = body -> code ();
45 {printf (
" Splitting expression: "); body ->
print (); printf (
"\n");}
59 auxInd = (*alist) -> Index ();
70 auxInd = (alist [1]) -> Index ();
92 if (coeff == 1.) auxdef =
clone;
93 else if (coeff == -1.) auxdef =
new exprOpp (clone);
120 int maxindex = -1, nlin = 0, which = 1;
122 bool which_was_set =
false;
135 c0 = egBody -> getc0 ();
137 for (
int i=0,
n = lcoe.size ();
n--; i++, nlin++) {
139 int j = lcoe [i]. first -> Index ();
144 if ((j > maxindex) &&
147 (!(lcoe [i].first ->
isInteger ()) || (which==1))) {
152 exprVar *saveVar = lcoe [i].first;
154 lcoe [i].first =
new exprVar (-1);
159 printf (
"body does not depend on x%d: ", j);
165 auxcoe = lcoe [i]. second;
169 delete lcoe [i].first;
170 lcoe [i].first = saveVar;
176 which_was_set =
true;
181 for (
int i = body -> nArgs (); i--;) {
184 int index = alist [i] -> Index ();
190 if ((index > maxindex) &&
191 !(wentAux [index]) &&
213 if (!which_was_set && (which == -1))
218 if (maxindex < 0)
break;
224 int nargs = body -> nArgs ();
228 printf (
" [[ind %d, coe %.1g, wh %d, nargs %d, nlin %d]] ",
229 maxindex, auxcoe, which, nargs, nlin);
234 int j, mid = (which < 0) ? nargs : which;
238 for (j=0; j<mid; j++) newarglist [j] = alist [j];
239 for (j++; j<nargs; j++) newarglist [j-1] = alist [j];
269 int mid = (which >= 0) ? nlin : - which - 1;
271 linind2 =
new int [nlin + 1];
283 for (j=0; j<mid; j++){linind2[
j] =lcoe[
j].first->Index();lincoe2[
j] =divider*lcoe[
j].second;}
284 for (j++; j<nlin; j++){linind2[j-1]=lcoe[
j].first->Index();lincoe2[j-1]=divider*lcoe[
j].second;}
289 for (j=0; j<mid; j++) printf (
"<%g x%d> ", lincoe2 [j], linind2 [j]);
290 for (j++; j<nlin; j++) printf (
"<%g x%d> ", lincoe2 [j-1], linind2 [j-1]);
299 int nqt = eq -> getnQTerms (), j=0;
301 qindI =
new int [nqt];
302 qindJ =
new int [nqt];
307 for (exprQuad::sparseQ::iterator row = M.begin ();
308 row != M.end (); ++row) {
310 int xind = row -> first -> Index ();
312 for (exprQuad::sparseQcol::iterator col = row -> second.begin ();
313 col != row -> second.end (); ++col, ++
j) {
316 qindJ [
j] = col -> first -> Index ();
317 qcoe [
j] = divider * col -> second;
327 if (which >= 0) --nargs;
330 jnlst_ -> Printf (Ipopt::J_ALL,
J_REFORMULATE,
"\n::: auxcoe %g, rhs %g, lin %d, nl %d\n", auxcoe, rhs, nlin, nargs);
352 rest =
new exprGroup (c0-rhs, lcoeff, newarglist, nargs);
355 std::vector <quadElem> qcoeff;
357 rest =
new exprQuad (c0-rhs, lcoeff, qcoeff, newarglist, nargs);
365 if ((nargs <= 1) && ((*newarglist) -> Linearity () <=
CONSTANT)) {
366 *mullist =
new exprConst ((*newarglist) -> Value ());
368 delete [] newarglist;
370 else if ((nargs <= 1) &&
374 *mullist = (*newarglist) -> Argument ();
382 new exprSum (newarglist, nargs));
385 std::vector <std::pair <exprVar *, CouNumber> > lcoeff;
390 rest =
new exprGroup ((rhs - c0) / auxcoe, lcoeff, mullist,1);
393 std::vector <quadElem> qcoeff;
395 rest =
new exprQuad ((rhs - c0) / auxcoe, lcoeff, qcoeff, mullist,1);
403 if ((nargs == 1) && ((*newarglist) -> Type () ==
CONST)) {
405 CouNumber val = (*newarglist) -> Value () - rhs;
409 else newarglist [nargs++] =
new exprConst (-rhs);
417 auxDef = *newarglist;
418 delete [] newarglist;
419 }
else auxDef =
new exprSum (newarglist, nargs);
423 else if ((auxcoe == 1.) &&
425 rest = auxDef -> Argument ();
427 if (auxDef -> Type () ==
CONST)
429 rest =
new exprConst (- auxDef -> Value () / auxcoe);
437 auxDef = auxDef -> Argument ();
444 ((auxDef -> Type () ==
AUX) ||
445 (auxDef -> Type () ==
VAR)) ?
new exprClone (auxDef) : auxDef);
455 printf (
" Generated "); rest ->
print (); printf (
"\n");
470 if ((auxInd < 0) || (wentAux [auxInd]))
479 printf (
" Standardize rest (2nd level). Rest: "); fflush (stdout); rest ->
print ();
480 printf (
"\n Body: "); fflush (stdout); body ->
print ();
490 printf (
" Aux: "); aux ->
print ();
491 printf (
" := "); aux -> Image () ->
print ();
497 rest = aux -> Image ();
503 {printf (
" ==> (%d)", auxInd); rest ->
print (); printf (
"\n");}
class Group, with constant, linear and nonlinear terms:
std::vector< std::pair< exprVar *, sparseQcol > > sparseQ
pos
position where the operator should be printed when printing the expression
void print(std::ostream &=std::cout)
Display current representation of problem: objective, linear and nonlinear constraints, and auxiliary variables.
int splitAux(CouNumber, expression *, expression *&, bool *, enum expression::auxSign &)
split a constraint w - f(x) = c into w's index (it is returned) and rest = f(x) + c ...
void elementBreak(expression *arg, int &index, CouNumber &coeff)
given an element of a sum, check if it is a variable (possibly with a coefficient) and return its ind...
CouenneProblem * clone() const
Clone method (for use within CouenneCutGenerator::clone)
auxSign
"sign" of the constraint defining an auxiliary.
expression clone (points to another expression)
const Ipopt::EJournalCategory J_REFORMULATE(Ipopt::J_USER7)
Domain domain_
current point and bounds;
bool standardize()
Break problem's nonlinear constraints in simple expressions to be convexified later.
std::vector< std::pair< exprVar *, CouNumber > > lincoeff
double CouNumber
main number type in Couenne
class exprQuad, with constant, linear and quadratic terms
JnlstPtr jnlst_
SmartPointer to the Journalist.
void indcoe2vector(int *indexL, CouNumber *coeff, std::vector< std::pair< exprVar *, CouNumber > > &lcoeff)
translates pair (indices, coefficients) into vector with pointers to variables
bool isInteger(CouNumber x)
is this number integer?