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

Generated on Thu Oct 8 03:16:26 2009 by  doxygen 1.4.7