Changeset 307


Ignore:
Timestamp:
Mar 8, 2010 2:06:18 PM (10 years ago)
Author:
pbelotti
Message:

introducing semi-auxiliaries, i.e., variables defined with an inequality constraint. Instead of w := f(x), they can be defined as w >= f(x) or w <= f(x). Saves on number of auxiliary variables and constraints in the linearization. NOTE: Not totally stable yet, optima can be wrong.

Location:
trunk/Couenne/src
Files:
54 edited

Legend:

Unmodified
Added
Removed
  • trunk/Couenne/src/bound_tightening/aggressiveBT.cpp

    r230 r307  
    77 *          bounds/infeasibility
    88 *
    9  * (C) Carnegie-Mellon University, 2007-09.
     9 * (C) Carnegie-Mellon University, 2007-10.
    1010 * This file is licensed under the Common Public License (CPL)
    1111 */
     
    208208          // if (index == objind) continue; // don't do it on objective function
    209209
    210           Jnlst()->Printf(J_DETAILED, J_BOUNDTIGHTENING,
    211                           "------------- tighten left x%d\n", index);
    212 
    213           // tighten on left
    214           if ((X [index] >= Lb (index) + COUENNE_EPS)
    215               && ((improved = fake_tighten (0, index, X, olb, oub, chg_bds, f_chg)) < 0)) {
    216             retval = false;
    217             break;
     210          improved = 0;
     211
     212          if (variables_ [index] -> sign () != exprVar::GEQ) {
     213
     214            Jnlst()->Printf(J_DETAILED, J_BOUNDTIGHTENING,
     215                            "------------- tighten left x%d\n", index);
     216
     217            // tighten on left
     218            if ((X [index] >= Lb (index) + COUENNE_EPS)
     219                && ((improved = fake_tighten (0, index, X, olb, oub, chg_bds, f_chg)) < 0)) {
     220              retval = false;
     221              break;
     222            }
    218223          }
    219224
    220225          second = 0;
    221226
    222           Jnlst()->Printf(J_DETAILED, J_BOUNDTIGHTENING,
    223                           "------------- tighten right x%d\n", index);
    224 
    225           // tighten on right
    226           if ((X [index] <= Ub (index) - COUENNE_EPS)
    227               && ((second = fake_tighten (1, index, X, olb, oub, chg_bds, f_chg) < 0))) {
    228             retval = false;
    229             break;
     227          if (variables_ [index] -> sign () != exprVar::LEQ) {
     228            Jnlst()->Printf(J_DETAILED, J_BOUNDTIGHTENING,
     229                            "------------- tighten right x%d\n", index);
     230
     231            // tighten on right
     232            if ((X [index] <= Ub (index) - COUENNE_EPS)
     233                && ((second = fake_tighten (1, index, X, olb, oub, chg_bds, f_chg) < 0))) {
     234              retval = false;
     235              break;
     236            }
    230237          }
    231238
  • trunk/Couenne/src/bound_tightening/impliedBounds.cpp

    r141 r307  
    1 /* $Id$ */
    2 /*
     1/* $Id$
     2 *
    33 * Name:    impliedBounds.cpp
    44 * Author:  Pietro Belotti
    55 * Purpose: backward implied bound search
    66 *
    7  * (C) Carnegie-Mellon University, 2006.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    2929      }
    3030    if (j % 6) Jnlst()->Printf(Ipopt::J_MOREVECTOR, J_BOUNDTIGHTENING,"\n");
    31     }
     31  }
    3232
    3333  for (int ii = nVars (); ii--;) {
     
    7373
    7474      if (variables_ [i] -> Image () -> impliedBound
    75           (variables_ [i] -> Index (), Lb (), Ub (), chg_bds)) {
     75          (variables_ [i] -> Index (), Lb (), Ub (), chg_bds, variables_ [i] -> sign ())) {
    7676
    7777        // conservative check for integer variables.
  • trunk/Couenne/src/bound_tightening/operators/impliedBounds-exprDiv.cpp

    r203 r307  
    1 /* $Id$ */
    2 /*
     1/* $Id$
     2 *
    33 * Name:    impliedBounds-exprDiv.cpp
    44 * Author:  Pietro Belotti
    55 * Purpose: implied bounds for division operators
    66 *
    7  * (C) Carnegie-Mellon University, 2006.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    1717/// lower- and/or upper bound of w, whose index is wind
    1818
    19 bool exprDiv::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg) {
     19bool exprDiv::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg, enum auxSign sign) {
    2020
    2121  //return false; // !!!
    2222
    2323  bool resx, resy = resx = false;
     24
     25  CouNumber
     26    wl = sign == expression::GEQ ? -COIN_DBL_MAX : l [wind],
     27    wu = sign == expression::LEQ ?  COIN_DBL_MAX : u [wind];
    2428
    2529  // y is a constant
     
    4650    if (c > COUENNE_EPS) {
    4751
    48       if (updateBound (-1, l+ind, xInt ? ceil (l[wind]*c - COUENNE_EPS) : (l[wind]*c))) {
     52      if (updateBound (-1, l+ind, xInt ? ceil (wl*c - COUENNE_EPS) : (wl*c))) {
    4953        resx = true;
    5054        chg [ind].setLower (t_chg_bounds::CHANGED);
    5155      }
    5256
    53       if (updateBound (+1, u+ind, xInt ? floor (u[wind]*c + COUENNE_EPS) : (u[wind]*c))) {
     57      if (updateBound (+1, u+ind, xInt ? floor (wu*c + COUENNE_EPS) : (wu*c))) {
    5458        resx = true;
    5559        chg [ind].setUpper (t_chg_bounds::CHANGED);
     
    5862    else if (c < - COUENNE_EPS) {
    5963
    60       if (updateBound (-1, l+ind, xInt ? ceil  (u[wind]*c - COUENNE_EPS) : (u[wind]*c))) {
     64      if (updateBound (-1, l+ind, xInt ? ceil  (wu*c - COUENNE_EPS) : (wu*c))) {
    6165        resx = true;
    6266        chg [ind].setLower (t_chg_bounds::CHANGED);
    6367      }
    6468
    65       if (updateBound (+1, u+ind, xInt ? floor (l[wind]*c + COUENNE_EPS) : (l[wind]*c))) {
     69      if (updateBound (+1, u+ind, xInt ? floor (wl*c + COUENNE_EPS) : (wl*c))) {
    6670        resx = true;
    6771        chg [ind].setUpper (t_chg_bounds::CHANGED);
     
    107111        yi = arglist_ [1] -> Index ();
    108112
    109     CouNumber x0=0;
    110 
    111     CouNumber *xl = l + xi, *yl = l + yi, wl = l [wind],
    112               *xu = u + xi, *yu = u + yi, wu = u [wind];
     113    CouNumber x0 = 0,
     114      *xl = l + xi, *yl = l + yi,
     115      *xu = u + xi, *yu = u + yi;
    113116
    114117    /*printf ("from              : w[%d] [%e %e], x%d [%e %e] / y%d [%e %e]",
  • trunk/Couenne/src/bound_tightening/operators/impliedBounds-exprMul.cpp

    r203 r307  
    1 /* $Id$ */
    2 /*
     1/* $Id$
     2 *
    33 * Name:    impliedBounds-exprMul.cpp
    44 * Author:  Pietro Belotti
    55 * Purpose: implied bounds for multiplications
    66 *
    7  * (C) Carnegie-Mellon University, 2006.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    1111#include "exprMul.hpp"
    1212#include "CouennePrecisions.hpp"
     13#include "CoinFinite.hpp"
    1314
    1415
     
    1617/// lower- and/or upper bound of w, whose index is wind
    1718
    18 bool exprMul::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg) {
     19bool exprMul::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg, enum auxSign sign) {
    1920
    2021  //return false; // !!!
     
    2223  bool resL, resU = resL = false;
    2324  int ind;
     25
     26  CouNumber
     27    wl = sign == expression::GEQ ? -COIN_DBL_MAX : l [wind],
     28    wu = sign == expression::LEQ ?  COIN_DBL_MAX : u [wind];
    2429
    2530  if ((arglist_ [ind=0] -> Type () <= CONST) ||
     
    4348    if (c > COUENNE_EPS) {
    4449
    45       resL = (l [wind] > - COUENNE_INFINITY) &&
    46         updateBound (-1, l + ind, argInt ? ceil  (l [wind] / c - COUENNE_EPS) : (l [wind] / c));
    47       resU = (u [wind] <   COUENNE_INFINITY) &&
    48         updateBound ( 1, u + ind, argInt ? floor (u [wind] / c + COUENNE_EPS) : (u [wind] / c));
     50      resL = (wl > - COUENNE_INFINITY) &&
     51        updateBound (-1, l + ind, argInt ? ceil  (wl / c - COUENNE_EPS) : (wl / c));
     52      resU = (wu <   COUENNE_INFINITY) &&
     53        updateBound ( 1, u + ind, argInt ? floor (wu / c + COUENNE_EPS) : (wu / c));
    4954    }
    5055    else if (c < - COUENNE_EPS) {
     
    5358      //              wind, l [wind], u [wind], c, ind, l [ind], u [ind]);
    5459
    55       resL = (u [wind] <   COUENNE_INFINITY) &&
    56         updateBound (-1, l + ind, argInt ? ceil  (u [wind] / c - COUENNE_EPS) : (u [wind] / c));
    57       resU = (l [wind] > - COUENNE_INFINITY) &&
    58         updateBound ( 1, u + ind, argInt ? floor (l [wind] / c + COUENNE_EPS) : (l [wind] / c));
     60      resL = (wu <   COUENNE_INFINITY) &&
     61        updateBound (-1, l + ind, argInt ? ceil  (wu / c - COUENNE_EPS) : (wu / c));
     62      resU = (wl > - COUENNE_INFINITY) &&
     63        updateBound ( 1, u + ind, argInt ? floor (wl / c + COUENNE_EPS) : (wl / c));
    5964    }
    6065
     
    7479        yi = arglist_ [1] -> Index ();
    7580
    76     CouNumber *xl = l + xi, *yl = l + yi, wl = l [wind],
    77               *xu = u + xi, *yu = u + yi, wu = u [wind];
    78 
     81    CouNumber
     82      *xl = l + xi, *yl = l + yi,
     83      *xu = u + xi, *yu = u + yi;
    7984
    8085    // w's lower bound ///////////////////////////////////////////
  • trunk/Couenne/src/bound_tightening/operators/impliedBounds-exprPow.cpp

    r141 r307  
    1 /* $Id$ */
    2 /*
     1/* $Id$
     2 *
    33 * Name:    impliedBounds-exprPow.cpp
    44 * Author:  Pietro Belotti
    55 * Purpose: implied bounds for power operators
    66 *
    7  * (C) Carnegie-Mellon University, 2008.
     7 * (C) Carnegie-Mellon University, 2008-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
    1010
    1111#include "exprPow.hpp"
     12#include "expression.hpp"
    1213#include "CoinHelperFunctions.hpp"
    1314
     
    1516/// inverse integer, and odd
    1617
    17 void invPowImplBounds (int, int, CouNumber *, CouNumber *, CouNumber, bool &, bool &);
     18void invPowImplBounds (int, int, CouNumber *, CouNumber *, CouNumber, bool &, bool &, enum expression::auxSign);
    1819
    1920
     
    2122/// lower- and/or upper bound of w, whose index is wind
    2223
    23 bool exprPow::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg) {
     24bool exprPow::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg, enum expression::auxSign sign) {
    2425
    2526  //int xi = arglist_ [0] -> Index ();
     
    4950    isinvint = !isint && (fabs (1./k - (intk = COUENNE_round (1./k))) < COUENNE_EPS); // 1/k integer
    5051
    51   CouNumber wl = l [wind], // lower w
    52             wu = u [wind]; // upper w
     52  CouNumber wl = sign == expression::GEQ ? -COIN_DBL_MAX : l [wind], // lower w
     53            wu = sign == expression::LEQ ?  COIN_DBL_MAX : u [wind]; // upper w
    5354
    5455  if ((isint || isinvint) && (intk % 2)) {
     
    6364
    6465    } else // slightly more complicated, resort to same method as in exprInv
    65       invPowImplBounds (wind, index, l, u, 1./k, resL, resU);
     66      invPowImplBounds (wind, index, l, u, 1./k, resL, resU, sign);
    6667  }
    6768  else
  • trunk/Couenne/src/bound_tightening/operators/impliedBounds-exprQuad.cpp

    r141 r307  
    1 /* $Id$ */
    2 /*
     1/* $Id$
     2 *
    33 * Name:    impliedBounds-exprQuad.cpp
    44 * Author:  Pietro Belotti
     
    66 *          given bounds on the auxiliary variable
    77 *
    8  * (C) Carnegie-Mellon University, 2006.
     8 * (C) Carnegie-Mellon University, 2006-10.
    99 * This file is licensed under the Common Public License (CPL)
    1010 */
     
    3434/// and/or upper bound of w, whose index is wind
    3535
    36 bool exprQuad::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg) {
     36bool exprQuad::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg, enum auxSign sign) {
    3737
    3838  //return false; // !!!
     
    4242  // tightening bounds of each aux, to infer new bounds
    4343
    44 #ifdef DEBUG
    45   printf ("################ implied bounds: [%g,%g], ", l [wind], u [wind]);
     44  CouNumber
     45    wl = sign == expression::GEQ ? -COIN_DBL_MAX : l [wind],
     46    wu = sign == expression::LEQ ?  COIN_DBL_MAX : u [wind];
     47
     48#ifdef DEBUG
     49  printf ("################ implied bounds: [%g,%g], ", wl, wu);
    4650  print (); printf ("\n");
    4751#endif
     
    106110  if (((indInfLo == -2) && (indInfUp == -2)) || // at least two variables are unbounded
    107111      ((indInfLo == -1) && (indInfUp == -1) &&  // or, none is (and qMin, qMax are exact)
    108        (qMin > l [wind]) && (qMax < u [wind]))) // but explicit bounds are loose
     112       (qMin > wl) && (qMax < wu))) // but explicit bounds are loose
    109113    return false;
    110114
     
    297301
    298302        CouNumber
    299           l_b = l [wind] - qMax + bCutUb [indn],
    300           u_b = u [wind] - qMin + bCutLb [indn];
     303          l_b = wl - qMax + bCutUb [indn],
     304          u_b = wu - qMin + bCutLb [indn];
    301305
    302306        if (al > 0) { // care about min -- see outer if, it means 0 < al < au
     
    334338
    335339      // case 2: qii is positive, the parabola is facing upwards and
    336       // we only need to look at w_U = u [wind]
     340      // we only need to look at w_U = wu
    337341
    338342      // there are two parabolas, with linear coefficient linCoeMin
     
    348352
    349353      CouNumber
    350         deltaSecond = 4 * q * (qMin - bCutLb [indn] - u [wind]),
     354        deltaSecond = 4 * q * (qMin - bCutLb [indn] - wu),
    351355        deltaUp     = au*au - deltaSecond,
    352356        deltaLo     = al*al - deltaSecond;
     
    410414
    411415      // case 3: qii is negative, the parabola is facing downwards and
    412       // we only need to look at l [wind]
     416      // we only need to look at wl
    413417
    414418      // skip if constant term is unbounded from above
     
    418422
    419423      CouNumber
    420         deltaSecond = 4 * q * (qMax - bCutUb [indn] - l [wind]),
     424        deltaSecond = 4 * q * (qMax - bCutUb [indn] - wl),
    421425        deltaUp     = au*au - deltaSecond,
    422426        deltaLo     = al*al - deltaSecond;
  • trunk/Couenne/src/bound_tightening/operators/impliedBounds-exprSum.cpp

    r203 r307  
    1 /* $Id$ */
    2 /*
     1/* $Id$
     2 *
    33 * Name:    impliedBounds-exprSum.cpp
    44 * Author:  Pietro Belotti
    55 * Purpose: implied bound enforcing for exprSum and exprGroup
    66 *
    7  * (C) Carnegie-Mellon University, 2006-09.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    2020/// in lower- and/or upper bound of w, whose index is wind
    2121
    22 bool exprSum::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg) {
     22bool exprSum::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg, enum auxSign sign) {
    2323
    2424  /**
     
    4848  // compute number of pos/neg coefficients and sum up constants
    4949
     50  CouNumber
     51    a0 = 0.,   // constant term in the sum
     52    wl = /*sign == expression::GEQ ? -COIN_DBL_MAX : */ l [wind],
     53    wu = /*sign == expression::LEQ ?  COIN_DBL_MAX : */ u [wind];
     54
     55  // quick check: if both are infinite, nothing is implied...
     56
     57  if ((wl < -COUENNE_INFINITY) &&
     58      (wu >  COUENNE_INFINITY))
     59    return false;
     60
    5061  int
    5162    nterms = nargs_, // # nonconstant terms
    5263    nlin   = 0;      // # linear terms
    53 
    54   CouNumber
    55     a0 = 0.,   // constant term in the sum
    56     wl = l [wind],
    57     wu = u [wind];
    58 
    59   // quick check: if both are infinite, nothing is implied...
    60 
    61   if ((wl < -COUENNE_INFINITY) &&
    62       (wu >  COUENNE_INFINITY))
    63     return false;
    6464
    6565  exprGroup *eg = NULL;
     
    184184
    185185      // propagate lower bound to w
    186       if (updateBound (-1, l + wind, lower)) {
     186      if ((sign != expression::LEQ) && (updateBound (-1, l + wind, lower))) {
    187187        chg [wind].setLower(t_chg_bounds::CHANGED);
    188188        tighter = true;
     
    196196
    197197        // propagate upper bound to w
    198         if (updateBound (+1, u + wind, upper)) {
     198        if ((sign != expression::GEQ) && (updateBound (+1, u + wind, upper))) {
    199199          chg [wind].setUpper(t_chg_bounds::CHANGED);
    200200          tighter = true;
     
    214214
    215215      // propagate upper bound to w
    216       if (updateBound (+1, u + wind, upper)) {
     216      if ((sign != expression::GEQ) && (updateBound (+1, u + wind, upper))) {
    217217        tighter = true;
    218218        chg [wind].setUpper(t_chg_bounds::CHANGED);
  • trunk/Couenne/src/bound_tightening/tightenBounds.cpp

    r191 r307  
    1 /* $Id$ */
    2 /*
     1/* $Id$
     2 *
    33 * Name:    tightenBounds.cpp
    44 * Author:  Pietro Belotti
    55 * Purpose: bound tightening for current linear relaxation
    66 *
    7  * (C) Carnegie-Mellon University, 2006-08.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    1313#include "CouenneProblem.hpp"
    1414
    15 //#define DEBUG
    16 
    1715/// Bound propagation for auxiliary variables
    1816
     
    2826  // they depend on
    2927
    30   if (Jnlst () -> ProduceOutput (J_DETAILED, J_BOUNDTIGHTENING)) {
     28  bool dbgOutput = Jnlst () -> ProduceOutput (J_DETAILED, J_BOUNDTIGHTENING);
     29
     30  if (dbgOutput) {
    3131    // ToDo: Pipe all output through journalist
    32     Jnlst()->Printf(J_DETAILED, J_BOUNDTIGHTENING,
    33                     "  forward  =====================\n  ");
     32    Jnlst()->Printf(J_DETAILED, J_BOUNDTIGHTENING, "  forward  =====================\n  ");
    3433    int j=0;
    3534    for (int i=0; i < nVars (); i++)
    36       if (variables_ [i] -> Multiplicity () >= 0) {
     35      if (variables_ [i] -> Multiplicity () > 0) {
    3736        Jnlst()->Printf(J_VECTOR, J_BOUNDTIGHTENING,
    3837                        "x_%03d [%+10g %+10g] ", i,
     
    6564                        "pre-check: w_%d has infeasible bounds [%.10e,%.10e]. ", i, lower_i, upper_i);
    6665
    67         if (Jnlst()->ProduceOutput(J_DETAILED, J_BOUNDTIGHTENING)) {
     66        if (dbgOutput) {
    6867          Var (i) -> Lb () -> print (std::cout);
    6968          Jnlst()->Printf(J_DETAILED, J_BOUNDTIGHTENING," --- ");
     
    9493
    9594      if (variables_ [i] -> isInteger ()) {
    96         ll = ceil  (ll - COUENNE_EPS);
    97         uu = floor (uu + COUENNE_EPS);
    98       }
     95        if (variables_ [i] -> sign () != expression::LEQ) ll = ceil  (ll - COUENNE_EPS);
     96        if (variables_ [i] -> sign () != expression::GEQ) uu = floor (uu + COUENNE_EPS);
     97      }
     98
     99      if      (variables_ [i] -> sign () == expression::LEQ) ll = (*(variables_ [i] -> Lb ())) ();
     100      else if (variables_ [i] -> sign () == expression::GEQ) uu = (*(variables_ [i] -> Ub ())) ();
    99101
    100102      if (ll - uu > COUENNE_EPS * (1 + CoinMin (fabs (ll), fabs (uu)))) {
     
    105107                        "w_%d has infeasible bounds [%g,%g]: ", i, ll, uu);
    106108
    107         if (Jnlst()->ProduceOutput(J_DETAILED, J_BOUNDTIGHTENING)) {
     109        if (dbgOutput) {
    108110          Var (i) -> Lb () -> print (std::cout);
    109111          Jnlst()->Printf(J_DETAILED, J_BOUNDTIGHTENING," --- ");
     
    116118        return -1; // declare this node infeasible
    117119      }
     120
     121      // Enter the sign of this auxiliary: if defined as w <= f(x),
     122      // then the lower bound on f(x) shouldn't be propagated to
     123      // w. similarly, if defined as w >= f(x), then the same should
     124      // hold for the upper bound.
     125
     126      if (variables_ [i] -> sign () == exprVar::LEQ) ll = -COUENNE_INFINITY;
     127      if (variables_ [i] -> sign () == exprVar::GEQ) uu =  COUENNE_INFINITY;
    118128
    119129      // check if lower bound got higher
     
    124134           (fabs (ll / (lower_i) - 1) > COUENNE_EPS)) ) {
    125135
    126         if (Jnlst()->ProduceOutput(J_DETAILED, J_BOUNDTIGHTENING)) {
     136        if (dbgOutput) {
    127137
    128138          Jnlst()->Printf(J_DETAILED, J_BOUNDTIGHTENING,
     
    177187          i+j, uu, ub_ [i+j]);*/
    178188
    179         if (Jnlst()->ProduceOutput(J_DETAILED, J_BOUNDTIGHTENING)) {
     189        if (dbgOutput) {
    180190
    181191          Jnlst()->Printf(J_DETAILED, J_BOUNDTIGHTENING,
  • trunk/Couenne/src/branch/CouenneObject.cpp

    r244 r307  
    66 * Purpose: Base object for variables (to be used in branching)
    77 *
    8  * (C) Carnegie-Mellon University, 2006-09.
     8 * (C) Carnegie-Mellon University, 2006-10.
    99 * This file is licensed under the Common Public License (CPL)
    1010 */
     
    312312  problem_ -> domain () -> pop ();
    313313
     314  bool isInt = reference_ -> isInteger ();
     315
    314316  if (pseudoMultType_ == INFEASIBILITY) {
    315317
    316318    double point = info -> solution_ [reference_ -> Index ()];
    317319
    318     if (reference_ -> isInteger ()) {
     320    if (isInt) {
    319321      if (retval < intInfeasibility (point)) {
    320322        if (downEstimate_ <       point  - floor (point)) downEstimate_ =       point  - floor (point);
     
    327329  else setEstimates (info, &retval, NULL);
    328330
    329   return (reference_ -> isInteger ()) ?
    330     CoinMax (retval, intInfeasibility (info -> solution_ [reference_ -> Index ()])) :
    331     retval;
     331  return (isInt ?
     332          CoinMax (retval, intInfeasibility (info -> solution_ [reference_ -> Index ()])) :
     333          retval);
    332334}
    333335
     
    357359
    358360  double
    359     retval = fabs (vval - fval),
     361    retval =
     362    ((reference_ -> sign () == expression::GEQ) && (vval >= fval)) ? 0. :
     363    ((reference_ -> sign () == expression::LEQ) && (vval <= fval)) ? 0. : fabs (vval - fval),
     364
    360365    ratio = (CoinMax (1., fabs (vval)) /
    361366             CoinMax (1., fabs (fval)));
  • trunk/Couenne/src/convex/operators/conv-exprAbs.cpp

    r217 r307  
    55 * Purpose: convexification methods for |f(x)|
    66 *
    7  * (C) Carnegie-Mellon University, 2006-09.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    1212#include "CouenneTypes.hpp"
    1313#include "CouenneCutGenerator.hpp"
     14#include "CouenneProblem.hpp"
    1415#include "exprAbs.hpp"
    1516#include "exprAux.hpp"
     
    1819// generate convexification cut for constraint w = |x|
    1920
    20 void exprAbs::generateCuts (expression *w, //const OsiSolverInterface &si,
     21void exprAbs::generateCuts (expression *w,
    2122                            OsiCuts &cs, const CouenneCutGenerator *cg,
    2223                            t_chg_bounds *chg, int wind,
     
    2930  argument_ -> getBounds (l, u);
    3031
     32  enum auxSign sign = cg -> Problem () -> Var (w_ind) -> sign ();
     33
    3134  bool
    3235    cbase  = !chg || cg -> isFirst (),
     
    3437    cRight = cbase || (chg [x_ind].upper() != t_chg_bounds::UNCHANGED);
    3538
    36   // if l, u have the same sign, then w = x (l > 0) or w = -x (u < 0)
     39  // if l, u have the same sign, then w = x (l >= 0) or w = -x (u <= 0)
    3740
    38   if      (l >= -0) {if (cLeft)  cg -> createCut (cs, 0., 0, w_ind, 1., x_ind, -1.);}
    39   else if (u <=  0) {if (cRight) cg -> createCut (cs, 0., 0, w_ind, 1., x_ind, +1.);}
     41  if      (l >= -0) {if (cLeft)  cg -> createCut (cs, 0., sign, w_ind, 1., x_ind, -1.);}
     42  else if (u <=  0) {if (cRight) cg -> createCut (cs, 0., sign, w_ind, 1., x_ind, +1.);}
    4043  else {
    4144
    4245    // add two global cuts: w >= x and w >= -x
    43     if (cg -> isFirst ()) {
     46    if (cg -> isFirst () && sign != expression::LEQ) {
    4447      cg -> createCut (cs, 0., +1, w_ind, 1., x_ind, -1.);
    4548      cg -> createCut (cs, 0., +1, w_ind, 1., x_ind,  1.);
     
    5053    // from above) or -1 (from below)
    5154
    52     if (l > - COUENNE_INFINITY) {
    53       if (u < COUENNE_INFINITY) { // the upper approximation has slope other than -1, 1
     55    if (sign != expression::GEQ) {
    5456
    55         CouNumber slope = (u+l) / (u-l); // should be stable, l < 0 < u
     57      if (l > - COUENNE_INFINITY) {
     58        if (u < COUENNE_INFINITY) { // the upper approximation has slope other than -1, 1
    5659
    57         // add an upper segment, which depends on the lower/upper bounds
    58         if (cLeft || cRight)
    59           cg -> createCut (cs, -l*(slope+1.), -1, w_ind, 1., x_ind, -slope);
     60          CouNumber slope = (u+l) / (u-l); // should be stable, l < 0 < u
     61
     62          // add an upper segment, which depends on the lower/upper bounds
     63          if (cLeft || cRight)
     64            cg -> createCut (cs, -l*(slope+1.), -1, w_ind, 1., x_ind, -slope);
     65        }
     66        else // slope = 1
     67          if (cLeft) cg -> createCut (cs, -2*l, -1, w_ind, 1., x_ind, -1.);
    6068      }
    61       else // slope = 1
    62         if (cLeft) cg -> createCut (cs, -2*l, -1, w_ind, 1., x_ind, -1.);
     69      else if (u < COUENNE_INFINITY) // slope = -1
     70        if (cRight) cg -> createCut (cs, 2*u, -1, w_ind, 1., x_ind, 1.);
    6371    }
    64     else if (u < COUENNE_INFINITY) // slope = -1
    65       if (cRight) cg -> createCut (cs, 2*u, -1, w_ind, 1., x_ind, 1.);
    6672  }
    6773}
  • trunk/Couenne/src/convex/operators/conv-exprDiv.cpp

    r217 r307  
    5454  if ((yl < -0) && (yu > 0)) return;   // no convexification
    5555
    56   // special case #1: y is almost constant (nonzero) --> y = k. We
    57   // only need a single plane w = x/k.
    58 
    5956  CouNumber k;
    6057
     58  enum auxSign sign = cg -> Problem () -> Var (wi) -> sign ();
     59
     60  // special case #1: y is almost constant (nonzero) --> y = k. We
     61  // only need a single plane w >/</= x/k.
    6162  if ((fabs (yl-yu) < COUENNE_EPS) &&
    6263      ((fabs (k = ((yl+yu) / 2)) > COUENNE_EPS))) {
    6364    if (cLY || cRY)
    64       cg -> createCut (cs, 0., 0, wi, -1, xi, 1/k);
     65      cg -> createCut (cs, 0., sign, wi, -1, xi, 1/k);
    6566    return;
    6667  }
     
    7879      ((k = fabs (wl+wu) / 2) > COUENNE_EPS)) {
    7980    if (cLW || cRW)
    80       cg -> createCut (cs, 0., 0, yi, k, xi, -1.);
     81      cg -> createCut (cs, 0., sign, yi, k, xi, -1.);
    8182    return;
    8283  }
     
    9192
    9293  unifiedProdCuts (cg, cs,
    93                    wi, x [wi], wl, wu,
     94                   wi, x [wi],
     95                   sign == expression::LEQ ? -COIN_DBL_MAX : wl,
     96                   sign == expression::GEQ ?  COIN_DBL_MAX : wu,
    9497                   yi, x [yi], yl, yu,
    9598                   xi, x [xi], xl, xu, chg);
  • trunk/Couenne/src/convex/operators/conv-exprExp.cpp

    r217 r307  
    55 * Purpose: convexification and bounding methods for the exponential operator
    66 *
    7  * (C) Carnegie-Mellon University, 2006-09.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    3434  bool cR = !chg || (chg [x_ind].upper() != t_chg_bounds::UNCHANGED) || cg -> isFirst ();
    3535
     36  enum auxSign sign = cg -> Problem () -> Var (w_ind) -> sign ();
     37
    3638  if (fabs (u-l) < COUENNE_EPS) {  // bounds very close, convexify with a single line
    3739
    3840    CouNumber x0 = 0.5 * (u+l), ex0 = exp (x0);
    3941    if (cL || cR)
    40       cg -> createCut (cs, ex0 * (1 - x0), 0, w_ind, 1., x_ind, - ex0);
     42      cg -> createCut (cs, ex0 * (1 - x0), sign, w_ind, 1., x_ind, - ex0);
    4143
    4244    return;
     
    4850  // upper segment
    4951
    50   if ((cL || cR)
     52  if ((sign != expression::GEQ)
     53      && (cL || cR)
    5154      && (u < log (COUENNE_INFINITY) )
    5255      && (l > -    COUENNE_INFINITY / 1e4)) { // tame lower bound
     
    6972
    7073  // approximate the exponential function from below
    71   cg -> addEnvelope (cs, +1, exp, exp, w_ind, x_ind, x, l, u, chg, true);
     74  if (sign != expression::LEQ)
     75    cg -> addEnvelope (cs, +1, exp, exp, w_ind, x_ind, x, l, u, chg, true);
    7276}
  • trunk/Couenne/src/convex/operators/conv-exprGroup.cpp

    r217 r307  
    55 * Purpose: implementation of convexification methods for exprGroup
    66 *
    7  * (C) Carnegie-Mellon University, 2006-09.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    191191
    192192// generate equality between *this and *w
    193 void exprGroup::generateCuts (expression *w, //const OsiSolverInterface &si,
     193void exprGroup::generateCuts (expression *w,
    194194                              OsiCuts &cs, const CouenneCutGenerator *cg,
    195195                              t_chg_bounds *chg,
     
    228228
    229229    if (fabs (el -> second) > 1.0e-21) {
    230       // why 1.0e-21? Look at CoinPackedMatrix.cpp:2188
     230      // why 1.0e-21? Look at CoinPackedMatrix.cpp:2237
    231231
    232232      coeff [i   + displacement] = el -> second;
     
    254254  delete [] coeff;
    255255
    256   if (lb > -COUENNE_INFINITY) cut -> setLb (lb);
    257   if (ub <  COUENNE_INFINITY) cut -> setUb (ub);
     256  enum auxSign sign;
     257
     258  if (wind < 0)
     259    sign = cg -> Problem () -> Var (w -> Index ()) -> sign ();
     260
     261  if (lb > -COUENNE_INFINITY && (wind >= 0 || sign != expression::GEQ)) cut -> setLb (lb);
     262  if (ub <  COUENNE_INFINITY && (wind >= 0 || sign != expression::LEQ)) cut -> setUb (ub);
    258263
    259264  cut -> setGloballyValid (); // added only once, it is global
  • trunk/Couenne/src/convex/operators/conv-exprInv.cpp

    r217 r307  
    55 * Purpose: convexification and bounding methods for the inverse operator
    66 *
    7  * (C) Carnegie-Mellon University, 2006-09.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    8888  // linear term
    8989
     90  enum auxSign sign = cg -> Problem () -> Var (wi) -> sign ();
     91
    9092  if (fabs (u - l) < COUENNE_EPS) {
    9193
    9294    CouNumber x0 = 0.5 * (u+l);
    9395    if (cL || cR)
    94       cg -> createCut (cs, 2/x0, 0, wi, 1., xi, 1/(x0*x0));
     96      cg -> createCut (cs, 2/x0, sign, wi, 1., xi, 1/(x0*x0));
    9597    return;
    9698  }
     
    100102  if (cL || cR) {
    101103    // bounding box is within ]0,+inf[
    102     if ((l> COUENNE_EPS) && (u< COU_MAX_COEFF)) cg -> createCut (cs, 1/l+1/u, -1, wi,1., xi,1/(l*u));
    103     if ((u<-COUENNE_EPS) && (l>-COU_MAX_COEFF)) cg -> createCut (cs, 1/l+1/u, +1, wi,1., xi,1/(l*u));
     104    if ((l> COUENNE_EPS) && (u< COU_MAX_COEFF) && sign != expression::GEQ) cg -> createCut (cs, 1/l+1/u, -1, wi,1., xi,1/(l*u));
     105    if ((u<-COUENNE_EPS) && (l>-COU_MAX_COEFF) && sign != expression::LEQ) cg -> createCut (cs, 1/l+1/u, +1, wi,1., xi,1/(l*u));
    104106    // bounding box is within ]-inf,0[
    105107  }
     
    117119
    118120  // bound
    119   cg -> addEnvelope
    120     (cs, (l > 0) ? +1 : -1,
    121      inv, oppInvSqr, wi, xi,
    122      (cg -> isFirst ()) ? // is this first call?
     121  if ((l > 0 && sign != expression::LEQ) ||
     122               (sign != expression::GEQ))
     123    cg -> addEnvelope
     124      (cs, (l > 0) ? +1 : -1,
     125       inv, oppInvSqr, wi, xi,
     126       (cg -> isFirst ()) ? // is this first call?
    123127       // place it somewhere in the interval (we don't care)
    124128       ((l > COUENNE_EPS) ? l : u) :
    125129       // otherwise, replace it where it gives deepest cut
    126130       powNewton ((*argument_) (), (*aux) (), inv, oppInvSqr, inv_dblprime),
    127      l, u, chg);
     131       l, u, chg);
    128132}
  • trunk/Couenne/src/convex/operators/conv-exprLog.cpp

    r217 r307  
    3939  argument_ -> getBounds (l, u);
    4040
     41  enum auxSign sign = cg -> Problem () -> Var (w_ind) -> sign ();
     42
    4143  // if bounds are very close, convexify with a single line
    4244  if ((fabs (u - l) < COUENNE_EPS) && (l > COUENNE_EPS)) {
    4345
    4446    CouNumber x0 = 0.5 * (u+l);
    45     if (changed) cg -> createCut (cs, log (x0) - 1, 0, w_ind, 1., x_ind, - 1/x0);
     47    if (changed) cg -> createCut (cs, log (x0) - 1, sign, w_ind, 1., x_ind, - 1/x0);
    4648    return;
    4749  }
     
    5052  if (l < LOG_MININF) l = LOG_MININF;
    5153  else   // lower segment (if l is far from zero and u finite)
    52     if ((u < COUENNE_INFINITY) && changed) {
     54    if ((u < COUENNE_INFINITY) && changed && sign != expression::LEQ) {
    5355
    5456      CouNumber dx   = u-l;
     
    5860      cg -> createCut (cs, dx*logu - u*dw, +1, w_ind, dx, x_ind, -dw);
    5961    }
     62
     63  // no need to continue if auxiliary is defined as w >= log (x)
     64  if (sign == expression::GEQ)
     65    return;
    6066
    6167  // pick tangent point closest to current point (x0,y0)
  • trunk/Couenne/src/convex/operators/conv-exprMul-genCuts.cpp

    r217 r307  
    55 * Purpose: method to convexify multiplications
    66 *
    7  * (C) Carnegie-Mellon University, 2006-09.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    1212#include "exprMul.hpp"
    1313#include "CouenneCutGenerator.hpp"
     14#include "CouenneProblem.hpp"
    1415
    1516
    1617/// generate convexification cut for constraint w = x*y
    1718
    18 void exprMul::generateCuts (expression *w, //const OsiSolverInterface &si,
     19void exprMul::generateCuts (expression *w,
    1920                            OsiCuts &cs, const CouenneCutGenerator *cg,
    2021                            t_chg_bounds *chg, int wind,
     
    100101        // narrow, or because these are indeed constant (which should
    101102        // have been dealt with in simplify(), but who knows...)
    102         cg -> createCut (cs, c0 * c1, 0, wi, 1.);
     103        cg -> createCut (cs, c0 * c1, cg -> Problem () -> Var (wi) -> sign (), wi, 1.);
    103104
    104105      else {
     
    110111        else          {coe = c1; ind = xi;} // x*c
    111112
    112         cg -> createCut (cs, 0., 0, wi, -1., ind, coe);
     113        cg -> createCut (cs, 0., cg -> Problem () -> Var (wi) -> sign (), wi, 1., ind, -coe);
    113114      }
    114115    }
     
    116117    return;
    117118  }
     119
     120  enum auxSign sign = cg -> Problem () -> Var (wi) -> sign ();
    118121
    119122  // add different cuts, to cut out current point in bounding box but
     
    126129                   xi, x0,      xl, xu,
    127130                   yi, y0,      yl, yu,
    128                    wi, (*w) (), wl, wu, chg);
     131                   wi, (*w) (),
     132                   sign == expression::LEQ ? -COIN_DBL_MAX : wl,
     133                   sign == expression::GEQ ?  COIN_DBL_MAX : wu,
     134                   chg);
    129135}
  • trunk/Couenne/src/convex/operators/conv-exprOpp.cpp

    r217 r307  
    55 * Purpose: methods to convexify opposite of expressions
    66 *
    7  * (C) Carnegie-Mellon University, 2006-09.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    3434    if (xind < 0) {
    3535      printf ("#### invalid index for exprOpp::gencuts()\n");
    36       return;
     36      exit (-1);
    3737    }
    3838
     
    5353    delete (cut);
    5454  }
    55   else // easy...
    56     if (cg -> isFirst ())
    57       cg -> createCut (cs, 0., 0, w->Index (), 1., argument_->Index (), 1.);
     55  else // easy...
     56
     57    if (cg -> isFirst ()) {
     58
     59      int wi = w -> Index ();
     60      cg -> createCut (cs, 0., cg -> Problem () -> Var (wi) -> sign (), wi, 1., argument_->Index (), 1.);
     61    }
    5862}
  • trunk/Couenne/src/convex/operators/conv-exprPow.cpp

    r217 r307  
    55 * Purpose: methods to convexify an expression x^k, k constant
    66 *
    7  * (C) Carnegie-Mellon University, 2006-09.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    126126    x = (*xe)  ();
    127127
     128  enum auxSign aSign = cg -> Problem () -> Var (w_ind) -> sign ();
     129
    128130  // if xl and xu are too close, approximate it as a line: sum the
    129131  // segment through the two extreme points (l,l^k) and (u,u^k), and
     
    138140
    139141    if (cL || cR)
    140       cg -> createCut (cs, u*lk - l*uk + avg * avg_k_1 * (1-k), 0,
     142      cg -> createCut (cs, u*lk - l*uk + avg * avg_k_1 * (1-k), aSign,
    141143                       w_ind, u - l + 1, x_ind, lk-uk - k * avg_k_1);
    142144    return;
     
    148150
    149151  if (k < - COUENNE_INFINITY) { // w=x^{-inf} means w=0
    150     if (cL || cR) cg -> createCut (cs, 0., 0, w_ind, 1.);
     152    if (cL || cR) cg -> createCut (cs, 0., aSign, w_ind, 1.);
    151153    return;
    152154  }
     
    156158
    157159  if (fabs (k) < COUENNE_EPS) { // w = x^0 means w=1
    158     if (cL || cR) cg -> createCut (cs, 1., 0, w_ind, 1.);
     160    if (cL || cR) cg -> createCut (cs, 1., aSign, w_ind, 1.);
    159161    return;
    160162  }
     
    209211
    210212    // lower envelope
    211     if (l > -powThres) {
     213    if ((aSign != expression::LEQ) && (l > -powThres)) {
    212214      if (l>0) addPowEnvelope (cg, cs, w_ind, x_ind, x, w, k,   l, u, sign); // 0<l<u, tangents only
    213215      else if (u > q * l) { // upper x is after "turning point", add lower envelope
     
    218220
    219221    // upper envelope
    220     if (u < powThres) {
     222    if ((aSign != expression::GEQ) && (u < powThres)) {
    221223      if (u<0) addPowEnvelope (cg, cs, w_ind, x_ind, x, w, k, l,   u, -sign);  // l<u<0, tangents only
    222224      else if (l < q * u) { // lower x is before "turning point", add upper envelope
     
    246248    if ((k < 0) &&
    247249        (l < - COUENNE_EPS) &&
    248         (u >   COUENNE_EPS)) {
     250        (u >   COUENNE_EPS) &&
     251        aSign != expression::LEQ) {
    249252
    250253      if (!(intk % 2))
     
    277280        (u >  COUENNE_EPS) &&
    278281        (l > - powThres) &&         // and are finite
    279         (u <   powThres))
     282        (u <   powThres) &&
     283        aSign != expression::LEQ)
    280284
    281285      cg -> addSegment (cs, w_ind, x_ind, l, safe_pow (l, k), u, safe_pow (u, k), 1);
     
    288292        (l > - powThres) &&         // and are finite
    289293        (u <   powThres) &&
    290         (fabs (l+u) > COUENNE_EPS)) // bounds are not opposite (otherwise it's a variable bound)
     294        (fabs (l+u) > COUENNE_EPS) &&
     295        aSign != expression::GEQ) // bounds are not opposite (otherwise it's a variable bound)
    291296
    292297      cg -> addSegment (cs, w_ind, x_ind, l, safe_pow (l, k), u, safe_pow (u, k), -sign);
     
    310315    }
    311316
    312     addPowEnvelope (cg, cs, w_ind, x_ind, x, w, k, l, u, sign);
     317    if ((sign ==  1 && aSign != expression::LEQ) ||
     318        (sign == -1 && aSign != expression::GEQ))
     319      addPowEnvelope (cg, cs, w_ind, x_ind, x, w, k, l, u, sign);
    313320  }
    314321}
  • trunk/Couenne/src/convex/operators/conv-exprSinCos.cpp

    r217 r307  
    55 * Purpose: convexification methods for sines and cosines
    66 *
    7  * (C) Carnegie-Mellon University, 2006-09.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    2020#include "CouenneTypes.hpp"
    2121#include "CouenneCutGenerator.hpp"
     22#include "CouenneProblem.hpp"
     23
     24//#include "expression.hpp"
     25
    2226#include "exprSin.hpp"
    2327#include "exprCos.hpp"
     
    120124    else                        {f = cos (x0); fp = -sin (x0);}
    121125
    122     return cg -> createCut (cs, f - fp*x0, 0, wi, 1., xi, -fp);
     126    return cg -> createCut (cs, f - fp*x0, cg -> Problem () -> Var (wi) -> sign (), wi, 1., xi, -fp);
    123127  }
    124128
     
    149153                 bool &skip_dn) {
    150154
     155  enum expression::auxSign sign = cg -> Problem () -> Var (wi) -> sign ();
     156
    151157  CouNumber tpt,
    152158    rx0  = modulo (x0 + displacement, 2*M_PI),
     
    174180    // out of the "belly": tangent. If on upper bay consider the lower
    175181    // half-plane, and viceversa --> use -up
    176     ncuts += cg -> addTangent (cs, wi, xi, x0, sin (rx0), cos (rx0), -up);
     182    if (sign != up)
     183      ncuts += cg -> addTangent (cs, wi, xi, x0, sin (rx0), cos (rx0), -up);
    177184
    178185    // leftmost extreme to search for tangent point
     
    183190        (left * (rx1 - (tpt = trigNewton
    184191                        (rx0, extr0, extr0 + M_PI_2))) <= 0)) { // before closest leaning point
    185       if (!*s1) // -> chord, if not already added in previous call
     192      if (!*s1 && (sign != -up)) // -> chord, if not already added in previous call
    186193        *s1 = ((ncuts += cg -> addSegment (cs, wi, xi, x0, sin (rx0), x1,       sin (rx1), up)) > 0);
    187     } else      ncuts += cg -> addSegment (cs, wi, xi, x0, sin (rx0), base+tpt, sin (tpt), up);
    188   }
    189   else {
     194    } else     
     195      if (sign != -up)
     196        ncuts += cg -> addSegment (cs, wi, xi, x0, sin (rx0), base+tpt, sin (tpt), up);
     197  } else {
    190198
    191199    // after  stationary point (i.e., _/ or ~\ ) for left  bound,
     
    195203    if (left * (rx1 - (4*left - up + 2) * M_PI_2) < 0) {
    196204      CouNumber cosrx0 = cos (rx0);
    197       if (up * (sin (rx1) - sinrx0 - cosrx0 * (rx1-rx0)) < 0)
     205      if (up * (sin (rx1) - sinrx0 - cosrx0 * (rx1-rx0)) < 0) {
    198206        // (b,sinb) below tangent --> tangent
    199         ncuts += cg -> addTangent (cs, wi, xi, x0, sinrx0, cosrx0, -up);
    200       else {    // up: either chord or leaning plane
     207        if (sign != up)
     208          ncuts += cg -> addTangent (cs, wi, xi, x0, sinrx0, cosrx0, -up);
     209      } else {    // up: either chord or leaning plane
    201210        CouNumber searchpt = M_PI_2 * (2 + 3*left - up);
    202211        tpt = trigNewton (rx0, searchpt, searchpt + left * M_PI_2);
    203212        if (left * (rx1 - tpt) < 0) {
    204           if (!*s0)
     213          if (!*s0 && (sign != up) )
    205214            *s0 = ((ncuts += cg->addSegment (cs, wi, xi, x0, sin(rx0), x1,       sin(rx1), -up)) > 0);
    206         } else      ncuts += cg->addSegment (cs, wi, xi, x0, sin(rx0), base+tpt, sin(tpt), -up);
     215        } else
     216          if (sign != up)
     217            ncuts += cg->addSegment (cs, wi, xi, x0, sin(rx0), base+tpt, sin(tpt), -up);
    207218      }
    208219    } else {
    209220      CouNumber searchpt = M_PI_2 * (2 + 3*left - up);
    210221      tpt = trigNewton (rx0, searchpt, searchpt + left * M_PI_2);
    211       ncuts += cg -> addSegment (cs, wi, xi, x0, sin (rx0), base + tpt, sin (tpt), -up);
     222      if (sign != up)
     223        ncuts += cg -> addSegment (cs, wi, xi, x0, sin (rx0), base + tpt, sin (tpt), -up);
    212224    }
    213225
     
    216228        (left * (rx1 - (tpt = trigNewton (rx0, (2 +   left - up) * M_PI_2,
    217229                                               (2 + 2*left - up) * M_PI_2))) < 0)) {
    218       if (!*s1)
     230      if (!*s1 && (sign != -up))
    219231        *s1 = ((ncuts += cg -> addSegment (cs, wi, xi, x0, sin (rx0), x1, sin (rx1), up)) > 0);
    220     } else      ncuts += cg -> addSegment (cs, wi, xi, x0, sin (rx0), base + tpt, sin (tpt), up);
     232    } else
     233      if (sign != -up)
     234        ncuts += cg -> addSegment (cs, wi, xi, x0, sin (rx0), base + tpt, sin (tpt), up);
    221235  }
    222236
     
    244258    w_ind = aux -> Index ();
    245259
     260  enum auxSign sign = cg -> Problem () -> Var (w_ind) -> sign ();
     261
    246262  if (fabs (ub - lb) < COUENNE_EPS) {
    247263
     
    251267    else                {f = cos (x0); fp = -sin (x0);}
    252268
    253     return cg -> createCut (cs, f - fp*x0, 0, w_ind, 1., x_ind, -fp);
     269    return cg -> createCut (cs, f - fp*x0, sign, w_ind, 1., x_ind, -fp);
    254270  }
    255271
     
    260276  if (lb > -COUENNE_INFINITY) { // if not unbounded
    261277    if (tt == COU_SINE) {
    262       ncuts += cg -> createCut (cs, sin (lb) - lb, -1, w_ind, 1., x_ind, -1.); // up: w-x <= f lb - lb
    263       ncuts += cg -> createCut (cs, sin (lb) + lb, +1, w_ind, 1., x_ind,  1.); // dn: w+x >= f lb + lb
     278      if (sign != expression::GEQ) ncuts += cg -> createCut (cs, sin (lb) - lb, -1, w_ind, 1., x_ind, -1.); // up: w-x <= f lb - lb
     279      if (sign != expression::LEQ) ncuts += cg -> createCut (cs, sin (lb) + lb, +1, w_ind, 1., x_ind,  1.); // dn: w+x >= f lb + lb
    264280    }
    265281    else {
    266       ncuts += cg -> createCut (cs, cos (lb) - lb, -1, w_ind, 1., x_ind, -1.); // up: w-x <= f lb - lb
    267       ncuts += cg -> createCut (cs, cos (lb) + lb, +1, w_ind, 1., x_ind,  1.); // dn: w+x >= f lb + lb
     282      if (sign != expression::GEQ) ncuts += cg -> createCut (cs, cos (lb) - lb, -1, w_ind, 1., x_ind, -1.); // up: w-x <= f lb - lb
     283      if (sign != expression::LEQ) ncuts += cg -> createCut (cs, cos (lb) + lb, +1, w_ind, 1., x_ind,  1.); // dn: w+x >= f lb + lb
    268284    }
    269285  }
     
    272288  if (ub <  COUENNE_INFINITY) { // if not unbounded
    273289    if (tt == COU_SINE) {
    274       ncuts += cg -> createCut (cs, sin (ub) - ub, +1, w_ind, 1., x_ind, -1.); // dn: w-x >= f ub - ub
    275       ncuts += cg -> createCut (cs, sin (ub) + ub, -1, w_ind, 1., x_ind,  1.); // up: w+x <= f ub + ub
     290      if (sign != expression::LEQ) ncuts += cg -> createCut (cs, sin (ub) - ub, +1, w_ind, 1., x_ind, -1.); // dn: w-x >= f ub - ub
     291      if (sign != expression::GEQ) ncuts += cg -> createCut (cs, sin (ub) + ub, -1, w_ind, 1., x_ind,  1.); // up: w+x <= f ub + ub
    276292    }
    277293    else {
    278       ncuts += cg -> createCut (cs, cos (ub) - ub, +1, w_ind, 1., x_ind, -1.); // dn: w-x >= f ub - ub
    279       ncuts += cg -> createCut (cs, cos (ub) + ub, -1, w_ind, 1., x_ind,  1.); // up: w+x <= f ub + ub
     294      if (sign != expression::LEQ) ncuts += cg -> createCut (cs, cos (ub) - ub, +1, w_ind, 1., x_ind, -1.); // dn: w-x >= f ub - ub
     295      if (sign != expression::GEQ) ncuts += cg -> createCut (cs, cos (ub) + ub, -1, w_ind, 1., x_ind,  1.); // up: w+x <= f ub + ub
    280296    }
    281297  }
  • trunk/Couenne/src/convex/operators/conv-exprSub.cpp

    r217 r307  
    55 * Purpose: convexification methods for the Subtraction class
    66 *
    7  * (C) Carnegie-Mellon University, 2006-09.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    4747  }
    4848
     49  enum auxSign sign = cg -> Problem () -> Var (wi) -> sign ();
     50
     51  if      (sign == expression::GEQ) lb = -COIN_DBL_MAX;
     52  else if (sign == expression::LEQ) ub =  COIN_DBL_MAX;
     53
    4954  cg -> createCut (cs, lb, ub, wi, -1., xi, 1., yi, -1., true);
    5055}
  • trunk/Couenne/src/convex/operators/conv-exprSum.cpp

    r217 r307  
    55 * Purpose: methods to standardize/convexify sum expressions
    66 *
    7  * (C) Carnegie-Mellon University, 2006-09.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    6161  delete [] coeff;
    6262
    63   if (lb > -COUENNE_INFINITY) cut -> setLb (lb);
    64   if (ub <  COUENNE_INFINITY) cut -> setUb (ub);
     63  enum auxSign sign = cg -> Problem () -> Var (w -> Index ()) -> sign ();
     64
     65  if (lb > -COUENNE_INFINITY && (sign != expression::GEQ)) cut -> setLb (lb);
     66  if (ub <  COUENNE_INFINITY && (sign != expression::LEQ)) cut -> setUb (ub);
    6567
    6668  /// added only once, it is global
  • trunk/Couenne/src/convex/operators/quadCuts.cpp

    r217 r307  
    55 * Purpose: based on upper and lower convexification, add cuts to convexify
    66 *
    7  * (C) International Business Machines 2007.
     7 * (C) International Business Machines 2007-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    7878    convVal = 0.;
    7979
     80  enum auxSign sign = cg -> Problem () -> Var (w -> Index ()) -> sign ();
     81
     82  // if this is a "semi"-auxiliary, check if necessary to separate
     83  if ((sign == expression::GEQ && varVal > exprVal) ||
     84      (sign == expression::LEQ && varVal < exprVal))
     85    return;
     86
    8087  const CouenneProblem& problem = *(cg -> Problem ());
    8188  const int numcols = problem.nVars ();
  • trunk/Couenne/src/expression/exprAux.cpp

    r272 r307  
    55 * Purpose: methods of the class of auxiliary variables
    66 *
    7  * (C) Carnegie-Mellon University, 2006-09.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    2323
    2424// auxiliary expression Constructor
    25 exprAux::exprAux (expression *image, int index, int rank, enum intType isInteger, Domain *d):
     25exprAux::exprAux (expression *image, int index, int rank,
     26                  enum intType isInteger, Domain *d,
     27                  enum auxSign sign):
    2628
    2729  exprVar       (index, d),
     
    3032  multiplicity_ (1),
    3133  integer_      (isInteger),
    32   top_level_    (false) {
     34  top_level_    (false),
     35  sign_         (sign) {
    3336
    3437  // do this later, in standardize()
     
    4851
    4952/// Constructor to be used with standardize ([...], false)
    50 exprAux::exprAux (expression *image, Domain *d):
     53exprAux::exprAux (expression *image, Domain *d,
     54                  enum auxSign sign):
    5155
    5256  exprVar       (-1, d),
     
    5761  multiplicity_ (0),
    5862  integer_      (Unset),
    59   top_level_    (false) {}
     63  top_level_    (false),
     64  sign_         (sign) {}
    6065//(image -> isInteger () ? Integer : Continuous)
    6166
     
    6873  multiplicity_ (e.multiplicity_),
    6974  integer_      (e.integer_),
    70   top_level_    (e.top_level_) {
     75  top_level_    (e.top_level_),
     76  sign_         (e.sign_) {
    7177
    7278  //  image_ -> getBounds (lb_, ub_);
     
    123129  //image_ -> getBounds (lb_, ub_);
    124130
    125   lb_ = new exprMax (lb_, l0);
    126   ub_ = new exprMin (ub_, u0);
     131  if (sign_ != expression::LEQ) lb_ = new exprMax (lb_, l0);
     132  if (sign_ != expression::GEQ) ub_ = new exprMin (ub_, u0);
    127133}
    128134
  • trunk/Couenne/src/expression/exprAux.hpp

    r272 r307  
    66 *          standardization and convexification)
    77 *
    8  * (C) Carnegie-Mellon University, 2006-09.
     8 * (C) Carnegie-Mellon University, 2006-10.
    99 * This file is licensed under the Common Public License (CPL)
    1010 */
     
    6464  bool top_level_;
    6565
     66  /// "sign" of the defining constraint
     67  enum auxSign sign_;
     68
    6669 public:
    6770
     
    7174
    7275  /// Constructor
    73   exprAux (expression *, int, int, intType = Unset, Domain * = NULL);
     76  exprAux (expression *, int, int, intType = Unset, Domain * = NULL, enum auxSign = expression::EQ);
    7477
    7578  /// Constructor to be used with standardize ([...], false)
    76   exprAux (expression *, Domain * = NULL);
     79  exprAux (expression *, Domain * = NULL, enum auxSign = expression::EQ);
    7780
    7881  /// Destructor
     
    195198                              Bonmin::BabSetupBase *base,
    196199                              JnlstPtr jnlst);
     200
     201  /// return its sign in the definition constraint
     202  inline enum auxSign sign () const
     203  {return sign_;}
    197204};
    198205
  • trunk/Couenne/src/expression/exprVar.cpp

    r259 r307  
    55 * Purpose: methods of the class for defining variables
    66 *
    7  * (C) Carnegie-Mellon University, 2006-09.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
    1010
    1111#include "CouenneCutGenerator.hpp"
     12#include "CouenneProblem.hpp"
    1213#include "CouenneObject.hpp"
    1314#include "exprAux.hpp"
     
    3940                            CouNumber, CouNumber) {
    4041  if (cg -> isFirst ())
    41     cg -> createCut (cs, 0., 0, w -> Index (), 1., varIndex_, -1);
     42    cg -> createCut (cs, 0., cg -> Problem () -> Var (w -> Index ()) -> sign (), w -> Index (), 1., varIndex_, -1);
    4243}
    4344
     
    4546/// implied bound processing. Expression w = x, upon change in lower
    4647/// or upper bound of w, whose index is wind
    47 bool exprVar::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg) {
     48bool exprVar::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg, enum auxSign sign) {
    4849
    4950  bool res = false;
    5051
    51   if (updateBound (-1, l + varIndex_, l [wind]))
    52     {res = true; chg [varIndex_].setLower(t_chg_bounds::CHANGED);}
    53   if (updateBound (+1, u + varIndex_, u [wind]))
    54     {res = true; chg [varIndex_].setUpper(t_chg_bounds::CHANGED);}
     52  if (updateBound (-1, l + varIndex_, sign == expression::GEQ ? -COIN_DBL_MAX : l [wind])) {res = true; chg [varIndex_].setLower(t_chg_bounds::CHANGED);}
     53  if (updateBound (+1, u + varIndex_, sign == expression::LEQ ?  COIN_DBL_MAX : u [wind])) {res = true; chg [varIndex_].setUpper(t_chg_bounds::CHANGED);}
    5554
    5655  return res;
  • trunk/Couenne/src/expression/exprVar.hpp

    r259 r307  
    55 * Purpose: definition of the class exprVar for variables
    66 *
    7  * (C) Carnegie-Mellon University, 2006-09.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    158158
    159159  /// implied bound processing
    160   virtual bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *);
     160  virtual bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *, enum auxSign = expression::EQ);
    161161
    162162  /// rank of an original variable is always one
     
    198198                                       Bonmin::BabSetupBase *base,
    199199                                       JnlstPtr jnlst_);
     200
     201  /// return its sign in the definition constraint
     202  virtual inline enum auxSign sign () const
     203  {return exprVar::UNDEF;}
    200204};
    201205
  • trunk/Couenne/src/expression/expression.hpp

    r217 r307  
    55 * Purpose: definition of the class expression
    66 *
    7  * (C) Carnegie-Mellon University, 2006-08-09.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    4747
    4848 public:
     49
     50  /// "sign" of the constraint defining an auxiliary. If the auxiliary
     51  /// is defined as \f$w \le f(x)\f$, then it is LEQ. It is EQ and GEQ,
     52  /// respectively, if it is defined with \f$=\f$ and  \f$\ge\f$.
     53  enum auxSign {UNDEF=-2, LEQ=-1, EQ, GEQ};
    4954
    5055  /// Constructor
     
    209214  /// bound. The method returns true if there has been a change on any
    210215  /// bound on the variables on which the expression depends.
    211   virtual bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *)
     216  virtual bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *, enum auxSign = expression::EQ)
    212217  {return false;}
    213218
  • trunk/Couenne/src/expression/operators/exprAbs.cpp

    r141 r307  
    1 /* $Id$ */
    2 /*
     1/* $Id$
     2 *
    33 * Name:    exprAbs.cpp
    44 * Author:  Pietro Belotti
    55 * Purpose: definition of the absulute value of a function
    66 *
    7  * (C) Carnegie-Mellon University, 2006.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    8383/// lower- and/or upper bound of w, whose index is wind
    8484
    85 bool exprAbs::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg) {
     85bool exprAbs::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg, enum auxSign sign) {
    8686
    8787  int index = argument_ -> Index ();
    8888
    89   CouNumber *xl = l + index, wl = l [wind],
    90             *xu = u + index, wu = u [wind];
     89  CouNumber *xl = l + index, wl = sign == expression::GEQ ? -COIN_DBL_MAX : l [wind],
     90            *xu = u + index, wu = sign == expression::LEQ ?  COIN_DBL_MAX : u [wind];
    9191
    9292  // for w >= b > 0, we can only improve xlb if it is at least  b
  • trunk/Couenne/src/expression/operators/exprAbs.hpp

    r217 r307  
    55 * Purpose: definition of the absolute value of a function
    66 *
    7  * (C) Carnegie-Mellon University, 2006-09.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    6767
    6868  /// implied bound processing
    69   bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *);
     69  bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *, enum auxSign = expression::EQ);
    7070
    7171  /// set up branching object by evaluating many branching points for
  • trunk/Couenne/src/expression/operators/exprCos.hpp

    r217 r307  
    55 * Purpose: definition of cosine
    66 *
    7  * (C) Carnegie-Mellon University, 2006-09.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    6363
    6464  /// implied bound processing
    65   bool impliedBound (int index, CouNumber *l, CouNumber *u, t_chg_bounds *chg) {
     65  bool impliedBound (int index, CouNumber *l, CouNumber *u, t_chg_bounds *chg, enum auxSign = expression::EQ) {
    6666
    6767    bool impl = trigImpliedBound (COU_COSINE, index, argument_ -> Index (), l, u, chg);
  • trunk/Couenne/src/expression/operators/exprDiv.hpp

    r217 r307  
    55 * Purpose: definition of divisions
    66 *
    7  * (C) Carnegie-Mellon University, 2006-09.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    8585
    8686  /// Implied bound processing
    87   bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *);
     87  bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *, enum auxSign = expression::EQ);
    8888
    8989  /// Set up branching object by evaluating many branching points for
  • trunk/Couenne/src/expression/operators/exprExp.cpp

    r154 r307  
    1 /* $Id$ */
    2 /*
     1/* $Id$
     2 *
    33 * Name:    exprExp.cpp
    44 * Author:  Pietro Belotti
    55 * Purpose: definition of the exponential
    66 *
    7  * (C) Carnegie-Mellon University, 2006-08.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    4646/// implied bound processing for expression w = exp(x), upon change in
    4747/// lower- and/or upper bound of w, whose index is wind
    48 bool exprExp::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg) {
     48bool exprExp::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg, enum auxSign sign) {
    4949
    5050  bool resU, resL = resU = false;
     
    5353  CouNumber b;
    5454
    55   if ((b = l [wind]) >= COUENNE_EPS) // lower bound
     55  if ((b = sign == expression::GEQ ? 0            : l [wind]) >= COUENNE_EPS) // lower bound   
    5656    resL = updateBound (-1, l + ind, argument_->isInteger () ? ceil  (log (b)-COUENNE_EPS) : log (b));
    5757
    58   if ((b = u [wind]) < COUENNE_INFINITY / 1e5) // upper bound
     58  if ((b = sign == expression::LEQ ? COIN_DBL_MAX : u [wind]) < COUENNE_INFINITY / 1e5) // upper bound
    5959    resU = updateBound ( 1, u + ind, argument_->isInteger () ? floor (log (b)+COUENNE_EPS) : log (b));
     60
    6061  else if (b < - COUENNE_EPS) {
    6162    // make it infeasible
  • trunk/Couenne/src/expression/operators/exprExp.hpp

    r217 r307  
    55 * Purpose: definition of the exponential of a function
    66 *
    7  * (C) Carnegie-Mellon University, 2006-09.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    6161
    6262  /// Implied bound processing
    63   bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *);
     63  bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *, enum auxSign = expression::EQ);
    6464
    6565  /// Set up branching object by evaluating many branching points for
  • trunk/Couenne/src/expression/operators/exprInv.cpp

    r154 r307  
    1 /* $Id$ */
    2 /*
     1/* $Id$
     2 *
    33 * Name:    exprInv.cpp
    44 * Author:  Pietro Belotti
    55 * Purpose: definition of inverse of a function (1/f(x))
    66 *
    7  * (C) Carnegie-Mellon University, 2006.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    1313#include "exprMul.hpp"
    1414#include "CouenneProblem.hpp"
    15 
     15#include "expression.hpp"
    1616
    1717// differentiation
     
    4242void invPowImplBounds (int wind, int index,
    4343                       CouNumber *l, CouNumber *u, CouNumber k,
    44                        bool &resL, bool &resU) {
     44                       bool &resL, bool &resU,
     45                       enum expression::auxSign sign) {
    4546
    46   CouNumber wl = l [wind],
    47             wu = u [wind];
     47  CouNumber wl = sign == expression::GEQ ? -COIN_DBL_MAX : l [wind],
     48            wu = sign == expression::LEQ ?  COIN_DBL_MAX : u [wind];
    4849
    4950  // 0 <= l <= w <= u
     
    7172/// implied bound processing for expression w = 1/x, upon change in
    7273/// lower- and/or upper bound of w, whose index is wind
    73 bool exprInv::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg) {
     74bool exprInv::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg, enum auxSign sign) {
    7475
    7576  // Expression w = 1/x: we can only improve the bounds if
     
    8485  bool resL, resU = resL = false;
    8586
    86   invPowImplBounds (wind, index, l, u, -1., resL, resU);
     87  invPowImplBounds (wind, index, l, u, -1., resL, resU, sign);
    8788
    8889  bool argInt = argument_ -> isInteger ();
     
    124125    y = problem -> X (index);
    125126
    126   return ((problem -> Lb (xind) >= 0) && (x > 0) && (y*x <= 1) ||
    127           (problem -> Ub (xind) <= 0) && (x < 0) && (y*x <= 1));
     127  return (((problem -> Lb (xind) >= 0) && (x > 0) && (y*x <= 1)) ||
     128          ((problem -> Ub (xind) <= 0) && (x < 0) && (y*x <= 1)));
    128129}
  • trunk/Couenne/src/expression/operators/exprInv.hpp

    r217 r307  
    55 * Purpose: definition of inverse of a function (1/f(x))
    66 *
    7  * (C) Carnegie-Mellon University, 2006-09.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    7979
    8080  /// implied bound processing
    81   bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *);
     81  bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *, enum auxSign = expression::EQ);
    8282
    8383  /// set up branching object by evaluating many branching points for
  • trunk/Couenne/src/expression/operators/exprLog.cpp

    r154 r307  
    1 /* $Id$ */
    2 /*
     1/* $Id$
     2 *
    33 * Name:    exprLog.cpp
    44 * Author:  Pietro Belotti
    55 * Purpose: methods for class logarithm
    66 *
    7  * (C) Carnegie-Mellon University, 2006.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    7474/// implied bound processing for expression w = log(x), upon change in
    7575/// lower- and/or upper bound of w, whose index is wind
    76 bool exprLog::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg) {
     76bool exprLog::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg, enum auxSign sign) {
    7777
    7878  int ind = argument_ -> Index ();
     
    8282    isint = argument_ -> isInteger();
    8383
    84   if (updateBound (-1, l+ind, isint ? ceil (exp (l [wind]) - COUENNE_EPS) : exp (l [wind]))) {
     84  CouNumber
     85    wl = sign == expression::GEQ ? -COIN_DBL_MAX : l [wind],
     86    wu = sign == expression::LEQ ?  COIN_DBL_MAX : u [wind];
     87
     88  if (updateBound (-1, l+ind, isint ? ceil (exp (wl) - COUENNE_EPS) : exp (wl))) {
    8589    res = true;
    8690    chg [ind].setLower (t_chg_bounds::CHANGED);
    8791  }
    8892
    89   if (updateBound ( 1, u+ind, isint? floor (exp (u [wind]) + COUENNE_EPS) : exp (u [wind]))) {
     93  if (updateBound ( 1, u+ind, isint? floor (exp (wu) + COUENNE_EPS) : exp (wu))) {
    9094    res = true;
    9195    chg [ind].setUpper (t_chg_bounds::CHANGED);
  • trunk/Couenne/src/expression/operators/exprLog.hpp

    r217 r307  
    55 * Purpose: definition of logarithm
    66 *
    7  * (C) Carnegie-Mellon University, 2006-09.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    6161
    6262  /// implied bound processing
    63   bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *);
     63  bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *, enum auxSign = expression::EQ);
    6464
    6565  /// set up branching object by evaluating many branching points for
  • trunk/Couenne/src/expression/operators/exprMul.hpp

    r290 r307  
    7474
    7575  /// implied bound processing
    76   bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *);
     76  bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *, enum auxSign = expression::EQ);
    7777
    7878  /// set up branching object by evaluating many branching points for
  • trunk/Couenne/src/expression/operators/exprOpp.cpp

    r217 r307  
    55 * Purpose: definition of the opposite -f(x) of a function
    66 *
    7  * (C) Carnegie-Mellon University, 2006-09.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    1111#include "exprOpp.hpp"
    1212#include "exprConst.hpp"
    13 
     13#include "CoinHelperFunctions.hpp"
    1414
    1515// find bounds of -x given bounds on x
     
    4242/// implied bound processing for expression w = -x, upon change in
    4343/// lower- and/or upper bound of w, whose index is wind
    44 bool exprOpp::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg) {
     44bool exprOpp::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg, enum auxSign sign) {
    4545
    4646  int ind = argument_ -> Index ();
     
    5050    argInt = argument_ -> isInteger ();
    5151
    52   if (updateBound (-1, l + ind, argInt ? ceil  (- u [wind] - COUENNE_EPS) : - u [wind])) {
     52  CouNumber
     53    wl = sign == expression::GEQ ? -COIN_DBL_MAX : l [wind],
     54    wu = sign == expression::LEQ ?  COIN_DBL_MAX : u [wind];
     55
     56  if (updateBound (-1, l + ind, argInt ? ceil  (- wu - COUENNE_EPS) : - wu)) {
    5357    res = true;
    5458    chg [ind].setLower(t_chg_bounds::CHANGED);
    5559  }
    5660
    57   if (updateBound ( 1, u + ind, argInt ? floor (- l [wind] + COUENNE_EPS) : - l [wind])) {
     61  if (updateBound ( 1, u + ind, argInt ? floor (- wl + COUENNE_EPS) : - wl)) {
    5862    res = true;
    5963    chg [ind].setUpper(t_chg_bounds::CHANGED);
  • trunk/Couenne/src/expression/operators/exprOpp.hpp

    r217 r307  
    55 * Purpose: definition of the opposite -f(x) of a function
    66 *
    7  * (C) Carnegie-Mellon University, 2006.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    8080
    8181  /// implied bound processing
    82   bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *);
     82  bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *, enum auxSign = expression::EQ);
    8383
    8484  /// standardization (to deal with complex arguments)
  • trunk/Couenne/src/expression/operators/exprPow.hpp

    r217 r307  
    55 * Purpose: definition of powers
    66 *
    7  * (C) Carnegie-Mellon University, 2006.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    8989
    9090  /// implied bound processing
    91   bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *);
     91  bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *, enum auxSign = expression::EQ);
    9292
    9393  /// set up branching object by evaluating many branching points for
  • trunk/Couenne/src/expression/operators/exprQuad.hpp

    r217 r307  
    66 *          quadratic = constant + linear + [nonlinear] + quadratic)
    77 *
    8  * (C) Carnegie-Mellon University, 2006-09.
     8 * (C) Carnegie-Mellon University, 2006-10.
    99 * This file is licensed under the Common Public License (CPL)
    1010 */
     
    262262
    263263  /// implied bound processing
    264   virtual bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *);
     264  virtual bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *, enum auxSign = expression::EQ);
    265265
    266266  /// method to compute the bound based on sign: -1 for lower, +1 for
  • trunk/Couenne/src/expression/operators/exprSin.hpp

    r217 r307  
    55 * Purpose: definition of the sine of a function
    66 *
    7  * (C) Carnegie-Mellon University, 2006-09.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    9191
    9292  /// implied bound processing
    93   bool impliedBound (int index, CouNumber *l, CouNumber *u, t_chg_bounds *chg) {
     93  bool impliedBound (int index, CouNumber *l, CouNumber *u, t_chg_bounds *chg, enum auxSign = expression::EQ) {
    9494
    9595    bool impl = trigImpliedBound (COU_SINE, index, argument_ -> Index (), l, u, chg);
  • trunk/Couenne/src/expression/operators/exprSub.cpp

    r217 r307  
    55 * Purpose: definition of subtractions
    66 *
    7  * (C) Carnegie-Mellon University, 2006-08.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    117117/// lower- and/or upper bound of w, whose index is wind
    118118
    119 bool exprSub::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg) {
     119bool exprSub::impliedBound (int wind, CouNumber *l, CouNumber *u, t_chg_bounds *chg, enum auxSign sign) {
    120120
    121121  // caution, xi or yi might be -1
     
    127127
    128128  CouNumber xl, xu, yl, yu,
    129             wl = l [wind], wu = u [wind];
     129    wl = sign == expression::GEQ ? -COIN_DBL_MAX : l [wind],
     130    wu = sign == expression::LEQ ?  COIN_DBL_MAX : u [wind];
    130131
    131132  if (xi==-1) xl =         xu = arglist_ [0] -> Value ();
  • trunk/Couenne/src/expression/operators/exprSub.hpp

    r217 r307  
    55 * Purpose: definition of subtractions
    66 *
    7  * (C) Carnegie-Mellon University, 2006-09.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    7878
    7979  /// Implied bound processing
    80   bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *);
     80  bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *, enum auxSign = expression::EQ);
    8181};
    8282
  • trunk/Couenne/src/expression/operators/exprSum.hpp

    r286 r307  
    55 * Purpose: definition of sum expressions
    66 *
    7  * (C) Carnegie-Mellon University, 2006-09.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    9494   *  these bounds are infinite.
    9595   */
    96   virtual bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *);
     96  virtual bool impliedBound (int, CouNumber *, CouNumber *, t_chg_bounds *, enum auxSign = expression::EQ);
    9797
    9898  /// Checks for quadratic terms in the expression and returns an
  • trunk/Couenne/src/problem/CouenneProblem.hpp

    r290 r307  
    433433  /// split a constraint w - f(x) = c into w's index (it is returned)
    434434  /// and rest = f(x) + c
    435   int splitAux (CouNumber, expression *, expression *&, bool *);
     435  int splitAux (CouNumber, expression *, expression *&, bool *, enum expression::auxSign &);
    436436
    437437  /// translates pair (indices, coefficients) into vector with pointers to variables
  • trunk/Couenne/src/problem/checkNLP.cpp

    r302 r307  
    174174          varVal = (*v) (),
    175175          imgVal = (*(v -> Image ())) (),
    176           delta  = varVal - imgVal,
     176          delta  =
     177          ((v -> sign () == expression::GEQ) && (varVal >= imgVal)) ? 0. :
     178          ((v -> sign () == expression::LEQ) && (varVal <= imgVal)) ? 0. :
     179                                                                        (varVal - imgVal),
    177180          normz  = fabs (delta) / (1 + 0.5 * (fabs (varVal) + fabs (imgVal)));
    178181
  • trunk/Couenne/src/problem/problem.cpp

    r290 r307  
    1 /* $Id$ */
    2 /*
     1/* $Id$
     2 *
    33 * Name:    problem.cpp
    44 * Author:  Pietro Belotti
    55 * Purpose: methods of the class CouenneProblem
    66 *
    7  * (C) Carnegie-Mellon University, 2006-08.
     7 * (C) Carnegie-Mellon University, 2006-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    4545    int indvar = variables_ [i] -> Index ();
    4646
    47     if ((variables_ [i] -> Type () == AUX) &&                   // this is an auxiliary
    48         (indvar >= nOrigVars_) || // and not an original, originally
    49         (variables_ [i] -> Multiplicity () == 0))               // or a useless one
     47    if (((variables_ [i] -> Type () == AUX) &&     // this is an auxiliary
     48         (indvar >= nOrigVars_))            ||    // and not an original, originally
     49        (variables_ [i] -> Multiplicity () == 0))  // or a useless one
    5050      //int index = variables_ [i] -> Index ();
    5151      Lb (indvar) = - (Ub (indvar) = COIN_DBL_MAX);
     
    8787    }
    8888
     89    exprVar *var = variables_ [ord];
     90
    8991    // and handle only those with nonzero multiplicity
    90     if (variables_ [ord] -> Type () == AUX) {
     92    if (var -> Type () == AUX) {
    9193
    9294      Jnlst () -> Printf (Ipopt::J_MOREMATRIX, J_PROBLEM,
     
    9597      CouNumber l, u;
    9698
    97       variables_ [ord] -> Image () -> getBounds (l, u);
     99      var -> Image () -> getBounds (l, u);
    98100
    99101      /*printf ("printing bounds: [%g %g]\n", Lb (ord), Ub (ord));
    100       variables_ [ord] -> Lb () -> print (); printf ("\n");
    101       variables_ [ord] -> Ub () -> print (); printf ("\n");*/
     102      var -> Lb () -> print (); printf ("\n");
     103      var -> Ub () -> print (); printf ("\n");*/
    102104
    103105      Jnlst () -> Printf (Ipopt::J_MOREMATRIX, J_PROBLEM,
     
    106108
    107109      // set bounds
    108       if ((Lb (ord) = CoinMax (Lb (ord), l)) <= -COUENNE_INFINITY) Lb (ord) = -COIN_DBL_MAX;
    109       if ((Ub (ord) = CoinMin (Ub (ord), u)) >=  COUENNE_INFINITY) Ub (ord) =  COIN_DBL_MAX;
     110      if (var -> sign () != expression::GEQ) if ((Lb (ord) = CoinMax (Lb (ord), l)) <= -COUENNE_INFINITY) Lb (ord) = -COIN_DBL_MAX;
     111      if (var -> sign () != expression::LEQ) if ((Ub (ord) = CoinMin (Ub (ord), u)) >=  COUENNE_INFINITY) Ub (ord) =  COIN_DBL_MAX;
    110112      //if ((lb_ [ord] = (*(aux -> Lb ())) ()) <= -COUENNE_INFINITY) lb_ [ord] = -DBL_MAX;
    111113      //if ((ub_ [ord] = (*(aux -> Ub ())) ()) >=  COUENNE_INFINITY) ub_ [ord] =  DBL_MAX;
     
    114116                          " --> [%10g,%10g]\n", Lb (ord), Ub (ord));
    115117
    116       bool integer = variables_ [ord] -> isInteger ();
     118      bool integer = var -> isInteger ();
    117119
    118120      if (integer) {
     
    121123      }
    122124
    123       X (ord) = CoinMax (Lb (ord), CoinMin (Ub (ord), (*(variables_ [ord] -> Image ())) ()));
     125      X (ord) = CoinMax (Lb (ord), CoinMin (Ub (ord), (*(var -> Image ())) ()));
    124126    }
    125127  }
     
    159161      if (var -> Type () == AUX) {
    160162        X (index) =  // addresses of x[] and X() are equal
    161           CoinMax (l, CoinMin (u, (*(var -> Image ())) ()));
     163          CoinMax ((var -> sign () != expression::LEQ) ? l : -COIN_DBL_MAX,
     164          CoinMin ((var -> sign () != expression::GEQ) ? u :  COIN_DBL_MAX, (*(var -> Image ())) ()));
    162165      }
    163166    } else X (index) = 0.;
     
    266269  if ((indobj >= 0) && (cutoff < pcutoff_ -> getCutOff () - COUENNE_EPS)) {
    267270
    268     Jnlst () -> Printf (Ipopt::J_DETAILED, J_PROBLEM,
    269                         "Setting new cutoff %.10e for optimization variable index %d val = %.10e\n",
    270                         cutoff, indobj,
    271                         pcutoff_ -> getCutOff ());
     271    if (fabs (cutoff - pcutoff_ -> getCutOff ()) > (1 + fabs (cutoff)) * 2 * SafeCutoff) // avoid too many printouts
     272      Jnlst () -> Printf (Ipopt::J_WARNING, J_PROBLEM,
     273                          "Setting new cutoff %.10e for optimization variable index %d val = %.10e\n",
     274                          cutoff, indobj,
     275                          pcutoff_ -> getCutOff ());
    272276
    273277    if (Var (indobj) -> isInteger ())
     
    344348     "Tolerance for constraints/auxiliary variables",
    345349     feas_tolerance_default,
    346      "Default value is zero.");
     350     "Default value is 1e-5.");
    347351
    348352  roptions -> AddStringOption2
  • trunk/Couenne/src/problem/problemIO.cpp

    r295 r307  
    4545
    4646        out << " (r:" << (*i) -> rank ()
    47             << ", m:" << (*i) -> Multiplicity () << ") := ";
     47            << ", m:" << (*i) -> Multiplicity () << ") "
     48            << (((*i) -> sign () == expression::EQ)  ? ':' :
     49                ((*i) -> sign () == expression::GEQ) ? '>' :
     50                ((*i) -> sign () == expression::LEQ) ? '<' : '?')
     51            << "= ";
    4852
    4953        if ((*i) -> Image ())
  • trunk/Couenne/src/standardize/constrStandardize.cpp

    r294 r307  
    1212#include "CouenneProblem.hpp"
    1313
     14#include "expression.hpp"
    1415#include "exprAux.hpp"
    1516#include "exprIVar.hpp"
     
    4647#endif
    4748
    48   if (compareExpr (&lb_, &ub_) == 0) {
    49 
    50     // this is an equality constraint, and could be the definition of
    51     // an auxiliary
     49  // Auxiliaries used to be definable with a constraint f(x) + bw = c,
     50  // which implies w := (c - f(x)) / b. Semi-auxiliaries no longer
     51  // need the equality sign, but their sign will be determined by lb_
     52  // and ub_. Their values allow us to decide whether we should create
     53  // a (semi)auxiliary or not.
     54
     55  CouNumber
     56    rLb = (*lb_) (),
     57    rUb = (*ub_) ();
     58
     59  if (rLb < -COUENNE_INFINITY/2 ||
     60      rUb >  COUENNE_INFINITY/2 ||
     61      fabs (rLb-rUb) <= COUENNE_EPS) {
     62
     63    enum expression::auxSign aSign = expression::EQ;
     64
     65    if      (rLb < -COUENNE_INFINITY/2) aSign = expression::LEQ;
     66    else if (rUb >  COUENNE_INFINITY/2) aSign = expression::GEQ;
     67
     68    CouNumber rhs = rLb >= -COUENNE_INFINITY/2 ? rLb : rUb;
     69
     70    // this could be the definition of a (semi)-auxiliary
    5271
    5372    expression *rest;
    5473
    5574    // split w from f(x)
    56     int wind = p -> splitAux ((*lb_) (), body_, rest, p -> Commuted ());
     75    int wind = p -> splitAux (rhs, body_, rest, p -> Commuted (), aSign);
    5776
    5877    if (wind >= 0) { // this IS the definition of an auxiliary variable w = f(x)
     
    7291      if (rest -> code () == COU_EXPRCONST) {
    7392
    74         p -> Var (wind) -> lb () =
    75         p -> Var (wind) -> ub () = rest -> Value ();
     93        CouNumber constRHS = rest -> Value ();
     94
     95        if (aSign == expression::GEQ) p -> Var (wind) -> lb () = constRHS;
     96        if (aSign == expression::LEQ) p -> Var (wind) -> ub () = constRHS;
    7697
    7798        delete rest;
     
    87108#ifdef DEBUG
    88109      printf ("---> %d & ", wind); fflush (stdout);
    89       rest -> print (); printf ("\n");
     110      rest -> print (); printf ("[sign: %d]\n", aSign);
    90111#endif
    91112
    92113      assert (p -> Var (wind) -> Type () == VAR);
     114
     115      int xind = rest -> Index ();
    93116
    94117      // check if constraint now reduces to w_k = x_h, and if so
    95118      // replace all occurrences of x_k with x_h
    96119
    97       int xind = rest -> Index ();
    98 
    99       if (xind >= 0) {
     120      if ((xind >= 0) && (aSign == expression::EQ)) {
    100121
    101122        replace (p, wind, xind);
     
    108129        // create new variable, it has to be integer if original variable was integer
    109130        exprAux *w = new exprAux (rest, wind, 1 + rest -> rank (),
    110                                   p -> Var (wind) -> isInteger () ?
     131                                  ((p -> Var (wind) -> isInteger ()) ||
     132                                   (false && (rest -> isInteger ()) && (aSign == expression::EQ))) ?
    111133                                  exprAux::Integer : exprAux::Continuous,
    112                                   p -> domain ());
    113 
    114         std::set <exprAux *, compExpr>::iterator i = p -> AuxSet () -> find (w);
     134                                  p -> domain (), aSign);
     135
     136        std::set <exprAux *, compExpr>::iterator i;
     137
     138        if (aSign == expression::EQ)
     139          i = p -> AuxSet () -> find (w);
    115140
    116141        // no such expression found in the set:
    117         if (i == p -> AuxSet () -> end ()) {
     142        if ((i == p -> AuxSet () -> end ()) || (aSign != expression::EQ)) {
    118143
    119144          p -> AuxSet      () -> insert (w); // 1) beware of useless copies
     
    172197  printf ("\nnormal\n-----------------\n");
    173198#endif
     199
     200  //body_ -> standardize (p, false); // TODO: check!
     201
     202  //return NULL;
    174203
    175204  return body_ -> standardize (p);
  • trunk/Couenne/src/standardize/linStandardize.cpp

    r268 r307  
    123123
    124124#ifdef DEBUG
    125   printf ("\nlinstand ==> ");
     125  printf ("\nlinstand (addaux = %d) ==> ", addAux);
    126126  ret -> print (); printf ("\n");
    127127  //  ret -> Image () -> print (); printf ("\n");
  • trunk/Couenne/src/standardize/splitAux.cpp

    r268 r307  
    55 * Purpose: extract auxiliary variable from implicit equality constraint
    66 *
    7  * (C) Carnegie-Mellon University, 2007.
     7 * (C) Carnegie-Mellon University, 2007-10.
    88 * This file is licensed under the Common Public License (CPL)
    99 */
     
    2828
    2929
    30 /// split a constraint w - f(x) = c into w's index (returned)
    31 /// and rest = f(x) + c
    32 
    33 int CouenneProblem::splitAux (CouNumber rhs, expression *body, expression *&rest, bool *wentAux) {
     30/// split a constraint aw + f(x) >/</= c into w's index (returned)
     31/// and rest = (-f(x) + c)/a
     32
     33int CouenneProblem::splitAux (CouNumber rhs, expression *body, expression *&rest,
     34                              bool *wentAux, enum expression::auxSign &sign) {
    3435
    3536  int auxInd = -1,          // index of the auxiliary to be extracted
     
    9192      (auxdef) :                                                     // just put other argument
    9293      (new exprSum (auxdef, new exprConst ((pos==1) ? -rhs : rhs))); // otherwise sum it with \pm rhs
     94
     95    if (pos==1) {
     96      if      (sign == expression::GEQ)  sign = expression::LEQ;
     97      else if (sign == expression::LEQ)  sign = expression::GEQ;
     98    }
    9399
    94100  } break;
     
    431437    auxInd = maxindex;
    432438
     439    if (auxcoe < 0) {
     440      if      (sign == expression::GEQ)  sign = expression::LEQ;
     441      else if (sign == expression::LEQ)  sign = expression::GEQ;
     442    }
     443
    433444  } break;
    434445
  • trunk/Couenne/src/standardize/standardize.cpp

    r306 r307  
    66 * Purpose: standardize all expressions in a problem
    77 *
    8  * (C) Carnegie-Mellon University, 2006-09.
     8 * (C) Carnegie-Mellon University, 2006-10.
    99 * This file is licensed under the Common Public License (CPL)
    1010 */
     
    325325       i != variables_.end (); ++i)
    326326
    327     if ((*i) -> Type () == AUX) {
     327    if (((*i) -> Type () == AUX) && ((*i) -> sign () == expression::EQ)) {
    328328
    329329      int type = (*i) -> Image () -> Type ();
     
    398398    if ((Var (i) -> Multiplicity () > 0) &&
    399399        (Var (i) -> Type () == AUX) &&
    400         (Var (i) -> Image () -> isInteger ()))
     400        (Var (i) -> Image () -> isInteger ()) &&
     401        (Var (i) -> sign () == expression::EQ))
    401402      Var (i) -> setInteger (true);
    402403
Note: See TracChangeset for help on using the changeset viewer.