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