CoinHelperFunctions.hpp
Go to the documentation of this file.
1 /* $Id: CoinHelperFunctions.hpp 1679 2013-12-05 11:27:45Z forrest $ */
2 // Copyright (C) 2000, International Business Machines
3 // Corporation and others. All Rights Reserved.
4 // This code is licensed under the terms of the Eclipse Public License (EPL).
5 
6 #ifndef CoinHelperFunctions_H
7 #define CoinHelperFunctions_H
8 
9 #include "CoinUtilsConfig.h"
10 
11 #if defined(_MSC_VER)
12 # include <direct.h>
13 # include <cctype>
14 # define getcwd _getcwd
15 # include <cctype>
16 #else
17 # include <unistd.h>
18 #endif
19 //#define USE_MEMCPY
20 
21 #include <cstdlib>
22 #include <cstdio>
23 #include <algorithm>
24 #include "CoinTypes.hpp"
25 #include "CoinError.hpp"
26 
27 // Compilers can produce better code if they know about __restrict
28 #ifndef COIN_RESTRICT
29 #ifdef COIN_USE_RESTRICT
30 #define COIN_RESTRICT __restrict
31 #else
32 #define COIN_RESTRICT
33 #endif
34 #endif
35 
36 //#############################################################################
37 
43 template <class T> inline void
44 CoinCopyN(register const T* from, const int size, register T* to)
45 {
46  if (size == 0 || from == to)
47  return;
48 
49 #ifndef NDEBUG
50  if (size < 0)
51  throw CoinError("trying to copy negative number of entries",
52  "CoinCopyN", "");
53 #endif
54 
55  register int n = (size + 7) / 8;
56  if (to > from) {
57  register const T* downfrom = from + size;
58  register T* downto = to + size;
59  // Use Duff's device to copy
60  switch (size % 8) {
61  case 0: do{ *--downto = *--downfrom;
62  case 7: *--downto = *--downfrom;
63  case 6: *--downto = *--downfrom;
64  case 5: *--downto = *--downfrom;
65  case 4: *--downto = *--downfrom;
66  case 3: *--downto = *--downfrom;
67  case 2: *--downto = *--downfrom;
68  case 1: *--downto = *--downfrom;
69  }while(--n>0);
70  }
71  } else {
72  // Use Duff's device to copy
73  --from;
74  --to;
75  switch (size % 8) {
76  case 0: do{ *++to = *++from;
77  case 7: *++to = *++from;
78  case 6: *++to = *++from;
79  case 5: *++to = *++from;
80  case 4: *++to = *++from;
81  case 3: *++to = *++from;
82  case 2: *++to = *++from;
83  case 1: *++to = *++from;
84  }while(--n>0);
85  }
86  }
87 }
88 
89 //-----------------------------------------------------------------------------
90 
101 template <class T> inline void
102 CoinCopy(register const T* first, register const T* last, register T* to)
103 {
104  CoinCopyN(first, static_cast<int>(last-first), to);
105 }
106 
107 //-----------------------------------------------------------------------------
108 
116 template <class T> inline void
117 CoinDisjointCopyN(register const T* from, const int size, register T* to)
118 {
119 #ifndef _MSC_VER
120  if (size == 0 || from == to)
121  return;
122 
123 #ifndef NDEBUG
124  if (size < 0)
125  throw CoinError("trying to copy negative number of entries",
126  "CoinDisjointCopyN", "");
127 #endif
128 
129 #if 0
130  /* There is no point to do this test. If to and from are from different
131  blocks then dist is undefined, so this can crash correct code. It's
132  better to trust the user that the arrays are really disjoint. */
133  const long dist = to - from;
134  if (-size < dist && dist < size)
135  throw CoinError("overlapping arrays", "CoinDisjointCopyN", "");
136 #endif
137 
138  for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
139  to[0] = from[0];
140  to[1] = from[1];
141  to[2] = from[2];
142  to[3] = from[3];
143  to[4] = from[4];
144  to[5] = from[5];
145  to[6] = from[6];
146  to[7] = from[7];
147  }
148  switch (size % 8) {
149  case 7: to[6] = from[6];
150  case 6: to[5] = from[5];
151  case 5: to[4] = from[4];
152  case 4: to[3] = from[3];
153  case 3: to[2] = from[2];
154  case 2: to[1] = from[1];
155  case 1: to[0] = from[0];
156  case 0: break;
157  }
158 #else
159  CoinCopyN(from, size, to);
160 #endif
161 }
162 
163 //-----------------------------------------------------------------------------
164 
169 template <class T> inline void
170 CoinDisjointCopy(register const T* first, register const T* last,
171  register T* to)
172 {
173  CoinDisjointCopyN(first, static_cast<int>(last - first), to);
174 }
175 
176 //-----------------------------------------------------------------------------
177 
182 template <class T> inline T*
183 CoinCopyOfArray( const T * array, const int size)
184 {
185  if (array) {
186  T * arrayNew = new T[size];
187  std::memcpy(arrayNew,array,size*sizeof(T));
188  return arrayNew;
189  } else {
190  return NULL;
191  }
192 }
193 
194 
199 template <class T> inline T*
200 CoinCopyOfArrayPartial( const T * array, const int size,const int copySize)
201 {
202  if (array||size) {
203  T * arrayNew = new T[size];
204  assert (copySize<=size);
205  std::memcpy(arrayNew,array,copySize*sizeof(T));
206  return arrayNew;
207  } else {
208  return NULL;
209  }
210 }
211 
216 template <class T> inline T*
217 CoinCopyOfArray( const T * array, const int size, T value)
218 {
219  T * arrayNew = new T[size];
220  if (array) {
221  std::memcpy(arrayNew,array,size*sizeof(T));
222  } else {
223  int i;
224  for (i=0;i<size;i++)
225  arrayNew[i] = value;
226  }
227  return arrayNew;
228 }
229 
230 
235 template <class T> inline T*
236 CoinCopyOfArrayOrZero( const T * array , const int size)
237 {
238  T * arrayNew = new T[size];
239  if (array) {
240  std::memcpy(arrayNew,array,size*sizeof(T));
241  } else {
242  std::memset(arrayNew,0,size*sizeof(T));
243  }
244  return arrayNew;
245 }
246 
247 
248 //-----------------------------------------------------------------------------
249 
257 #ifndef COIN_USE_RESTRICT
258 template <class T> inline void
259 CoinMemcpyN(register const T* from, const int size, register T* to)
260 {
261 #ifndef _MSC_VER
262 #ifdef USE_MEMCPY
263  // Use memcpy - seems a lot faster on Intel with gcc
264 #ifndef NDEBUG
265  // Some debug so check
266  if (size < 0)
267  throw CoinError("trying to copy negative number of entries",
268  "CoinMemcpyN", "");
269 
270 #if 0
271  /* There is no point to do this test. If to and from are from different
272  blocks then dist is undefined, so this can crash correct code. It's
273  better to trust the user that the arrays are really disjoint. */
274  const long dist = to - from;
275  if (-size < dist && dist < size)
276  throw CoinError("overlapping arrays", "CoinMemcpyN", "");
277 #endif
278 #endif
279  std::memcpy(to,from,size*sizeof(T));
280 #else
281  if (size == 0 || from == to)
282  return;
283 
284 #ifndef NDEBUG
285  if (size < 0)
286  throw CoinError("trying to copy negative number of entries",
287  "CoinMemcpyN", "");
288 #endif
289 
290 #if 0
291  /* There is no point to do this test. If to and from are from different
292  blocks then dist is undefined, so this can crash correct code. It's
293  better to trust the user that the arrays are really disjoint. */
294  const long dist = to - from;
295  if (-size < dist && dist < size)
296  throw CoinError("overlapping arrays", "CoinMemcpyN", "");
297 #endif
298 
299  for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
300  to[0] = from[0];
301  to[1] = from[1];
302  to[2] = from[2];
303  to[3] = from[3];
304  to[4] = from[4];
305  to[5] = from[5];
306  to[6] = from[6];
307  to[7] = from[7];
308  }
309  switch (size % 8) {
310  case 7: to[6] = from[6];
311  case 6: to[5] = from[5];
312  case 5: to[4] = from[4];
313  case 4: to[3] = from[3];
314  case 3: to[2] = from[2];
315  case 2: to[1] = from[1];
316  case 1: to[0] = from[0];
317  case 0: break;
318  }
319 #endif
320 #else
321  CoinCopyN(from, size, to);
322 #endif
323 }
324 #else
325 template <class T> inline void
326 CoinMemcpyN(const T * COIN_RESTRICT from, int size, T* COIN_RESTRICT to)
327 {
328 #ifdef USE_MEMCPY
329  std::memcpy(to,from,size*sizeof(T));
330 #else
331  T * COIN_RESTRICT put = to;
332  const T * COIN_RESTRICT get = from;
333  for ( ; 0<size ; --size)
334  *put++ = *get++;
335 #endif
336 }
337 #endif
338 
339 //-----------------------------------------------------------------------------
340 
345 template <class T> inline void
346 CoinMemcpy(register const T* first, register const T* last,
347  register T* to)
348 {
349  CoinMemcpyN(first, static_cast<int>(last - first), to);
350 }
351 
352 //#############################################################################
353 
360 template <class T> inline void
361 CoinFillN(register T* to, const int size, register const T value)
362 {
363  if (size == 0)
364  return;
365 
366 #ifndef NDEBUG
367  if (size < 0)
368  throw CoinError("trying to fill negative number of entries",
369  "CoinFillN", "");
370 #endif
371 #if 1
372  for (register int n = size / 8; n > 0; --n, to += 8) {
373  to[0] = value;
374  to[1] = value;
375  to[2] = value;
376  to[3] = value;
377  to[4] = value;
378  to[5] = value;
379  to[6] = value;
380  to[7] = value;
381  }
382  switch (size % 8) {
383  case 7: to[6] = value;
384  case 6: to[5] = value;
385  case 5: to[4] = value;
386  case 4: to[3] = value;
387  case 3: to[2] = value;
388  case 2: to[1] = value;
389  case 1: to[0] = value;
390  case 0: break;
391  }
392 #else
393  // Use Duff's device to fill
394  register int n = (size + 7) / 8;
395  --to;
396  switch (size % 8) {
397  case 0: do{ *++to = value;
398  case 7: *++to = value;
399  case 6: *++to = value;
400  case 5: *++to = value;
401  case 4: *++to = value;
402  case 3: *++to = value;
403  case 2: *++to = value;
404  case 1: *++to = value;
405  }while(--n>0);
406  }
407 #endif
408 }
409 
410 //-----------------------------------------------------------------------------
411 
415 template <class T> inline void
416 CoinFill(register T* first, register T* last, const T value)
417 {
418  CoinFillN(first, last - first, value);
419 }
420 
421 //#############################################################################
422 
429 template <class T> inline void
430 CoinZeroN(register T* to, const int size)
431 {
432 #ifdef USE_MEMCPY
433  // Use memset - seems faster on Intel with gcc
434 #ifndef NDEBUG
435  // Some debug so check
436  if (size < 0)
437  throw CoinError("trying to fill negative number of entries",
438  "CoinZeroN", "");
439 #endif
440  memset(to,0,size*sizeof(T));
441 #else
442  if (size == 0)
443  return;
444 
445 #ifndef NDEBUG
446  if (size < 0)
447  throw CoinError("trying to fill negative number of entries",
448  "CoinZeroN", "");
449 #endif
450 #if 1
451  for (register int n = size / 8; n > 0; --n, to += 8) {
452  to[0] = 0;
453  to[1] = 0;
454  to[2] = 0;
455  to[3] = 0;
456  to[4] = 0;
457  to[5] = 0;
458  to[6] = 0;
459  to[7] = 0;
460  }
461  switch (size % 8) {
462  case 7: to[6] = 0;
463  case 6: to[5] = 0;
464  case 5: to[4] = 0;
465  case 4: to[3] = 0;
466  case 3: to[2] = 0;
467  case 2: to[1] = 0;
468  case 1: to[0] = 0;
469  case 0: break;
470  }
471 #else
472  // Use Duff's device to fill
473  register int n = (size + 7) / 8;
474  --to;
475  switch (size % 8) {
476  case 0: do{ *++to = 0;
477  case 7: *++to = 0;
478  case 6: *++to = 0;
479  case 5: *++to = 0;
480  case 4: *++to = 0;
481  case 3: *++to = 0;
482  case 2: *++to = 0;
483  case 1: *++to = 0;
484  }while(--n>0);
485  }
486 #endif
487 #endif
488 }
490 inline void
491 CoinCheckDoubleZero(double * to, const int size)
492 {
493  int n=0;
494  for (int j=0;j<size;j++) {
495  if (to[j])
496  n++;
497  }
498  if (n) {
499  printf("array of length %d should be zero has %d nonzero\n",size,n);
500  }
501 }
503 inline void
504 CoinCheckIntZero(int * to, const int size)
505 {
506  int n=0;
507  for (int j=0;j<size;j++) {
508  if (to[j])
509  n++;
510  }
511  if (n) {
512  printf("array of length %d should be zero has %d nonzero\n",size,n);
513  }
514 }
515 
516 //-----------------------------------------------------------------------------
517 
521 template <class T> inline void
522 CoinZero(register T* first, register T* last)
523 {
524  CoinZeroN(first, last - first);
525 }
526 
527 //#############################################################################
528 
530 inline char * CoinStrdup(const char * name)
531 {
532  char* dup = NULL;
533  if (name) {
534  const int len = static_cast<int>(strlen(name));
535  dup = static_cast<char*>(malloc(len+1));
536  CoinMemcpyN(name, len, dup);
537  dup[len] = 0;
538  }
539  return dup;
540 }
541 
542 //#############################################################################
543 
547 template <class T> inline T
548 CoinMax(register const T x1, register const T x2)
549 {
550  return (x1 > x2) ? x1 : x2;
551 }
552 
553 //-----------------------------------------------------------------------------
554 
558 template <class T> inline T
559 CoinMin(register const T x1, register const T x2)
560 {
561  return (x1 < x2) ? x1 : x2;
562 }
563 
564 //-----------------------------------------------------------------------------
565 
569 template <class T> inline T
570 CoinAbs(const T value)
571 {
572  return value<0 ? -value : value;
573 }
574 
575 //#############################################################################
576 
580 template <class T> inline bool
581 CoinIsSorted(register const T* first, const int size)
582 {
583  if (size == 0)
584  return true;
585 
586 #ifndef NDEBUG
587  if (size < 0)
588  throw CoinError("negative number of entries", "CoinIsSorted", "");
589 #endif
590 #if 1
591  // size1 is the number of comparisons to be made
592  const int size1 = size - 1;
593  for (register int n = size1 / 8; n > 0; --n, first += 8) {
594  if (first[8] < first[7]) return false;
595  if (first[7] < first[6]) return false;
596  if (first[6] < first[5]) return false;
597  if (first[5] < first[4]) return false;
598  if (first[4] < first[3]) return false;
599  if (first[3] < first[2]) return false;
600  if (first[2] < first[1]) return false;
601  if (first[1] < first[0]) return false;
602  }
603 
604  switch (size1 % 8) {
605  case 7: if (first[7] < first[6]) return false;
606  case 6: if (first[6] < first[5]) return false;
607  case 5: if (first[5] < first[4]) return false;
608  case 4: if (first[4] < first[3]) return false;
609  case 3: if (first[3] < first[2]) return false;
610  case 2: if (first[2] < first[1]) return false;
611  case 1: if (first[1] < first[0]) return false;
612  case 0: break;
613  }
614 #else
615  register const T* next = first;
616  register const T* last = first + size;
617  for (++next; next != last; first = next, ++next)
618  if (*next < *first)
619  return false;
620 #endif
621  return true;
622 }
623 
624 //-----------------------------------------------------------------------------
625 
629 template <class T> inline bool
630 CoinIsSorted(register const T* first, register const T* last)
631 {
632  return CoinIsSorted(first, static_cast<int>(last - first));
633 }
634 
635 //#############################################################################
636 
640 template <class T> inline void
641 CoinIotaN(register T* first, const int size, register T init)
642 {
643  if (size == 0)
644  return;
645 
646 #ifndef NDEBUG
647  if (size < 0)
648  throw CoinError("negative number of entries", "CoinIotaN", "");
649 #endif
650 #if 1
651  for (register int n = size / 8; n > 0; --n, first += 8, init += 8) {
652  first[0] = init;
653  first[1] = init + 1;
654  first[2] = init + 2;
655  first[3] = init + 3;
656  first[4] = init + 4;
657  first[5] = init + 5;
658  first[6] = init + 6;
659  first[7] = init + 7;
660  }
661  switch (size % 8) {
662  case 7: first[6] = init + 6;
663  case 6: first[5] = init + 5;
664  case 5: first[4] = init + 4;
665  case 4: first[3] = init + 3;
666  case 3: first[2] = init + 2;
667  case 2: first[1] = init + 1;
668  case 1: first[0] = init;
669  case 0: break;
670  }
671 #else
672  // Use Duff's device to fill
673  register int n = (size + 7) / 8;
674  --first;
675  --init;
676  switch (size % 8) {
677  case 0: do{ *++first = ++init;
678  case 7: *++first = ++init;
679  case 6: *++first = ++init;
680  case 5: *++first = ++init;
681  case 4: *++first = ++init;
682  case 3: *++first = ++init;
683  case 2: *++first = ++init;
684  case 1: *++first = ++init;
685  }while(--n>0);
686  }
687 #endif
688 }
689 
690 //-----------------------------------------------------------------------------
691 
695 template <class T> inline void
696 CoinIota(T* first, const T* last, T init)
697 {
698  CoinIotaN(first, last-first, init);
699 }
700 
701 //#############################################################################
702 
708 template <class T> inline T *
709 CoinDeleteEntriesFromArray(register T * arrayFirst, register T * arrayLast,
710  const int * firstDelPos, const int * lastDelPos)
711 {
712  int delNum = static_cast<int>(lastDelPos - firstDelPos);
713  if (delNum == 0)
714  return arrayLast;
715 
716  if (delNum < 0)
717  throw CoinError("trying to delete negative number of entries",
718  "CoinDeleteEntriesFromArray", "");
719 
720  int * delSortedPos = NULL;
721  if (! (CoinIsSorted(firstDelPos, lastDelPos) &&
722  std::adjacent_find(firstDelPos, lastDelPos) == lastDelPos)) {
723  // the positions of the to be deleted is either not sorted or not unique
724  delSortedPos = new int[delNum];
725  CoinDisjointCopy(firstDelPos, lastDelPos, delSortedPos);
726  std::sort(delSortedPos, delSortedPos + delNum);
727  delNum = static_cast<int>(std::unique(delSortedPos,
728  delSortedPos+delNum) - delSortedPos);
729  }
730  const int * delSorted = delSortedPos ? delSortedPos : firstDelPos;
731 
732  const int last = delNum - 1;
733  int size = delSorted[0];
734  for (int i = 0; i < last; ++i) {
735  const int copyFirst = delSorted[i] + 1;
736  const int copyLast = delSorted[i+1];
737  CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
738  arrayFirst + size);
739  size += copyLast - copyFirst;
740  }
741  const int copyFirst = delSorted[last] + 1;
742  const int copyLast = static_cast<int>(arrayLast - arrayFirst);
743  CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
744  arrayFirst + size);
745  size += copyLast - copyFirst;
746 
747  if (delSortedPos)
748  delete[] delSortedPos;
749 
750  return arrayFirst + size;
751 }
752 
753 //#############################################################################
754 
755 #define COIN_OWN_RANDOM_32
756 
757 #if defined COIN_OWN_RANDOM_32
758 /* Thanks to Stefano Gliozzi for providing an operating system
759  independent random number generator. */
760 
773 inline double CoinDrand48 (bool isSeed = false, unsigned int seed = 1)
774 {
775  static unsigned int last = 123456;
776  if (isSeed) {
777  last = seed;
778  } else {
779  last = 1664525*last+1013904223;
780  return ((static_cast<double> (last))/4294967296.0);
781  }
782  return (0.0);
783 }
784 
786 inline void CoinSeedRandom(int iseed)
787 {
788  CoinDrand48(true, iseed);
789 }
790 
791 #else // COIN_OWN_RANDOM_32
792 
793 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
794 
796 inline double CoinDrand48() { return rand() / (double) RAND_MAX; }
798 inline void CoinSeedRandom(int iseed) { srand(iseed + 69822); }
799 
800 #else
801 
803 inline double CoinDrand48() { return drand48(); }
805 inline void CoinSeedRandom(int iseed) { srand48(iseed + 69822); }
806 
807 #endif
808 
809 #endif // COIN_OWN_RANDOM_32
810 
811 //#############################################################################
812 
815 inline char CoinFindDirSeparator()
816 {
817  int size = 1000;
818  char* buf = 0;
819  while (true) {
820  buf = new char[size];
821  if (getcwd(buf, size))
822  break;
823  delete[] buf;
824  buf = 0;
825  size = 2*size;
826  }
827  // if first char is '/' then it's unix and the dirsep is '/'. otherwise we
828  // assume it's dos and the dirsep is '\'
829  char dirsep = buf[0] == '/' ? '/' : '\\';
830  delete[] buf;
831  return dirsep;
832 }
833 //#############################################################################
834 
835 inline int CoinStrNCaseCmp(const char* s0, const char* s1,
836  const size_t len)
837 {
838  for (size_t i = 0; i < len; ++i) {
839  if (s0[i] == 0) {
840  return s1[i] == 0 ? 0 : -1;
841  }
842  if (s1[i] == 0) {
843  return 1;
844  }
845  const int c0 = std::tolower(s0[i]);
846  const int c1 = std::tolower(s1[i]);
847  if (c0 < c1)
848  return -1;
849  if (c0 > c1)
850  return 1;
851  }
852  return 0;
853 }
854 
855 //#############################################################################
856 
858 template <class T> inline void CoinSwap (T &x, T &y)
859 {
860  T t = x;
861  x = y;
862  y = t;
863 }
864 
865 //#############################################################################
866 
871 template <class T> inline int
872 CoinToFile( const T* array, CoinBigIndex size, FILE * fp)
873 {
874  CoinBigIndex numberWritten;
875  if (array&&size) {
876  numberWritten =
877  static_cast<CoinBigIndex>(fwrite(&size,sizeof(int),1,fp));
878  if (numberWritten!=1)
879  return 1;
880  numberWritten =
881  static_cast<CoinBigIndex>(fwrite(array,sizeof(T),size_t(size),fp));
882  if (numberWritten!=size)
883  return 1;
884  } else {
885  size = 0;
886  numberWritten =
887  static_cast<CoinBigIndex>(fwrite(&size,sizeof(int),1,fp));
888  if (numberWritten!=1)
889  return 1;
890  }
891  return 0;
892 }
893 
894 //#############################################################################
895 
902 template <class T> inline int
903 CoinFromFile( T* &array, CoinBigIndex size, FILE * fp, CoinBigIndex & newSize)
904 {
905  CoinBigIndex numberRead;
906  numberRead =
907  static_cast<CoinBigIndex>(fread(&newSize,sizeof(int),1,fp));
908  if (numberRead!=1)
909  return 1;
910  int returnCode=0;
911  if (size!=newSize&&(newSize||array))
912  returnCode=2;
913  if (newSize) {
914  array = new T [newSize];
915  numberRead =
916  static_cast<CoinBigIndex>(fread(array,sizeof(T),newSize,fp));
917  if (numberRead!=newSize)
918  returnCode=1;
919  } else {
920  array = NULL;
921  }
922  return returnCode;
923 }
924 
925 //#############################################################################
926 
928 #if 0
929 inline double CoinCbrt(double x)
930 {
931 #if defined(_MSC_VER)
932  return pow(x,(1./3.));
933 #else
934  return cbrt(x);
935 #endif
936 }
937 #endif
938 
939 //-----------------------------------------------------------------------------
940 
942 #define CoinSizeofAsInt(type) (static_cast<int>(sizeof(type)))
943 inline int
945 CoinStrlenAsInt(const char * string)
946 {
947  return static_cast<int>(strlen(string));
948 }
949 
952 #if defined COIN_OWN_RANDOM_32
954 public:
960  { seed_=12345678;}
963  {
964  seed_ = seed;
965  }
968  // Copy
970  { seed_ = rhs.seed_;}
971  // Assignment
973  {
974  if (this != &rhs) {
975  seed_ = rhs.seed_;
976  }
977  return *this;
978  }
979 
981 
986  inline void setSeed(int seed)
987  {
988  seed_ = seed;
989  }
991  inline unsigned int getSeed() const
992  {
993  return seed_;
994  }
996  inline double randomDouble() const
997  {
998  double retVal;
999  seed_ = 1664525*(seed_)+1013904223;
1000  retVal = ((static_cast<double> (seed_))/4294967296.0);
1001  return retVal;
1002  }
1004  inline void randomize(int n=0)
1005  {
1006  if (!n)
1007  n=seed_ & 255;
1008  for (int i=0;i<n;i++)
1009  randomDouble();
1010  }
1012 
1013 
1014 protected:
1018  mutable unsigned int seed_;
1021 };
1022 #else
1023 class CoinThreadRandom {
1024 public:
1030  { seed_[0]=50000;seed_[1]=40000;seed_[2]=30000;}
1032  CoinThreadRandom(const unsigned short seed[3])
1033  { memcpy(seed_,seed,3*sizeof(unsigned short));}
1035  CoinThreadRandom(int seed)
1036  {
1037  union { int i[2]; unsigned short int s[4];} put;
1038  put.i[0]=seed;
1039  put.i[1]=seed;
1040  memcpy(seed_,put.s,3*sizeof(unsigned short));
1041  }
1043  ~CoinThreadRandom() {}
1044  // Copy
1045  CoinThreadRandom(const CoinThreadRandom & rhs)
1046  { memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));}
1047  // Assignment
1049  {
1050  if (this != &rhs) {
1051  memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));
1052  }
1053  return *this;
1054  }
1055 
1057 
1062  inline void setSeed(const unsigned short seed[3])
1063  { memcpy(seed_,seed,3*sizeof(unsigned short));}
1065  inline void setSeed(int seed)
1066  {
1067  union { int i[2]; unsigned short int s[4];} put;
1068  put.i[0]=seed;
1069  put.i[1]=seed;
1070  memcpy(seed_,put.s,3*sizeof(unsigned short));
1071  }
1073  inline double randomDouble() const
1074  {
1075  double retVal;
1076 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
1077  retVal=rand();
1078  retVal=retVal/(double) RAND_MAX;
1079 #else
1080  retVal = erand48(seed_);
1081 #endif
1082  return retVal;
1083  }
1085  inline void randomize(int n=0)
1086  {
1087  if (!n) {
1088  n=seed_[0]+seed_[1]+seed_[2];
1089  n &= 255;
1090  }
1091  for (int i=0;i<n;i++)
1092  randomDouble();
1093  }
1095 
1096 
1097 protected:
1101  mutable unsigned short seed_[3];
1104 };
1105 #endif
1106 #ifndef COIN_DETAIL
1107 #define COIN_DETAIL_PRINT(s) {}
1108 #else
1109 #define COIN_DETAIL_PRINT(s) s
1110 #endif
1111 #endif
double randomDouble() const
return a random number
int CoinBigIndex
void CoinSwap(T &x, T &y)
Swap the arguments.
void CoinCheckDoubleZero(double *to, const int size)
This Debug helper function checks an array is all zero.
T CoinMax(register const T x1, register const T x2)
Return the larger (according to operator&lt;() of the arguments.
char * CoinStrdup(const char *name)
Returns strdup or NULL if original NULL.
void CoinDisjointCopyN(register const T *from, const int size, register T *to)
This helper function copies an array to another location.
CoinThreadRandom()
Default constructor.
void CoinIota(T *first, const T *last, T init)
This helper function fills an array with the values init, init+1, init+2, etc.
T * CoinCopyOfArrayPartial(const T *array, const int size, const int copySize)
Return an array of length size filled with first copySize from array, or null if array is null...
void setSeed(int seed)
Set seed.
T CoinAbs(const T value)
Return the absolute value of the argument.
void CoinZeroN(register T *to, const int size)
This helper function fills an array with zero.
unsigned int getSeed() const
Get seed.
void CoinCopyN(register const T *from, const int size, register T *to)
This helper function copies an array to another location using Duff&#39;s device (for a speedup of ~2)...
void CoinMemcpy(register const T *first, register const T *last, register T *to)
This helper function copies an array to another location.
char CoinFindDirSeparator()
This function figures out whether file names should contain slashes or backslashes as directory separ...
~CoinThreadRandom()
Destructor.
T * CoinCopyOfArray(const T *array, const int size)
Return an array of length size filled with input from array, or null if array is null.
T * CoinCopyOfArrayOrZero(const T *array, const int size)
Return an array of length size filled with input from array, or filled with zero if array is null...
void CoinDisjointCopy(register const T *first, register const T *last, register T *to)
This helper function copies an array to another location.
void CoinZero(register T *first, register T *last)
This helper function fills an array with a given value.
void CoinIotaN(register T *first, const int size, register T init)
This helper function fills an array with the values init, init+1, init+2, etc.
void CoinMemcpyN(register const T *from, const int size, register T *to)
This helper function copies an array to another location.
unsigned int seed_
Current seed.
#define COIN_RESTRICT
void CoinSeedRandom(int iseed)
Set the seed for the random number generator.
int CoinFromFile(T *&array, CoinBigIndex size, FILE *fp, CoinBigIndex &newSize)
This helper function copies an array from file and creates with new.
int CoinStrNCaseCmp(const char *s0, const char *s1, const size_t len)
T * CoinDeleteEntriesFromArray(register T *arrayFirst, register T *arrayLast, const int *firstDelPos, const int *lastDelPos)
This helper function deletes certain entries from an array.
void randomize(int n=0)
make more random (i.e. for startup)
CoinThreadRandom(int seed)
Constructor wih seed.
Error Class thrown by an exception.
Definition: CoinError.hpp:42
Class for thread specific random numbers.
int CoinStrlenAsInt(const char *string)
This helper returns &quot;strlen&quot; as an int.
CoinThreadRandom(const CoinThreadRandom &rhs)
Default constructor.
void CoinFill(register T *first, register T *last, const T value)
This helper function fills an array with a given value.
T CoinMin(register const T x1, register const T x2)
Return the smaller (according to operator&lt;() of the arguments.
void CoinCopy(register const T *first, register const T *last, register T *to)
This helper function copies an array to another location using Duff&#39;s device (for a speedup of ~2)...
int CoinToFile(const T *array, CoinBigIndex size, FILE *fp)
This helper function copies an array to file Returns 0 if OK, 1 if bad write.
void CoinFillN(register T *to, const int size, register const T value)
This helper function fills an array with a given value.
void CoinCheckIntZero(int *to, const int size)
This Debug helper function checks an array is all zero.
double CoinDrand48(bool isSeed=false, unsigned int seed=1)
Return a random number between 0 and 1.
bool CoinIsSorted(register const T *first, const int size)
This helper function tests whether the entries of an array are sorted according to operator&lt;...
CoinThreadRandom & operator=(const CoinThreadRandom &rhs)
Default constructor.