CoinHelperFunctions.hpp
Go to the documentation of this file.
1 /* $Id: CoinHelperFunctions.hpp 1240 2009-12-10 17:07:20Z ladanyi $ */
2 // Copyright (C) 2000, International Business Machines
3 // Corporation and others. All Rights Reserved.
4 
5 #ifndef CoinHelperFunctions_H
6 #define CoinHelperFunctions_H
7 #if defined(_MSC_VER)
8 # include <direct.h>
9 # define getcwd _getcwd
10 #else
11 # include <unistd.h>
12 #endif
13 //#define USE_MEMCPY
14 
15 #include <cstdlib>
16 #include <cstdio>
17 #include "CoinError.hpp"
18 #include "CoinFinite.hpp"
19 //#############################################################################
20 
26 template <class T> inline void
27 CoinCopyN(register const T* from, const int size, register T* to)
28 {
29  if (size == 0 || from == to)
30  return;
31 
32 #ifndef NDEBUG
33  if (size < 0)
34  throw CoinError("trying to copy negative number of entries",
35  "CoinCopyN", "");
36 #endif
37 
38  register int n = (size + 7) / 8;
39  if (to > from) {
40  register const T* downfrom = from + size;
41  register T* downto = to + size;
42  // Use Duff's device to copy
43  switch (size % 8) {
44  case 0: do{ *--downto = *--downfrom;
45  case 7: *--downto = *--downfrom;
46  case 6: *--downto = *--downfrom;
47  case 5: *--downto = *--downfrom;
48  case 4: *--downto = *--downfrom;
49  case 3: *--downto = *--downfrom;
50  case 2: *--downto = *--downfrom;
51  case 1: *--downto = *--downfrom;
52  }while(--n>0);
53  }
54  } else {
55  // Use Duff's device to copy
56  --from;
57  --to;
58  switch (size % 8) {
59  case 0: do{ *++to = *++from;
60  case 7: *++to = *++from;
61  case 6: *++to = *++from;
62  case 5: *++to = *++from;
63  case 4: *++to = *++from;
64  case 3: *++to = *++from;
65  case 2: *++to = *++from;
66  case 1: *++to = *++from;
67  }while(--n>0);
68  }
69  }
70 }
71 
72 //-----------------------------------------------------------------------------
73 
78 template <class T> inline void
79 CoinCopy(register const T* first, register const T* last, register T* to)
80 {
81  CoinCopyN(first, last - first, to);
82 }
83 
84 //-----------------------------------------------------------------------------
85 
93 template <class T> inline void
94 CoinDisjointCopyN(register const T* from, const int size, register T* to)
95 {
96 #ifndef _MSC_VER
97  if (size == 0 || from == to)
98  return;
99 
100 #ifndef NDEBUG
101  if (size < 0)
102  throw CoinError("trying to copy negative number of entries",
103  "CoinDisjointCopyN", "");
104 #endif
105 
106 #if 0
107  /* There is no point to do this test. If to and from are from different
108  blocks then dist is undefined, so this can crash correct code. It's
109  better to trust the user that the arrays are really disjoint. */
110  const long dist = to - from;
111  if (-size < dist && dist < size)
112  throw CoinError("overlapping arrays", "CoinDisjointCopyN", "");
113 #endif
114 
115  for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
116  to[0] = from[0];
117  to[1] = from[1];
118  to[2] = from[2];
119  to[3] = from[3];
120  to[4] = from[4];
121  to[5] = from[5];
122  to[6] = from[6];
123  to[7] = from[7];
124  }
125  switch (size % 8) {
126  case 7: to[6] = from[6];
127  case 6: to[5] = from[5];
128  case 5: to[4] = from[4];
129  case 4: to[3] = from[3];
130  case 3: to[2] = from[2];
131  case 2: to[1] = from[1];
132  case 1: to[0] = from[0];
133  case 0: break;
134  }
135 #else
136  CoinCopyN(from, size, to);
137 #endif
138 }
139 
140 //-----------------------------------------------------------------------------
141 
146 template <class T> inline void
147 CoinDisjointCopy(register const T* first, register const T* last,
148  register T* to)
149 {
150  CoinDisjointCopyN(first, static_cast<int>(last - first), to);
151 }
152 
153 //-----------------------------------------------------------------------------
154 
159 template <class T> inline T*
160 CoinCopyOfArray( const T * array, const int size)
161 {
162  if (array) {
163  T * arrayNew = new T[size];
164  std::memcpy(arrayNew,array,size*sizeof(T));
165  return arrayNew;
166  } else {
167  return NULL;
168  }
169 }
170 
171 
176 template <class T> inline T*
177 CoinCopyOfArrayPartial( const T * array, const int size,const int copySize)
178 {
179  if (array||size) {
180  T * arrayNew = new T[size];
181  assert (copySize<=size);
182  std::memcpy(arrayNew,array,copySize*sizeof(T));
183  return arrayNew;
184  } else {
185  return NULL;
186  }
187 }
188 
193 template <class T> inline T*
194 CoinCopyOfArray( const T * array, const int size, T value)
195 {
196  T * arrayNew = new T[size];
197  if (array) {
198  std::memcpy(arrayNew,array,size*sizeof(T));
199  } else {
200  int i;
201  for (i=0;i<size;i++)
202  arrayNew[i] = value;
203  }
204  return arrayNew;
205 }
206 
207 
212 template <class T> inline T*
213 CoinCopyOfArrayOrZero( const T * array , const int size)
214 {
215  T * arrayNew = new T[size];
216  if (array) {
217  std::memcpy(arrayNew,array,size*sizeof(T));
218  } else {
219  std::memset(arrayNew,0,size*sizeof(T));
220  }
221  return arrayNew;
222 }
223 
224 
225 //-----------------------------------------------------------------------------
226 
234 #ifndef COIN_USE_RESTRICT
235 template <class T> inline void
236 CoinMemcpyN(register const T* from, const int size, register T* to)
237 {
238 #ifndef _MSC_VER
239 #ifdef USE_MEMCPY
240  // Use memcpy - seems a lot faster on Intel with gcc
241 #ifndef NDEBUG
242  // Some debug so check
243  if (size < 0)
244  throw CoinError("trying to copy negative number of entries",
245  "CoinMemcpyN", "");
246 
247 #if 0
248  /* There is no point to do this test. If to and from are from different
249  blocks then dist is undefined, so this can crash correct code. It's
250  better to trust the user that the arrays are really disjoint. */
251  const long dist = to - from;
252  if (-size < dist && dist < size)
253  throw CoinError("overlapping arrays", "CoinMemcpyN", "");
254 #endif
255 #endif
256  std::memcpy(to,from,size*sizeof(T));
257 #else
258  if (size == 0 || from == to)
259  return;
260 
261 #ifndef NDEBUG
262  if (size < 0)
263  throw CoinError("trying to copy negative number of entries",
264  "CoinMemcpyN", "");
265 #endif
266 
267 #if 0
268  /* There is no point to do this test. If to and from are from different
269  blocks then dist is undefined, so this can crash correct code. It's
270  better to trust the user that the arrays are really disjoint. */
271  const long dist = to - from;
272  if (-size < dist && dist < size)
273  throw CoinError("overlapping arrays", "CoinMemcpyN", "");
274 #endif
275 
276  for (register int n = size / 8; n > 0; --n, from += 8, to += 8) {
277  to[0] = from[0];
278  to[1] = from[1];
279  to[2] = from[2];
280  to[3] = from[3];
281  to[4] = from[4];
282  to[5] = from[5];
283  to[6] = from[6];
284  to[7] = from[7];
285  }
286  switch (size % 8) {
287  case 7: to[6] = from[6];
288  case 6: to[5] = from[5];
289  case 5: to[4] = from[4];
290  case 4: to[3] = from[3];
291  case 3: to[2] = from[2];
292  case 2: to[1] = from[1];
293  case 1: to[0] = from[0];
294  case 0: break;
295  }
296 #endif
297 #else
298  CoinCopyN(from, size, to);
299 #endif
300 }
301 #else
302 template <class T> inline void
303 CoinMemcpyN(const T * COIN_RESTRICT from, int size, T* COIN_RESTRICT to)
304 {
305 #ifdef USE_MEMCPY
306  std::memcpy(to,from,size*sizeof(T));
307 #else
308  T * COIN_RESTRICT put = to;
309  const T * COIN_RESTRICT get = from;
310  for ( ; 0<size ; --size)
311  *put++ = *get++;
312 #endif
313 }
314 #endif
315 
316 //-----------------------------------------------------------------------------
317 
322 template <class T> inline void
323 CoinMemcpy(register const T* first, register const T* last,
324  register T* to)
325 {
326  CoinMemcpyN(first, static_cast<int>(last - first), to);
327 }
328 
329 //#############################################################################
330 
337 template <class T> inline void
338 CoinFillN(register T* to, const int size, register const T value)
339 {
340  if (size == 0)
341  return;
342 
343 #ifndef NDEBUG
344  if (size < 0)
345  throw CoinError("trying to fill negative number of entries",
346  "CoinFillN", "");
347 #endif
348 #if 1
349  for (register int n = size / 8; n > 0; --n, to += 8) {
350  to[0] = value;
351  to[1] = value;
352  to[2] = value;
353  to[3] = value;
354  to[4] = value;
355  to[5] = value;
356  to[6] = value;
357  to[7] = value;
358  }
359  switch (size % 8) {
360  case 7: to[6] = value;
361  case 6: to[5] = value;
362  case 5: to[4] = value;
363  case 4: to[3] = value;
364  case 3: to[2] = value;
365  case 2: to[1] = value;
366  case 1: to[0] = value;
367  case 0: break;
368  }
369 #else
370  // Use Duff's device to fill
371  register int n = (size + 7) / 8;
372  --to;
373  switch (size % 8) {
374  case 0: do{ *++to = value;
375  case 7: *++to = value;
376  case 6: *++to = value;
377  case 5: *++to = value;
378  case 4: *++to = value;
379  case 3: *++to = value;
380  case 2: *++to = value;
381  case 1: *++to = value;
382  }while(--n>0);
383  }
384 #endif
385 }
386 
387 //-----------------------------------------------------------------------------
388 
392 template <class T> inline void
393 CoinFill(register T* first, register T* last, const T value)
394 {
395  CoinFillN(first, last - first, value);
396 }
397 
398 //#############################################################################
399 
406 template <class T> inline void
407 CoinZeroN(register T* to, const int size)
408 {
409 #ifdef USE_MEMCPY
410  // Use memset - seems faster on Intel with gcc
411 #ifndef NDEBUG
412  // Some debug so check
413  if (size < 0)
414  throw CoinError("trying to fill negative number of entries",
415  "CoinZeroN", "");
416 #endif
417  memset(to,0,size*sizeof(T));
418 #else
419  if (size == 0)
420  return;
421 
422 #ifndef NDEBUG
423  if (size < 0)
424  throw CoinError("trying to fill negative number of entries",
425  "CoinZeroN", "");
426 #endif
427 #if 1
428  for (register int n = size / 8; n > 0; --n, to += 8) {
429  to[0] = 0;
430  to[1] = 0;
431  to[2] = 0;
432  to[3] = 0;
433  to[4] = 0;
434  to[5] = 0;
435  to[6] = 0;
436  to[7] = 0;
437  }
438  switch (size % 8) {
439  case 7: to[6] = 0;
440  case 6: to[5] = 0;
441  case 5: to[4] = 0;
442  case 4: to[3] = 0;
443  case 3: to[2] = 0;
444  case 2: to[1] = 0;
445  case 1: to[0] = 0;
446  case 0: break;
447  }
448 #else
449  // Use Duff's device to fill
450  register int n = (size + 7) / 8;
451  --to;
452  switch (size % 8) {
453  case 0: do{ *++to = 0;
454  case 7: *++to = 0;
455  case 6: *++to = 0;
456  case 5: *++to = 0;
457  case 4: *++to = 0;
458  case 3: *++to = 0;
459  case 2: *++to = 0;
460  case 1: *++to = 0;
461  }while(--n>0);
462  }
463 #endif
464 #endif
465 }
467 inline void
468 CoinCheckDoubleZero(double * to, const int size)
469 {
470  int n=0;
471  for (int j=0;j<size;j++) {
472  if (to[j])
473  n++;
474  }
475  if (n) {
476  printf("array of length %d should be zero has %d nonzero\n",size,n);
477  }
478 }
480 inline void
481 CoinCheckIntZero(int * to, const int size)
482 {
483  int n=0;
484  for (int j=0;j<size;j++) {
485  if (to[j])
486  n++;
487  }
488  if (n) {
489  printf("array of length %d should be zero has %d nonzero\n",size,n);
490  }
491 }
492 
493 //-----------------------------------------------------------------------------
494 
498 template <class T> inline void
499 CoinZero(register T* first, register T* last)
500 {
501  CoinZeroN(first, last - first);
502 }
503 
504 //#############################################################################
505 
507 inline char * CoinStrdup(const char * name)
508 {
509  char* dup = NULL;
510  if (name) {
511  const int len = static_cast<int>(strlen(name));
512  dup = static_cast<char*>(malloc(len+1));
513  CoinMemcpyN(name, len, dup);
514  dup[len] = 0;
515  }
516  return dup;
517 }
518 
519 //#############################################################################
520 
524 template <class T> inline T
525 CoinMax(register const T x1, register const T x2)
526 {
527  return (x1 > x2) ? x1 : x2;
528 }
529 
530 //-----------------------------------------------------------------------------
531 
535 template <class T> inline T
536 CoinMin(register const T x1, register const T x2)
537 {
538  return (x1 < x2) ? x1 : x2;
539 }
540 
541 //-----------------------------------------------------------------------------
542 
546 template <class T> inline T
547 CoinAbs(const T value)
548 {
549  return value<0 ? -value : value;
550 }
551 
552 //#############################################################################
553 
557 template <class T> inline bool
558 CoinIsSorted(register const T* first, const int size)
559 {
560  if (size == 0)
561  return true;
562 
563 #ifndef NDEBUG
564  if (size < 0)
565  throw CoinError("negative number of entries", "CoinIsSorted", "");
566 #endif
567 #if 1
568  // size1 is the number of comparisons to be made
569  const int size1 = size - 1;
570  for (register int n = size1 / 8; n > 0; --n, first += 8) {
571  if (first[8] < first[7]) return false;
572  if (first[7] < first[6]) return false;
573  if (first[6] < first[5]) return false;
574  if (first[5] < first[4]) return false;
575  if (first[4] < first[3]) return false;
576  if (first[3] < first[2]) return false;
577  if (first[2] < first[1]) return false;
578  if (first[1] < first[0]) return false;
579  }
580 
581  switch (size1 % 8) {
582  case 7: if (first[7] < first[6]) return false;
583  case 6: if (first[6] < first[5]) return false;
584  case 5: if (first[5] < first[4]) return false;
585  case 4: if (first[4] < first[3]) return false;
586  case 3: if (first[3] < first[2]) return false;
587  case 2: if (first[2] < first[1]) return false;
588  case 1: if (first[1] < first[0]) return false;
589  case 0: break;
590  }
591 #else
592  register const T* next = first;
593  register const T* last = first + size;
594  for (++next; next != last; first = next, ++next)
595  if (*next < *first)
596  return false;
597 #endif
598  return true;
599 }
600 
601 //-----------------------------------------------------------------------------
602 
606 template <class T> inline bool
607 CoinIsSorted(register const T* first, register const T* last)
608 {
609  return CoinIsSorted(first, static_cast<int>(last - first));
610 }
611 
612 //#############################################################################
613 
617 template <class T> inline void
618 CoinIotaN(register T* first, const int size, register T init)
619 {
620  if (size == 0)
621  return;
622 
623 #ifndef NDEBUG
624  if (size < 0)
625  throw CoinError("negative number of entries", "CoinIotaN", "");
626 #endif
627 #if 1
628  for (register int n = size / 8; n > 0; --n, first += 8, init += 8) {
629  first[0] = init;
630  first[1] = init + 1;
631  first[2] = init + 2;
632  first[3] = init + 3;
633  first[4] = init + 4;
634  first[5] = init + 5;
635  first[6] = init + 6;
636  first[7] = init + 7;
637  }
638  switch (size % 8) {
639  case 7: first[6] = init + 6;
640  case 6: first[5] = init + 5;
641  case 5: first[4] = init + 4;
642  case 4: first[3] = init + 3;
643  case 3: first[2] = init + 2;
644  case 2: first[1] = init + 1;
645  case 1: first[0] = init;
646  case 0: break;
647  }
648 #else
649  // Use Duff's device to fill
650  register int n = (size + 7) / 8;
651  --first;
652  --init;
653  switch (size % 8) {
654  case 0: do{ *++first = ++init;
655  case 7: *++first = ++init;
656  case 6: *++first = ++init;
657  case 5: *++first = ++init;
658  case 4: *++first = ++init;
659  case 3: *++first = ++init;
660  case 2: *++first = ++init;
661  case 1: *++first = ++init;
662  }while(--n>0);
663  }
664 #endif
665 }
666 
667 //-----------------------------------------------------------------------------
668 
672 template <class T> inline void
673 CoinIota(T* first, const T* last, T init)
674 {
675  CoinIotaN(first, last-first, init);
676 }
677 
678 //#############################################################################
679 
685 template <class T> inline T *
686 CoinDeleteEntriesFromArray(register T * arrayFirst, register T * arrayLast,
687  const int * firstDelPos, const int * lastDelPos)
688 {
689  int delNum = lastDelPos - firstDelPos;
690  if (delNum == 0)
691  return arrayLast;
692 
693  if (delNum < 0)
694  throw CoinError("trying to delete negative number of entries",
695  "CoinDeleteEntriesFromArray", "");
696 
697  int * delSortedPos = NULL;
698  if (! (CoinIsSorted(firstDelPos, lastDelPos) &&
699  std::adjacent_find(firstDelPos, lastDelPos) == lastDelPos)) {
700  // the positions of the to be deleted is either not sorted or not unique
701  delSortedPos = new int[delNum];
702  CoinDisjointCopy(firstDelPos, lastDelPos, delSortedPos);
703  std::sort(delSortedPos, delSortedPos + delNum);
704  delNum = std::unique(delSortedPos, delSortedPos + delNum) - delSortedPos;
705  }
706  const int * delSorted = delSortedPos ? delSortedPos : firstDelPos;
707 
708  const int last = delNum - 1;
709  int size = delSorted[0];
710  for (int i = 0; i < last; ++i) {
711  const int copyFirst = delSorted[i] + 1;
712  const int copyLast = delSorted[i+1];
713  CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
714  arrayFirst + size);
715  size += copyLast - copyFirst;
716  }
717  const int copyFirst = delSorted[last] + 1;
718  const int copyLast = arrayLast - arrayFirst;
719  CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast,
720  arrayFirst + size);
721  size += copyLast - copyFirst;
722 
723  if (delSortedPos)
724  delete[] delSortedPos;
725 
726  return arrayFirst + size;
727 }
728 
729 //#############################################################################
730 
731 #define COIN_OWN_RANDOM_32
732 
733 #if defined COIN_OWN_RANDOM_32
734 /* Thanks to Stefano Gliozzi for providing an operating system
735  independent random number generator. */
736 
737 // linear congruential generator. given the seed, the generated numbers are
738 // always the same regardless the (32 bit) architecture. This allows to
739 // build & test in different environments (i.e. Wintel, Linux/Intel AIX Power5)
740 // getting in most cases the same optimization path.
742 inline double CoinDrand48(bool isSeed = false, unsigned int seed=1)
743 {
744  static unsigned int last = 123456;
745  if (isSeed) {
746  last = seed;
747  } else {
748  last = 1664525*last+1013904223;
749  return ((static_cast<double> (last))/4294967296.0);
750  }
751  return(0.0);
752 }
754 inline void CoinSeedRandom(int iseed)
755 {
756  CoinDrand48(true, iseed);
757 }
758 
759 #else // COIN_OWN_RANDOM_32
760 
761 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
762 
763 inline double CoinDrand48() { return rand() / (double) RAND_MAX; }
764 inline void CoinSeedRandom(int iseed) { srand(iseed + 69822); }
765 
766 #else
767 
768 inline double CoinDrand48() { return drand48(); }
769 inline void CoinSeedRandom(int iseed) { srand48(iseed + 69822); }
770 
771 #endif
772 
773 #endif // COIN_OWN_RANDOM_32
774 
775 //#############################################################################
776 
779 inline char CoinFindDirSeparator()
780 {
781  int size = 1000;
782  char* buf = 0;
783  while (true) {
784  buf = new char[size];
785  if (getcwd(buf, size))
786  break;
787  delete[] buf;
788  buf = 0;
789  size = 2*size;
790  }
791  // if first char is '/' then it's unix and the dirsep is '/'. otherwise we
792  // assume it's dos and the dirsep is '\'
793  char dirsep = buf[0] == '/' ? '/' : '\\';
794  delete[] buf;
795  return dirsep;
796 }
797 //#############################################################################
798 
799 inline int CoinStrNCaseCmp(const char* s0, const char* s1,
800  const size_t len)
801 {
802  for (size_t i = 0; i < len; ++i) {
803  if (s0[i] == 0) {
804  return s1[i] == 0 ? 0 : -1;
805  }
806  if (s1[i] == 0) {
807  return 1;
808  }
809  const int c0 = tolower(s0[i]);
810  const int c1 = tolower(s1[i]);
811  if (c0 < c1)
812  return -1;
813  if (c0 > c1)
814  return 1;
815  }
816  return 0;
817 }
818 
819 //#############################################################################
820 
822 template <class T> inline void CoinSwap (T &x, T &y)
823 {
824  T t = x;
825  x = y;
826  y = t;
827 }
828 
829 //#############################################################################
830 
835 /* FIXME64 */
836 
837 template <class T> inline int
838 CoinToFile( const T* array, int size, FILE * fp)
839 {
840  size_t numberWritten;
841  if (array&&size) {
842  numberWritten = fwrite(&size,sizeof(int),1,fp);
843  if (numberWritten!=1)
844  return 1;
845  numberWritten = fwrite(array,sizeof(T),size_t(size),fp);
846  if (numberWritten!=size)
847  return 1;
848  } else {
849  size = 0;
850  numberWritten = fwrite(&size,sizeof(int),1,fp);
851  if (numberWritten!=1)
852  return 1;
853  }
854  return 0;
855 }
856 
857 //#############################################################################
858 
865 /* FIXME64 */
866 
867 template <class T> inline int
868 CoinFromFile( T* &array, int size, FILE * fp,int & newSize)
869 {
870  size_t numberRead;
871  numberRead = fread(&newSize,sizeof(int),1,fp);
872  if (numberRead!=1)
873  return 1;
874  int returnCode=0;
875  if (size!=newSize&&(newSize||array))
876  returnCode=2;
877  if (newSize) {
878  array = new T [newSize];
879  numberRead = fread(array,sizeof(T),size_t(newSize),fp);
880  if (numberRead!=newSize)
881  returnCode=1;
882  } else {
883  array = NULL;
884  }
885  return returnCode;
886 }
887 
888 //#############################################################################
889 
891 inline double CoinCbrt(double x)
892 {
893 #if defined(_MSC_VER)
894  return pow(x,(1./3.));
895 #else
896  return cbrt(x);
897 #endif
898 }
899 //-----------------------------------------------------------------------------
900 
902 #define CoinSizeofAsInt(type) (static_cast<int>(sizeof(type)))
903 inline int
905 CoinStrlenAsInt(const char * string)
906 {
907  return static_cast<int>(strlen(string));
908 }
909 
912 #if defined COIN_OWN_RANDOM_32
914 public:
920  { seed_=12345678;}
923  {
924  seed_ = seed;
925  }
928  // Copy
930  { seed_ = rhs.seed_;}
931  // Assignment
933  {
934  if (this != &rhs) {
935  seed_ = rhs.seed_;
936  }
937  return *this;
938  }
939 
941 
946  inline void setSeed(int seed)
947  {
948  seed_ = seed;
949  }
951  inline unsigned int getSeed() const
952  {
953  return seed_;
954  }
956  inline double randomDouble() const
957  {
958  double retVal;
959  seed_ = 1664525*(seed_)+1013904223;
960  retVal = ((static_cast<double> (seed_))/4294967296.0);
961  return retVal;
962  }
964 
965 
966 protected:
970  mutable unsigned int seed_;
973 };
974 #else
975 class CoinThreadRandom {
976 public:
982  { seed_[0]=50000;seed_[1]=40000;seed_[2]=30000;}
984  CoinThreadRandom(const unsigned short seed[3])
985  { memcpy(seed_,seed,3*sizeof(unsigned short));}
987  CoinThreadRandom(int seed)
988  {
989  union { int i[2]; unsigned short int s[4];} put;
990  put.i[0]=seed;
991  put.i[1]=seed;
992  memcpy(seed_,put.s,3*sizeof(unsigned short));
993  }
995  ~CoinThreadRandom() {}
996  // Copy
998  { memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));}
999  // Assignment
1001  {
1002  if (this != &rhs) {
1003  memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));
1004  }
1005  return *this;
1006  }
1007 
1009 
1014  inline void setSeed(const unsigned short seed[3])
1015  { memcpy(seed_,seed,3*sizeof(unsigned short));}
1017  inline void setSeed(int seed)
1018  {
1019  union { int i[2]; unsigned short int s[4];} put;
1020  put.i[0]=seed;
1021  put.i[1]=seed;
1022  memcpy(seed_,put.s,3*sizeof(unsigned short));
1023  }
1025  inline double randomDouble() const
1026  {
1027  double retVal;
1028 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__)
1029  retVal=rand();
1030  retVal=retVal/(double) RAND_MAX;
1031 #else
1032  retVal = erand48(seed_);
1033 #endif
1034  return retVal;
1035  }
1037 
1038 
1039 protected:
1043  mutable unsigned short seed_[3];
1046 };
1047 #endif
1048 #endif
double randomDouble() const
return a random number
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<() 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.
int CoinFromFile(T *&array, int size, FILE *fp, int &newSize)
This helper function copies an array from file and creates with new.
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'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...
double CoinCbrt(double x)
Cube Root.
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.
#define COIN_RESTRICT
Definition: CoinFinite.hpp:45
unsigned int seed_
Current seed.
void CoinSeedRandom(int iseed)
Seed random number generator.
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.
CoinThreadRandom(int seed)
Constructor wih seed.
Error Class thrown by an exception.
Definition: CoinError.hpp:40
Class for thread specific random numbers.
int CoinToFile(const T *array, int size, FILE *fp)
This helper function copies an array to file Returns 0 if OK, 1 if bad write.
int CoinStrlenAsInt(const char *string)
This helper returns "strlen" 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<() 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's device (for a speedup of ~2)...
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 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<...
CoinThreadRandom & operator=(const CoinThreadRandom &rhs)
Default constructor.