random_well512a_simd/WELL512a.cpp

64 lines
2.0 KiB
C++

/*************************************************************************
Copyright: Francois Panneton and Pierre L'Ecuyer, Université de Montréal
Makoto Matsumoto, Hiroshima University
Notice: This code can be used freely for personal, academic,
or non-commercial purposes. For commercial purposes,
please contact P. L'Ecuyer at: lecuyer@iro.UMontreal.ca
This code can also be used under the terms of the GNU General Public
License as published by the Free Software Foundation, either version 3
of the License, or any later version. See the GPL licence at URL
http://www.gnu.org/licenses
**************************************************************************/
#include "WELL512a.h"
#define W 32
#define R 16
#define P 0
#define M1 13
#define M2 9
#define M3 5
#define MAT0POS(t,v) (v^(v>>t))
#define MAT0NEG(t,v) (v^(v<<(-(t))))
#define MAT3NEG(t,v) (v<<(-(t)))
#define MAT4NEG(t,b,v) (v ^ ((v<<(-(t))) & b))
#define V0 STATE[state_i ]
#define VM1 STATE[(state_i+M1) & 0x0000000fU]
#define VM2 STATE[(state_i+M2) & 0x0000000fU]
#define VM3 STATE[(state_i+M3) & 0x0000000fU]
#define VRm1 STATE[(state_i+15) & 0x0000000fU]
#define VRm2 STATE[(state_i+14) & 0x0000000fU]
#define newV0 STATE[(state_i+15) & 0x0000000fU]
#define newV1 STATE[state_i ]
#define newVRm1 STATE[(state_i+14) & 0x0000000fU]
#define FACT 2.32830643653869628906e-10
static unsigned int state_i = 0;
static unsigned int STATE[R];
static unsigned int z0, z1, z2;
void InitWELLRNG512a (unsigned int *init)
{
int j;
state_i = 0;
for (j = 0; j < R; j++)
STATE[j] = init[j];
}
double WELLRNG512a (void)
{
z0 = VRm1;
z1 = MAT0NEG(-16, V0) ^ MAT0NEG(-15, VM1);
z2 = MAT0POS(11, VM2);
newV1 = z1 ^ z2;
newV0 = MAT0NEG(-2, z0) ^ MAT0NEG(-18, z1) ^ MAT3NEG(-28, z2) ^ MAT4NEG(-5, 0xda442d24U, newV1);
state_i = (state_i + 15) & 0x0000000fU;
return ((double) STATE[state_i]) * FACT;
}