/home/coin/SVN-release/OS-2.4.0/Couenne/src/expression/domain.cpp

Go to the documentation of this file.
00001 /* $Id: domain.cpp 490 2011-01-14 16:07:12Z pbelotti $
00002  *
00003  * Name:    domain.cpp
00004  * Author:  Pietro Belotti
00005  * Purpose: implementation of methods of classes for point and bounding box
00006  *
00007  * (C) Carnegie-Mellon University, 2008-09.
00008  * This file is licensed under the Eclipse Public License (EPL)
00009  */
00010 
00011 #include "CoinHelperFunctions.hpp"
00012 #include "OsiSolverInterface.hpp"
00013 #include "OsiCuts.hpp"
00014 
00015 #include "CouenneDomain.hpp"
00016 #include "CouennePrecisions.hpp"
00017 
00018 // a buffer against continuous reallocs
00019 #define EXTRA_STORAGE 1024
00020 
00021 using namespace Couenne;
00022 
00024 DomainPoint::DomainPoint (int dim, 
00025                           CouNumber *x, 
00026                           CouNumber *lb, 
00027                           CouNumber *ub,
00028                           bool copy):
00029   dimension_ (dim),
00030   x_         (x),
00031   lb_        (lb),
00032   ub_        (ub),
00033   copied_    (copy) {
00034 
00035   if ((dimension_ > 0) && copied_) {
00036 
00037     int size = dim * sizeof (CouNumber);
00038 
00039     x_  = (CouNumber *) malloc (size);
00040     lb_ = (CouNumber *) malloc (size);
00041     ub_ = (CouNumber *) malloc (size);
00042 
00043     if (x)  CoinCopyN (x,  dim, x_);  else CoinFillN (x_,  dim, 0.);
00044     if (lb) CoinCopyN (lb, dim, lb_); else CoinFillN (lb_, dim, -COUENNE_INFINITY);
00045     if (ub) CoinCopyN (ub, dim, ub_); else CoinFillN (ub_, dim,  COUENNE_INFINITY);
00046   }
00047 }
00048 
00049 
00051 DomainPoint::DomainPoint (int dim, 
00052                           const CouNumber *x, 
00053                           const CouNumber *lb, 
00054                           const CouNumber *ub,
00055                           bool copy):
00056   dimension_ (dim),
00057   x_         (const_cast<CouNumber *>(x)),
00058   lb_        (const_cast<CouNumber *>(lb)),
00059   ub_        (const_cast<CouNumber *>(ub)),
00060   copied_    (copy) {
00061 
00062   if ((dimension_ > 0) && copied_) {
00063 
00064     x_  = (CouNumber *) malloc (dim * sizeof (CouNumber)); 
00065     lb_ = (CouNumber *) malloc (dim * sizeof (CouNumber)); 
00066     ub_ = (CouNumber *) malloc (dim * sizeof (CouNumber)); 
00067 
00068     if (x)  CoinCopyN (x,  dim, x_);  else CoinFillN (x_,  dim, 0.);
00069     if (lb) CoinCopyN (lb, dim, lb_); else CoinFillN (lb_, dim, -COUENNE_INFINITY);
00070     if (ub) CoinCopyN (ub, dim, ub_); else CoinFillN (ub_, dim,  COUENNE_INFINITY);
00071   }
00072 }
00073 
00074 
00076 DomainPoint::DomainPoint (const DomainPoint &src):
00077   dimension_ (src.dimension_),
00078   x_         (src.x_),
00079   lb_        (src.lb_),
00080   ub_        (src.ub_),
00081   copied_    (src.copied_) {
00082 
00083   if ((dimension_ > 0) && copied_) {
00084 
00085     x_  = (CouNumber *) malloc (dimension_ * sizeof (CouNumber));
00086     lb_ = (CouNumber *) malloc (dimension_ * sizeof (CouNumber));
00087     ub_ = (CouNumber *) malloc (dimension_ * sizeof (CouNumber));
00088 
00089     CoinCopyN (src.x_,  dimension_, x_);
00090     CoinCopyN (src.lb_, dimension_, lb_);
00091     CoinCopyN (src.ub_, dimension_, ub_);
00092   }
00093 }
00094 
00095 
00097 void DomainPoint::resize (int newdim) {
00098 
00099   if (newdim == dimension_) return;
00100 
00101   assert (copied_); // cannot resize domain point as it was not copied
00102 
00103   if (newdim==0) { // clear
00104 
00105     free (x_);  x_  = NULL;
00106     free (lb_); lb_ = NULL;
00107     free (ub_); ub_ = NULL;
00108 
00109     dimension_ = newdim;
00110 
00111   } else if (newdim < dimension_) { // resize exactly
00112 
00113     x_  = (CouNumber *) realloc (x_,  newdim * sizeof (CouNumber)); 
00114     lb_ = (CouNumber *) realloc (lb_, newdim * sizeof (CouNumber)); 
00115     ub_ = (CouNumber *) realloc (ub_, newdim * sizeof (CouNumber)); 
00116 
00117     dimension_ = newdim;
00118 
00119   } else if (newdim > dimension_) { // expand and leave some extra space
00120 
00121     newdim += EXTRA_STORAGE;
00122 
00123     x_  = (CouNumber *) realloc (x_,  newdim * sizeof (CouNumber)); 
00124     lb_ = (CouNumber *) realloc (lb_, newdim * sizeof (CouNumber)); 
00125     ub_ = (CouNumber *) realloc (ub_, newdim * sizeof (CouNumber)); 
00126 
00127     dimension_ = newdim;
00128   }
00129 }
00130 
00131 
00133 DomainPoint &DomainPoint::operator= (const DomainPoint &src) {
00134 
00135   copied_ = src.copied_;
00136 
00137   if (src.dimension_ != dimension_) {
00138     if (x_)  free (x_);  x_  = (CouNumber *) malloc (src.dimension_ * sizeof (CouNumber));
00139     if (lb_) free (lb_); lb_ = (CouNumber *) malloc (src.dimension_ * sizeof (CouNumber));
00140     if (ub_) free (ub_); ub_ = (CouNumber *) malloc (src.dimension_ * sizeof (CouNumber));
00141     dimension_ = src.dimension_;
00142   }
00143 
00144   CoinCopyN (src.x_,  dimension_, x_);
00145   CoinCopyN (src.lb_, dimension_, lb_);
00146   CoinCopyN (src.ub_, dimension_, ub_);
00147 
00148   return *this;
00149 }
00150 
00151 
00153 Domain::~Domain () {
00154 
00155   if (point_) 
00156     delete point_;
00157 
00158   while (!(domStack_.empty ())) {
00159     delete domStack_.top ();
00160     domStack_.pop ();
00161   }
00162 }
00163 
00164 
00166 void Domain::push (int dim, CouNumber *x, CouNumber *lb, CouNumber *ub, bool copy) {
00167 
00168   if (!x)  x  = point_ -> x  ();
00169   if (!lb) lb = point_ -> lb ();
00170   if (!ub) ub = point_ -> ub ();
00171 
00172   if (point_)
00173     domStack_.push (point_);
00174 
00175   point_ = new DomainPoint (dim, x, lb, ub, copy);
00176 }
00177 
00178 
00180 void Domain::push (int dim, 
00181                    const CouNumber *x, 
00182                    const CouNumber *lb, 
00183                    const CouNumber *ub,
00184                    bool copy) {
00185 
00186   if (point_) 
00187     domStack_.push (point_);
00188 
00189   point_ = new DomainPoint (dim, x, lb, ub, copy);
00190 }
00191 
00192 
00195 void Domain::push (const OsiSolverInterface *si,
00196                    OsiCuts *cs, 
00197                    bool copy) {
00198 
00199   int dim = si -> getNumCols ();
00200 
00201   if (point_) 
00202     domStack_.push (point_);
00203 
00204   point_ = new DomainPoint (dim, 
00205                             si -> getColSolution (), 
00206                             si -> getColLower    (), 
00207                             si -> getColUpper    (), copy);
00208 
00209   // copy latest tightened bounds to problem, if any ColCut is there
00210 
00211   if (cs)
00212     for (int i = cs -> sizeColCuts (); i--;) {
00213 
00214       OsiColCut *cut = cs -> colCutPtr (i);
00215 
00216       register const CoinPackedVector
00217         &lbs = cut -> lbs (),
00218         &ubs = cut -> ubs ();
00219 
00220       register const int    *indices  = lbs. getIndices ();
00221       register const double *elements = lbs. getElements ();
00222 
00223       register CouNumber
00224         *lb = point_ -> lb_,
00225         *ub = point_ -> ub_;
00226 
00227       // copy lbs
00228 
00229       for (register int j = lbs. getNumElements (); j--; elements++, indices++)
00230         if (*elements > lb [*indices])
00231           lb [*indices] = *elements;
00232 
00233       // copy ubs
00234 
00235       indices  = ubs. getIndices ();
00236       elements = ubs. getElements ();
00237 
00238       for (register int j = ubs. getNumElements (); j--; elements++, indices++)
00239         if (*elements < ub [*indices])
00240           ub [*indices] = *elements;
00241     }
00242 }
00243 
00244 
00246 void Domain::push (const DomainPoint &dp, bool copy) {
00247 
00248   if (point_)
00249     domStack_.push (point_);
00250   point_ = new DomainPoint (dp);
00251 }
00252 
00253 
00255 void Domain::pop () {
00256 
00257   delete point_;
00258   if (!(domStack_.empty ())) {
00259     point_ = domStack_.top ();
00260     domStack_.pop ();
00261   }
00262   else point_ = NULL;
00263 }
00264 
00265 /*int main (int argc, char **argv) {
00266 
00267 CouNumber 
00268 x1 [] = {1,2,3},
00269 l1 [] = {0,-1,-2},
00270 u1 [] = {2,5,8},
00271 
00272 x3 [] = {14,15,16,17,18,19},
00273 l3 [] = {-100,-100,-100,-100,-100,-100},
00274 u3 [] = {10,10,10,10,10,10},
00275 
00276 x2 [] = {5001,5002,5003,5006},
00277 l2 [] = {4000,3000,2000,1000},
00278 u2 [] = {5000,6000,8000,6000};
00279 
00280 Domain dom;
00281 
00282 for (int i=80; i--;) {
00283 dom.push (3,x1,l1,u1);printf("1: %g %g %g\n", dom.x(1),dom.x(2),dom.x(0));
00284 dom.push(5,x3,l3,u3);printf("2: %g %g %g %g %g\n",dom.x(1),dom.x(2),dom.x(3),dom.x(4),dom.x(0));
00285 dom.push (4,x2,l2,u2); printf ("3: %g %g %g %g\n", dom.x(1),dom.x(2),dom.x(3),dom.x(0));
00286 dom.push (3,x1,l1,u1); printf ("4: %g %g %g\n", dom.x(1),dom.x(2),dom.x(0));
00287 dom.push (4,x2,l2,u2); printf ("5: %g %g %g %g\n", dom.x(1),dom.x(2),dom.x(3),dom.x(0));
00288 dom.push(5,x3,l3,u3);printf("6: %g %g %g %g %g\n",dom.x(1),dom.x(2),dom.x(3),dom.x(4),dom.x(0));
00289 dom.pop ();
00290 dom.pop ();
00291 dom.pop ();
00292 dom.pop ();
00293 dom.pop ();
00294 dom.pop ();
00295 }
00296 }*/

Generated on Thu Sep 22 03:05:57 2011 by  doxygen 1.4.7