00001
00002
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
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
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
00102
00103
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
00234 #ifndef NDEBUG
00235
00236 if (size < 0)
00237 throw CoinError("trying to copy negative number of entries",
00238 "CoinMemcpyN", "");
00239
00240 #if 0
00241
00242
00243
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
00260
00261
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
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
00387 #ifndef NDEBUG
00388
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
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
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
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
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
00686
00687
00688 #define COIN_OWN_RANDOM_32
00689
00690 #if defined COIN_OWN_RANDOM_32
00691
00692
00693
00694
00695
00696
00697
00699 inline double CoinDrand48(bool isSeed = false, unsigned int seed=1)
00700 {
00701 static unsigned int last = 123456;
00702 if (isSeed) {
00703 last = seed;
00704 } else {
00705 last = 1664525*last+1013904223;
00706 return (((double) last)/4294967296.0);
00707 }
00708 return(0.0);
00709 }
00711 inline void CoinSeedRandom(int iseed)
00712 {
00713 CoinDrand48(true, iseed);
00714 }
00715
00716 #else // COIN_OWN_RANDOM_32
00717
00718 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
00719
00720 inline double CoinDrand48() { return rand() / (double) RAND_MAX; }
00721 inline void CoinSeedRandom(int iseed) { srand(iseed + 69822); }
00722
00723 #else
00724
00725 inline double CoinDrand48() { return drand48(); }
00726 inline void CoinSeedRandom(int iseed) { srand48(iseed + 69822); }
00727
00728 #endif
00729
00730 #endif // COIN_OWN_RANDOM_32
00731
00732
00733
00736 inline char CoinFindDirSeparator()
00737 {
00738 int size = 1000;
00739 char* buf = 0;
00740 while (true) {
00741 buf = new char[size];
00742 if (getcwd(buf, size))
00743 break;
00744 delete[] buf;
00745 buf = 0;
00746 size = 2*size;
00747 }
00748
00749
00750 char dirsep = buf[0] == '/' ? '/' : '\\';
00751 delete[] buf;
00752 return dirsep;
00753 }
00754
00755
00756 inline int CoinStrNCaseCmp(const char* s0, const char* s1,
00757 const size_t len)
00758 {
00759 for (size_t i = 0; i < len; ++i) {
00760 if (s0[i] == 0) {
00761 return s1[i] == 0 ? 0 : -1;
00762 }
00763 if (s1[i] == 0) {
00764 return 1;
00765 }
00766 const int c0 = tolower(s0[i]);
00767 const int c1 = tolower(s1[i]);
00768 if (c0 < c1)
00769 return -1;
00770 if (c0 > c1)
00771 return 1;
00772 }
00773 return 0;
00774 }
00775
00776
00777
00779 template <class T> inline void CoinSwap (T &x, T &y)
00780 {
00781 T t = x;
00782 x = y;
00783 y = t;
00784 }
00785
00786
00787
00792 template <class T> inline int
00793 CoinToFile( const T* array, int size, FILE * fp)
00794 {
00795 int numberWritten;
00796 if (array&&size) {
00797 numberWritten = fwrite(&size,sizeof(int),1,fp);
00798 if (numberWritten!=1)
00799 return 1;
00800 numberWritten = fwrite(array,sizeof(T),size,fp);
00801 if (numberWritten!=size)
00802 return 1;
00803 } else {
00804 size = 0;
00805 numberWritten = fwrite(&size,sizeof(int),1,fp);
00806 if (numberWritten!=1)
00807 return 1;
00808 }
00809 return 0;
00810 }
00811
00812
00813
00820 template <class T> inline int
00821 CoinFromFile( T* &array, int size, FILE * fp,int & newSize)
00822 {
00823 int numberRead;
00824 numberRead = fread(&newSize,sizeof(int),1,fp);
00825 if (numberRead!=1)
00826 return 1;
00827 int returnCode=0;
00828 if (size!=newSize&&(newSize||array))
00829 returnCode=2;
00830 if (newSize) {
00831 array = new T [newSize];
00832 numberRead = fread(array,sizeof(T),newSize,fp);
00833 if (numberRead!=newSize)
00834 returnCode=1;
00835 } else {
00836 array = NULL;
00837 }
00838 return returnCode;
00839 }
00840
00841
00842
00844 inline double CoinCbrt(double x)
00845 {
00846 #if defined(_MSC_VER)
00847 return pow(x,(1./3.));
00848 #else
00849 return cbrt(x);
00850 #endif
00851 }
00854 #if defined COIN_OWN_RANDOM_32
00855 class CoinThreadRandom {
00856 public:
00861 CoinThreadRandom()
00862 { seed_=12345678;}
00864 CoinThreadRandom(int seed)
00865 {
00866 seed_ = seed;
00867 }
00869 ~CoinThreadRandom() {}
00870
00871 CoinThreadRandom(const CoinThreadRandom & rhs)
00872 { seed_ = rhs.seed_;}
00873
00874 CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
00875 {
00876 if (this != &rhs) {
00877 seed_ = rhs.seed_;
00878 }
00879 return *this;
00880 }
00881
00883
00888 inline void setSeed(int seed)
00889 {
00890 seed_ = seed;
00891 }
00893 inline double randomDouble() const
00894 {
00895 double retVal;
00896 seed_ = 1664525*(seed_)+1013904223;
00897 retVal = (((double) seed_)/4294967296.0);
00898 return retVal;
00899 }
00901
00902
00903 protected:
00907
00908 mutable unsigned int seed_;
00910 };
00911 #else
00912 class CoinThreadRandom {
00913 public:
00918 CoinThreadRandom()
00919 { seed_[0]=50000;seed_[1]=40000;seed_[2]=30000;}
00921 CoinThreadRandom(const unsigned short seed[3])
00922 { memcpy(seed_,seed,3*sizeof(unsigned short));}
00924 CoinThreadRandom(int seed)
00925 {
00926 union { int i[2]; unsigned short int s[4];} put;
00927 put.i[0]=seed;
00928 put.i[1]=seed;
00929 memcpy(seed_,put.s,3*sizeof(unsigned short));
00930 }
00932 ~CoinThreadRandom() {}
00933
00934 CoinThreadRandom(const CoinThreadRandom & rhs)
00935 { memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));}
00936
00937 CoinThreadRandom& operator=(const CoinThreadRandom & rhs)
00938 {
00939 if (this != &rhs) {
00940 memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));
00941 }
00942 return *this;
00943 }
00944
00946
00951 inline void setSeed(const unsigned short seed[3])
00952 { memcpy(seed_,seed,3*sizeof(unsigned short));}
00954 inline void setSeed(int seed)
00955 {
00956 union { int i[2]; unsigned short int s[4];} put;
00957 put.i[0]=seed;
00958 put.i[1]=seed;
00959 memcpy(seed_,put.s,3*sizeof(unsigned short));
00960 }
00962 inline double randomDouble() const
00963 {
00964 double retVal;
00965 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
00966 retVal=rand();
00967 retVal=retVal/(double) RAND_MAX;
00968 #else
00969 retVal = erand48(seed_);
00970 #endif
00971 return retVal;
00972 }
00974
00975
00976 protected:
00980
00981 mutable unsigned short seed_[3];
00983 };
00984 #endif
00985 #endif