/home/coin/SVN-release/Bcp-1.2.1/CoinUtils/src/CoinHelperFunctions.hpp

Go to the documentation of this file.
00001 // Copyright (C) 2000, International Business Machines
00002 // Corporation and others.  All Rights Reserved.
00003 
00004 #ifndef CoinHelperFunctions_H
00005 #define CoinHelperFunctions_H
00006 #if defined(_MSC_VER)
00007 #  include <direct.h>
00008 #  define getcwd _getcwd
00009 #else
00010 #  include <unistd.h>
00011 #endif
00012 
00013 #include <cstdlib>
00014 #include <cstdio>
00015 #include "CoinError.hpp"
00016 #include "CoinFinite.hpp"
00017 //#############################################################################
00018 
00024 template <class T> inline void
00025 CoinCopyN(register const T* from, const int size, register T* to)
00026 {
00027     if (size == 0 || from == to)
00028         return;
00029 
00030     if (size < 0)
00031         throw CoinError("trying to copy negative number of entries",
00032                         "CoinCopyN", "");
00033 
00034     register int n = (size + 7) / 8;
00035     if (to > from) {
00036         register const T* downfrom = from + size;
00037         register T* downto = to + size;
00038         // Use Duff's device to copy
00039         switch (size % 8) {
00040         case 0: do{     *--downto = *--downfrom;
00041         case 7:         *--downto = *--downfrom;
00042         case 6:         *--downto = *--downfrom;
00043         case 5:         *--downto = *--downfrom;
00044         case 4:         *--downto = *--downfrom;
00045         case 3:         *--downto = *--downfrom;
00046         case 2:         *--downto = *--downfrom;
00047         case 1:         *--downto = *--downfrom;
00048         }while(--n>0);
00049         }
00050     } else {
00051         // Use Duff's device to copy
00052         --from;
00053         --to;
00054         switch (size % 8) {
00055         case 0: do{     *++to = *++from;
00056         case 7:         *++to = *++from;
00057         case 6:         *++to = *++from;
00058         case 5:         *++to = *++from;
00059         case 4:         *++to = *++from;
00060         case 3:         *++to = *++from;
00061         case 2:         *++to = *++from;
00062         case 1:         *++to = *++from;
00063         }while(--n>0);
00064         }
00065     }
00066 }
00067 
00068 //-----------------------------------------------------------------------------
00069 
00074 template <class T> inline void
00075 CoinCopy(register const T* first, register const T* last, register T* to)
00076 {
00077     CoinCopyN(first, last - first, to);
00078 }
00079 
00080 //-----------------------------------------------------------------------------
00081 
00089 template <class T> inline void
00090 CoinDisjointCopyN(register const T* from, const int size, register T* to)
00091 {
00092 #ifndef _MSC_VER
00093     if (size == 0 || from == to)
00094         return;
00095 
00096     if (size < 0)
00097         throw CoinError("trying to copy negative number of entries",
00098                         "CoinDisjointCopyN", "");
00099 
00100 #if 0
00101     /* There is no point to do this test. If to and from are from different
00102        blocks then dist is undefined, so this can crash correct code. It's
00103        better to trust the user that the arrays are really disjoint. */
00104     const long dist = to - from;
00105     if (-size < dist && dist < size)
00106         throw CoinError("overlapping arrays", "CoinDisjointCopyN", "");
00107 #endif
00108 
00109     for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
00110         to[0] = from[0];
00111         to[1] = from[1];
00112         to[2] = from[2];
00113         to[3] = from[3];
00114         to[4] = from[4];
00115         to[5] = from[5];
00116         to[6] = from[6];
00117         to[7] = from[7];
00118     }
00119     switch (size % 8) {
00120     case 7: to[6] = from[6];
00121     case 6: to[5] = from[5];
00122     case 5: to[4] = from[4];
00123     case 4: to[3] = from[3];
00124     case 3: to[2] = from[2];
00125     case 2: to[1] = from[1];
00126     case 1: to[0] = from[0];
00127     case 0: break;
00128     }
00129 #else
00130     CoinCopyN(from, size, to);
00131 #endif
00132 }
00133 
00134 //-----------------------------------------------------------------------------
00135 
00140 template <class T> inline void
00141 CoinDisjointCopy(register const T* first, register const T* last,
00142                  register T* to)
00143 {
00144     CoinDisjointCopyN(first, static_cast<int>(last - first), to);
00145 }
00146 
00147 //-----------------------------------------------------------------------------
00148 
00153 template <class T> inline T*
00154 CoinCopyOfArray( const T * array, const int size)
00155 {
00156     if (array) {
00157         T * arrayNew = new T[size];
00158         std::memcpy(arrayNew,array,size*sizeof(T));
00159         return arrayNew;
00160     } else {
00161         return NULL;
00162     }
00163 }
00164 
00165 
00170 template <class T> inline T*
00171 CoinCopyOfArrayPartial( const T * array, const int size,const int copySize)
00172 {
00173     if (array||size) {
00174         T * arrayNew = new T[size];
00175         assert (copySize<=size);
00176         std::memcpy(arrayNew,array,copySize*sizeof(T));
00177         return arrayNew;
00178     } else {
00179         return NULL;
00180     }
00181 }
00182 
00187 template <class T> inline T*
00188 CoinCopyOfArray( const T * array, const int size, T value)
00189 {
00190     T * arrayNew = new T[size];
00191     if (array) {
00192         std::memcpy(arrayNew,array,size*sizeof(T));
00193     } else {
00194         int i;
00195         for (i=0;i<size;i++) 
00196             arrayNew[i] = value;
00197     }
00198     return arrayNew;
00199 }
00200 
00201 
00206 template <class T> inline T*
00207 CoinCopyOfArrayOrZero( const T * array , const int size)
00208 {
00209     T * arrayNew = new T[size];
00210     if (array) {
00211       std::memcpy(arrayNew,array,size*sizeof(T));
00212     } else {
00213       std::memset(arrayNew,0,size*sizeof(T));
00214     }
00215     return arrayNew;
00216 }
00217 
00218 
00219 //-----------------------------------------------------------------------------
00220 
00228 #ifndef COIN_USE_RESTRICT
00229 template <class T> inline void
00230 CoinMemcpyN(register const T* from, const int size, register T* to)
00231 {
00232 #ifndef _MSC_VER
00233 #ifdef USE_MEMCPY
00234     // Use memcpy - seems a lot faster on Intel with gcc
00235 #ifndef NDEBUG
00236     // Some debug so check
00237     if (size < 0)
00238         throw CoinError("trying to copy negative number of entries",
00239                         "CoinMemcpyN", "");
00240   
00241 #if 0
00242     /* There is no point to do this test. If to and from are from different
00243        blocks then dist is undefined, so this can crash correct code. It's
00244        better to trust the user that the arrays are really disjoint. */
00245     const long dist = to - from;
00246     if (-size < dist && dist < size)
00247         throw CoinError("overlapping arrays", "CoinMemcpyN", "");
00248 #endif
00249 #endif
00250     std::memcpy(to,from,size*sizeof(T));
00251 #else
00252     if (size == 0 || from == to)
00253         return;
00254 
00255     if (size < 0)
00256         throw CoinError("trying to copy negative number of entries",
00257                         "CoinMemcpyN", "");
00258 
00259 #if 0
00260     /* There is no point to do this test. If to and from are from different
00261        blocks then dist is undefined, so this can crash correct code. It's
00262        better to trust the user that the arrays are really disjoint. */
00263     const long dist = to - from;
00264     if (-size < dist && dist < size)
00265         throw CoinError("overlapping arrays", "CoinMemcpyN", "");
00266 #endif
00267 
00268     for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
00269         to[0] = from[0];
00270         to[1] = from[1];
00271         to[2] = from[2];
00272         to[3] = from[3];
00273         to[4] = from[4];
00274         to[5] = from[5];
00275         to[6] = from[6];
00276         to[7] = from[7];
00277     }
00278     switch (size % 8) {
00279     case 7: to[6] = from[6];
00280     case 6: to[5] = from[5];
00281     case 5: to[4] = from[4];
00282     case 4: to[3] = from[3];
00283     case 3: to[2] = from[2];
00284     case 2: to[1] = from[1];
00285     case 1: to[0] = from[0];
00286     case 0: break;
00287     }
00288 #endif
00289 #else
00290     CoinCopyN(from, size, to);
00291 #endif
00292 }
00293 #else
00294 template <class T> inline void
00295 CoinMemcpyN(const T * COIN_RESTRICT from, int size, T* COIN_RESTRICT to)
00296 {
00297   T * put = (T *) to;
00298   const T * get = (const T *) from;
00299   for ( ; 0<size ; --size)
00300     *put++ = *get++;
00301 }
00302 #endif
00303 
00304 //-----------------------------------------------------------------------------
00305 
00310 template <class T> inline void
00311 CoinMemcpy(register const T* first, register const T* last,
00312            register T* to)
00313 {
00314     CoinMemcpyN(first, static_cast<int>(last - first), to);
00315 }
00316 
00317 //#############################################################################
00318 
00325 template <class T> inline void
00326 CoinFillN(register T* to, const int size, register const T value)
00327 {
00328     if (size == 0)
00329         return;
00330 
00331     if (size < 0)
00332         throw CoinError("trying to fill negative number of entries",
00333                         "CoinFillN", "");
00334 
00335 #if 1
00336     for (register int n = size / 8; n > 0; --n, to += 8) {
00337         to[0] = value;
00338         to[1] = value;
00339         to[2] = value;
00340         to[3] = value;
00341         to[4] = value;
00342         to[5] = value;
00343         to[6] = value;
00344         to[7] = value;
00345     }
00346     switch (size % 8) {
00347     case 7: to[6] = value;
00348     case 6: to[5] = value;
00349     case 5: to[4] = value;
00350     case 4: to[3] = value;
00351     case 3: to[2] = value;
00352     case 2: to[1] = value;
00353     case 1: to[0] = value;
00354     case 0: break;
00355     }
00356 #else
00357     // Use Duff's device to fill
00358     register int n = (size + 7) / 8;
00359     --to;
00360     switch (size % 8) {
00361     case 0: do{     *++to = value;
00362     case 7:         *++to = value;
00363     case 6:         *++to = value;
00364     case 5:         *++to = value;
00365     case 4:         *++to = value;
00366     case 3:         *++to = value;
00367     case 2:         *++to = value;
00368     case 1:         *++to = value;
00369     }while(--n>0);
00370     }
00371 #endif
00372 }
00373 
00374 //-----------------------------------------------------------------------------
00375 
00379 template <class T> inline void
00380 CoinFill(register T* first, register T* last, const T value)
00381 {
00382     CoinFillN(first, last - first, value);
00383 }
00384 
00385 //#############################################################################
00386 
00393 template <class T> inline void
00394 CoinZeroN(register T* to, const int size)
00395 {
00396 #ifdef USE_MEMCPY
00397     // Use memset - seems faster on Intel with gcc
00398 #ifndef NDEBUG
00399     // Some debug so check
00400     if (size < 0)
00401         throw CoinError("trying to fill negative number of entries",
00402                         "CoinZeroN", "");
00403 #endif
00404     memset(to,0,size*sizeof(T));
00405 #else
00406     if (size == 0)
00407         return;
00408 
00409     if (size < 0)
00410         throw CoinError("trying to fill negative number of entries",
00411                         "CoinZeroN", "");
00412 #if 1
00413     for (register int n = size / 8; n > 0; --n, to += 8) {
00414         to[0] = 0;
00415         to[1] = 0;
00416         to[2] = 0;
00417         to[3] = 0;
00418         to[4] = 0;
00419         to[5] = 0;
00420         to[6] = 0;
00421         to[7] = 0;
00422     }
00423     switch (size % 8) {
00424     case 7: to[6] = 0;
00425     case 6: to[5] = 0;
00426     case 5: to[4] = 0;
00427     case 4: to[3] = 0;
00428     case 3: to[2] = 0;
00429     case 2: to[1] = 0;
00430     case 1: to[0] = 0;
00431     case 0: break;
00432     }
00433 #else
00434     // Use Duff's device to fill
00435     register int n = (size + 7) / 8;
00436     --to;
00437     switch (size % 8) {
00438     case 0: do{     *++to = 0;
00439     case 7:         *++to = 0;
00440     case 6:         *++to = 0;
00441     case 5:         *++to = 0;
00442     case 4:         *++to = 0;
00443     case 3:         *++to = 0;
00444     case 2:         *++to = 0;
00445     case 1:         *++to = 0;
00446     }while(--n>0);
00447     }
00448 #endif
00449 #endif
00450 }
00452 inline void
00453 CoinCheckDoubleZero(double * to, const int size)
00454 {
00455     int n=0;
00456     for (int j=0;j<size;j++) {
00457         if (to[j]) 
00458             n++;
00459     }
00460     if (n) {
00461         printf("array of length %d should be zero has %d nonzero\n",size,n);
00462     }
00463 }
00465 inline void
00466 CoinCheckIntZero(int * to, const int size)
00467 {
00468     int n=0;
00469     for (int j=0;j<size;j++) {
00470         if (to[j]) 
00471             n++;
00472     }
00473     if (n) {
00474         printf("array of length %d should be zero has %d nonzero\n",size,n);
00475     }
00476 }
00477 
00478 //-----------------------------------------------------------------------------
00479 
00483 template <class T> inline void
00484 CoinZero(register T* first, register T* last)
00485 {
00486     CoinZeroN(first, last - first);
00487 }
00488 
00489 //#############################################################################
00490 
00492 inline char * CoinStrdup(const char * name)
00493 {
00494   char* dup = NULL;
00495   if (name) {
00496     const int len = strlen(name);
00497     dup = (char*)malloc(len+1);
00498     CoinMemcpyN(name, len, dup);
00499     dup[len] = 0;
00500   }
00501   return dup;
00502 }
00503 
00504 //#############################################################################
00505 
00509 template <class T> inline T
00510 CoinMax(register const T x1, register const T x2)
00511 {
00512     return (x1 > x2) ? x1 : x2;
00513 }
00514 
00515 //-----------------------------------------------------------------------------
00516 
00520 template <class T> inline T
00521 CoinMin(register const T x1, register const T x2)
00522 {
00523     return (x1 < x2) ? x1 : x2;
00524 }
00525 
00526 //-----------------------------------------------------------------------------
00527 
00531 template <class T> inline T
00532 CoinAbs(const T value)
00533 {
00534     return value<0 ? -value : value;
00535 }
00536 
00537 //#############################################################################
00538 
00542 template <class T> inline bool
00543 CoinIsSorted(register const T* first, const int size)
00544 {
00545     if (size == 0)
00546         return true;
00547 
00548     if (size < 0)
00549         throw CoinError("negative number of entries", "CoinIsSorted", "");
00550 
00551 #if 1
00552     // size1 is the number of comparisons to be made
00553     const int size1 = size  - 1;
00554     for (register int n = size1 / 8; n > 0; --n, first += 8) {
00555         if (first[8] < first[7]) return false;
00556         if (first[7] < first[6]) return false;
00557         if (first[6] < first[5]) return false;
00558         if (first[5] < first[4]) return false;
00559         if (first[4] < first[3]) return false;
00560         if (first[3] < first[2]) return false;
00561         if (first[2] < first[1]) return false;
00562         if (first[1] < first[0]) return false;
00563     }
00564 
00565     switch (size1 % 8) {
00566     case 7: if (first[7] < first[6]) return false;
00567     case 6: if (first[6] < first[5]) return false;
00568     case 5: if (first[5] < first[4]) return false;
00569     case 4: if (first[4] < first[3]) return false;
00570     case 3: if (first[3] < first[2]) return false;
00571     case 2: if (first[2] < first[1]) return false;
00572     case 1: if (first[1] < first[0]) return false;
00573     case 0: break;
00574     }
00575 #else
00576     register const T* next = first;
00577     register const T* last = first + size;
00578     for (++next; next != last; first = next, ++next)
00579         if (*next < *first)
00580             return false;
00581 #endif   
00582     return true;
00583 }
00584 
00585 //-----------------------------------------------------------------------------
00586 
00590 template <class T> inline bool
00591 CoinIsSorted(register const T* first, register const T* last)
00592 {
00593     return CoinIsSorted(first, static_cast<int>(last - first));
00594 }
00595 
00596 //#############################################################################
00597 
00601 template <class T> inline void
00602 CoinIotaN(register T* first, const int size, register T init)
00603 {
00604     if (size == 0)
00605         return;
00606 
00607     if (size < 0)
00608         throw CoinError("negative number of entries", "CoinIotaN", "");
00609 
00610 #if 1
00611     for (register int n = size / 8; n > 0; --n, first += 8, init += 8) {
00612         first[0] = init;
00613         first[1] = init + 1;
00614         first[2] = init + 2;
00615         first[3] = init + 3;
00616         first[4] = init + 4;
00617         first[5] = init + 5;
00618         first[6] = init + 6;
00619         first[7] = init + 7;
00620     }
00621     switch (size % 8) {
00622     case 7: first[6] = init + 6;
00623     case 6: first[5] = init + 5;
00624     case 5: first[4] = init + 4;
00625     case 4: first[3] = init + 3;
00626     case 3: first[2] = init + 2;
00627     case 2: first[1] = init + 1;
00628     case 1: first[0] = init;
00629     case 0: break;
00630     }
00631 #else
00632     // Use Duff's device to fill
00633     register int n = (size + 7) / 8;
00634     --first;
00635     --init;
00636     switch (size % 8) {
00637     case 0: do{     *++first = ++init;
00638     case 7:         *++first = ++init;
00639     case 6:         *++first = ++init;
00640     case 5:         *++first = ++init;
00641     case 4:         *++first = ++init;
00642     case 3:         *++first = ++init;
00643     case 2:         *++first = ++init;
00644     case 1:         *++first = ++init;
00645     }while(--n>0);
00646     }
00647 #endif
00648 }
00649 
00650 //-----------------------------------------------------------------------------
00651 
00655 template <class T> inline void
00656 CoinIota(T* first, const T* last, T init)
00657 {
00658     CoinIotaN(first, last-first, init);
00659 }
00660 
00661 //#############################################################################
00662 
00668 template <class T> inline T *
00669 CoinDeleteEntriesFromArray(register T * arrayFirst, register T * arrayLast,
00670                            const int * firstDelPos, const int * lastDelPos)
00671 {
00672     int delNum = lastDelPos - firstDelPos;
00673     if (delNum == 0)
00674         return arrayLast;
00675 
00676     if (delNum < 0)
00677         throw CoinError("trying to delete negative number of entries",
00678                         "CoinDeleteEntriesFromArray", "");
00679 
00680     int * delSortedPos = NULL;
00681     if (! (CoinIsSorted(firstDelPos, lastDelPos) &&
00682            std::adjacent_find(firstDelPos, lastDelPos) == lastDelPos)) {
00683         // the positions of the to be deleted is either not sorted or not unique
00684         delSortedPos = new int[delNum];
00685         CoinDisjointCopy(firstDelPos, lastDelPos, delSortedPos);
00686         std::sort(delSortedPos, delSortedPos + delNum);
00687         delNum = std::unique(delSortedPos, delSortedPos + delNum) - delSortedPos;
00688     }
00689     const int * delSorted = delSortedPos ? delSortedPos : firstDelPos;
00690 
00691     const int last = delNum - 1;
00692     int size = delSorted[0];
00693     for (int i = 0; i < last; ++i) {
00694         const int copyFirst = delSorted[i] + 1;
00695         const int copyLast = delSorted[i+1];
00696         CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
00697                  arrayFirst + size);
00698         size += copyLast - copyFirst;
00699     }
00700     const int copyFirst = delSorted[last] + 1;
00701     const int copyLast = arrayLast - arrayFirst;
00702     CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
00703              arrayFirst + size);
00704     size += copyLast - copyFirst;
00705 
00706     if (delSortedPos)
00707         delete[] delSortedPos;
00708 
00709     return arrayFirst + size;
00710 }
00711 
00712 //#############################################################################
00713 
00714 #define COIN_OWN_RANDOM_32
00715 
00716 #if defined COIN_OWN_RANDOM_32
00717 /* Thanks to Stefano Gliozzi for providing an operating system
00718    independent random number generator.  */
00719 
00720 // linear congruential generator. given the seed, the generated numbers are  
00721 // always the same regardless the (32 bit) architecture. This allows to 
00722 // build & test in different environments (i.e. Wintel, Linux/Intel AIX Power5)
00723 // getting in most cases the same optimization path. 
00725 inline double CoinDrand48(bool isSeed = false, unsigned int seed=1)
00726 {
00727   static unsigned int last = 123456;
00728   if (isSeed) { 
00729     last = seed;
00730   } else {
00731     last = 1664525*last+1013904223;
00732     return (((double) last)/4294967296.0);
00733   }
00734   return(0.0);
00735 }
00737 inline void CoinSeedRandom(int iseed)
00738 {
00739   CoinDrand48(true, iseed);
00740 }
00741 
00742 #else // COIN_OWN_RANDOM_32
00743 
00744 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
00745 
00746 inline double CoinDrand48() { return rand() / (double) RAND_MAX; }
00747 inline void CoinSeedRandom(int iseed) { srand(iseed + 69822); }
00748 
00749 #else
00750 
00751 inline double CoinDrand48() { return drand48(); }
00752 inline void CoinSeedRandom(int iseed) { srand48(iseed + 69822); }
00753 
00754 #endif
00755 
00756 #endif // COIN_OWN_RANDOM_32
00757 
00758 //#############################################################################
00759 
00762 inline char CoinFindDirSeparator()
00763 {
00764     int size = 1000;
00765     char* buf = 0;
00766     while (true) {
00767         buf = new char[size];
00768         if (getcwd(buf, size))
00769             break;
00770         delete[] buf;
00771         buf = 0;
00772         size = 2*size;
00773     }
00774     // if first char is '/' then it's unix and the dirsep is '/'. otherwise we 
00775     // assume it's dos and the dirsep is '\'
00776     char dirsep = buf[0] == '/' ? '/' : '\\';
00777     delete[] buf;
00778     return dirsep;
00779 }
00780 //#############################################################################
00781 
00782 inline int CoinStrNCaseCmp(const char* s0, const char* s1,
00783                            const size_t len)
00784 {
00785     for (size_t i = 0; i < len; ++i) {
00786         if (s0[i] == 0) {
00787             return s1[i] == 0 ? 0 : -1;
00788         }
00789         if (s1[i] == 0) {
00790             return 1;
00791         }
00792         const int c0 = tolower(s0[i]);
00793         const int c1 = tolower(s1[i]);
00794         if (c0 < c1)
00795             return -1;
00796         if (c0 > c1)
00797             return 1;
00798     }
00799     return 0;
00800 }
00801 
00802 //#############################################################################
00803 
00805 template <class T> inline void CoinSwap (T &x, T &y)
00806 {
00807     T t = x;
00808     x = y;
00809     y = t;
00810 }
00811 
00812 //#############################################################################
00813 
00818 template <class T> inline int
00819 CoinToFile( const T* array, int size, FILE * fp)
00820 {
00821     int numberWritten;
00822     if (array&&size) {
00823         numberWritten = fwrite(&size,sizeof(int),1,fp);
00824         if (numberWritten!=1)
00825             return 1;
00826         numberWritten = fwrite(array,sizeof(T),size,fp);
00827         if (numberWritten!=size)
00828             return 1;
00829     } else {
00830         size = 0;
00831         numberWritten = fwrite(&size,sizeof(int),1,fp);
00832         if (numberWritten!=1)
00833             return 1;
00834     }
00835     return 0;
00836 }
00837 
00838 //#############################################################################
00839 
00846 template <class T> inline int
00847 CoinFromFile( T* &array, int size, FILE * fp,int & newSize)
00848 {
00849     int numberRead;
00850     numberRead = fread(&newSize,sizeof(int),1,fp);
00851     if (numberRead!=1)
00852         return 1;
00853     int returnCode=0;
00854     if (size!=newSize&&(newSize||array))
00855         returnCode=2;
00856     if (newSize) {
00857         array = new T [newSize];
00858         numberRead = fread(array,sizeof(T),newSize,fp);
00859         if (numberRead!=newSize)
00860             returnCode=1;
00861     } else {
00862         array = NULL;
00863     }
00864     return returnCode;
00865 }
00866 
00867 //#############################################################################
00868 
00870 inline double CoinCbrt(double x)
00871 {
00872 #if defined(_MSC_VER) 
00873     return pow(x,(1./3.));
00874 #else
00875     return cbrt(x);
00876 #endif
00877 }
00880 #if defined COIN_OWN_RANDOM_32
00881 class CoinThreadRandom  {
00882 public:
00887   CoinThreadRandom()
00888   { seed_=12345678;}
00890   CoinThreadRandom(int seed)
00891   { 
00892     seed_ = seed;
00893   }
00895   ~CoinThreadRandom() {}
00896   // Copy
00897   CoinThreadRandom(const CoinThreadRandom & rhs)
00898   { seed_ = rhs.seed_;}
00899   // Assignment
00900   CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
00901   {
00902     if (this != &rhs) {
00903       seed_ = rhs.seed_;
00904     }
00905     return *this;
00906   }
00907 
00909   
00914   inline void setSeed(int seed)
00915   { 
00916     seed_ = seed;
00917   }
00919   inline double randomDouble() const
00920   {
00921     double retVal;
00922     seed_ = 1664525*(seed_)+1013904223;
00923     retVal = (((double) seed_)/4294967296.0);
00924     return retVal;
00925   }
00927   
00928   
00929 protected:
00933 
00934   mutable unsigned int seed_;
00936 };
00937 #else
00938 class CoinThreadRandom  {
00939 public:
00944   CoinThreadRandom()
00945   { seed_[0]=50000;seed_[1]=40000;seed_[2]=30000;}
00947   CoinThreadRandom(const unsigned short seed[3])
00948   { memcpy(seed_,seed,3*sizeof(unsigned short));}
00950   CoinThreadRandom(int seed)
00951   { 
00952     union { int i[2]; unsigned short int s[4];} put;
00953     put.i[0]=seed;
00954     put.i[1]=seed;
00955     memcpy(seed_,put.s,3*sizeof(unsigned short));
00956   }
00958   ~CoinThreadRandom() {}
00959   // Copy
00960   CoinThreadRandom(const CoinThreadRandom & rhs)
00961   { memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));}
00962   // Assignment
00963   CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
00964   {
00965     if (this != &rhs) {
00966       memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));
00967     }
00968     return *this;
00969   }
00970 
00972   
00977   inline void setSeed(const unsigned short seed[3])
00978   { memcpy(seed_,seed,3*sizeof(unsigned short));}
00980   inline void setSeed(int seed)
00981   { 
00982     union { int i[2]; unsigned short int s[4];} put;
00983     put.i[0]=seed;
00984     put.i[1]=seed;
00985     memcpy(seed_,put.s,3*sizeof(unsigned short));
00986   }
00988   inline double randomDouble() const
00989   {
00990     double retVal;
00991 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
00992     retVal=rand();
00993     retVal=retVal/(double) RAND_MAX;
00994 #else
00995     retVal = erand48(seed_);
00996 #endif
00997     return retVal;
00998   }
01000   
01001   
01002 protected:
01006 
01007   mutable unsigned short seed_[3];
01009 };
01010 #endif
01011 #endif

Generated on Thu Jan 15 03:01:00 2009 for coin-Bcp by  doxygen 1.4.7