Calculating the nth number of xorshift - random

I know that XorShift32 is the random function that returns a value between 1 and 2^32-1.
uint32_t xorshift32(uint32_t x)
{
x ^= x << 13;
x ^= x >> 17;
x ^= x << 5;
return x;
}
Since numbers are repeated, I want to know how to find the when the specific number appears starting from a specific number (for example, starting from 1, 307599695 is the 5th number).
Is there any method without using for loop?

Related

Random number generator with 3 inputs

I am looking for a random number generator with 3 inputs for a terrain generator. The inputs are an x, y (position) and a seed value. And the function returns back a random number from 0-1.
So far I found this question, but this has 2 inputs. Although I can combine x and y to a single number, to get two inputs, this will restrict the choices I will have for x, y as they need to be sufficiently large (the terrain is infinite).
Is there any random function that takes in 3 inputs, or would I need to end up using the 2 input version?
Something like this should work. It takes three 32-bit integers, and outputs a single 32-bit integer. If you want to turn the output into a double between 0 and 1, just divide by UINT32_MAX.
The input and output sizes can be adjusted.
You can also tweak the balance between output quality and speed. You'll notice that the middle section is just repeated 3 lines, remove or add more of them to make the output more or less biased.
Here's the C code.
uint32_t rotl32(uint32_t n, uint8_t k) {
uint32_t a = n << k;
uint32_t b = n >> (32 - k);
return a | b;
}
uint32_t three_input_random(uint32_t x, uint32_t y, uint32_t z) {
uint32_t a = x;
uint32_t b = y;
uint32_t c = z;
b ^= rotl32(a + c, 7);
c ^= rotl32(b + a, 9);
a ^= rotl32(c + b, 18);
b ^= rotl32(a + c, 7);
c ^= rotl32(b + a, 9);
a ^= rotl32(c + b, 18);
b ^= rotl32(a + c, 7);
c ^= rotl32(b + a, 9);
a ^= rotl32(c + b, 18);
return a + b + c + x + y + z;
}

Produce solutions of k & x = k in range (0,n)

How to efficiently generate all numbers within 0,1,2...n.
(large n).
Such that for a fixed x and varying k (0 <= k < n), k & x = k.
It is easily found out that all the bits with value 1 in k is also 1 in x.
But I have trouble computing all of them.
I used DP to find all the subset sums of set bit in x,to arrive at all the possible solutions.
But this method proves inefficient over multiple such cases requesting for a different x.
Do I have to consider each and every bit which needs to be changed to get all the possibilities?Any other efficient way? Also I certainly dont want to check with all of n.
There is a neat way to do that
for(int i = x ;; i = x & (i - 1)){
print i;
if(i == 0)
break;
}
Notice the condition i = x & (i - 1) make sure i always decreasing and only contains bits in x
See running Java code in here
In case x > n, so i should start with i = min(x, n - 1) & x
First note that the 0-bits in x denote the bits that must be 0 in k, while the 1-bits in x can be either 0 or 1 in k. The algorithm should thus iterate over all possible bit combinations in k for where x has a 1 bit and the resulting number (k) is not greater than n.
These combinations can best be produced by using something like a Grey code sequence, since one can then step from one bit pattern to the next in constant time.
Example:
x = 0b011010 (26)
n = 0b010000 (16)
The values to generate for k are (in order of Grey code sequence):
0b000000 ( = 0)
0b000010 ( = 2)
0b001010 ( = 10)
0b001000 ( = 8)
0b011000 ( = 24) too large: exclude
0b011010 ( = 26) too large: exclude
0b010010 ( = 18) too large: exclude
0b010000 ( = 16)
Because of using a Grey code scheme, only one bit changes from one combination to the next. This means that numbers are not generated in order and some can be too large (> n). This downside is worth it still, as generating them in order would involve more bit changes per step.
Here is a snippet that implements this idea in JavaScript:
function get_nums(n, x) {
// Solution array. Add zero as it is always a solution (assuming non-negative n)
let result = [0],
k = 0,
arr = []; // Helper to follow Grey code sequence
for (let i = 1; i <= n && i <= x; i <<= 1) { // Shift bit to the left
if (x & i) { // This bit is set to 1 in x
arr.push(i);
k += i; // Set this bit in k
if (k <= n) result.push(k); // Add k to solution array
// Produce other matches following Grey code sequence
for (let j = arr.length-2; j >= 0; j--) {
arr.push(-arr[j]);
k -= arr[j]; // Toggle a bit in k
if (k <= n) result.push(k);
}
}
}
return result;
}
console.log(get_nums(16, 26));
Note that the output is not ordered (because of the Grey code sequence used). If you need them ordered, apply some radix sort (or hashing).
In JavaScript it is quite easy to implement such a radix sort, given the values are unique. But in other languages you could implement a more explicit, simplified radix sort. Here is the JavaScript function for it:
function radix_sort_uniques(arr) {
let result = {};
// Add a property to the object for each value in the array
for (let i of arr) result[i] = true;
// Get those properties and convert them back to numeric data type (via map)
// JavaScript will produce them in ascending order:
return Object.keys(result).map(Number);
}
console.log(radix_sort_uniques([0, 2, 10, 8, 16]));
Complexity:
The outer loop iterates once per bit position in n, i.e. log(n) times, while the inner loop approximately doubles each time its number of iterations. So in the worst case (when x is 0 and the inner loop always executes) we get a total number of innermost operations in the order of 2log(n) times, giving a O(n) time complexity.
As x is fixed, the complexity should be expressed in x too. Let's say x has b 1-bits, then the time complexity is O(b+2b).
Imagine, that we have x in binary representation, like this:
x = 00001010110
In this case all k such that k & x = k should be in form
x = 00001010110
k = 0000?0?0??0
where ? is either 0 or 1. So we have to obtain all indexes 1 in x ([1, 2, 4, 6] in the example above) and generate all combinations (16 in the example) of 0 and 1s at the corresponding indexes:
C# implementation:
private static IEnumerable<int> MySolution(int x) {
int[] indexes = Enumerable
.Range(0, 32)
.Where(i => (x >> i) % 2 != 0)
.ToArray();
for (int value = 0; value < 1 << indexes.Length; ++value)
yield return indexes
.Select((v, i) => ((value >> i) % 2) * (1 << v))
.Sum();
}
Test:
Console.WriteLine(String.Join(", ", MySolution(5)));
Outcome (please, notice that the solutions are sorted out):
0, 1, 4, 5
If you want to restrict solutions generated, you can modify the loop:
private static IEnumerable<int> MySolution(int x, int n = -1) {
int[] indexes = Enumerable
.Range(0, 32)
.Where(i => (x >> i) % 2 != 0)
.ToArray();
for (int value = 0; value < 1 << indexes.Length; ++value) {
int result = indexes
.Select((v, i) => ((value >> i) % 2) * (1 << v))
.Sum();
if (n < 0 || result <= n)
yield return;
else
break;
}
}

