- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

- File List
- File Members

# /home/coin/SVN-release/Osi-0.98.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