Random: add seed parameter
Add a parameter (at configuration) that modifies the random number generated.
I am simply shifting the ID (and/or timeinteger) by a constant number.
Should I add a warning when this shift is non zero?
You can compile the code with the following way: ./configure --with-random-shift-time=12 --with-random-shift-id=122
Merge request reports
Activity
What do you think about that? I am only shifting the buffer by a given number of bits. My main concern is that we only have 31 different random seeds, but I am not expecting to run a large number of simulation with different seeds.
/* Start by packing the state into a sequence of 16-bit seeds for rand_r. */ uint16_t buff[9]; id += type; memcpy(&buff[0], &id, 8); memcpy(&buff[4], &ti_current, 8); /* The inputs give 16 bytes of state, but we need a multiple of 6 for the calls to erand48(), so we add an additional aribrary constant two-byte value to get 18 bytes of state. */ buff[8] = 6178; /* Shift the bits */ int shift = 5; // TODO define it in the configure.ac uint16_t tmp = shift == 0 ? 0 : *buff >> (8 * sizeof(uint16_t) - shift); *buff = (shift == 8 * sizeof(uint16_t)) ? 0 : *buff << shift; *buff = *buff + tmp; /* Shuffle the buffer values, this will be our source of entropy for the erand48 generator. */ uint32_t seed16 = 0; for (int k = 0; k < 9; k++) { seed16 ^= buff[k]; inl_rand_r(&seed16); } for (int k = 0; k < 9; k++) buff[k] ^= inl_rand_r(&seed16) & 0xffff; /* Do three steps of erand48() over the state generated previously. */ uint16_t seed48[3] = {0, 0, 0}; for (int k = 0; k < 3; k++) { for (int j = 0; j < 3; j++) seed48[j] ^= buff[3 * k + j]; inl_erand48(seed48); } /* Generate one final value, this is our output. */ return inl_erand48(seed48);
Diving in here uninvited :)
So first of all, you're not shifting, you're rotating. I think the canonical way to do this is
const int safe_shift = shift & (1 - (1 << (8 * sizeof(buff[0]))); buff[0] = (buff[0] << safe_shift) | (buff[0] >> (8 * sizeof(buff[0]) - safe_shift));
The
safe_shift
is just making sure we don't shift by more bits than we have (assuming this is a power of two).Instead of rotating, though, you could also xor (
^
) with an arbitrary value. That's by far not as dangerous as adding a value.Thanks for diving in.
So you mean just doing a
*buff ^= RANDOM_SEED
?Edited by Loic HausammannThere is two different tests about the random number generator in the repository. Is it enough or do you need additional tests?
Edited by Loic Hausammann@lhausammann, yes, essentially that. Since the xor just flips bits, there's no way it can reduce entropy (bold statement).
No need to change the signature of the function. The configuration help string should say that this is a short int and ideally check somewhere that it is.
- Can you check that it does indeed pass the tests we have for a few seed values?
- Should we write the seed in the snapshots?
- Can the online documentation be amended?
Edited by Matthieu Schaller- Resolved by Loic Hausammann
- Resolved by Loic Hausammann