How to correctly seed the random function in Scheme? - random

I was under the impression, upon starting up Scheme, the randomize procedure was called with the current time as its seed. However, if I have a Scheme script consisting solely of (print (random 10)), the only output I receive is 7; no other number. So, what am I doing wrong? For the record, I am using Chicken Scheme.

What random library are you using, exactly? according to the documentation your assumption about random's seeding is correct:
(randomize [SEED]) : Set random-number seed. If SEED (an exact integer) is not supplied, the current time is used. On startup (when Unit extras is initialized), the random number generator is initialized with the current time.
(random N) : Returns a pseudo-random integer in [0, N-1]. N is an integer.
Also notice the warnings, in particular the second one that seems to explain the behaviour you're witnessing:
Warning: This procedure uses rand(3) internally and exhibits its deficiencies, including low quality pseudo-randomness:
On Windows and Solaris, only 32768 unique random values can be generated in the range [0, N-1]. If N >= 32768, there will be gaps in the result set.
On Mac OS X, Windows and some other platforms, little variance in output is seen with nearby seeds. Since the random generator is seeded with current-seconds at startup, new processes may see similar or identical random sequences for up to a minute.
On Linux, rand(3) is an alias to random(3), which provides output of reasonable quality.

Related

Behaviour of random_number across different platforms [duplicate]

I'm using the random_number subroutine from Fortran, but in different runs of program the number which is being produced doesn't change. What should I include in my code so every time I compile and run the program the numbers change?
The random number generator produces pseudo-random numbers. To get different numbers each run, you need to initialise the random seed at the start of your program. This picks a different starting position in the pseudo-random stream.
The sequence of pseudorandom numbers coming from call(s) to random_number depends on the algorithm used by the processor and the value of the seed.
The initial value of the seed is processor dependent. For some processors this seed value will be the same each time the program runs, and for some it will be different. The first case gives a repeatable pseudorandom sequence and the second a non-repeatable sequence.
gfortran (before version 7) falls into this first category. You will need to explicitly change the random seed if you wish to get non-repeatable sequences.
As stated in another answer the intrinsic random_seed can be used to set the value of the seed and restart the pseudorandom generator. Again, it is processor dependent what happens when the call is call random_seed() (that is, without a put= argument). Some processors will restart the generator with a repeatable sequence, some won't. gfortran (again, before version 7) is in the first category.
For processors where call random_seed() gives rise to a repeatable sequence an explicit run-time varying seed will be required to generate distinct sequences. An example for those older gfortran versions can be found in the documentation.
It should be noted that choosing a seed can be a complicated thing. Not only will there be portability issues, but care may be required in ensuring that the generator is not restarted in a low entropy region. For multi-image programs the user will have to work to have varying sequences across these images.
On a final note, Fortran 2018 introduced the standard intrinsic procedure random_init. This handles both cases of selecting repeatability across invocations and distinctness over (coarray) images.

urandom_range(), urandom(), random() in verilog

I am confused between these three functions and I was wondering for some explanation. If I set the range how do I make the range exclusive or inclusive? Are the ranges inclusive or exclusive if I don't specify the range?
In addition to the answer from #dave_59, there are other important differences:
i) $random returns a signed 32-bit integer; $urandom and $urandom_range return unsigned 32-bit integers.
ii) The random number generator for $random is specified in IEEE Std 1800-2012. With the same seed you will get exactly the same sequence of random numbers in any SystemVerilog simulator. That is not the case for $urandom and $urandom_range, where the design of the random number generator is up to the EDA vendor.
iii) Each thread has its own random number generator for $urandom and $urandom_range, whereas there is only one random number generator for $random shared between all threads (ie only one for the entire simulation). This is really important, because having separate random number generators for each thread helps you simulation improve a property called random stability. Suppose you are using a random number generator to generate random stimulus. Suppose you find a bug and fix it. This could easily change the order in which threads (ie initial and always blocks) are executed. If that change changed the order in which random numbers were generated then you would never know whether the bug had gone away because you'd fixed it or because the stimulus has changed. If you have a random number generator for each thread then your testbench is far less vulnerable to such an effect - you can be far more sure that the bug has disappeared because you fixed it. That property is called random stability.
So, As #dave_59 says, you should only be using $urandom and $urandom_range.
You should only be using $urandom and $urandom_range. These two functions provide better quality random numbers and better seed initialization and stability than $random. The range specified by $urandom_range is always inclusive.
Although $random generates the exact same sequence of random numbers for each call, it is extremely difficult to keep the same call ordering as soon as any change is made to the design or testbench. Even more difficult when multiple threads are concurrently generating random numbers.

