UtilMacros.h

Go to the documentation of this file.
00001 //===========================================================================//
00002 // This file is part of the Decomp Solver Framework.                         //
00003 //                                                                           //
00004 // Decomp is distributed under the Common Public License as part of the      //
00005 // COIN-OR repository (http://www.coin-or.org).                              //
00006 //                                                                           //
00007 // Author: Matthew Galati, Lehigh University                                 //
00008 //                                                                           //
00009 // Copyright (C) 2002-2007, Lehigh University, Matthew Galati, and Ted Ralphs//
00010 // All Rights Reserved.                                                      //
00011 //===========================================================================//
00012 
00013 #ifndef UTIL_MACROS_INCLUDED
00014 #define UTIL_MACROS_INCLUDED
00015 
00016 // =========================================================================
00017 #include "DecompConfig.h"
00018 #include "DecompPortable.h"
00019 class DecompApp;
00020 // =========================================================================
00021 const string UtilSpaces   = " \t\r\n";
00022 const double UtilEpsilon  = 1.0e-6;
00023 // =========================================================================
00024 
00025 // =========================================================================
00026 // Memory Macros
00027 // =========================================================================
00028 #define UTIL_DELPTR(x) if(x) {delete    x; x = 0;}
00029 #define UTIL_DELARR(x) if(x) {delete [] x; x = 0;}
00030 
00031 // =========================================================================
00032 // Debug Macros
00033 // =========================================================================
00034 #define UTIL_DEBUG(param, level, x) if(param > level) {x fflush(stdout);}
00035 #define UTIL_DEBUG0(x)                                {x fflush(stdout);}
00036 
00037 // ------------------------------------------------------------------------- //
00038 template <class T> inline void
00039 UtilPrintVector(const vector<T> & v,
00040                 ostream*          os = &cout)
00041 {
00042    typename vector<T>::const_iterator it;
00043    (*os) << "\n";
00044 
00045    for (it = v.begin(); it != v.end(); it++) {
00046       (*os) << *it << " ";
00047    }
00048 }
00049 
00050 // ------------------------------------------------------------------------- //
00051 template <class T> inline void
00052 UtilPrintList(const list<T> & v,
00053               ostream*        os = &cout)
00054 {
00055    typename list<T>::const_iterator it;
00056    (*os) << "\n";
00057 
00058    for (it = v.begin(); it != v.end(); it++) {
00059       (*os) << *it << " ";
00060    }
00061 }
00062 
00063 
00064 // =========================================================================
00065 // COIN Macros
00066 // TODO: anything that depends on COIN should probably not be in util lib
00067 // =========================================================================
00068 CoinPackedVector* UtilPackedVectorFromDense(const int      len,
00069       const double* dense,
00070       const double   etol);
00071 void UtilPackedVectorFromDense(const int          len,
00072                                const double*      dense,
00073                                const double       etol,
00074                                CoinPackedVector& v);
00075 
00076 //TODO: now depends on DecompApp!? ugh... then belongs in DecompUtil,
00077 // not Util...
00078 void UtilPrintPackedVector(const CoinPackedVector& v,
00079                            ostream*                 os  = &cout,
00080                            DecompApp*               app = 0);
00081 
00082 // =========================================================================
00083 // Graph Macros
00084 // =========================================================================
00085 
00086 /* -------------------------------------------------------------------------
00087    --- Assumption: a complete undirected graph,
00088    ---   (i,j) = (j,i), i!=j (setup for i>j)
00089 
00090    --- Loop thru edges: i: 1 -> n-1, j: 0 -> i-1
00091    --- Number of edges: m = (n^2 - n)/2
00092 
00093    --- Get the edge index from (i,j):
00094    ---   INDEX_U(i,j) = i > j ? (i * (i-1) / 2) + j : (j * (j-1) / 2) + i
00095 
00096    --- Get (i,j) from the edge index:
00097    ---   index = (i * (i-1) / 2) + j
00098    ---   index = (j * (j-1) / 2) + i
00099    ---    ax^2 + bx + c = 0 -> x = (-b +- sqrt(b^2 - 4ac)) / 2a
00100    ---    j = index - (j * (j-1))/2
00101    ---    i = -1/2 + 1/2 sqrt(1 + 8 * index)
00102 
00103    --- Example: n = 5 (i>j)
00104 
00105    ---  0       1       2      3 = j
00106    ---  0
00107    ---  1  0 (1,0)
00108    ---  2  1 (2,0)  2 (2,1)
00109    ---  3  3 (3,0)  4 (3,1)  5 (3,2)
00110    ---  4  6 (4,0)  7 (4,1)  8 (4,2)  9 (4,3)
00111 
00112    --- For the directed version (see EWCP):
00113 
00114    --- Loop thru edges:
00115    ---  i: 1 -> n-1, j: 0 -> i-1 (i>j)
00116    ---  j: 1 -> n-1, i: 0 -> j-1 (i<j)
00117 
00118    --- Number of edges: m = (n^2 - n)/2
00119 
00120    ---  0       1        2        3       4 = j
00121    ---  0           10 (0,1) 11 (0,2) 13 (0,3) 16 (0,4)
00122    ---  1                    12 (1,2) 14 (1,3) 17 (1,4)
00123    ---  2                             15 (2,3) 18 (2,4)
00124    ---  3                                      19 (3,4)
00125    -------------------------------------------------------------------------*/
00126 
00127 /*-----------------------------------------------------------------------*/
00128 inline int UtilNumEdgesU(const int n)
00129 {
00130    return ((n * n) - n) / 2;
00131 }
00132 
00133 /*-----------------------------------------------------------------------*/
00134 inline int UtilIndexU(const int i, const int j)
00135 {
00136    return i > j ? (i * (i - 1) / 2) + j : (j * (j - 1) / 2) + i;
00137 }
00138 
00139 /*-----------------------------------------------------------------------*/
00140 pair<int, int> UtilBothEndsU(const int index);
00141 
00142 /*-----------------------------------------------------------------------*/
00143 inline void UtilPrintEdge(const int   index,
00144                           ostream*    os = &cout)
00145 {
00146    pair<int, int> uv = UtilBothEndsU(index);
00147    (*os) << "(" << setw(2) << uv.first << "," << setw(2) << uv.second << ") ";
00148 }
00149 
00150 // =========================================================================
00151 // Fill-In Macros
00152 // =========================================================================
00153 
00154 #include "CoinHelperFunctions.hpp"
00155 
00156 /*-----------------------------------------------------------------------*/
00157 template <class T> inline void
00158 UtilFillN(T* to, const int size, const T value)
00159 {
00160    CoinFillN(to, size, value); //dep on COIN
00161 }
00162 
00163 /*-----------------------------------------------------------------------*/
00164 template <class T> inline void
00165 UtilFillN(vector<T> & v, const int size, const T value)
00166 {
00167    std::fill_n(back_inserter(v), size, value);
00168 }
00169 
00170 /*-----------------------------------------------------------------------*/
00171 inline void UtilIotaN(int*        first,
00172                       const int   size,
00173                       const int   init)
00174 {
00175    int val = init + size;
00176    int ii;
00177 
00178    for (ii = size; ii-- != 0; ) {
00179       first[ii] = --val;
00180    }
00181 }
00182 
00183 /*-----------------------------------------------------------------------*/
00184 //TODO: something faster?
00185 inline void UtilIotaN(vector<int> & first,
00186                       const int     size,
00187                       const int     init)
00188 {
00189    first.reserve(size);
00190    int i, val = init + size;
00191 
00192    for (i = init; i < val; i++) {
00193       first.push_back(i);
00194    }
00195 }
00196 
00197 // =========================================================================
00198 // Random Numbers
00199 // =========================================================================
00200 
00201 /*-----------------------------------------------------------------------*/
00202 inline double UtilURand(const double a, const double b)
00203 {
00204    double rand01 = static_cast<double>(rand()) / static_cast<double>(RAND_MAX);
00205    return a + (rand01 * (b - a));
00206 }
00207 
00208 /*-----------------------------------------------------------------------*/
00209 inline int UtilURand(const int a, const int b)
00210 {
00211    double rand01 = static_cast<double>(rand()) / static_cast<double>(RAND_MAX);
00212    return a + static_cast<int>(rand01 * (b - a));
00213 }
00214 
00215 // =========================================================================
00216 // Statistics
00217 // =========================================================================
00218 //?? make templates?
00219 /*-----------------------------------------------------------------------*/
00220 inline double UtilAve(const vector<double> & x)
00221 {
00222    return std::accumulate(x.begin(), x.end(), 0.0) / x.size();
00223 }
00224 
00225 /*-----------------------------------------------------------------------*/
00226 inline double UtilAve(const vector<int> & x)
00227 {
00228    return std::accumulate(x.begin(), x.end(), 0.0) / x.size();
00229 }
00230 
00231 /*-----------------------------------------------------------------------*/
00232 inline double UtilAve(const double* x,
00233                       const int      len)
00234 {
00235    return std::accumulate(x, x + len, 0.0) / len;
00236 }
00237 
00238 // =========================================================================
00239 // Other Macros
00240 // =========================================================================
00241 
00242 // ------------------------------------------------------------------------- //
00243 inline double UtilFracPart(const double x)
00244 {
00245    double floor_x     = floor(x);
00246    double floor_xplus = floor(x + 0.5);
00247 
00248    if (fabs(floor_xplus - x) < (UtilEpsilon * (fabs(floor_xplus) + 1.0))) {
00249       return 0.0;
00250    }
00251 
00252    return x - floor_x;
00253 }
00254 
00255 // ------------------------------------------------------------------------- //
00256 int UtilScaleDblToIntArr(const int      arrLen,
00257                          const double* arrDbl,
00258                          int*           arrInt,
00259                          const double   oneDbl,
00260                          int*           oneInt,
00261                          const double   epstol = UtilEpsilon);
00262 
00263 // ------------------------------------------------------------------------- //
00264 int UtilScaleDblToIntArr(const int      arrLen,
00265                          const double* arrDbl,
00266                          int*           arrInt,
00267                          const double   epstol = UtilEpsilon);
00268 
00269 
00270 
00271 // ------------------------------------------------------------------------- //
00272 inline bool UtilIsZero(const double x,
00273                        const double etol = 1.0e-8)
00274 {
00275    return fabs(x) < etol;
00276 }
00277 
00278 // ------------------------------------------------------------------------- //
00279 inline string UtilIntToStr(const int i)
00280 {
00281    stringstream ss;
00282    ss << i;
00283    return ss.str();
00284 }
00285 
00286 // ------------------------------------------------------------------------- //
00287 template <class T>
00288 void UtilDeleteVectorPtr(vector<T*> & vectorPtr,
00289                          typename vector<T*>::iterator first,
00290                          typename vector<T*>::iterator last)
00291 {
00292    typename vector<T*>::iterator it;
00293 
00294    for (it = first; it != last; it++) {
00295       delete *it;
00296    }
00297 
00298    vectorPtr.erase(first, last);
00299 }
00300 
00301 // ------------------------------------------------------------------------- //
00302 template <class T> void UtilDeleteVectorPtr(vector<T*> & vectorPtr)
00303 {
00304    UtilDeleteVectorPtr(vectorPtr, vectorPtr.begin(), vectorPtr.end());
00305 }
00306 
00307 // ------------------------------------------------------------------------- //
00308 template <class T> void UtilDeleteListPtr(list<T*> & listPtr,
00309       typename list<T*>::iterator first,
00310       typename list<T*>::iterator last)
00311 {
00312    typename list<T*>::iterator it;
00313 
00314    for (it = first; it != last; it++) {
00315       delete *it;
00316    }
00317 
00318    listPtr.erase(first, last);
00319 }
00320 
00321 // ------------------------------------------------------------------------- //
00322 template <class T> void UtilDeleteListPtr(list<T*> & listPtr)
00323 {
00324    UtilDeleteListPtr(listPtr, listPtr.begin(), listPtr.end());
00325 }
00326 
00327 // ------------------------------------------------------------------------- //
00328 inline bool UtilIsIntegral(const double x,
00329                            const double etol = 1.0e-10)
00330 {
00331    return UtilIsZero(x - floor(x), etol) || UtilIsZero(ceil(x) - x, etol);
00332 }
00333 
00334 // ------------------------------------------------------------------------- //
00335 template <class T> inline void UtilNegateArr(const int   arrLen,
00336       T*          arr)
00337 {
00338    transform(arr, arr + arrLen, arr, negate<T>());
00339 }
00340 
00341 // ------------------------------------------------------------------------- //
00342 template <class T>
00343 struct AddOffset : public unary_function<T, T> {
00344    T m_n;
00345    T operator() (const T& k) {
00346       return k + m_n;
00347    }
00348    AddOffset(T n) : m_n (n) {};
00349 };
00350 
00351 // ------------------------------------------------------------------------- //
00352 template <class T> inline void UtilAddOffsetArr(const int   arrLen,
00353       T           offset,
00354       T*          arr)
00355 {
00356    transform(arr, arr + arrLen, arr, AddOffset<T>(offset));
00357 }
00358 
00359 // ------------------------------------------------------------------------- //
00360 struct Perturb { //: public unary_function
00361    double m_randLB;
00362    double m_randUB;
00363    double operator() (const double& k) {
00364       return k + UtilURand(m_randLB, m_randUB);
00365    }
00366    Perturb(double randLB, double randUB) :
00367       m_randLB(randLB), m_randUB(randUB) {};
00368 };
00369 
00370 // ------------------------------------------------------------------------- //
00371 inline void UtilPerturbCost(const int      seed,
00372                             const int      arrLen,
00373                             const double   randLB,
00374                             const double   randUB,
00375                             double*        arr)
00376 {
00377    srand(seed);
00378    transform(arr, arr + arrLen, arr, Perturb(randLB, randUB));
00379 }
00380 
00381 // ------------------------------------------------------------------------- //
00382 inline void UtilFlipRowLtoG(const int    len,
00383                             double*      els,
00384                             char&        sense,
00385                             double&      rhs)
00386 {
00387    if (sense == 'L') {
00388       return;
00389    }
00390 
00391    if (sense == 'G') {
00392       //C++ row to negate? TODO
00393       for (int i = 0; i < len; i++) {
00394          els[i] = -els[i];
00395       }
00396 
00397       sense = 'L';
00398       rhs   = -rhs;
00399    }
00400 
00401    assert(0);
00402 }
00403 
00404 // ------------------------------------------------------------------------- //
00405 inline void UtilBoundToSense(const double   lb,
00406                              const double   ub,
00407                              const double   inf,
00408                              char&          sense,
00409                              double&        rhs,
00410                              double&        range)
00411 {
00412    range = 0.0;
00413 
00414    if (lb > -inf) {
00415       if (ub < inf) {
00416          rhs = ub;
00417 
00418          if (UtilIsZero(ub - lb)) {
00419             sense = 'E';
00420          } else {
00421             sense = 'R';
00422             range = ub - lb;
00423          }
00424       } else {
00425          sense = 'G';
00426          rhs = lb;
00427       }
00428    } else {
00429       if (ub < inf) {
00430          sense = 'L';
00431          rhs = ub;
00432       } else {
00433          sense = 'N';
00434          rhs = 0.0;
00435       }
00436    }
00437 }
00438 
00439 // ------------------------------------------------------------------------- //
00440 inline void UtilSenseToBound(const char     sense,
00441                              const double   rhs,
00442                              const double   range,
00443                              const double   inf,
00444                              double&        lb,
00445                              double&        ub)
00446 {
00447    switch (sense) {
00448    case 'E':
00449       lb = rhs;
00450       ub = rhs;
00451       break;
00452    case 'L':
00453       lb = -inf;
00454       ub = rhs;
00455       break;
00456    case 'G':
00457       lb = rhs;
00458       ub = inf;
00459       break;
00460    case 'R':
00461       lb = rhs - range;
00462       ub = rhs;
00463       break;
00464    case 'N':
00465       lb = -inf;
00466       ub = inf;
00467       break;
00468    }
00469 }
00470 
00471 // --------------------------------------------------------------------- //
00472 template<class S, class T> class UtilIsGreaterThan {
00473 public:
00474    bool operator()( const pair<S, T> & x,
00475                     const pair<S, T> & y) {
00476       return x.second > y.second;
00477    }
00478 };
00479 
00480 // --------------------------------------------------------------------- //
00481 template<class S, class T> class UtilIsLessThan {
00482 public:
00483    bool operator()( const pair<S, T> & x,
00484                     const pair<S, T> & y) {
00485       return x.second < y.second;
00486    }
00487 };
00488 
00489 #if 0
00490 // ------------------------------------------------------------------------- //
00491 class UtilIsLessThan {
00492 public:
00493    bool operator()( const pair<int, double> & x,
00494                     const pair<int, double> & y) {
00495       return x.second < y.second;
00496    }
00497    bool operator()( const pair< pair<int, int>, double> & x,
00498                     const pair< pair<int, int>, double> & y) {
00499       return x.second < y.second;
00500    }
00501 };
00502 
00503 // ------------------------------------------------------------------------- //
00504 class UtilIsGreaterThan {
00505 public:
00506    bool operator()( const pair<int, double> & x,
00507                     const pair<int, double> & y) {
00508       return x.second > y.second;
00509    }
00510 };
00511 #endif
00512 
00513 // ------------------------------------------------------------------------- //
00514 inline string UtilDirSlash()
00515 {
00516    string slash;
00517 #if defined(_MSC_VER)
00518    slash = "\\";
00519 #else
00520    slash = "/";
00521 #endif
00522    return slash;
00523 }
00524 
00525 // ------------------------------------------------------------------------- //
00526 inline void UtilOpenFile(ifstream&    fs,
00527                          const char* fileName) throw(CoinError)
00528 {
00529    fs.open(fileName);
00530 
00531    if (!fs) {
00532       string errMessage = "Error: Filename = ";
00533       errMessage += fileName;
00534       errMessage += " failed to open.";
00535       CoinAssertHint(fs, errMessage.c_str());
00536    }
00537 }
00538 
00539 // =========================================================================
00540 // String Macros
00541 // =========================================================================
00542 
00543 // ------------------------------------------------------------------------- //
00544 //trims white space (as defined by UtilSpaces) in-place
00545 inline string& UtilStrTrim(string&        s,
00546                            const string& t = UtilSpaces)
00547 {
00548    if (s.size() == 0) {
00549       return s;
00550    }
00551 
00552    string::size_type pos = s.find_last_not_of(t);
00553 
00554    if (pos != string::npos) {
00555       s.erase(pos + 1);
00556       pos = s.find_first_not_of(' ');
00557 
00558       if (pos != string::npos) {
00559          s.erase(0, pos);
00560       }
00561    } else {
00562       s.erase(s.begin(), s.end());
00563    }
00564 
00565    return s;
00566 }
00567 
00568 // ------------------------------------------------------------------------- //
00569 // returns a lower case version of the string in-place
00570 inline string& UtilStrToLower(string& s)
00571 {
00572    // Purify did not like this version:
00573    //   transform (s.begin(), s.end(), s.begin(), myToLower());
00574    if (s.size() == 0) {
00575       return s;
00576    }
00577 
00578    int i;
00579 
00580    for (i = 0; s[i] != '\0'; i++) {
00581       s[i] = static_cast<char>(tolower(s[i]));
00582    }
00583 
00584    return s;
00585 }
00586 
00587 
00588 // ------------------------------------------------------------------------- //
00589 // returns an upper case version of the string in-place
00590 inline string& UtilStrToUpper(string& s)
00591 {
00592    // Purify did not like this version:
00593    //   transform (s.begin(), s.end(), s.begin(), myToUpper());
00594    int i;
00595 
00596    if (s.size() == 0) {
00597       return s;
00598    }
00599 
00600    for (i = 0; s[i] != '\0'; i++) {
00601       s[i] = static_cast<char>(toupper(s[i]));
00602    }
00603 
00604    return s;
00605 }
00606 
00607 
00608 #endif

Generated on 3 Jun 2015 for Dip-All by  doxygen 1.6.1