Geant4-11
Functions
ranlux_lcg.h File Reference
#include "helpers.h"
#include <cstdint>

Go to the source code of this file.

Functions

static void to_lcg (const uint64_t *ranlux, unsigned c, uint64_t *lcg)
 
static void to_ranlux (const uint64_t *lcg, uint64_t *ranlux, unsigned &c_out)
 

Function Documentation

◆ to_lcg()

static void to_lcg ( const uint64_t *  ranlux,
unsigned  c,
uint64_t *  lcg 
)
static

Convert RANLUX numbers to an LCG state

Parameters
[in]ranluxthe RANLUX numbers as 576 bits
[out]lcgthe 576 bits of the LCG state, smaller than m
[in]cthe carry bit of the RANLUX state

$ m = 2^{576} - 2^{240} + 1 $

Definition at line 24 of file ranlux_lcg.h.

24 {
25 unsigned carry = 0;
26 // Subtract the final 240 bits.
27 for (int i = 0; i < 9; i++) {
28 uint64_t ranlux_i = ranlux[i];
29 uint64_t lcg_i = sub_overflow(ranlux_i, carry, carry);
30
31 uint64_t bits = 0;
32 if (i < 4) {
33 bits += ranlux[i + 5] >> 16;
34 if (i < 3) {
35 bits += ranlux[i + 6] << 48;
36 }
37 }
38 lcg_i = sub_carry(lcg_i, bits, carry);
39 lcg[i] = lcg_i;
40 }
41
42 // Add and propagate the carry bit.
43 for (int i = 0; i < 9; i++) {
44 lcg[i] = add_overflow(lcg[i], c, c);
45 }
46}
static uint64_t sub_overflow(uint64_t a, uint64_t b, unsigned &overflow)
Compute a - b and set overflow accordingly.
Definition: helpers.h:34
static uint64_t sub_carry(uint64_t a, uint64_t b, unsigned &carry)
Compute a - b and increment carry if there was an overflow.
Definition: helpers.h:42
static uint64_t add_overflow(uint64_t a, uint64_t b, unsigned &overflow)
Compute a + b and set overflow accordingly.
Definition: helpers.h:16

References add_overflow(), sub_carry(), and sub_overflow().

Referenced by CLHEP::RanluxppEngine::advance(), and CLHEP::RanluxppEngine::skip().

◆ to_ranlux()

static void to_ranlux ( const uint64_t *  lcg,
uint64_t *  ranlux,
unsigned &  c_out 
)
static

Convert an LCG state to RANLUX numbers

Parameters
[in]lcgthe 576 bits of the LCG state, must be smaller than m
[out]ranluxthe RANLUX numbers as 576 bits
[out]cthe carry bit of the RANLUX state

$ m = 2^{576} - 2^{240} + 1 $

Definition at line 55 of file ranlux_lcg.h.

55 {
56 uint64_t r[9] = {0};
57 int64_t c = compute_r(lcg, r);
58
59 // ranlux = t1 + t2 + c
60 unsigned carry = 0;
61 for (int i = 0; i < 9; i++) {
62 uint64_t in_i = lcg[i];
63 uint64_t tmp_i = add_overflow(in_i, carry, carry);
64
65 uint64_t bits = 0;
66 if (i < 4) {
67 bits += lcg[i + 5] >> 16;
68 if (i < 3) {
69 bits += lcg[i + 6] << 48;
70 }
71 }
72 tmp_i = add_carry(tmp_i, bits, carry);
73 ranlux[i] = tmp_i;
74 }
75
76 // If c = -1, we need to add it to all components.
77 int64_t c1 = c >> 1;
78 ranlux[0] = add_overflow(ranlux[0], c, carry);
79 for (int i = 1; i < 9; i++) {
80 uint64_t ranlux_i = ranlux[i];
81 ranlux_i = add_overflow(ranlux_i, carry, carry);
82 ranlux_i = add_carry(ranlux_i, c1, carry);
83 }
84
85 c_out = carry;
86}
static uint64_t add_carry(uint64_t a, uint64_t b, unsigned &carry)
Compute a + b and increment carry if there was an overflow.
Definition: helpers.h:24
static int64_t compute_r(const uint64_t *upper, uint64_t *r)
Definition: helpers.h:58

References add_carry(), add_overflow(), and compute_r().

Referenced by CLHEP::RanluxppEngine::advance(), CLHEP::RanluxppEngine::setSeed(), and CLHEP::RanluxppEngine::skip().