Simplify the inverse of Z = X ^ (X << Y) function

I'm having difficulty with simplifying the following function into several several atomic binary operations, it feels like it's possible however I'm unable to do it, I'm scratching my head for few hours already:
public UInt32 reverse_xor_lshift(UInt32 y, Int32 shift)
{
var x = y & (UInt32)((1 << shift) - 1);
for (int i = 0; i < (32 - shift); i++) {
var bit = ((x & (1 << i)) >> i) ^ ((y & (1 << (shift + i))) >> (shift + i));
x |= (UInt32)(bit << (shift + i));
}
return x;
}
what the function does is just it computes the inverse of the Z = X ^ (X << Y), in other words reverse_xor_lshift(Z, Y) == X
You can inverse it with much fewer operations, though in a harder to understand way, by using the same technique as used in converting back from grey code:
Apply the transformation z ^= z << i where i starts at shift and doubles every iteration.
In pseudocode:
while (i < 32)
x ^= x << i
i *= 2
This works because in the first step, you xor the lowest bits (unaffected) by the place where they were "xored in", thus "xoring them out". Then the part that has been changed to the original is twice as wide. The new number is then of the form x ^ (x << k) ^ (x << k) ^ (x << 2k) = x ^ (x << 2k) which is the same thing again but with twice the offset, so the same trick will work again, decoding yet more of the original bits.

Most efficient method of generating a random number with a fixed number of bits set

