1 /* Implementation of the RANDOM intrinsics
2 Copyright 2002, 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
3 Contributed by Lars Segerlund <seger@linuxmail.org>
6 This file is part of the GNU Fortran 95 runtime library (libgfortran).
8 Libgfortran is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public
10 License as published by the Free Software Foundation; either
11 version 3 of the License, or (at your option) any later version.
13 Ligbfortran is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 Under Section 7 of GPL version 3, you are granted additional
19 permissions described in the GCC Runtime Library Exception, version
20 3.1, as published by the Free Software Foundation.
22 You should have received a copy of the GNU General Public License and
23 a copy of the GCC Runtime Library Exception along with this program;
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 <http://www.gnu.org/licenses/>. */
27 #include "libgfortran.h"
31 extern void random_r4 (GFC_REAL_4
*);
32 iexport_proto(random_r4
);
34 extern void random_r8 (GFC_REAL_8
*);
35 iexport_proto(random_r8
);
37 extern void arandom_r4 (gfc_array_r4
*);
38 export_proto(arandom_r4
);
40 extern void arandom_r8 (gfc_array_r8
*);
41 export_proto(arandom_r8
);
43 #ifdef HAVE_GFC_REAL_10
45 extern void random_r10 (GFC_REAL_10
*);
46 iexport_proto(random_r10
);
48 extern void arandom_r10 (gfc_array_r10
*);
49 export_proto(arandom_r10
);
53 #ifdef HAVE_GFC_REAL_16
55 extern void random_r16 (GFC_REAL_16
*);
56 iexport_proto(random_r16
);
58 extern void arandom_r16 (gfc_array_r16
*);
59 export_proto(arandom_r16
);
63 #ifdef __GTHREAD_MUTEX_INIT
64 static __gthread_mutex_t random_lock
= __GTHREAD_MUTEX_INIT
;
66 static __gthread_mutex_t random_lock
;
69 /* Helper routines to map a GFC_UINTEGER_* to the corresponding
70 GFC_REAL_* types in the range of [0,1). If GFC_REAL_*_RADIX are 2
71 or 16, respectively, we mask off the bits that don't fit into the
72 correct GFC_REAL_*, convert to the real type, then multiply by the
77 rnumber_4 (GFC_REAL_4
*f
, GFC_UINTEGER_4 v
)
80 #if GFC_REAL_4_RADIX == 2
81 mask
= ~ (GFC_UINTEGER_4
) 0u << (32 - GFC_REAL_4_DIGITS
);
82 #elif GFC_REAL_4_RADIX == 16
83 mask
= ~ (GFC_UINTEGER_4
) 0u << ((8 - GFC_REAL_4_DIGITS
) * 4);
85 #error "GFC_REAL_4_RADIX has unknown value"
88 *f
= (GFC_REAL_4
) v
* (GFC_REAL_4
) 0x1.p
-32f
;
92 rnumber_8 (GFC_REAL_8
*f
, GFC_UINTEGER_8 v
)
95 #if GFC_REAL_8_RADIX == 2
96 mask
= ~ (GFC_UINTEGER_8
) 0u << (64 - GFC_REAL_8_DIGITS
);
97 #elif GFC_REAL_8_RADIX == 16
98 mask
= ~ (GFC_UINTEGER_8
) 0u << (16 - GFC_REAL_8_DIGITS
) * 4);
100 #error "GFC_REAL_8_RADIX has unknown value"
103 *f
= (GFC_REAL_8
) v
* (GFC_REAL_8
) 0x1.p
-64;
106 #ifdef HAVE_GFC_REAL_10
109 rnumber_10 (GFC_REAL_10
*f
, GFC_UINTEGER_8 v
)
112 #if GFC_REAL_10_RADIX == 2
113 mask
= ~ (GFC_UINTEGER_8
) 0u << (64 - GFC_REAL_10_DIGITS
);
114 #elif GFC_REAL_10_RADIX == 16
115 mask
= ~ (GFC_UINTEGER_10
) 0u << ((16 - GFC_REAL_10_DIGITS
) * 4);
117 #error "GFC_REAL_10_RADIX has unknown value"
120 *f
= (GFC_REAL_10
) v
* (GFC_REAL_10
) 0x1.p
-64;
124 #ifdef HAVE_GFC_REAL_16
126 /* For REAL(KIND=16), we only need to mask off the lower bits. */
129 rnumber_16 (GFC_REAL_16
*f
, GFC_UINTEGER_8 v1
, GFC_UINTEGER_8 v2
)
132 #if GFC_REAL_16_RADIX == 2
133 mask
= ~ (GFC_UINTEGER_8
) 0u << (128 - GFC_REAL_16_DIGITS
);
134 #elif GFC_REAL_16_RADIX == 16
135 mask
= ~ (GFC_UINTEGER_8
) 0u << ((32 - GFC_REAL_16_DIGITS
) * 4);
137 #error "GFC_REAL_16_RADIX has unknown value"
140 *f
= (GFC_REAL_16
) v1
* (GFC_REAL_16
) 0x1.p
-64
141 + (GFC_REAL_16
) v2
* (GFC_REAL_16
) 0x1.p
-128;
144 /* libgfortran previously had a Mersenne Twister, taken from the paper:
146 Mersenne Twister: 623-dimensionally equidistributed
147 uniform pseudorandom generator.
149 by Makoto Matsumoto & Takuji Nishimura
150 which appeared in the: ACM Transactions on Modelling and Computer
151 Simulations: Special Issue on Uniform Random Number
152 Generation. ( Early in 1998 ).
154 The Mersenne Twister code was replaced due to
156 (1) Simple user specified seeds lead to really bad sequences for
157 nearly 100000 random numbers.
158 (2) open(), read(), and close() were not properly declared via header
160 (3) The global index i was abused and caused unexpected behavior with
165 libgfortran currently uses George Marsaglia's KISS (Keep It Simple Stupid)
166 random number generator. This PRNG combines:
168 (1) The congruential generator x(n)=69069*x(n-1)+1327217885 with a period
170 (2) A 3-shift shift-register generator with a period of 2^32-1,
171 (3) Two 16-bit multiply-with-carry generators with a period of
172 597273182964842497 > 2^59.
174 The overall period exceeds 2^123.
176 http://www.ciphersbyritter.com/NEWS4/RANDC.HTM#369F6FCA.74C7C041@stat.fsu.edu
178 The above web site has an archive of a newsgroup posting from George
179 Marsaglia with the statement:
181 Subject: Random numbers for C: Improvements.
182 Date: Fri, 15 Jan 1999 11:41:47 -0500
183 From: George Marsaglia <geo@stat.fsu.edu>
184 Message-ID: <369F6FCA.74C7C041@stat.fsu.edu>
185 References: <369B5E30.65A55FD1@stat.fsu.edu>
186 Newsgroups: sci.stat.math,sci.math,sci.math.numer-analysis
189 As I hoped, several suggestions have led to
190 improvements in the code for RNG's I proposed for
191 use in C. (See the thread "Random numbers for C: Some
192 suggestions" in previous postings.) The improved code
195 A question of copyright has also been raised. Unlike
196 DIEHARD, there is no copyright on the code below. You
197 are free to use it in any way you want, but you may
198 wish to acknowledge the source, as a courtesy.
200 "There is no copyright on the code below." included the original
203 /* We use three KISS random number generators, with different
205 As a matter of Quality of Implementation, the random numbers
206 we generate for different REAL kinds, starting from the same
207 seed, are always the same up to the precision of these types.
208 We do this by using three generators with different seeds, the
209 first one always for the most significant bits, the second one
210 for bits 33..64 (if present in the REAL kind), and the third one
211 (called twice) for REAL(16). */
213 #define GFC_SL(k, n) ((k)^((k)<<(n)))
214 #define GFC_SR(k, n) ((k)^((k)>>(n)))
216 /* Reference for the seed:
217 From: "George Marsaglia" <g...@stat.fsu.edu>
219 Message-ID: <e7CcnWxczriWssCjXTWc3A@comcast.com>
221 The KISS RNG uses four seeds, x, y, z, c,
222 with 0<=x<2^32, 0<y<2^32, 0<=z<2^32, 0<=c<698769069
223 except that the two pairs
224 z=0,c=0 and z=2^32-1,c=698769068
225 should be avoided. */
227 /* Any modifications to the seeds that change kiss_size below need to be
228 reflected in check.c (gfc_check_random_seed) to enable correct
229 compile-time checking of PUT size for the RANDOM_SEED intrinsic. */
231 #define KISS_DEFAULT_SEED_1 123456789, 362436069, 521288629, 316191069
232 #define KISS_DEFAULT_SEED_2 987654321, 458629013, 582859209, 438195021
233 #ifdef HAVE_GFC_REAL_16
234 #define KISS_DEFAULT_SEED_3 573658661, 185639104, 582619469, 296736107
237 static GFC_UINTEGER_4 kiss_seed
[] = {
240 #ifdef HAVE_GFC_REAL_16
245 static GFC_UINTEGER_4 kiss_default_seed
[] = {
248 #ifdef HAVE_GFC_REAL_16
253 static const GFC_INTEGER_4 kiss_size
= sizeof(kiss_seed
)/sizeof(kiss_seed
[0]);
255 static GFC_UINTEGER_4
* const kiss_seed_1
= kiss_seed
;
256 static GFC_UINTEGER_4
* const kiss_seed_2
= kiss_seed
+ 4;
258 #ifdef HAVE_GFC_REAL_16
259 static GFC_UINTEGER_4
* const kiss_seed_3
= kiss_seed
+ 8;
262 /* kiss_random_kernel() returns an integer value in the range of
263 (0, GFC_UINTEGER_4_HUGE]. The distribution of pseudorandom numbers
264 should be uniform. */
266 static GFC_UINTEGER_4
267 kiss_random_kernel(GFC_UINTEGER_4
* seed
)
271 seed
[0] = 69069 * seed
[0] + 1327217885;
272 seed
[1] = GFC_SL(GFC_SR(GFC_SL(seed
[1],13),17),5);
273 seed
[2] = 18000 * (seed
[2] & 65535) + (seed
[2] >> 16);
274 seed
[3] = 30903 * (seed
[3] & 65535) + (seed
[3] >> 16);
275 kiss
= seed
[0] + seed
[1] + (seed
[2] << 16) + seed
[3];
280 /* This function produces a REAL(4) value from the uniform distribution
284 random_r4 (GFC_REAL_4
*x
)
288 __gthread_mutex_lock (&random_lock
);
289 kiss
= kiss_random_kernel (kiss_seed_1
);
291 __gthread_mutex_unlock (&random_lock
);
295 /* This function produces a REAL(8) value from the uniform distribution
299 random_r8 (GFC_REAL_8
*x
)
303 __gthread_mutex_lock (&random_lock
);
304 kiss
= ((GFC_UINTEGER_8
) kiss_random_kernel (kiss_seed_1
)) << 32;
305 kiss
+= kiss_random_kernel (kiss_seed_2
);
307 __gthread_mutex_unlock (&random_lock
);
311 #ifdef HAVE_GFC_REAL_10
313 /* This function produces a REAL(10) value from the uniform distribution
317 random_r10 (GFC_REAL_10
*x
)
321 __gthread_mutex_lock (&random_lock
);
322 kiss
= ((GFC_UINTEGER_8
) kiss_random_kernel (kiss_seed_1
)) << 32;
323 kiss
+= kiss_random_kernel (kiss_seed_2
);
324 rnumber_10 (x
, kiss
);
325 __gthread_mutex_unlock (&random_lock
);
331 /* This function produces a REAL(16) value from the uniform distribution
334 #ifdef HAVE_GFC_REAL_16
337 random_r16 (GFC_REAL_16
*x
)
339 GFC_UINTEGER_8 kiss1
, kiss2
;
341 __gthread_mutex_lock (&random_lock
);
342 kiss1
= ((GFC_UINTEGER_8
) kiss_random_kernel (kiss_seed_1
)) << 32;
343 kiss1
+= kiss_random_kernel (kiss_seed_2
);
345 kiss2
= ((GFC_UINTEGER_8
) kiss_random_kernel (kiss_seed_3
)) << 32;
346 kiss2
+= kiss_random_kernel (kiss_seed_3
);
348 rnumber_16 (x
, kiss1
, kiss2
);
349 __gthread_mutex_unlock (&random_lock
);
355 /* This function fills a REAL(4) array with values from the uniform
356 distribution with range [0,1). */
359 arandom_r4 (gfc_array_r4
*x
)
361 index_type count
[GFC_MAX_DIMENSIONS
];
362 index_type extent
[GFC_MAX_DIMENSIONS
];
363 index_type stride
[GFC_MAX_DIMENSIONS
];
372 dim
= GFC_DESCRIPTOR_RANK (x
);
374 for (n
= 0; n
< dim
; n
++)
377 stride
[n
] = x
->dim
[n
].stride
;
378 extent
[n
] = x
->dim
[n
].ubound
+ 1 - x
->dim
[n
].lbound
;
385 __gthread_mutex_lock (&random_lock
);
389 /* random_r4 (dest); */
390 kiss
= kiss_random_kernel (kiss_seed_1
);
391 rnumber_4 (dest
, kiss
);
393 /* Advance to the next element. */
396 /* Advance to the next source element. */
398 while (count
[n
] == extent
[n
])
400 /* When we get to the end of a dimension, reset it and increment
401 the next dimension. */
403 /* We could precalculate these products, but this is a less
404 frequently used path so probably not worth it. */
405 dest
-= stride
[n
] * extent
[n
];
419 __gthread_mutex_unlock (&random_lock
);
422 /* This function fills a REAL(8) array with values from the uniform
423 distribution with range [0,1). */
426 arandom_r8 (gfc_array_r8
*x
)
428 index_type count
[GFC_MAX_DIMENSIONS
];
429 index_type extent
[GFC_MAX_DIMENSIONS
];
430 index_type stride
[GFC_MAX_DIMENSIONS
];
439 dim
= GFC_DESCRIPTOR_RANK (x
);
441 for (n
= 0; n
< dim
; n
++)
444 stride
[n
] = x
->dim
[n
].stride
;
445 extent
[n
] = x
->dim
[n
].ubound
+ 1 - x
->dim
[n
].lbound
;
452 __gthread_mutex_lock (&random_lock
);
456 /* random_r8 (dest); */
457 kiss
= ((GFC_UINTEGER_8
) kiss_random_kernel (kiss_seed_1
)) << 32;
458 kiss
+= kiss_random_kernel (kiss_seed_2
);
459 rnumber_8 (dest
, kiss
);
461 /* Advance to the next element. */
464 /* Advance to the next source element. */
466 while (count
[n
] == extent
[n
])
468 /* When we get to the end of a dimension, reset it and increment
469 the next dimension. */
471 /* We could precalculate these products, but this is a less
472 frequently used path so probably not worth it. */
473 dest
-= stride
[n
] * extent
[n
];
487 __gthread_mutex_unlock (&random_lock
);
490 #ifdef HAVE_GFC_REAL_10
492 /* This function fills a REAL(10) array with values from the uniform
493 distribution with range [0,1). */
496 arandom_r10 (gfc_array_r10
*x
)
498 index_type count
[GFC_MAX_DIMENSIONS
];
499 index_type extent
[GFC_MAX_DIMENSIONS
];
500 index_type stride
[GFC_MAX_DIMENSIONS
];
509 dim
= GFC_DESCRIPTOR_RANK (x
);
511 for (n
= 0; n
< dim
; n
++)
514 stride
[n
] = x
->dim
[n
].stride
;
515 extent
[n
] = x
->dim
[n
].ubound
+ 1 - x
->dim
[n
].lbound
;
522 __gthread_mutex_lock (&random_lock
);
526 /* random_r10 (dest); */
527 kiss
= ((GFC_UINTEGER_8
) kiss_random_kernel (kiss_seed_1
)) << 32;
528 kiss
+= kiss_random_kernel (kiss_seed_2
);
529 rnumber_10 (dest
, kiss
);
531 /* Advance to the next element. */
534 /* Advance to the next source element. */
536 while (count
[n
] == extent
[n
])
538 /* When we get to the end of a dimension, reset it and increment
539 the next dimension. */
541 /* We could precalculate these products, but this is a less
542 frequently used path so probably not worth it. */
543 dest
-= stride
[n
] * extent
[n
];
557 __gthread_mutex_unlock (&random_lock
);
562 #ifdef HAVE_GFC_REAL_16
564 /* This function fills a REAL(16) array with values from the uniform
565 distribution with range [0,1). */
568 arandom_r16 (gfc_array_r16
*x
)
570 index_type count
[GFC_MAX_DIMENSIONS
];
571 index_type extent
[GFC_MAX_DIMENSIONS
];
572 index_type stride
[GFC_MAX_DIMENSIONS
];
576 GFC_UINTEGER_8 kiss1
, kiss2
;
581 dim
= GFC_DESCRIPTOR_RANK (x
);
583 for (n
= 0; n
< dim
; n
++)
586 stride
[n
] = x
->dim
[n
].stride
;
587 extent
[n
] = x
->dim
[n
].ubound
+ 1 - x
->dim
[n
].lbound
;
594 __gthread_mutex_lock (&random_lock
);
598 /* random_r16 (dest); */
599 kiss1
= ((GFC_UINTEGER_8
) kiss_random_kernel (kiss_seed_1
)) << 32;
600 kiss1
+= kiss_random_kernel (kiss_seed_2
);
602 kiss2
= ((GFC_UINTEGER_8
) kiss_random_kernel (kiss_seed_3
)) << 32;
603 kiss2
+= kiss_random_kernel (kiss_seed_3
);
605 rnumber_16 (dest
, kiss1
, kiss2
);
607 /* Advance to the next element. */
610 /* Advance to the next source element. */
612 while (count
[n
] == extent
[n
])
614 /* When we get to the end of a dimension, reset it and increment
615 the next dimension. */
617 /* We could precalculate these products, but this is a less
618 frequently used path so probably not worth it. */
619 dest
-= stride
[n
] * extent
[n
];
633 __gthread_mutex_unlock (&random_lock
);
641 scramble_seed (unsigned char *dest
, unsigned char *src
, int size
)
645 for (i
= 0; i
< size
; i
++)
646 dest
[(i
% 2) * (size
/ 2) + i
/ 2] = src
[i
];
651 unscramble_seed (unsigned char *dest
, unsigned char *src
, int size
)
655 for (i
= 0; i
< size
; i
++)
656 dest
[i
] = src
[(i
% 2) * (size
/ 2) + i
/ 2];
661 /* random_seed is used to seed the PRNG with either a default
662 set of seeds or user specified set of seeds. random_seed
663 must be called with no argument or exactly one argument. */
666 random_seed_i4 (GFC_INTEGER_4
*size
, gfc_array_i4
*put
, gfc_array_i4
*get
)
669 unsigned char seed
[4*kiss_size
];
671 __gthread_mutex_lock (&random_lock
);
673 /* Check that we only have one argument present. */
674 if ((size
? 1 : 0) + (put
? 1 : 0) + (get
? 1 : 0) > 1)
675 runtime_error ("RANDOM_SEED should have at most one argument present.");
677 /* From the standard: "If no argument is present, the processor assigns
678 a processor-dependent value to the seed." */
679 if (size
== NULL
&& put
== NULL
&& get
== NULL
)
680 for (i
= 0; i
< kiss_size
; i
++)
681 kiss_seed
[i
] = kiss_default_seed
[i
];
688 /* If the rank of the array is not 1, abort. */
689 if (GFC_DESCRIPTOR_RANK (put
) != 1)
690 runtime_error ("Array rank of PUT is not 1.");
692 /* If the array is too small, abort. */
693 if (((put
->dim
[0].ubound
+ 1 - put
->dim
[0].lbound
)) < kiss_size
)
694 runtime_error ("Array size of PUT is too small.");
696 /* We copy the seed given by the user. */
697 for (i
= 0; i
< kiss_size
; i
++)
698 memcpy (seed
+ i
* sizeof(GFC_UINTEGER_4
),
699 &(put
->data
[(kiss_size
- 1 - i
) * put
->dim
[0].stride
]),
700 sizeof(GFC_UINTEGER_4
));
702 /* We put it after scrambling the bytes, to paper around users who
703 provide seeds with quality only in the lower or upper part. */
704 scramble_seed ((unsigned char *) kiss_seed
, seed
, 4*kiss_size
);
707 /* Return the seed to GET data. */
710 /* If the rank of the array is not 1, abort. */
711 if (GFC_DESCRIPTOR_RANK (get
) != 1)
712 runtime_error ("Array rank of GET is not 1.");
714 /* If the array is too small, abort. */
715 if (((get
->dim
[0].ubound
+ 1 - get
->dim
[0].lbound
)) < kiss_size
)
716 runtime_error ("Array size of GET is too small.");
718 /* Unscramble the seed. */
719 unscramble_seed (seed
, (unsigned char *) kiss_seed
, 4*kiss_size
);
721 /* Then copy it back to the user variable. */
722 for (i
= 0; i
< kiss_size
; i
++)
723 memcpy (&(get
->data
[(kiss_size
- 1 - i
) * get
->dim
[0].stride
]),
724 seed
+ i
* sizeof(GFC_UINTEGER_4
),
725 sizeof(GFC_UINTEGER_4
));
728 __gthread_mutex_unlock (&random_lock
);
730 iexport(random_seed_i4
);
734 random_seed_i8 (GFC_INTEGER_8
*size
, gfc_array_i8
*put
, gfc_array_i8
*get
)
738 __gthread_mutex_lock (&random_lock
);
740 /* Check that we only have one argument present. */
741 if ((size
? 1 : 0) + (put
? 1 : 0) + (get
? 1 : 0) > 1)
742 runtime_error ("RANDOM_SEED should have at most one argument present.");
744 /* From the standard: "If no argument is present, the processor assigns
745 a processor-dependent value to the seed." */
746 if (size
== NULL
&& put
== NULL
&& get
== NULL
)
747 for (i
= 0; i
< kiss_size
; i
++)
748 kiss_seed
[i
] = kiss_default_seed
[i
];
751 *size
= kiss_size
/ 2;
755 /* If the rank of the array is not 1, abort. */
756 if (GFC_DESCRIPTOR_RANK (put
) != 1)
757 runtime_error ("Array rank of PUT is not 1.");
759 /* If the array is too small, abort. */
760 if (((put
->dim
[0].ubound
+ 1 - put
->dim
[0].lbound
)) < kiss_size
/ 2)
761 runtime_error ("Array size of PUT is too small.");
763 /* This code now should do correct strides. */
764 for (i
= 0; i
< kiss_size
/ 2; i
++)
765 memcpy (&kiss_seed
[2*i
], &(put
->data
[i
* put
->dim
[0].stride
]),
766 sizeof (GFC_UINTEGER_8
));
769 /* Return the seed to GET data. */
772 /* If the rank of the array is not 1, abort. */
773 if (GFC_DESCRIPTOR_RANK (get
) != 1)
774 runtime_error ("Array rank of GET is not 1.");
776 /* If the array is too small, abort. */
777 if (((get
->dim
[0].ubound
+ 1 - get
->dim
[0].lbound
)) < kiss_size
/ 2)
778 runtime_error ("Array size of GET is too small.");
780 /* This code now should do correct strides. */
781 for (i
= 0; i
< kiss_size
/ 2; i
++)
782 memcpy (&(get
->data
[i
* get
->dim
[0].stride
]), &kiss_seed
[2*i
],
783 sizeof (GFC_UINTEGER_8
));
786 __gthread_mutex_unlock (&random_lock
);
788 iexport(random_seed_i8
);
791 #ifndef __GTHREAD_MUTEX_INIT
792 static void __attribute__((constructor
))
795 __GTHREAD_MUTEX_INIT_FUNCTION (&random_lock
);