Skip to content

Commit 118c3b6

Browse files
committed
REF: Refactor uint generators
Refactor uint generators so that they can be used more generally
1 parent 0a55ecb commit 118c3b6

File tree

1 file changed

+76
-72
lines changed

1 file changed

+76
-72
lines changed

randomstate/distributions.c

Lines changed: 76 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1401,32 +1401,82 @@ static inline uint64_t gen_mask(uint64_t max)
14011401
* Fills an array with cnt random npy_uint64 between off and off + rng
14021402
* inclusive. The numbers wrap if rng is sufficiently large.
14031403
*/
1404-
void random_bounded_uint64_fill(aug_state *state, uint64_t off, uint64_t rng, npy_intp cnt, uint64_t *out)
1405-
{
1406-
uint64_t val, mask;
1407-
npy_intp i;
14081404

1409-
if (rng == 0) {
1410-
for (i = 0; i < cnt; i++) {
1411-
out[i] = off;
1412-
}
1413-
return;
1414-
}
14151405

1416-
/* Smallest bit mask >= max */
1417-
mask = gen_mask(rng);
1406+
inline uint64_t random_bounded_uint64(aug_state *state, uint64_t off, uint64_t rng, uint64_t mask)
1407+
{
1408+
uint64_t val;
1409+
if (rng == 0)
1410+
return off;
14181411

14191412
if (rng <= 0xffffffffUL) {
1420-
for (i = 0; i < cnt; i++) {
1421-
while ((val = (random_uint32(state) & mask)) > rng);
1422-
out[i] = off + val;
1423-
}
1413+
while ((val = (random_uint32(state) & mask)) > rng);
14241414
}
14251415
else {
1426-
for (i = 0; i < cnt; i++) {
1427-
while ((val = (random_uint64(state) & mask)) > rng);
1428-
out[i] = off + val;
1416+
while ((val = (random_uint64(state) & mask)) > rng);
1417+
}
1418+
return off + val;
1419+
}
1420+
1421+
1422+
inline uint32_t random_bounded_uint32(aug_state *state, uint32_t off, uint32_t rng, uint32_t mask)
1423+
{
1424+
uint32_t val;
1425+
if (rng == 0)
1426+
return off;
1427+
1428+
while ((val = (random_uint32(state) & mask)) > rng);
1429+
return off + val;
1430+
}
1431+
1432+
inline uint16_t random_buffered_bounded_uint16(aug_state *state, uint16_t off, uint16_t rng, uint16_t mask, int *bcnt, uint32_t *buf)
1433+
{
1434+
uint16_t val;
1435+
if (rng == 0)
1436+
return off;
1437+
1438+
do {
1439+
if (!(bcnt[0])) {
1440+
buf[0] = random_uint32(state);
1441+
bcnt[0] = 1;
1442+
}
1443+
else {
1444+
buf[0] >>= 16;
1445+
bcnt[0] -= 1;
14291446
}
1447+
val = (uint16_t)buf[0] & mask;
1448+
} while (val > rng);
1449+
return off + val;
1450+
}
1451+
1452+
inline uint8_t random_buffered_bounded_uint8(aug_state *state, uint8_t off, uint8_t rng, uint8_t mask, int *bcnt, uint32_t *buf)
1453+
{
1454+
uint8_t val;
1455+
if (rng == 0)
1456+
return off;
1457+
do {
1458+
if (!(bcnt[0])) {
1459+
buf[0] = random_uint32(state);
1460+
bcnt[0] = 3;
1461+
}
1462+
else {
1463+
buf[0] >>= 8;
1464+
bcnt[0] -= 1;
1465+
}
1466+
val = (uint8_t)buf[0] & mask;
1467+
} while (val > rng);
1468+
return off + val;
1469+
}
1470+
1471+
void random_bounded_uint64_fill(aug_state *state, uint64_t off, uint64_t rng, npy_intp cnt, uint64_t *out)
1472+
{
1473+
uint64_t mask;
1474+
npy_intp i;
1475+
1476+
/* Smallest bit mask >= max */
1477+
mask = gen_mask(rng);
1478+
for (i = 0; i < cnt; i++) {
1479+
out[i] = random_bounded_uint64(state, off, rng, mask);
14301480
}
14311481
}
14321482

@@ -1437,22 +1487,13 @@ void random_bounded_uint64_fill(aug_state *state, uint64_t off, uint64_t rng, np
14371487
*/
14381488
void random_bounded_uint32_fill(aug_state *state, uint32_t off, uint32_t rng, npy_intp cnt, uint32_t *out)
14391489
{
1440-
uint32_t val, mask = rng;
1490+
uint32_t val, mask;
14411491
npy_intp i;
14421492

1443-
if (rng == 0) {
1444-
for (i = 0; i < cnt; i++) {
1445-
out[i] = off;
1446-
}
1447-
return;
1448-
}
1449-
14501493
/* Smallest bit mask >= max */
14511494
mask = (uint32_t)gen_mask(rng);
1452-
14531495
for (i = 0; i < cnt; i++) {
1454-
while ((val = (random_uint32(state) & mask)) > rng);
1455-
out[i] = off + val;
1496+
out[i] = random_bounded_uint32(state, off, rng, mask);
14561497
}
14571498
}
14581499

@@ -1463,34 +1504,15 @@ void random_bounded_uint32_fill(aug_state *state, uint32_t off, uint32_t rng, np
14631504
*/
14641505
void random_bounded_uint16_fill(aug_state *state, uint16_t off, uint16_t rng, npy_intp cnt, uint16_t *out)
14651506
{
1466-
uint16_t val, mask;
1507+
uint16_t mask;
14671508
npy_intp i;
14681509
uint32_t buf = 0;
14691510
int bcnt = 0;
14701511

1471-
if (rng == 0) {
1472-
for (i = 0; i < cnt; i++) {
1473-
out[i] = off;
1474-
}
1475-
return;
1476-
}
1477-
14781512
/* Smallest bit mask >= max */
14791513
mask = (uint16_t)gen_mask(rng);
1480-
14811514
for (i = 0; i < cnt; i++) {
1482-
do {
1483-
if (!bcnt) {
1484-
buf = random_uint32(state);
1485-
bcnt = 1;
1486-
}
1487-
else {
1488-
buf >>= 16;
1489-
bcnt--;
1490-
}
1491-
val = (uint16_t)buf & mask;
1492-
} while (val > rng);
1493-
out[i] = off + val;
1515+
out[i] = random_buffered_bounded_uint16(state, off, rng, mask, &bcnt, &buf);
14941516
}
14951517
}
14961518

@@ -1500,35 +1522,17 @@ void random_bounded_uint16_fill(aug_state *state, uint16_t off, uint16_t rng, np
15001522
*/
15011523
void random_bounded_uint8_fill(aug_state *state, uint8_t off, uint8_t rng, npy_intp cnt, uint8_t *out)
15021524
{
1503-
uint8_t val, mask = rng;
1525+
uint8_t mask;
15041526
npy_intp i;
15051527
uint32_t buf = 0;
15061528
int bcnt = 0;
15071529

1508-
if (rng == 0) {
1509-
for (i = 0; i < cnt; i++) {
1510-
out[i] = off;
1511-
}
1512-
return;
1513-
}
1514-
15151530
/* Smallest bit mask >= max */
15161531
mask = (uint8_t)gen_mask(rng);
1517-
15181532
for (i = 0; i < cnt; i++) {
1519-
do {
1520-
if (!bcnt) {
1521-
buf = random_uint32(state);
1522-
bcnt = 3;
1523-
}
1524-
else {
1525-
buf >>= 8;
1526-
bcnt--;
1527-
}
1528-
val = (uint8_t)buf & mask;
1529-
} while (val > rng);
1530-
out[i] = off + val;
1533+
out[i] = random_buffered_bounded_uint8(state, off, rng, mask, &bcnt, &buf);
15311534
}
1535+
15321536
}
15331537

15341538

0 commit comments

Comments
 (0)