home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / prgramer / adaptor / dalib / pvm3 / random.c < prev    next >
Text File  |  1993-12-01  |  9KB  |  214 lines

  1. /**************************************************************************
  2. *                                                                         *
  3. *  Author      : Dr. Thomas Brandes, GMD, I1.HR                           *
  4. *  Copyright   : GMD St. Augustin, Germany                                *
  5. *  Date        : Feb 92                                                   *
  6. *  Last Update : Apr 93                                                   *
  7. *                                                                         *
  8. *  This Module is part of the DALIB                                       *
  9. *                                                                         *
  10. *  Module      : random.c                                                 *
  11. *                                                                         *
  12. *  Function    : Getting random numbers (integer, float, double)          *
  13. *                                                                         *
  14. *  Export : Internal Use                                                  *
  15. *                                                                         *
  16. *      void random_block_init ()                                          *
  17. *                                                                         *
  18. *  Export : FORTRAN Interface                                             *
  19. *                                                                         *
  20. *     dalib_random_init (n)  : initialization of generator by seed        *
  21. *     int *n;                                                             *
  22. *                                                                         *
  23. *     dalib_get_real_randoms (a, size, limit)                             *
  24. *     float a[];                                                          *
  25. *     int *size;                                                          *
  26. *     float *limit;                                                       *
  27. *                                                                         *
  28. *     dalib_get_double_randoms (a, size, limit)                           *
  29. *     double a[];                                                         *
  30. *     int *size;                                                          *
  31. *     double *limit;                                                      *
  32. *                                                                         *
  33. *     dalib_get_int_randoms (a, size, limit)                              *
  34. *     int a[];                                                            *
  35. *     int *size;                                                          *
  36. *     int *limit;        ! integers between 0 .. limit-1                  *
  37. *                                                                         *
  38. **************************************************************************/
  39.  
  40. # include "system.h"      /* needs pcb.i */
  41.  
  42. /*******************************************************************
  43. *                                                                  *
  44. *  Local Block for random numbers on each process                  *
  45. *                                                                  *
  46. *******************************************************************/
  47.  
  48. #define RANDOM_SIZE 20  /* 250 */
  49. #define RANDOM_K1   17  /* 103 */
  50. #define RANDOM_K2    5
  51.  
  52. struct
  53.   {  int state[RANDOM_SIZE];
  54.      int pos;
  55.   } random_block;
  56.  
  57. void random_block_init ()
  58. /* This routine is called concurrently */
  59. { int j;
  60. #if defined(SUN4) || defined(ALLIANT) || defined(KSR1) || defined(OS2)
  61.   srand (pcb.i*(2*3*5*7 - 1));
  62. #endif
  63. #if defined(IBM) || defined (GC) || defined(IPSC) || defined(SRM) || defined(MEIKO) || defined(SGI)
  64.   srand48 (pcb.i*(2*3*5*7 - 1));
  65. #endif
  66.   for (j=0;j<RANDOM_SIZE;j++)
  67. #if defined(SUN4) || defined(ALLIANT) || defined(KSR1) || defined(OS2)
  68.      random_block.state[j] = rand();
  69. #endif
  70. #if defined(IBM) || defined (GC) || defined(IPSC) || defined(SRM) || defined(MEIKO) || defined(SGI)
  71.      random_block.state[j] = mrand48 ();
  72. #endif
  73.   random_block.pos = 0;
  74. }
  75.  
  76. int random_block_get ()
  77. /* get a new 32-bit random value from random_block
  78.    this routine can be called concurrently      */
  79. { int k1, k2, pos, z;
  80.   pos = random_block.pos;
  81.   k1 = pos - RANDOM_K1;
  82.   k2 = pos - RANDOM_K2;
  83.   if (k1 < 0) k1+=RANDOM_SIZE;
  84.   if (k2 < 0) k2+=RANDOM_SIZE;
  85.   z = random_block.state[k1] - random_block.state[k2]; /* xor */
  86.   random_block.state[pos] = z;
  87.   pos += 1;
  88.   if (pos >= RANDOM_SIZE) pos = 0;
  89.   random_block.pos = pos;
  90.   return(z);
  91. }
  92.  
  93. /*******************************************************************
  94. *                                                                  *
  95. * FORTRAN - Interface                                              *
  96. *                                                                  *
  97. *     dalib_random_init (n)  : initialization of generator by node *
  98. *                                                                  *
  99. *     dalib_get_int_randoms (a, size, limit)                       *
  100. *                                                                  *
  101. *******************************************************************/
  102.  
  103. void dalib_random_init__ (n)
  104. /* new initialization of the number generator with n */
  105. int *n;
  106. { int j, p;
  107. #if defined(SUN4) || defined(ALLIANT) || defined(KSR1) || defined(OS2)
  108.   srand(*n * pcb.i);   /* set value */
  109. #endif
  110. #if defined(IBM) || defined (GC) || defined(IPSC) || defined(SRM) || defined(MEIKO) || defined(SGI)
  111.   srand48(*n * pcb.i);   /* set value */
  112. #endif
  113.   random_block_init ();
  114. }
  115.  
  116. void dalib_get_int_randoms__ (a, size, limit)
  117. int a[], *size, *limit;
  118. { int j, hz;
  119.   unsigned char *ptr;
  120.  
  121.   for (j=0;j<*size;j++)
  122.      { hz = random_block_get ();
  123.        ptr = (unsigned char *) &hz;
  124.        if (*limit != 0)
  125.          { /* make value positive , big endian , otherwise replace 3 with 0 */
  126. #if defined(SUN4) || defined(IBM) || defined(KSR1) || defined(SGI)
  127.            ptr[0] = ptr[0] & 127;
  128. #endif
  129. #if defined(ALLIANT) || defined(GC) || defined(IPSC) || defined(SRM) || defined(MEIKO) || defined(OS2)
  130.            ptr[3] = ptr[3] & 127;
  131. #endif
  132.            a[j] = hz % *limit;
  133.          }
  134.         else
  135.           a[j] = hz;
  136.      }
  137. }
  138.  
  139. void dalib_get_real_randoms__ (a, size, limit)
  140. float a[];
  141. int *size;
  142. float *limit;
  143.  
  144. { int j, hz;
  145.   unsigned char *ptr;
  146.  
  147. /****************************************************************
  148. *                                                               *
  149. * float    byte1      byte2    byte3      byte4                 *
  150. * =============================================                 *
  151. *                                                               *
  152. *  0.5      3f       00        00         00                    *
  153. *  1.0      3f       80        00         00                    *
  154. *  1.+      3f       80        00         01                    *
  155. *  2.-      3f       ff        ff         ff                    *
  156. *  2.0      40       00        00         00                    *
  157. *                                                               *
  158. ****************************************************************/
  159.  
  160.   for (j=0;j<*size;j++)
  161.      { hz = random_block_get ();
  162.        ptr = (unsigned char *) &hz;
  163.        /* little endian, otherwise replace 3 with 0, 2 with 1 */
  164. #if defined(SUN4) || defined(IBM) || defined(KSR1) || defined(SGI)
  165.        ptr[0] = 63;  /* 3f */
  166.        ptr[1] = ptr[1] | 128;   /* 80 */
  167. #endif
  168. #if defined(ALLIANT) || defined(GC) || defined(IPSC) || defined(SRM) || defined(MEIKO) || defined(OS2)
  169.        ptr[3] = 63;  /* 3f */
  170.        ptr[2] = ptr[1] | 128;   /* 80 */
  171. #endif
  172.        /* hz is now between 1.0 and 2.0 */
  173.        a[j] = *((float *) &hz) - 1.0;
  174.      }
  175. }
  176.  
  177. void dalib_get_double_randoms__ (a, size, limit)
  178. double a[], limit;
  179. int *size;
  180. { int i, j;
  181.   char *ptr;
  182.   int  hz[2];
  183.  
  184. /****************************************************************
  185. *                                                               *
  186. * double   byte1      byte2    byte3      byte4  ...   byte8    *
  187. * ==========================================================    *
  188. *                                                               *
  189. *  0.5      3f       E0        00         00     ....   00      *
  190. *  1.0      3f       F0        00         00     ....   00      *
  191. *  1.+      3f       F0        00         00     ....   01      *
  192. *  2.-      3f       ff        ff         ff     ....   ff      *
  193. *  2.0      40       00        00         00     ....   00      *
  194. *                                                               *
  195. ****************************************************************/
  196.  
  197.   for (j=0;j<*size;j++)
  198.      { hz[0] = random_block_get ();
  199.        hz[1] = random_block_get ();
  200.        ptr = (char *) hz;
  201.        /* big endian, otherwise replace 7 with 0, 6 with 1 */
  202. #if defined(SUN4) || defined(IBM) || defined(KSR1) || defined(SGI)
  203.        ptr[0] = 63;  /* 3f */
  204.        ptr[1] = ptr[1] | 240;   /* F0 */
  205. #endif
  206. #if defined(ALLIANT) || defined(GC) || defined(IPSC) || defined(SRM) || defined(MEIKO) || defined(OS2)
  207.        ptr[7] = 63;  /* 3f */
  208.        ptr[6] = ptr[1] | 240;   /* F0 */
  209. #endif
  210.        /* hz is now between 1.0 and 2.0 */
  211.        a[j] = *((double *) ptr) - (double)1.0;
  212.      }
  213. }
  214.