Rust GSL library always returns the same number for a random number generator

I am using the rgsl library in Rust that wraps functions from the C GSL math libraries. I was using a random number generator function, but I am always getting the same exact value whenever I generate a new random number. I imagine that the number should vary upon each run of the function. Is there something that I am missing? Do I need to set a new random seed each time or such?
extern crate rgsl;
use rgsl::Rng;
fn main() {
rgsl::RngType::env_setup();
let t = rgsl::rng::default();
let r = Rng::new(&t).unwrap()
let val = rgsl::randist::binomial::binomial(&r, 0.01f64, 1u32);
print!("{}",val);
}
The value I keep getting is 1, which seems really high considering the probability of obtaining a 1 is 0.01.
The documentation for env_setup explains everything you need to know:
This function reads the environment variables GSL_RNG_TYPE and GSL_RNG_SEED and uses their values to set the corresponding library variables gsl_rng_default and gsl_rng_default_seed
If you don’t specify a generator for GSL_RNG_TYPE then gsl_rng_mt19937 is used as the default. The initial value of gsl_rng_default_seed is zero.
(Emphasis mine)
Like all software random number generators, this is really an algorithm that produces pseudo random numbers. The algorithm and the initial seed uniquely identify a sequence of these numbers. Since the seed is always the same, the first (and second, third, ...) number in the sequence will always be the same.
So if I want to generate a new series of random numbers, then I need to change the seed each time. However, if I use the rng to generate a set of random seeds, then I will get the same seeds each time.
That's correct.
Other languages don't seem to have this constraint, meaning that the seed can be manually set if desired, but is otherwise is random.
A classical way to do this is to seed your RNG with the current time. This produces an "acceptable" seed for many cases. You can also get access to true random data from the operating system and use that as a seed or mix it in to produce more random data.
Is there no way to do this in Rust?
This is a very different question. If you just want a random number generator in Rust, use the rand crate. This uses techniques like I described above.
You could even do something crazy like using random values from the rand crate to seed your other random number generator. I just assumed that there is some important reason you are using that crate instead of rand.

"Resetting" pseudo-random number generator seed multiple times?

