Multiply-with-carry
The Multiply-with-Carry (short: MWC ) and its modified variant Complimentary-Multiply-with-Carry (short: CMWC ) are pseudo-random number generators , which were presented in 2003 by George Marsaglia .
properties
- Extremely long period (2 131086 for the CMWC with 16 kB status register).
- Delivers an evenly distributed bit sequence.
algorithm
The algorithm for the MWC is quite simple and can be described by two recurrence equations:
The result of the multiplication is divided into x
(the lower 32 bits) and the carry c
(the upper 31 bits).
Here stands for the i th generated number, a for a constant factor and b for the number base.
The constants a and b should be chosen so that is a prime number. Then the generator outputs for all non-trivial start values and a sequence with the period length .
example
Be , and as initial values , :
Sequence length:
n | |||
1 | - | 3 | 5 |
2 | 33 | 3 | 3 |
3 | 21st | 2 | 1 |
4th | 8th | 0 | 8th |
5 | 48 | 4th | 8th |
6th | 52 | 5 | 2 |
The MWC outputs the decimal fraction expansion of in reverse order .
Complimentary multiply-with-carry
In order to obtain a maximum period length, z. B. when using 32-bit integers for selected, as this makes maximum use of the range of values and at the same time can be calculated very quickly. With MWC generators, however, the period is reduced by half and it becomes more difficult to find suitable prime numbers.
These problems can be remedied by a small modification of the original algorithm, using as a recurrence equation
used.
initialization
The status register should be initialized with bits that are as random as possible and evenly distributed, i.e. about as many 1 as 0 bits. Otherwise the generator needs a "warm-up phase", i. H. A certain amount of random numbers has to be generated until the generator delivers uniformly distributed random numbers.
implementation
MWC
#include <stdint.h>
static uint32_t Q[1038];
static uint32_t c = 123;
uint32_t MWC1038() {
static uint32_t i = 1037;
uint64_t t;
t = (611376378ULL * Q[i]) + c;
c = t >> 32;
if (--i != 0)
return (Q[i] = t);
i = 1037;
return (Q[0] = t);
}
CMWC
#include <stdint.h>
static uint32_t Q[4096];
static uint32_t c = 123; /* 0 <= c < 18782 */
uint32_t CMWC() {
static uint32_t i = 4095;
uint64_t t;
uint32_t x;
i = (i + 1) & 4095;
t = (18782ULL * Q[i]) + c;
c = t >> 32;
x = t + c;
if (x < c) { ++x; ++c; }
Q[i] = 0xfffffffe - x;
return Q[i];
}
See also
literature
- G. Marsaglia: Random number generators . (PDF) In: Journal of Modern Applied Statistical Methods , V. 2, May 2003.
- G. Marsaglia: On the randomness of Pi and other decimal expansions . (PDF) Interstat, October 2005, # 5
Web links
- Statistical test library: TestU01
- F. Panneton, P. L'Ecuyer: Improved Long-Period Generators Base on Linear Recurrences Modulo 2 . (PDF; 301 kB).
- groups.google.com
- groups.google.com