forked from MersenneTwister-Lab/TinyMT
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjump64.c
93 lines (87 loc) · 2.49 KB
/
jump64.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/**
* @file jump64.c
*
* @brief jump function for tinymt64
*
* Jump function changes the internal state vector of tinymt64
* pseudorandom number generator to the state which is N step after
* current state, as if it generated N random numbers. The jump is
* much faster than generating N numbers, when N is large.
*
* @author Mutsuo Saito (Hiroshima University)
* @author Makoto Matsumoto (The University of Tokyo)
*
* Copyright (C) 2011, 2012 Mutsuo Saito, Makoto Matsumoto,
* Hiroshima University and University of Tokyo.
* All rights reserved.
*
* The 3-clause BSD License is applied to this software, see
* LICENSE.txt
*/
#include "jump64.h"
#include <stdio.h>
static void tinymt64_add(tinymt64_t *dest, const tinymt64_t *src);
/**
* Addition of internal state as F<sub>2</sub> vector.
* @param dest destination
* @param src source
*/
static void tinymt64_add(tinymt64_t *dest, const tinymt64_t *src)
{
dest->status[0] ^= src->status[0];
dest->status[1] ^= src->status[1];
}
/**
* jump function
* @param tiny tinymt64 structure, overwritten by new state after calling
* this function.
* @param lower_step lower bit of 128-bit integer
* @param upper_step upper bit of 128-bit integer
* @param poly_str string of the characteristic polynomial generated by
* tinymt32dc
*/void tinymt64_jump(tinymt64_t *tiny,
uint64_t lower_step,
uint64_t upper_step,
const char * poly_str)
{
f2_polynomial jump_poly;
calculate_jump_polynomial(
&jump_poly, lower_step, upper_step, poly_str);
tinymt64_jump_by_polynomial(tiny, &jump_poly);
}
/**
* jump using the jump polynomial.
* This function is not as time consuming as calculating jump polynomial.
* This function can use multiple time for the tinymt64 structure.
* @param tiny tinymt64 structure, overwritten by new state after calling
* this function.
* @param jump_poly the jump polynomial calculated by
* tinymt64_calculate_jump_polynomial.
*/
void tinymt64_jump_by_polynomial(tinymt64_t *tiny,
f2_polynomial * jump_poly)
{
tinymt64_t work_z;
tinymt64_t * work = &work_z;
*work = *tiny;
for (int i = 0; i < 2; i++) {
work->status[i] = 0;
}
uint64_t x64 = jump_poly->ar[0];
for (int i = 0; i < 64; i++) {
if ((x64 & 1) != 0) {
tinymt64_add(work, tiny);
}
tinymt64_next_state(tiny);
x64 = x64 >> 1;
}
x64 = jump_poly->ar[1];
while (x64 != 0) {
if ((x64 & 1) != 0) {
tinymt64_add(work, tiny);
}
tinymt64_next_state(tiny);
x64 = x64 >> 1;
}
*tiny = *work;
}