/home/coin/SVN-release/Osi-0.98.0/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 <cstdio>
00014 #include "CoinError.hpp"
00015 #include "CoinFinite.hpp"
00016 //#############################################################################
00017 
00023 template <class T> inline void
00024 CoinCopyN(register const T* from, const int size, register T* to)
00025 {
00026     if (size == 0 || from == to)
00027         return;
00028 
00029     if (size < 0)
00030         throw CoinError("trying to copy negative number of entries",
00031                         "CoinCopyN", "");
00032 
00033     register int n = (size + 7) / 8;
00034     if (to > from) {
00035         register const T* downfrom = from + size;
00036         register T* downto = to + size;
00037         // Use Duff's device to copy
00038         switch (size % 8) {
00039         case 0: do{     *--downto = *--downfrom;
00040         case 7:         *--downto = *--downfrom;
00041         case 6:         *--downto = *--downfrom;
00042         case 5:         *--downto = *--downfrom;
00043         case 4:         *--downto = *--downfrom;
00044         case 3:         *--downto = *--downfrom;
00045         case 2:         *--downto = *--downfrom;
00046         case 1:         *--downto = *--downfrom;
00047         }while(--n>0);
00048         }
00049     } else {
00050         // Use Duff's device to copy
00051         --from;
00052         --to;
00053         switch (size % 8) {
00054         case 0: do{     *++to = *++from;
00055         case 7:         *++to = *++from;
00056         case 6:         *++to = *++from;
00057         case 5:         *++to = *++from;
00058         case 4:         *++to = *++from;
00059         case 3:         *++to = *++from;
00060         case 2:         *++to = *++from;
00061         case 1:         *++to = *++from;
00062         }while(--n>0);
00063         }
00064     }
00065 }
00066 
00067 //-----------------------------------------------------------------------------
00068 
00073 template <class T> inline void
00074 CoinCopy(register const T* first, register const T* last, register T* to)
00075 {
00076     CoinCopyN(first, last - first, to);
00077 }
00078 
00079 //-----------------------------------------------------------------------------
00080 
00088 template <class T> inline void
00089 CoinDisjointCopyN(register const T* from, const int size, register T* to)
00090 {
00091 #ifndef _MSC_VER
00092     if (size == 0 || from == to)
00093         return;
00094 
00095     if (size < 0)
00096         throw CoinError("trying to copy negative number of entries",
00097                         "CoinDisjointCopyN", "");
00098 
00099 #if 0
00100     /* There is no point to do this test. If to and from are from different
00101        blocks then dist is undefined, so this can crash correct code. It's
00102        better to trust the user that the arrays are really disjoint. */
00103     const long dist = to - from;
00104     if (-size < dist && dist < size)
00105         throw CoinError("overlapping arrays", "CoinDisjointCopyN", "");
00106 #endif
00107 
00108     for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
00109         to[0] = from[0];
00110         to[1] = from[1];
00111         to[2] = from[2];
00112         to[3] = from[3];
00113         to[4] = from[4];
00114         to[5] = from[5];
00115         to[6] = from[6];
00116         to[7] = from[7];
00117     }
00118     switch (size % 8) {
00119     case 7: to[6] = from[6];
00120     case 6: to[5] = from[5];
00121     case 5: to[4] = from[4];
00122     case 4: to[3] = from[3];
00123     case 3: to[2] = from[2];
00124     case 2: to[1] = from[1];
00125     case 1: to[0] = from[0];
00126     case 0: break;
00127     }
00128 #else
00129     CoinCopyN(from, size, to);
00130 #endif
00131 }
00132 
00133 //-----------------------------------------------------------------------------
00134 
00139 template <class T> inline void
00140 CoinDisjointCopy(register const T* first, register const T* last,
00141                  register T* to)
00142 {
00143     CoinDisjointCopyN(first, static_cast<int>(last - first), to);
00144 }
00145 
00146 //-----------------------------------------------------------------------------
00147 
00152 template <class T> inline T*
00153 CoinCopyOfArray( const T * array, const int size)
00154 {
00155     if (array) {
00156         T * arrayNew = new T[size];
00157         memcpy(arrayNew,array,size*sizeof(T));
00158         return arrayNew;
00159     } else {
00160         return NULL;
00161     }
00162 }
00163 
00164 
00169 template <class T> inline T*
00170 CoinCopyOfArrayPartial( const T * array, const int size,const int copySize)
00171 {
00172     if (array) {
00173         T * arrayNew = new T[size];
00174         assert (copySize<=size);
00175         memcpy(arrayNew,array,copySize*sizeof(T));
00176         return arrayNew;
00177     } else {
00178         return NULL;
00179     }
00180 }
00181 
00186 template <class T> inline T*
00187 CoinCopyOfArray( const T * array, const int size, T value)
00188 {
00189     T * arrayNew = new T[size];
00190     if (array) {
00191         memcpy(arrayNew,array,size*sizeof(T));
00192     } else {
00193         int i;
00194         for (i=0;i<size;i++) 
00195             arrayNew[i] = value;
00196     }
00197     return arrayNew;
00198 }
00199 
00200 
00205 template <class T> inline T*
00206 CoinCopyOfArrayOrZero( const T * array , const int size)
00207 {
00208     T * arrayNew = new T[size];
00209     if (array) {
00210         memcpy(arrayNew,array,size*sizeof(T));
00211     } else {
00212         memset(arrayNew,0,size*sizeof(T));
00213     }
00214     return arrayNew;
00215 }
00216 
00217 
00218 //-----------------------------------------------------------------------------
00219 
00227 template <class T> inline void
00228 CoinMemcpyN(register const T* from, const int size, register T* to)
00229 {
00230 #ifndef _MSC_VER
00231 #ifdef USE_MEMCPY
00232     // Use memcpy - seems a lot faster on Intel with gcc
00233 #ifndef NDEBUG
00234     // Some debug so check
00235     if (size < 0)
00236         throw CoinError("trying to copy negative number of entries",
00237                         "CoinMemcpyN", "");
00238   
00239 #if 0
00240     /* There is no point to do this test. If to and from are from different
00241        blocks then dist is undefined, so this can crash correct code. It's
00242        better to trust the user that the arrays are really disjoint. */
00243     const long dist = to - from;
00244     if (-size < dist && dist < size)
00245         throw CoinError("overlapping arrays", "CoinMemcpyN", "");
00246 #endif
00247 #endif
00248     memcpy(to,from,size*sizeof(T));
00249 #else
00250     if (size == 0 || from == to)
00251         return;
00252 
00253     if (size < 0)
00254         throw CoinError("trying to copy negative number of entries",
00255                         "CoinMemcpyN", "");
00256 
00257 #if 0
00258     /* There is no point to do this test. If to and from are from different
00259        blocks then dist is undefined, so this can crash correct code. It's
00260        better to trust the user that the arrays are really disjoint. */
00261     const long dist = to - from;
00262     if (-size < dist && dist < size)
00263         throw CoinError("overlapping arrays", "CoinMemcpyN", "");
00264 #endif
00265 
00266     for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
00267         to[0] = from[0];
00268         to[1] = from[1];
00269         to[2] = from[2];
00270         to[3] = from[3];
00271         to[4] = from[4];
00272         to[5] = from[5];
00273         to[6] = from[6];
00274         to[7] = from[7];
00275     }
00276     switch (size % 8) {
00277     case 7: to[6] = from[6];
00278     case 6: to[5] = from[5];
00279     case 5: to[4] = from[4];
00280     case 4: to[3] = from[3];
00281     case 3: to[2] = from[2];
00282     case 2: to[1] = from[1];
00283     case 1: to[0] = from[0];
00284     case 0: break;
00285     }
00286 #endif
00287 #else
00288     CoinCopyN(from, size, to);
00289 #endif
00290 }
00291 
00292 //-----------------------------------------------------------------------------
00293 
00298 template <class T> inline void
00299 CoinMemcpy(register const T* first, register const T* last,
00300            register T* to)
00301 {
00302     CoinMemcpyN(first, static_cast<int>(last - first), to);
00303 }
00304 
00305 //#############################################################################
00306 
00313 template <class T> inline void
00314 CoinFillN(register T* to, const int size, register const T value)
00315 {
00316     if (size == 0)
00317         return;
00318 
00319     if (size < 0)
00320         throw CoinError("trying to fill negative number of entries",
00321                         "CoinFillN", "");
00322 
00323 #if 1
00324     for (register int n = size / 8; n > 0; --n, to += 8) {
00325         to[0] = value;
00326         to[1] = value;
00327         to[2] = value;
00328         to[3] = value;
00329         to[4] = value;
00330         to[5] = value;
00331         to[6] = value;
00332         to[7] = value;
00333     }
00334     switch (size % 8) {
00335     case 7: to[6] = value;
00336     case 6: to[5] = value;
00337     case 5: to[4] = value;
00338     case 4: to[3] = value;
00339     case 3: to[2] = value;
00340     case 2: to[1] = value;
00341     case 1: to[0] = value;
00342     case 0: break;
00343     }
00344 #else
00345     // Use Duff's device to fill
00346     register int n = (size + 7) / 8;
00347     --to;
00348     switch (size % 8) {
00349     case 0: do{     *++to = value;
00350     case 7:         *++to = value;
00351     case 6:         *++to = value;
00352     case 5:         *++to = value;
00353     case 4:         *++to = value;
00354     case 3:         *++to = value;
00355     case 2:         *++to = value;
00356     case 1:         *++to = value;
00357     }while(--n>0);
00358     }
00359 #endif
00360 }
00361 
00362 //-----------------------------------------------------------------------------
00363 
00367 template <class T> inline void
00368 CoinFill(register T* first, register T* last, const T value)
00369 {
00370     CoinFillN(first, last - first, value);
00371 }
00372 
00373 //#############################################################################
00374 
00381 template <class T> inline void
00382 CoinZeroN(register T* to, const int size)
00383 {
00384 #ifdef USE_MEMCPY
00385     // Use memset - seems faster on Intel with gcc
00386 #ifndef NDEBUG
00387     // Some debug so check
00388     if (size < 0)
00389         throw CoinError("trying to fill negative number of entries",
00390                         "CoinZeroN", "");
00391 #endif
00392     memset(to,0,size*sizeof(T));
00393 #else
00394     if (size == 0)
00395         return;
00396 
00397     if (size < 0)
00398         throw CoinError("trying to fill negative number of entries",
00399                         "CoinZeroN", "");
00400 #if 1
00401     for (register int n = size / 8; n > 0; --n, to += 8) {
00402         to[0] = 0;
00403         to[1] = 0;
00404         to[2] = 0;
00405         to[3] = 0;
00406         to[4] = 0;
00407         to[5] = 0;
00408         to[6] = 0;
00409         to[7] = 0;
00410     }
00411     switch (size % 8) {
00412     case 7: to[6] = 0;
00413     case 6: to[5] = 0;
00414     case 5: to[4] = 0;
00415     case 4: to[3] = 0;
00416     case 3: to[2] = 0;
00417     case 2: to[1] = 0;
00418     case 1: to[0] = 0;
00419     case 0: break;
00420     }
00421 #else
00422     // Use Duff's device to fill
00423     register int n = (size + 7) / 8;
00424     --to;
00425     switch (size % 8) {
00426     case 0: do{     *++to = 0;
00427     case 7:         *++to = 0;
00428     case 6:         *++to = 0;
00429     case 5:         *++to = 0;
00430     case 4:         *++to = 0;
00431     case 3:         *++to = 0;
00432     case 2:         *++to = 0;
00433     case 1:         *++to = 0;
00434     }while(--n>0);
00435     }
00436 #endif
00437 #endif
00438 }
00440 inline void
00441 CoinCheckDoubleZero(double * to, const int size)
00442 {
00443     int n=0;
00444     for (int j=0;j<size;j++) {
00445         if (to[j]) 
00446             n++;
00447     }
00448     if (n) {
00449         printf("array of length %d should be zero has %d nonzero\n",size,n);
00450     }
00451 }
00453 inline void
00454 CoinCheckIntZero(int * to, const int size)
00455 {
00456     int n=0;
00457     for (int j=0;j<size;j++) {
00458         if (to[j]) 
00459             n++;
00460     }
00461     if (n) {
00462         printf("array of length %d should be zero has %d nonzero\n",size,n);
00463     }
00464 }
00465 
00466 //-----------------------------------------------------------------------------
00467 
00471 template <class T> inline void
00472 CoinZero(register T* first, register T* last)
00473 {
00474     CoinZeroN(first, last - first);
00475 }
00476 
00477 //#############################################################################
00478 
00482 template <class T> inline T
00483 CoinMax(register const T x1, register const T x2)
00484 {
00485     return (x1 > x2) ? x1 : x2;
00486 }
00487 
00488 //-----------------------------------------------------------------------------
00489 
00493 template <class T> inline T
00494 CoinMin(register const T x1, register const T x2)
00495 {
00496     return (x1 < x2) ? x1 : x2;
00497 }
00498 
00499 //-----------------------------------------------------------------------------
00500 
00504 template <class T> inline T
00505 CoinAbs(const T value)
00506 {
00507     return value<0 ? -value : value;
00508 }
00509 
00510 //#############################################################################
00511 
00515 template <class T> inline bool
00516 CoinIsSorted(register const T* first, const int size)
00517 {
00518     if (size == 0)
00519         return true;
00520 
00521     if (size < 0)
00522         throw CoinError("negative number of entries", "CoinIsSorted", "");
00523 
00524 #if 1
00525     // size1 is the number of comparisons to be made
00526     const int size1 = size  - 1;
00527     for (register int n = size1 / 8; n > 0; --n, first += 8) {
00528         if (first[8] < first[7]) return false;
00529         if (first[7] < first[6]) return false;
00530         if (first[6] < first[5]) return false;
00531         if (first[5] < first[4]) return false;
00532         if (first[4] < first[3]) return false;
00533         if (first[3] < first[2]) return false;
00534         if (first[2] < first[1]) return false;
00535         if (first[1] < first[0]) return false;
00536     }
00537 
00538     switch (size1 % 8) {
00539     case 7: if (first[7] < first[6]) return false;
00540     case 6: if (first[6] < first[5]) return false;
00541     case 5: if (first[5] < first[4]) return false;
00542     case 4: if (first[4] < first[3]) return false;
00543     case 3: if (first[3] < first[2]) return false;
00544     case 2: if (first[2] < first[1]) return false;
00545     case 1: if (first[1] < first[0]) return false;
00546     case 0: break;
00547     }
00548 #else
00549     register const T* next = first;
00550     register const T* last = first + size;
00551     for (++next; next != last; first = next, ++next)
00552         if (*next < *first)
00553             return false;
00554 #endif   
00555     return true;
00556 }
00557 
00558 //-----------------------------------------------------------------------------
00559 
00563 template <class T> inline bool
00564 CoinIsSorted(register const T* first, register const T* last)
00565 {
00566     return CoinIsSorted(first, static_cast<int>(last - first));
00567 }
00568 
00569 //#############################################################################
00570 
00574 template <class T> inline void
00575 CoinIotaN(register T* first, const int size, register T init)
00576 {
00577     if (size == 0)
00578         return;
00579 
00580     if (size < 0)
00581         throw CoinError("negative number of entries", "CoinIotaN", "");
00582 
00583 #if 1
00584     for (register int n = size / 8; n > 0; --n, first += 8, init += 8) {
00585         first[0] = init;
00586         first[1] = init + 1;
00587         first[2] = init + 2;
00588         first[3] = init + 3;
00589         first[4] = init + 4;
00590         first[5] = init + 5;
00591         first[6] = init + 6;
00592         first[7] = init + 7;
00593     }
00594     switch (size % 8) {
00595     case 7: first[6] = init + 6;
00596     case 6: first[5] = init + 5;
00597     case 5: first[4] = init + 4;
00598     case 4: first[3] = init + 3;
00599     case 3: first[2] = init + 2;
00600     case 2: first[1] = init + 1;
00601     case 1: first[0] = init;
00602     case 0: break;
00603     }
00604 #else
00605     // Use Duff's device to fill
00606     register int n = (size + 7) / 8;
00607     --first;
00608     --init;
00609     switch (size % 8) {
00610     case 0: do{     *++first = ++init;
00611     case 7:         *++first = ++init;
00612     case 6:         *++first = ++init;
00613     case 5:         *++first = ++init;
00614     case 4:         *++first = ++init;
00615     case 3:         *++first = ++init;
00616     case 2:         *++first = ++init;
00617     case 1:         *++first = ++init;
00618     }while(--n>0);
00619     }
00620 #endif
00621 }
00622 
00623 //-----------------------------------------------------------------------------
00624 
00628 template <class T> inline void
00629 CoinIota(T* first, const T* last, T init)
00630 {
00631     CoinIotaN(first, last-first, init);
00632 }
00633 
00634 //#############################################################################
00635 
00641 template <class T> inline T *
00642 CoinDeleteEntriesFromArray(register T * arrayFirst, register T * arrayLast,
00643                            const int * firstDelPos, const int * lastDelPos)
00644 {
00645     int delNum = lastDelPos - firstDelPos;
00646     if (delNum == 0)
00647         return arrayLast;
00648 
00649     if (delNum < 0)
00650         throw CoinError("trying to delete negative number of entries",
00651                         "CoinDeleteEntriesFromArray", "");
00652 
00653     int * delSortedPos = NULL;
00654     if (! (CoinIsSorted(firstDelPos, lastDelPos) &&
00655            std::adjacent_find(firstDelPos, lastDelPos) == lastDelPos)) {
00656         // the positions of the to be deleted is either not sorted or not unique
00657         delSortedPos = new int[delNum];
00658         CoinDisjointCopy(firstDelPos, lastDelPos, delSortedPos);
00659         std::sort(delSortedPos, delSortedPos + delNum);
00660         delNum = std::unique(delSortedPos, delSortedPos + delNum) - delSortedPos;
00661     }
00662     const int * delSorted = delSortedPos ? delSortedPos : firstDelPos;
00663 
00664     const int last = delNum - 1;
00665     int size = delSorted[0];
00666     for (int i = 0; i < last; ++i) {
00667         const int copyFirst = delSorted[i] + 1;
00668         const int copyLast = delSorted[i+1];
00669         CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
00670                  arrayFirst + size);
00671         size += copyLast - copyFirst;
00672     }
00673     const int copyFirst = delSorted[last] + 1;
00674     const int copyLast = arrayLast - arrayFirst;
00675     CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
00676              arrayFirst + size);
00677     size += copyLast - copyFirst;
00678 
00679     if (delSortedPos)
00680         delete[] delSortedPos;
00681 
00682     return arrayFirst + size;
00683 }
00684 #define COIN_OWN_RANDOM_32
00685 
00686 //#############################################################################
00687 /* Thanks to Stefano Gliozzi for providing an operating system
00688    independent random number generator.  */
00690 inline void CoinSeedRandom(int iseed)
00691 {
00692 #if defined COIN_OWN_RANDOM_32
00693   double CoinDrand48(bool isSeed = false, unsigned long seed=1);
00694   CoinDrand48(true, iseed);
00695 #else
00696   int jseed;
00697   jseed = iseed + 69822;
00698 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
00699   srand(jseed);
00700 #else
00701   srand48(jseed);
00702 #endif
00703 #endif // end else COIN_OWN_RANDOM
00704 }
00705 
00707 #if defined COIN_OWN_RANDOM_32
00708 // linear congruential generator. given the seed, the generated numbers are  
00709 // always the same regardless the (32 bit) architecture. This allows to 
00710 // build & test in different environments (i.e. Wintel, Linux/Intel AIX Power5)
00711 // getting in most cases the same optimization path. 
00712 inline double CoinDrand48(bool isSeed = false, unsigned long seed=1)
00713 {
00714   static unsigned last;
00715   if (isSeed) { 
00716     last = seed;
00717   } else {
00718     last = 1664525*last+1013904223;
00719     return (((double) last)/4294967296.0);
00720   }
00721   return(0.0);
00722 }
00723 #else 
00724 inline double CoinDrand48()
00725 {  
00726   double retVal;
00727 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
00728   retVal=rand();
00729   retVal=retVal/(double) RAND_MAX;
00730 #else
00731   retVal = drand48();
00732 #endif
00733   return retVal;
00734 }
00735 #endif
00736 
00737 //#############################################################################
00738 
00741 inline char CoinFindDirSeparator()
00742 {
00743     int size = 1000;
00744     char* buf = 0;
00745     while (true) {
00746         buf = new char[size];
00747         if (getcwd(buf, size))
00748             break;
00749         delete[] buf;
00750         buf = 0;
00751         size = 2*size;
00752     }
00753     // if first char is '/' then it's unix and the dirsep is '/'. otherwise we 
00754     // assume it's dos and the dirsep is '\'
00755     char dirsep = buf[0] == '/' ? '/' : '\\';
00756     delete[] buf;
00757     return dirsep;
00758 }
00759 //#############################################################################
00760 
00761 inline int CoinStrNCaseCmp(const char* s0, const char* s1,
00762                            const size_t len)
00763 {
00764     for (size_t i = 0; i < len; ++i) {
00765         if (s0[i] == 0) {
00766             return s1[i] == 0 ? 0 : -1;
00767         }
00768         if (s1[i] == 0) {
00769             return 1;
00770         }
00771         const int c0 = tolower(s0[i]);
00772         const int c1 = tolower(s1[i]);
00773         if (c0 < c1)
00774             return -1;
00775         if (c0 > c1)
00776             return 1;
00777     }
00778     return 0;
00779 }
00780 
00781 //#############################################################################
00782 
00784 template <class T> inline void CoinSwap (T &x, T &y)
00785 {
00786     T t = x;
00787     x = y;
00788     y = t;
00789 }
00790 
00791 //#############################################################################
00792 
00797 template <class T> inline int
00798 CoinToFile( const T* array, int size, FILE * fp)
00799 {
00800     int numberWritten;
00801     if (array&&size) {
00802         numberWritten = fwrite(&size,sizeof(int),1,fp);
00803         if (numberWritten!=1)
00804             return 1;
00805         numberWritten = fwrite(array,sizeof(T),size,fp);
00806         if (numberWritten!=size)
00807             return 1;
00808     } else {
00809         size = 0;
00810         numberWritten = fwrite(&size,sizeof(int),1,fp);
00811         if (numberWritten!=1)
00812             return 1;
00813     }
00814     return 0;
00815 }
00816 
00817 //#############################################################################
00818 
00825 template <class T> inline int
00826 CoinFromFile( T* &array, int size, FILE * fp,int & newSize)
00827 {
00828     int numberRead;
00829     numberRead = fread(&newSize,sizeof(int),1,fp);
00830     if (numberRead!=1)
00831         return 1;
00832     int returnCode=0;
00833     if (size!=newSize&&(newSize||array))
00834         returnCode=2;
00835     if (newSize) {
00836         array = new T [newSize];
00837         numberRead = fread(array,sizeof(T),newSize,fp);
00838         if (numberRead!=newSize)
00839             returnCode=1;
00840     } else {
00841         array = NULL;
00842     }
00843     return returnCode;
00844 }
00845 
00846 //#############################################################################
00847 
00849 inline double CoinCbrt(double x)
00850 {
00851 #if defined(_MSC_VER) 
00852     return pow(x,(1./3.));
00853 #else
00854     return cbrt(x);
00855 #endif
00856 }
00859 #if defined COIN_OWN_RANDOM_32
00860 class CoinThreadRandom  {
00861 public:
00866   CoinThreadRandom()
00867   { seed_=12345678;}
00869   CoinThreadRandom(int seed)
00870   { 
00871     seed_ = seed;
00872   }
00874   ~CoinThreadRandom() {}
00875   // Copy
00876   CoinThreadRandom(const CoinThreadRandom & rhs)
00877   { seed_ = rhs.seed_;}
00878   // Assignment
00879   CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
00880   {
00881     if (this != &rhs) {
00882       seed_ = rhs.seed_;
00883     }
00884     return *this;
00885   }
00886 
00888   
00893   inline void setSeed(int seed)
00894   { 
00895     seed_ = seed;
00896   }
00898   inline double randomDouble() const
00899   {
00900     double retVal;
00901     seed_ = 1664525*(seed_)+1013904223;
00902     retVal = (((double) seed_)/4294967296.0);
00903     return retVal;
00904   }
00906   
00907   
00908 protected:
00912 
00913   mutable unsigned int seed_;
00915 };
00916 #else
00917 class CoinThreadRandom  {
00918 public:
00923   CoinThreadRandom()
00924   { seed_[0]=50000;seed_[1]=40000;seed_[2]=30000;}
00926   CoinThreadRandom(const unsigned short seed[3])
00927   { memcpy(seed_,seed,3*sizeof(unsigned short));}
00929   CoinThreadRandom(int seed)
00930   { 
00931     union { int i[2]; unsigned short int s[4];} put;
00932     put.i[0]=seed;
00933     put.i[1]=seed;
00934     memcpy(seed_,put.s,3*sizeof(unsigned short));
00935   }
00937   ~CoinThreadRandom() {}
00938   // Copy
00939   CoinThreadRandom(const CoinThreadRandom & rhs)
00940   { memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));}
00941   // Assignment
00942   CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
00943   {
00944     if (this != &rhs) {
00945       memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));
00946     }
00947     return *this;
00948   }
00949 
00951   
00956   inline void setSeed(const unsigned short seed[3])
00957   { memcpy(seed_,seed,3*sizeof(unsigned short));}
00959   inline void setSeed(int seed)
00960   { 
00961     union { int i[2]; unsigned short int s[4];} put;
00962     put.i[0]=seed;
00963     put.i[1]=seed;
00964     memcpy(seed_,put.s,3*sizeof(unsigned short));
00965   }
00967   inline double randomDouble() const
00968   {
00969     double retVal;
00970 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
00971     retVal=rand();
00972     retVal=retVal/(double) RAND_MAX;
00973 #else
00974     retVal = erand48(seed_);
00975 #endif
00976     return retVal;
00977   }
00979   
00980   
00981 protected:
00985 
00986   mutable unsigned short seed_[3];
00988 };
00989 #endif
00990 #endif

Generated on Fri May 16 00:18:51 2008 by  doxygen 1.4.7