+#pragma once
/**
- * @file dSFMT_bcc.h
+ * @file dSFMT.h
*
* @brief double precision SIMD oriented Fast Mersenne Twister(dSFMT)
* pseudorandom number generator based on IEEE 754 format.
*
* Copyright (C) 2007, 2008 Mutsuo Saito, Makoto Matsumoto and
* Hiroshima University. All rights reserved.
+ * Copyright (C) 2012 Mutsuo Saito, Makoto Matsumoto,
+ * Hiroshima University and The University of Tokyo.
+ * All rights reserved.
*
* The new BSD License is applied to this software.
* see LICENSE.txt
#ifndef DSFMT_H
#define DSFMT_H
+#if defined(__cplusplus)
+extern "C" {
+#endif
#include <stdio.h>
#include <assert.h>
/*-----------------
BASIC DEFINITIONS
-----------------*/
-/** Mersenne Exponent. The period of the sequence
+/* Mersenne Exponent. The period of the sequence
* is a multiple of 2^DSFMT_MEXP-1.
* #define DSFMT_MEXP 19937 */
/** DSFMT generator has an internal state array of 128-bit integers,
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
# include <inttypes.h>
-#elif defined(_MSC_VER)
-# if !defined(DSFMT_UINT32_DEFINED) && !defined(SFMT_UINT32_DEFINED)
-typedef unsigned int uint32_t;
-typedef unsigned long long uint64_t;
-# define DSFMT_UINT32_DEFINED
-# if !defined(inline)
-# define inline __inline
-# endif
-# endif
-#elif defined(__BORLANDC__)
+#elif defined(_MSC_VER) || defined(__BORLANDC__)
# if !defined(DSFMT_UINT32_DEFINED) && !defined(SFMT_UINT32_DEFINED)
typedef unsigned int uint32_t;
typedef unsigned __int64 uint64_t;
+# ifndef UINT64_C
+# define UINT64_C(v) (v ## ui64)
+# endif
# define DSFMT_UINT32_DEFINED
-# if !defined(inline)
+# if !defined(inline) && !defined(__cplusplus)
# define inline __inline
# endif
# endif
#else
# include <inttypes.h>
-# if !defined(inline)
+# if !defined(inline) && !defined(__cplusplus)
# if defined(__GNUC__)
# define inline __inline__
# else
#endif
#ifndef UINT64_C
-# if defined(__BORLANDC__)
-# define UINT64_C(v) (v ## UI64)
-# else
-# define UINT64_C(v) (v ## ULL)
-# endif
+# define UINT64_C(v) (v ## ULL)
#endif
-
/*------------------------------------------
128-bit SIMD like data type for standard C
------------------------------------------*/
/** dsfmt mexp for check */
extern const int dsfmt_global_mexp;
-#ifdef _cplusplus
-extern "C" {
-#endif
-
void dsfmt_gen_rand_all(dsfmt_t *dsfmt);
void dsfmt_fill_array_open_close(dsfmt_t *dsfmt, double array[], int size);
void dsfmt_fill_array_close_open(dsfmt_t *dsfmt, double array[], int size);
void dsfmt_fill_array_close1_open2(dsfmt_t *dsfmt, double array[], int size);
void dsfmt_chk_init_gen_rand(dsfmt_t *dsfmt, uint32_t seed, int mexp);
void dsfmt_chk_init_by_array(dsfmt_t *dsfmt, uint32_t init_key[],
- int key_length, int mexp);
+ int key_length, int mexp);
const char *dsfmt_get_idstring(void);
int dsfmt_get_min_array_size(void);
# define DSFMT_PRE_INLINE inline static
# define DSFMT_PST_INLINE __attribute__((always_inline))
#elif defined(_MSC_VER) && _MSC_VER >= 1200
-# define DSFMT_PRE_INLINE __forceinline
+# define DSFMT_PRE_INLINE __forceinline static
# define DSFMT_PST_INLINE
#else
# define DSFMT_PRE_INLINE inline static
# define DSFMT_PST_INLINE
#endif
+DSFMT_PRE_INLINE uint32_t dsfmt_genrand_uint32(dsfmt_t *dsfmt) DSFMT_PST_INLINE;
DSFMT_PRE_INLINE double dsfmt_genrand_close1_open2(dsfmt_t *dsfmt)
DSFMT_PST_INLINE;
DSFMT_PRE_INLINE double dsfmt_genrand_close_open(dsfmt_t *dsfmt)
DSFMT_PST_INLINE;
DSFMT_PRE_INLINE double dsfmt_genrand_open_open(dsfmt_t *dsfmt)
DSFMT_PST_INLINE;
+DSFMT_PRE_INLINE uint32_t dsfmt_gv_genrand_uint32(void) DSFMT_PST_INLINE;
DSFMT_PRE_INLINE double dsfmt_gv_genrand_close1_open2(void) DSFMT_PST_INLINE;
DSFMT_PRE_INLINE double dsfmt_gv_genrand_close_open(void) DSFMT_PST_INLINE;
DSFMT_PRE_INLINE double dsfmt_gv_genrand_open_close(void) DSFMT_PST_INLINE;
DSFMT_PST_INLINE;
DSFMT_PRE_INLINE void dsfmt_gv_init_gen_rand(uint32_t seed) DSFMT_PST_INLINE;
DSFMT_PRE_INLINE void dsfmt_gv_init_by_array(uint32_t init_key[],
- int key_length) DSFMT_PST_INLINE;
+ int key_length) DSFMT_PST_INLINE;
DSFMT_PRE_INLINE void dsfmt_init_gen_rand(dsfmt_t *dsfmt, uint32_t seed)
DSFMT_PST_INLINE;
DSFMT_PRE_INLINE void dsfmt_init_by_array(dsfmt_t *dsfmt, uint32_t init_key[],
- int key_length) DSFMT_PST_INLINE;
+ int key_length) DSFMT_PST_INLINE;
+
+/**
+ * This function generates and returns unsigned 32-bit integer.
+ * This is slower than SFMT, only for convenience usage.
+ * dsfmt_init_gen_rand() or dsfmt_init_by_array() must be called
+ * before this function.
+ * @param dsfmt dsfmt internal state date
+ * @return double precision floating point pseudorandom number
+ */
+inline static uint32_t dsfmt_genrand_uint32(dsfmt_t *dsfmt) {
+ uint32_t r;
+ uint64_t *psfmt64 = &dsfmt->status[0].u[0];
+
+ if (dsfmt->idx >= DSFMT_N64) {
+ dsfmt_gen_rand_all(dsfmt);
+ dsfmt->idx = 0;
+ }
+ r = psfmt64[dsfmt->idx++] & 0xffffffffU;
+ return r;
+}
/**
* This function generates and returns double precision pseudorandom
double *psfmt64 = &dsfmt->status[0].d[0];
if (dsfmt->idx >= DSFMT_N64) {
- dsfmt_gen_rand_all(dsfmt);
- dsfmt->idx = 0;
+ dsfmt_gen_rand_all(dsfmt);
+ dsfmt->idx = 0;
}
r = psfmt64[dsfmt->idx++];
return r;
}
/**
+ * This function generates and returns unsigned 32-bit integer.
+ * This is slower than SFMT, only for convenience usage.
+ * dsfmt_gv_init_gen_rand() or dsfmt_gv_init_by_array() must be called
+ * before this function. This function uses \b global variables.
+ * @return double precision floating point pseudorandom number
+ */
+inline static uint32_t dsfmt_gv_genrand_uint32(void) {
+ return dsfmt_genrand_uint32(&dsfmt_global_data);
+}
+
+/**
* This function generates and returns double precision pseudorandom
- * number which distributes uniformly in the range [1, 2). This is
- * the primitive and faster than generating numbers in other ranges.
+ * number which distributes uniformly in the range [1, 2).
* dsfmt_gv_init_gen_rand() or dsfmt_gv_init_by_array() must be called
* before this function. This function uses \b global variables.
* @return double precision floating point pseudorandom number
inline static double dsfmt_genrand_open_open(dsfmt_t *dsfmt) {
double *dsfmt64 = &dsfmt->status[0].d[0];
union {
- double d;
- uint64_t u;
+ double d;
+ uint64_t u;
} r;
if (dsfmt->idx >= DSFMT_N64) {
- dsfmt_gen_rand_all(dsfmt);
- dsfmt->idx = 0;
+ dsfmt_gen_rand_all(dsfmt);
+ dsfmt->idx = 0;
}
r.d = dsfmt64[dsfmt->idx++];
r.u |= 1;
* @param key_length the length of init_key.
*/
inline static void dsfmt_init_by_array(dsfmt_t *dsfmt, uint32_t init_key[],
- int key_length) {
+ int key_length) {
dsfmt_chk_init_by_array(dsfmt, init_key, key_length, DSFMT_MEXP);
}
}
#endif /* DSFMT_DO_NOT_USE_OLD_NAMES */
-#ifdef _cplusplus
+#if defined(__cplusplus)
}
#endif