/home/coin/SVN-release/Blis-0.9.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         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) {
00174         T * arrayNew = new T[size];
00175         assert (copySize<=size);
00176         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         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         memcpy(arrayNew,array,size*sizeof(T));
00212     } else {
00213         memset(arrayNew,0,size*sizeof(T));
00214     }
00215     return arrayNew;
00216 }
00217 
00218 
00219 //-----------------------------------------------------------------------------
00220 
00228 template <class T> inline void
00229 CoinMemcpyN(register const T* from, const int size, register T* to)
00230 {
00231 #ifndef _MSC_VER
00232 #ifdef USE_MEMCPY
00233     // Use memcpy - seems a lot faster on Intel with gcc
00234 #ifndef NDEBUG
00235     // Some debug so check
00236     if (size < 0)
00237         throw CoinError("trying to copy negative number of entries",
00238                         "CoinMemcpyN", "");
00239   
00240 #if 0
00241     /* There is no point to do this test. If to and from are from different
00242        blocks then dist is undefined, so this can crash correct code. It's
00243        better to trust the user that the arrays are really disjoint. */
00244     const long dist = to - from;
00245     if (-size < dist && dist < size)
00246         throw CoinError("overlapping arrays", "CoinMemcpyN", "");
00247 #endif
00248 #endif
00249     memcpy(to,from,size*sizeof(T));
00250 #else
00251     if (size == 0 || from == to)
00252         return;
00253 
00254     if (size < 0)
00255         throw CoinError("trying to copy negative number of entries",
00256                         "CoinMemcpyN", "");
00257 
00258 #if 0
00259     /* There is no point to do this test. If to and from are from different
00260        blocks then dist is undefined, so this can crash correct code. It's
00261        better to trust the user that the arrays are really disjoint. */
00262     const long dist = to - from;
00263     if (-size < dist && dist < size)
00264         throw CoinError("overlapping arrays", "CoinMemcpyN", "");
00265 #endif
00266 
00267     for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
00268         to[0] = from[0];
00269         to[1] = from[1];
00270         to[2] = from[2];
00271         to[3] = from[3];
00272         to[4] = from[4];
00273         to[5] = from[5];
00274         to[6] = from[6];
00275         to[7] = from[7];
00276     }
00277     switch (size % 8) {
00278     case 7: to[6] = from[6];
00279     case 6: to[5] = from[5];
00280     case 5: to[4] = from[4];
00281     case 4: to[3] = from[3];
00282     case 3: to[2] = from[2];
00283     case 2: to[1] = from[1];
00284     case 1: to[0] = from[0];
00285     case 0: break;
00286     }
00287 #endif
00288 #else
00289     CoinCopyN(from, size, to);
00290 #endif
00291 }
00292 
00293 //-----------------------------------------------------------------------------
00294 
00299 template <class T> inline void
00300 CoinMemcpy(register const T* first, register const T* last,
00301            register T* to)
00302 {
00303     CoinMemcpyN(first, static_cast<int>(last - first), to);
00304 }
00305 
00306 //#############################################################################
00307 
00314 template <class T> inline void
00315 CoinFillN(register T* to, const int size, register const T value)
00316 {
00317     if (size == 0)
00318         return;
00319 
00320     if (size < 0)
00321         throw CoinError("trying to fill negative number of entries",
00322                         "CoinFillN", "");
00323 
00324 #if 1
00325     for (register int n = size / 8; n > 0; --n, to += 8) {
00326         to[0] = value;
00327         to[1] = value;
00328         to[2] = value;
00329         to[3] = value;
00330         to[4] = value;
00331         to[5] = value;
00332         to[6] = value;
00333         to[7] = value;
00334     }
00335     switch (size % 8) {
00336     case 7: to[6] = value;
00337     case 6: to[5] = value;
00338     case 5: to[4] = value;
00339     case 4: to[3] = value;
00340     case 3: to[2] = value;
00341     case 2: to[1] = value;
00342     case 1: to[0] = value;
00343     case 0: break;
00344     }
00345 #else
00346     // Use Duff's device to fill
00347     register int n = (size + 7) / 8;
00348     --to;
00349     switch (size % 8) {
00350     case 0: do{     *++to = value;
00351     case 7:         *++to = value;
00352     case 6:         *++to = value;
00353     case 5:         *++to = value;
00354     case 4:         *++to = value;
00355     case 3:         *++to = value;
00356     case 2:         *++to = value;
00357     case 1:         *++to = value;
00358     }while(--n>0);
00359     }
00360 #endif
00361 }
00362 
00363 //-----------------------------------------------------------------------------
00364 
00368 template <class T> inline void
00369 CoinFill(register T* first, register T* last, const T value)
00370 {
00371     CoinFillN(first, last - first, value);
00372 }
00373 
00374 //#############################################################################
00375 
00382 template <class T> inline void
00383 CoinZeroN(register T* to, const int size)
00384 {
00385 #ifdef USE_MEMCPY
00386     // Use memset - seems faster on Intel with gcc
00387 #ifndef NDEBUG
00388     // Some debug so check
00389     if (size < 0)
00390         throw CoinError("trying to fill negative number of entries",
00391                         "CoinZeroN", "");
00392 #endif
00393     memset(to,0,size*sizeof(T));
00394 #else
00395     if (size == 0)
00396         return;
00397 
00398     if (size < 0)
00399         throw CoinError("trying to fill negative number of entries",
00400                         "CoinZeroN", "");
00401 #if 1
00402     for (register int n = size / 8; n > 0; --n, to += 8) {
00403         to[0] = 0;
00404         to[1] = 0;
00405         to[2] = 0;
00406         to[3] = 0;
00407         to[4] = 0;
00408         to[5] = 0;
00409         to[6] = 0;
00410         to[7] = 0;
00411     }
00412     switch (size % 8) {
00413     case 7: to[6] = 0;
00414     case 6: to[5] = 0;
00415     case 5: to[4] = 0;
00416     case 4: to[3] = 0;
00417     case 3: to[2] = 0;
00418     case 2: to[1] = 0;
00419     case 1: to[0] = 0;
00420     case 0: break;
00421     }
00422 #else
00423     // Use Duff's device to fill
00424     register int n = (size + 7) / 8;
00425     --to;
00426     switch (size % 8) {
00427     case 0: do{     *++to = 0;
00428     case 7:         *++to = 0;
00429     case 6:         *++to = 0;
00430     case 5:         *++to = 0;
00431     case 4:         *++to = 0;
00432     case 3:         *++to = 0;
00433     case 2:         *++to = 0;
00434     case 1:         *++to = 0;
00435     }while(--n>0);
00436     }
00437 #endif
00438 #endif
00439 }
00441 inline void
00442 CoinCheckDoubleZero(double * to, const int size)
00443 {
00444     int n=0;
00445     for (int j=0;j<size;j++) {
00446         if (to[j]) 
00447             n++;
00448     }
00449     if (n) {
00450         printf("array of length %d should be zero has %d nonzero\n",size,n);
00451     }
00452 }
00454 inline void
00455 CoinCheckIntZero(int * to, const int size)
00456 {
00457     int n=0;
00458     for (int j=0;j<size;j++) {
00459         if (to[j]) 
00460             n++;
00461     }
00462     if (n) {
00463         printf("array of length %d should be zero has %d nonzero\n",size,n);
00464     }
00465 }
00466 
00467 //-----------------------------------------------------------------------------
00468 
00472 template <class T> inline void
00473 CoinZero(register T* first, register T* last)
00474 {
00475     CoinZeroN(first, last - first);
00476 }
00477 
00478 //#############################################################################
00479 
00483 template <class T> inline T
00484 CoinMax(register const T x1, register const T x2)
00485 {
00486     return (x1 > x2) ? x1 : x2;
00487 }
00488 
00489 //-----------------------------------------------------------------------------
00490 
00494 template <class T> inline T
00495 CoinMin(register const T x1, register const T x2)
00496 {
00497     return (x1 < x2) ? x1 : x2;
00498 }
00499 
00500 //-----------------------------------------------------------------------------
00501 
00505 template <class T> inline T
00506 CoinAbs(const T value)
00507 {
00508     return value<0 ? -value : value;
00509 }
00510 
00511 //#############################################################################
00512 
00516 template <class T> inline bool
00517 CoinIsSorted(register const T* first, const int size)
00518 {
00519     if (size == 0)
00520         return true;
00521 
00522     if (size < 0)
00523         throw CoinError("negative number of entries", "CoinIsSorted", "");
00524 
00525 #if 1
00526     // size1 is the number of comparisons to be made
00527     const int size1 = size  - 1;
00528     for (register int n = size1 / 8; n > 0; --n, first += 8) {
00529         if (first[8] < first[7]) return false;
00530         if (first[7] < first[6]) return false;
00531         if (first[6] < first[5]) return false;
00532         if (first[5] < first[4]) return false;
00533         if (first[4] < first[3]) return false;
00534         if (first[3] < first[2]) return false;
00535         if (first[2] < first[1]) return false;
00536         if (first[1] < first[0]) return false;
00537     }
00538 
00539     switch (size1 % 8) {
00540     case 7: if (first[7] < first[6]) return false;
00541     case 6: if (first[6] < first[5]) return false;
00542     case 5: if (first[5] < first[4]) return false;
00543     case 4: if (first[4] < first[3]) return false;
00544     case 3: if (first[3] < first[2]) return false;
00545     case 2: if (first[2] < first[1]) return false;
00546     case 1: if (first[1] < first[0]) return false;
00547     case 0: break;
00548     }
00549 #else
00550     register const T* next = first;
00551     register const T* last = first + size;
00552     for (++next; next != last; first = next, ++next)
00553         if (*next < *first)
00554             return false;
00555 #endif   
00556     return true;
00557 }
00558 
00559 //-----------------------------------------------------------------------------
00560 
00564 template <class T> inline bool
00565 CoinIsSorted(register const T* first, register const T* last)
00566 {
00567     return CoinIsSorted(first, static_cast<int>(last - first));
00568 }
00569 
00570 //#############################################################################
00571 
00575 template <class T> inline void
00576 CoinIotaN(register T* first, const int size, register T init)
00577 {
00578     if (size == 0)
00579         return;
00580 
00581     if (size < 0)
00582         throw CoinError("negative number of entries", "CoinIotaN", "");
00583 
00584 #if 1
00585     for (register int n = size / 8; n > 0; --n, first += 8, init += 8) {
00586         first[0] = init;
00587         first[1] = init + 1;
00588         first[2] = init + 2;
00589         first[3] = init + 3;
00590         first[4] = init + 4;
00591         first[5] = init + 5;
00592         first[6] = init + 6;
00593         first[7] = init + 7;
00594     }
00595     switch (size % 8) {
00596     case 7: first[6] = init + 6;
00597     case 6: first[5] = init + 5;
00598     case 5: first[4] = init + 4;
00599     case 4: first[3] = init + 3;
00600     case 3: first[2] = init + 2;
00601     case 2: first[1] = init + 1;
00602     case 1: first[0] = init;
00603     case 0: break;
00604     }
00605 #else
00606     // Use Duff's device to fill
00607     register int n = (size + 7) / 8;
00608     --first;
00609     --init;
00610     switch (size % 8) {
00611     case 0: do{     *++first = ++init;
00612     case 7:         *++first = ++init;
00613     case 6:         *++first = ++init;
00614     case 5:         *++first = ++init;
00615     case 4:         *++first = ++init;
00616     case 3:         *++first = ++init;
00617     case 2:         *++first = ++init;
00618     case 1:         *++first = ++init;
00619     }while(--n>0);
00620     }
00621 #endif
00622 }
00623 
00624 //-----------------------------------------------------------------------------
00625 
00629 template <class T> inline void
00630 CoinIota(T* first, const T* last, T init)
00631 {
00632     CoinIotaN(first, last-first, init);
00633 }
00634 
00635 //#############################################################################
00636 
00642 template <class T> inline T *
00643 CoinDeleteEntriesFromArray(register T * arrayFirst, register T * arrayLast,
00644                            const int * firstDelPos, const int * lastDelPos)
00645 {
00646     int delNum = lastDelPos - firstDelPos;
00647     if (delNum == 0)
00648         return arrayLast;
00649 
00650     if (delNum < 0)
00651         throw CoinError("trying to delete negative number of entries",
00652                         "CoinDeleteEntriesFromArray", "");
00653 
00654     int * delSortedPos = NULL;
00655     if (! (CoinIsSorted(firstDelPos, lastDelPos) &&
00656            std::adjacent_find(firstDelPos, lastDelPos) == lastDelPos)) {
00657         // the positions of the to be deleted is either not sorted or not unique
00658         delSortedPos = new int[delNum];
00659         CoinDisjointCopy(firstDelPos, lastDelPos, delSortedPos);
00660         std::sort(delSortedPos, delSortedPos + delNum);
00661         delNum = std::unique(delSortedPos, delSortedPos + delNum) - delSortedPos;
00662     }
00663     const int * delSorted = delSortedPos ? delSortedPos : firstDelPos;
00664 
00665     const int last = delNum - 1;
00666     int size = delSorted[0];
00667     for (int i = 0; i < last; ++i) {
00668         const int copyFirst = delSorted[i] + 1;
00669         const int copyLast = delSorted[i+1];
00670         CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
00671                  arrayFirst + size);
00672         size += copyLast - copyFirst;
00673     }
00674     const int copyFirst = delSorted[last] + 1;
00675     const int copyLast = arrayLast - arrayFirst;
00676     CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
00677              arrayFirst + size);
00678     size += copyLast - copyFirst;
00679 
00680     if (delSortedPos)
00681         delete[] delSortedPos;
00682 
00683     return arrayFirst + size;
00684 }
00685 #define COIN_OWN_RANDOM_32
00686 
00687 //#############################################################################
00688 /* Thanks to Stefano Gliozzi for providing an operating system
00689    independent random number generator.  */
00691 inline void CoinSeedRandom(int iseed)
00692 {
00693 #if defined COIN_OWN_RANDOM_32
00694   double CoinDrand48(bool isSeed = false, unsigned long seed=1);
00695   CoinDrand48(true, iseed);
00696 #else
00697   int jseed;
00698   jseed = iseed + 69822;
00699 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
00700   srand(jseed);
00701 #else
00702   srand48(jseed);
00703 #endif
00704 #endif // end else COIN_OWN_RANDOM
00705 }
00706 
00708 #if defined COIN_OWN_RANDOM_32
00709 // linear congruential generator. given the seed, the generated numbers are  
00710 // always the same regardless the (32 bit) architecture. This allows to 
00711 // build & test in different environments (i.e. Wintel, Linux/Intel AIX Power5)
00712 // getting in most cases the same optimization path. 
00713 inline double CoinDrand48(bool isSeed = false, unsigned long seed=1)
00714 {
00715   static unsigned last;
00716   if (isSeed) { 
00717     last = seed;
00718   } else {
00719     last = 1664525*last+1013904223;
00720     return (((double) last)/4294967296.0);
00721   }
00722   return(0.0);
00723 }
00724 #else 
00725 inline double CoinDrand48()
00726 {  
00727   double retVal;
00728 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
00729   retVal=rand();
00730   retVal=retVal/(double) RAND_MAX;
00731 #else
00732   retVal = drand48();
00733 #endif
00734   return retVal;
00735 }
00736 #endif
00737 
00738 //#############################################################################
00739 
00742 inline char CoinFindDirSeparator()
00743 {
00744     int size = 1000;
00745     char* buf = 0;
00746     while (true) {
00747         buf = new char[size];
00748         if (getcwd(buf, size))
00749             break;
00750         delete[] buf;
00751         buf = 0;
00752         size = 2*size;
00753     }
00754     // if first char is '/' then it's unix and the dirsep is '/'. otherwise we 
00755     // assume it's dos and the dirsep is '\'
00756     char dirsep = buf[0] == '/' ? '/' : '\\';
00757     delete[] buf;
00758     return dirsep;
00759 }
00760 //#############################################################################
00761 
00762 inline int CoinStrNCaseCmp(const char* s0, const char* s1,
00763                            const size_t len)
00764 {
00765     for (size_t i = 0; i < len; ++i) {
00766         if (s0[i] == 0) {
00767             return s1[i] == 0 ? 0 : -1;
00768         }
00769         if (s1[i] == 0) {
00770             return 1;
00771         }
00772         const int c0 = tolower(s0[i]);
00773         const int c1 = tolower(s1[i]);
00774         if (c0 < c1)
00775             return -1;
00776         if (c0 > c1)
00777             return 1;
00778     }
00779     return 0;
00780 }
00781 
00782 //#############################################################################
00783 
00785 template <class T> inline void CoinSwap (T &x, T &y)
00786 {
00787     T t = x;
00788     x = y;
00789     y = t;
00790 }
00791 
00792 //#############################################################################
00793 
00798 template <class T> inline int
00799 CoinToFile( const T* array, int size, FILE * fp)
00800 {
00801     int numberWritten;
00802     if (array&&size) {
00803         numberWritten = fwrite(&size,sizeof(int),1,fp);
00804         if (numberWritten!=1)
00805             return 1;
00806         numberWritten = fwrite(array,sizeof(T),size,fp);
00807         if (numberWritten!=size)
00808             return 1;
00809     } else {
00810         size = 0;
00811         numberWritten = fwrite(&size,sizeof(int),1,fp);
00812         if (numberWritten!=1)
00813             return 1;
00814     }
00815     return 0;
00816 }
00817 
00818 //#############################################################################
00819 
00826 template <class T> inline int
00827 CoinFromFile( T* &array, int size, FILE * fp,int & newSize)
00828 {
00829     int numberRead;
00830     numberRead = fread(&newSize,sizeof(int),1,fp);
00831     if (numberRead!=1)
00832         return 1;
00833     int returnCode=0;
00834     if (size!=newSize&&(newSize||array))
00835         returnCode=2;
00836     if (newSize) {
00837         array = new T [newSize];
00838         numberRead = fread(array,sizeof(T),newSize,fp);
00839         if (numberRead!=newSize)
00840             returnCode=1;
00841     } else {
00842         array = NULL;
00843     }
00844     return returnCode;
00845 }
00846 
00847 //#############################################################################
00848 
00850 inline double CoinCbrt(double x)
00851 {
00852 #if defined(_MSC_VER) 
00853     return pow(x,(1./3.));
00854 #else
00855     return cbrt(x);
00856 #endif
00857 }
00860 #if defined COIN_OWN_RANDOM_32
00861 class CoinThreadRandom  {
00862 public:
00867   CoinThreadRandom()
00868   { seed_=12345678;}
00870   CoinThreadRandom(int seed)
00871   { 
00872     seed_ = seed;
00873   }
00875   ~CoinThreadRandom() {}
00876   // Copy
00877   CoinThreadRandom(const CoinThreadRandom & rhs)
00878   { seed_ = rhs.seed_;}
00879   // Assignment
00880   CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
00881   {
00882     if (this != &rhs) {
00883       seed_ = rhs.seed_;
00884     }
00885     return *this;
00886   }
00887 
00889   
00894   inline void setSeed(int seed)
00895   { 
00896     seed_ = seed;
00897   }
00899   inline double randomDouble() const
00900   {
00901     double retVal;
00902     seed_ = 1664525*(seed_)+1013904223;
00903     retVal = (((double) seed_)/4294967296.0);
00904     return retVal;
00905   }
00907   
00908   
00909 protected:
00913 
00914   mutable unsigned int seed_;
00916 };
00917 #else
00918 class CoinThreadRandom  {
00919 public:
00924   CoinThreadRandom()
00925   { seed_[0]=50000;seed_[1]=40000;seed_[2]=30000;}
00927   CoinThreadRandom(const unsigned short seed[3])
00928   { memcpy(seed_,seed,3*sizeof(unsigned short));}
00930   CoinThreadRandom(int seed)
00931   { 
00932     union { int i[2]; unsigned short int s[4];} put;
00933     put.i[0]=seed;
00934     put.i[1]=seed;
00935     memcpy(seed_,put.s,3*sizeof(unsigned short));
00936   }
00938   ~CoinThreadRandom() {}
00939   // Copy
00940   CoinThreadRandom(const CoinThreadRandom & rhs)
00941   { memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));}
00942   // Assignment
00943   CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
00944   {
00945     if (this != &rhs) {
00946       memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));
00947     }
00948     return *this;
00949   }
00950 
00952   
00957   inline void setSeed(const unsigned short seed[3])
00958   { memcpy(seed_,seed,3*sizeof(unsigned short));}
00960   inline void setSeed(int seed)
00961   { 
00962     union { int i[2]; unsigned short int s[4];} put;
00963     put.i[0]=seed;
00964     put.i[1]=seed;
00965     memcpy(seed_,put.s,3*sizeof(unsigned short));
00966   }
00968   inline double randomDouble() const
00969   {
00970     double retVal;
00971 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
00972     retVal=rand();
00973     retVal=retVal/(double) RAND_MAX;
00974 #else
00975     retVal = erand48(seed_);
00976 #endif
00977     return retVal;
00978   }
00980   
00981   
00982 protected:
00986 
00987   mutable unsigned short seed_[3];
00989 };
00990 #endif
00991 #endif

Generated on Fri May 16 16:41:47 2008 by  doxygen 1.4.7