I need to generate a random number, but it needs to be selected from the set of binary numbers with equal numbers of set bits. E.g. choose a random byte value with exactly 2 bits set...
00000000 - no
00000001 - no
00000010 - no
00000011 - YES
00000100 - no
00000101 - YES
00000110 - YES
...
=> Set of possible numbers 3, 5, 6...
Note that this is a simplified set of numbers. Think more along the lines of 'Choose a random 64-bit number with exactly 40 bits set'. Each number from the set must be equally likely to arise.
Do a random selection from the set of all bit positions, then set those bits.
Example in Python:
def random_bits(word_size, bit_count):
number = 0
for bit in random.sample(range(word_size), bit_count):
number |= 1 << bit
return number
Results of running the above 10 times:
0xb1f69da5cb867efbL
0xfceff3c3e16ea92dL
0xecaea89655befe77L
0xbf7d57a9b62f338bL
0x8cd1fee76f2c69f7L
0x8563bfc6d9df32dfL
0xdf0cdaebf0177e5fL
0xf7ab75fe3e2d11c7L
0x97f9f1cbb1f9e2f8L
0x7f7f075de5b73362L
I have found an elegant solution: random-dichotomy.
Idea is that on average:
and with a random number is dividing by 2 the number of set bits,
or is adding 50% of set bits.
C code to compile with gcc (to have __builtin_popcountll):
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
/// Return a random number, with nb_bits bits set out of the width LSB
uint64_t random_bits(uint8_t width, uint8_t nb_bits)
{
assert(nb_bits <= width);
assert(width <= 64);
uint64_t x_min = 0;
uint64_t x_max = width == 64 ? (uint64_t)-1 : (1UL<<width)-1;
int n = 0;
while (n != nb_bits)
{
// generate a random value of at least width bits
uint64_t x = random();
if (width > 31)
x ^= random() << 31;
if (width > 62)
x ^= random() << 33;
x = x_min | (x & x_max); // x_min is a subset of x, which is a subset of x_max
n = __builtin_popcountll(x);
printf("x_min = 0x%016lX, %d bits\n", x_min, __builtin_popcountll(x_min));
printf("x_max = 0x%016lX, %d bits\n", x_max, __builtin_popcountll(x_max));
printf("x = 0x%016lX, %d bits\n\n", x, n);
if (n > nb_bits)
x_max = x;
else
x_min = x;
}
return x_min;
}
In general less than 10 loops are needed to reach the requested number of bits (and with luck it can take 2 or 3 loops). Corner cases (nb_bits=0,1,width-1,width) are working even if a special case would be faster.
Example of result:
x_min = 0x0000000000000000, 0 bits
x_max = 0x1FFFFFFFFFFFFFFF, 61 bits
x = 0x1492717D79B2F570, 33 bits
x_min = 0x0000000000000000, 0 bits
x_max = 0x1492717D79B2F570, 33 bits
x = 0x1000202C70305120, 14 bits
x_min = 0x0000000000000000, 0 bits
x_max = 0x1000202C70305120, 14 bits
x = 0x0000200C10200120, 7 bits
x_min = 0x0000200C10200120, 7 bits
x_max = 0x1000202C70305120, 14 bits
x = 0x1000200C70200120, 10 bits
x_min = 0x1000200C70200120, 10 bits
x_max = 0x1000202C70305120, 14 bits
x = 0x1000200C70201120, 11 bits
x_min = 0x1000200C70201120, 11 bits
x_max = 0x1000202C70305120, 14 bits
x = 0x1000200C70301120, 12 bits
width = 61, nb_bits = 12, x = 0x1000200C70301120
Of course, you need a good prng. Otherwise you can face an infinite loop.
Say the number of bits to set is b and the word size is w. I would create a vector v of of length w with the first b values set to 1 and the rest set to 0. Then just shuffle v.
Here is another option which is very simple and reasonably fast in practice.
choose a bit at random
if it is already set
do nothing
else
set it
increment count
end if
Repeat until count equals the number of bits you want set.
This will only be slow when the number of bits you want set (call it k) is more than half the word length (call it N). In that case, use the algorithm to set N - k bits instead and then flip all the bits in the result.
I bet the expected running time here is pretty good, although I am too lazy/stupid to compute it precisely right now. But I can bound it as less than 2*k... The expected number of flips of a coin to get "heads" is two, and each iteration here has a better than 1/2 chance of succeeding.
If you don't have the convenience of Python's random.sample, you might do this in C using the classic sequential sampling algorithm:
unsigned long k_bit_helper(int n, int k, unsigned long bit, unsigned long accum) {
if !(n && k)
return accum;
if (k > rand() % n)
return k_bit_helper(n - 1, k - 1, bit + bit, accum + bit);
else
return k_bit_helper(n - 1, k, bit + bit, accum);
}
unsigned long random_k_bits(int k) {
return k_bit_helper(64, k, 1, 0);
}
The cost of the above will be dominated by the cost of generating the random numbers (true in the other solutions, also). You can optimize this a bit if you have a good prng by batching: for example, since you know that the random numbers will be in steadily decreasing ranges, you could get the random numbers for n through n-3 by getting a random number in the range 0..(n * (n - 1) * (n - 2) * (n - 3)) and then extracting the individual random numbers:
r = randint(0, n * (n - 1) * (n - 2) * (n - 3) - 1);
rn = r % n; r /= n
rn1 = r % (n - 1); r /= (n - 1);
rn2 = r % (n - 2); r /= (n - 2);
rn3 = r % (n - 3); r /= (n - 3);
The maximum value of n is presumably 64 or 26, so the maximum value of the product above is certainly less than 224. Indeed, if you used a 64-bit prng, you could extract as many as 10 random numbers out of it. However, don't do this unless you know the prng you use produces independently random bits.
I have another suggestion based on enumeration: choose a random number i between 1 and n choose k, and generate the i-th combination. For example, for n = 6, k = 3 the 20 combinations are:
000111
001011
010011
100011
001101
010101
100101
011001
101001
110001
001110
010110
100110
011010
101010
110010
011100
101100
110100
111000
Let's say we randomly choose combination number 7. We first check whether it has a 1 in the last position: it has, because the first 10 (5 choose 2) combinations have. We then recursively check the remaining positions. Here is some C++ code:
word ithCombination(int n, int k, word i) {
// i is zero-based
word x = 0;
word b = 1;
while (k) {
word c = binCoeff[n - 1][k - 1];
if (i < c) {
x |= b;
--k;
} else {
i -= c;
}
--n;
b <<= 1;
}
return x;
}
word randomKBits(int k) {
word i = randomRange(0, binCoeff[BITS_PER_WORD][k] - 1);
return ithCombination(BITS_PER_WORD, k, i);
}
To be fast, we use precalculated binomial coefficients in binCoeff. The function randomRange returns a random integer between the two bounds (inclusively).
I did some timings (source). With the C++11 default random number generator, most time is spent in generating random numbers. Then this solution is fastest, since it uses the absolute minimum number of random bits possible. If I use a fast random number generator, then the solution by mic006 is fastest. If k is known to be very small, it's best to just randomly set bits until k are set.
Not exactly an algorithm suggestion, but just found a really neat solution in JavaScript to get random bits directly from Math.random output bits using ArrayBuffer.
//Swap var out with const and let for maximum performance! I like to use var because of prototyping ease
var randomBitList = function(n){
var floats = Math.ceil(n/64)+1;
var buff = new ArrayBuffer(floats*8);
var floatView = new Float64Array(buff);
var int8View = new Uint8Array(buff);
var intView = new Int32Array(buff);
for(var i = 0; i < (floats-1)*2; i++){
floatView[floats-1] = Math.random();
int8View[(floats-1)*8] = int8View[(floats-1)*8+4];
intView[i] = intView[(floats-1)*2];
}
this.get = function(idx){
var i = idx>>5;//divide by 32
var j = idx%32;
return (intView[i]>>j)&1;
//return Math.random()>0.5?0:1;
};
this.getBitList = function(){
var arr = [];
for(var idx = 0; idx < n; idx++){
var i = idx>>5;//divide by 32
var j = idx%32;
arr[idx] = (intView[i]>>j)&1;
}
return arr;
}
};