Today, my friend had a thought that setting the seed of a pseudo-random number generator multiple times using the pseudo-random number generated to "make things more randomized".
An example in C#:
// Initiate one with a time-based seed
Random rand = new Random(milliseconds_since_unix_epoch());
// Then loop for a_number_of_times...
for (int i = 0; i < a_number_of_times; i++)
{
// ... to initiate with the next random number generated
rand = new Random(rand.Next());
}
// So is `rand` now really random?
assert(rand.Next() is really_random);
But I was thinking that this could probably increase the chance of getting a repeated seed being used for the pseudo-random number generator.
Will this
make things more randomized,
making it loop through a certain number of seeds used, or
does nothing to the randomness (i.e. neither increase nor decrease)?
Could any expert in pseudo-random number generators give some detailed explanations so that I can convince my friend? I would be happy to see answers explaining further detail in some pseudo-random number generator algorithm.
There are three basic levels of use for pseudorandom numbers. Each level subsumes the one below it.
Unexpected numbers with no particular correlation guarantees. Generators at this level typically have some hidden correlations that might matter to you, or might not.
Statistically-independent number with known non-correlation. These are generally required for numerical simulations.
Cryptographically secure numbers that cannot be guessed. These are always required when security is at issue.
Each of these is deterministic. A random number generator is an algorithm that has some internal state. Applying the algorithm once yields a new internal state and an output number. Seeding the generator means setting up an internal state; it's not always the case that the seed interface allows setting up every possible internal state. As a good rule of thumb, always assume that the default library random() routine operates at only the weakest level, level 1.
To answer your specific question, the algorithm in the question (1) cannot increase the randomness and (2) might decrease it. The expectation of randomness, thus, is strictly lower than seeding it once at the beginning. The reason comes from the possible existence of short iterative cycles. An iterative cycle for a function F is a pair of integers n and k where F^(n) (k) = k, where the exponent is the number of times F is applied. For example, F^(3) (x) = F(F(F(x))). If there's a short iterative cycle, the random numbers will repeat more often than they would otherwise. In the code presented, the iteration function is to seed the generator and then take the first output.
To answer a question you didn't quite ask, but which is relevant to getting an understanding of this, seeding with a millisecond counter makes your generator fail the test of level 3, unguessability. That's because the number of possible milliseconds is cryptographically small, which is a number known to be subject to exhaustive search. As of this writing, 2^50 should be considered cryptographically small. (For what counts as cryptographically large in any year, please find a reputable expert.) Now the number of milliseconds in a century is approximately 2^(41.5), so don't rely on that form of seeding for security purposes.
Your example won't increase the randomness because there is no increase in entropy. It is simply derived from the execution time of the program.
Instead of using something based of the current time, computers maintain an entropy pool, and build it up with data that is statistically random (or at least, unguessable). For example, the timing delay between network packets, or key-strokes, or hard-drive read times.
You should tap into that entropy pool if you want good random numbers. These are known as Cryptographically secure pseudorandom number generators.
In C#, see the Cryptography.RandomNumberGenerator Class for the right way to get a secure random number.
This will not make things more "random".
Our seed determines the random looking but completely determined sequence of numbers that rand.next() gives us.
Instead of making things more random, your code defines a mapping from your initial seed to some final seed, and, given the same initial seed, you will always end up with the same final seed.
Try playing with this code and you will see what I mean (also, here is a link to a version you can run in your browser):
int my_seed = 100; // change my seed to whatever you want
Random rand = new Random(my_seed);
for (int i = 0; i < a_number_of_times; i++)
{
rand = new Random(rand.Next());
}
// does this print the same number every run if we don't change the starting seed?
Console.WriteLine(rand.Next()); // yes, it does
The Random object with this final seed is just like any other Random object. It just took you more time then necessary to create it.

List handling and random number generation in Erlang

Why do I get a list of identical numbers when I run randy:spawner() below? I was expecting a list of random numbers. How could I change the code to achieve this?
-module(randy).
-export([randlister/2,spawner/0]).
-import(lists,[map/2]).
spawner() ->
[spawn(fun() -> randlister(X,random:uniform()) end) || X <- lists:seq(1,3)].
randlister(X, Randomnumber) ->
io:format("~p, ~p~n",[X,Randomnumber]).
Example output:
18> randy:spawner().
1, 0.4435846174457203
2, 0.4435846174457203
3, 0.4435846174457203
You must seed the random number generator in each process:
spawner() ->
[spawn(fun() ->
random:seed(now()),
randlister(X,random:uniform())
end) || X <- lists:seq(1,3)].
Why do I get a list of identical numbers when I run randy:spawner() below?
You must seed before generating random numbers.
Random number sequences generated from the same seed will be exactly the same.
If a process calls uniform/0 or uniform/1 without setting a seed first, seed/0 is called automatically.
seed/0 will seed random number generation with a default (fixed) value,
which can be accessed through seed0/0. On my laptop it always returns {3172,9814,20125} with a default process dictionary.
How could I change the code to achieve this?
In the simplest case, the solution from #EmilVikström is sufficient.
However, I do recommend to keep track of the random number generation state
so you can have a easier life when you're debugging.
A random number generation state is just a 3-tuple of integers, as returned by now(). The seed is just the first state. Then you can use uniform_s/1 or uniform_s/2 to generate random numbers from specified states.
By using these functions with states, you can specify random number seeds outside your Erlang code, e.g. passing a seed through command-line options or environment variables.
When you are testing/debugging, fix the seed so that each time you run your program will give the same result.
When you are satisfied, change the seed in order to (probably) continue debugging :-)
When you are ready for production, just pass the current time (or whatever) as the seed, so you can have some randomness.

Resources