Bit Reversal using bitwise

I am trying to do bit reversal in a byte. I use the code below
static int BitReversal(int n)
{
int u0 = 0x55555555; // 01010101010101010101010101010101
int u1 = 0x33333333; // 00110011001100110011001100110011
int u2 = 0x0F0F0F0F; // 00001111000011110000111100001111
int u3 = 0x00FF00FF; // 00000000111111110000000011111111
int u4 = 0x0000FFFF;
int x, y, z;
x = n;
y = (x >> 1) & u0;
z = (x & u0) << 1;
x = y | z;
y = (x >> 2) & u1;
z = (x & u1) << 2;
x = y | z;
y = (x >> 4) & u2;
z = (x & u2) << 4;
x = y | z;
y = (x >> 8) & u3;
z = (x & u3) << 8;
x = y | z;
y = (x >> 16) & u4;
z = (x & u4) << 16;
x = y | z;
return x;
}
It can reverser the bit (on a 32-bit machine), but there is a problem,
For example, the input is 10001111101, I want to get 10111110001, but this method would reverse the whole byte including the heading 0s. The output is 10111110001000000000000000000000.
Is there any method to only reverse the actual number? I do not want to convert it to string and reverser, then convert again. Is there any pure math method or bit operation method?
Best Regards,
Get the highest bit number using a similar approach and shift the resulting bits to the right 33 - #bits and voila!
Cheesy way is to shift until you get a 1 on the right:
if (x != 0) {
while ((x & 1) == 0) {
x >>= 1;
}
}
Note: You should switch all the variables to unsigned int. As written you can have unwanted sign-extension any time you right shift.
One method could be to find the leading number of sign bits in the number n, left shift n by that number and then run it through your above algorithm.
It's assuming all 32 bits are significant and reversing the whole thing. You COULD try to make it guess the number of significant bits by finding the highest 1, but that isn't necessarily accurate so I'd suggest you modify the function so it takes a second parameter indicating the number of significant bits. Then after reversing the bits just shift them to the right.
Try using Integer.reverse(int x);

Resources