I'm trying to generate discrete random numbers with uniform distribution using Intel MKL.
The function viRngUniformBits32 generates n random integers.
I want to generate random numbers on the fly rather than generating them n at a time.
I tried this but obviously it doesn't work. I call the function 5 times and it outputs the same value.
I assume it is generating the first number in the sequence every time based on the seed value.
Now how do I modify this so that every time I call this method, I get a random number
#include <stdio.h>
#include "mkl.h"
int main()
{
unsigned int out;
VSLStreamStatePtr stream;
vslNewStream(&stream,VSL_BRNG_MCG31,2);
for (int i=0;i<5;i++)
{
//FORMAT viRngUniformBits32( method, stream, n, r );
viRngUniformBits32(VSL_RNG_METHOD_UNIFORMBITS32_STD,stream,1,&out);
printf("%u\t",out);
}
printf("\n");
vslDeleteStream(&stream);
}
The method viRngUniformBits32 does not support the BRNG VSL_BRNG_MCG31.
So I used VSL_BRNG_MT19937 and it works without any errors.
Thanks to jaket for reminding me to look at the error code.
Related
This question already has answers here:
Why do I always get the same sequence of random numbers with rand()?
(12 answers)
Closed 8 years ago.
I'm using the following code for generate the random numbers in C programming, but for every compilation a particular set of random numbers are generating repeatedly. Can anybody mention the correction here???
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
main()
{
int i,a[40];
for(i=0;i<40;i++)
{
a[i] = rand() % 6;
printf("%d\n", a[i]);
}
getch();
}
You need to initialize random seed to a different value, please see http://www.cplusplus.com/reference/cstdlib/rand/
Per the documentation,
If rand() is called before any calls to srand() are made, the same sequence shall
be generated as when srand() is first called with a seed value of 1. [emph. mine]
You need to mix it up, something like this:
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include <time.h>
main()
{
int i,a[40];
// seed the PRNG with some random value
// the current time is often used. You might want to incorporate
// other sources of entropy as well.
srand(time(NULL));
for( i = 0 ; i < 40 ; i++ )
{
a[i] = rand() % 6;
printf("%d\n", a[i]);
}
getch();
}
One should note that
seed the PRNG just once at beginning of execution
The reason for incorporating more sources of entity, rather than just relying on the current system clock is that the system clock itself is not very random -- to invocations quite close to each other my result in similar sequences. Other good sources of entropy include:
hard disk statistics
network I/O
process activity
keystroke latency
mouse movements
etc.
Although looking at user interface components such as keystrokes and mouse movements won't buy you much in the way of entropy if your software is running, say, on a server, where the keyboard and mouse are likely to be idle for long periods of time.
Do something like this (inserted line) to seed the random number generator:
//...
int i,a[40];
srand(clock()); //inserted line
for(i=0;i<40;i++)
//...
The clock() function will provide a different seed value each clock tick, resulting in a new and different initialization to the rand() function.
How to write a random generator function without using standard C functions like time functions, static variables or global variables?
/* #include <time.h> Don't use time functions. */
/* int seed = 1234; Don't use global variables. */
int generate_random(void)
{
/* static int seed = 1234; Don't use static variables. */
/* return (time() % 100); Don't use time functions. */
}
In other words, this random generator function should not remember the last state.
you can also use srand by
#include<stdlib.h>
srand(getpid());
int num = rand();
This solution meets all your criterion, but it does require the Internet.*
unsigned generate_random () {
FILE *random;
char cmd[512];
unsigned number;
snprintf(cmd, sizeof(cmd),
"wget -qO - "
"'http://www.random.org/integers/"
"?num=1&min=0&max=%u&col=1&base=10&format=plain&rnd=new'",
USHRT_MAX);
random = popen(cmd, "r");
fscanf(random, "%u", &number);
pclose(random);
return number;
}
*That's not really a mark against the algorithm, though, since the Internet is an excellent source of random data. ;-)
Assuming you need to do your own pseudo-random number generator,
you need to remember the state.
If function shouldn't remember last state, you need to pass it as an argument:
int generate_random(int * lastState)
{
// generate next random from lastState
// store state to lastState
// return result
}
int main(void)
{
int lastState = 1234; // seed it
int random = generate_random(&lastState);
}
do
#include <time.h>
#include <stdlib.h>
srand(time(NULL));
int r = rand();
if you want to limit the number use
int r = minNum + rand() % maxNum;
do not try to create your own random function. it will not end well
Guessing about your question...I have to ask what is the requirement for wanting a random seed?
Being able to set the seed value is a plus for code because you at least try to do things like regression testing.
If your question is about random numbers in general. There are two steps needed to generate a series of random numbers.
First, set a seed value, for example, srand(1234); where 1234 is the seed value. Your code only issues this instruction once. When you run the program a second time your code can re-use the same seed value, in which case the sequence of random numbers will be the same. If you set a different seed, then you will get a different sequence of random numbers.
The second step is to retrieve the random number values for use in your code.
One Possible Method
In theory, you could use a fixed seed value and then generate R random numbers, where R is some number taken from the system mod 100 (for example). Then use that R'th random number as the seed value for the actual sequence of random numbers for your application.
You say that you don't want to use Time(), but maybe in this double sequence of random numbers and the Time() mod n function will provide enough randomness.
Now, I say in theory, because random numbers from rand() are actually psuedo-random and for all intents and purposes they really are random (guys with math PhDs say this...), so I doubt if doing this "double selection" will make the numbers more random. But, this method or one like it might make a reviewer or boss feel more comfortable, but this would be a false sense of security.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
calling rand() returning non-random results
In my workshop I need to takes 2 different random numbers but I get 2 same random number.
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int random1_6(){
int k;
srand(time(0));
k=((rand()%6)+1);
return k;
}
int main(void){
int a,b;
a=random1_6();
printf("%d.\n",a);
b=random1_6();
printf("%d.\n",b);
return 0;
}
How to get 2 different random number?
A non-cryptographic random number generator (RNG) is not truely random but it generates random-like numbers based on a seed.
What you do is initializing the RNG with the same seed two times, so you get the same results. Seed the RNG just once, e.g. at program start, and you will get random-like different results.
Edit: a code like follows should work:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int random1_6(){
return ((rand() % 6) + 1);
}
int main(void){
int a,b;
srand(time(NULL));
a = random1_6();
printf("%d.\n",a);
b=random1_6();
printf("%d.\n",b);
return 0;
}
Don't do srand(time(0)); on every call. Only call it once.
You must initialize the random number generator seed with srand() only once : upon each call you are re-initializing the RNG with the same seed since is it most likely that the two subsequent calls to time(0) will return the same timestamp (seconds-level precision), hence rand() will return the same number twice.
If you call srand() only once at the beginning of your program (in the main() entry-point), then every call to rand() will return a different number.
You always initialize the random number generator with the same seed, so you'll get the same random sequence, it is pseudo random anyway. Typically you will only want to call srand once in the beginning to initialize the generator.
Also, you only have 6 different possible outcomes, so it is perfectly legitimate to get same number twice, there is 1/6 chance for that.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char** argv) {
srand(time(NULL));
int r = rand();
printf("%d\n", r);
return (EXIT_SUCCESS);
}
When I run this code snippet repeatedly in the space of a few seconds, I get an increasing series of number such as 213252683, 213975384, 214193875, 214445980. It looks to me like I'm just printing out the system time - that hypothesis seems to be confirmed when I add the line printf("%d\n", time(NULL)); to the code. What am I doing wrong? I'm running on Mac OS X 10.6.1 (Snow Leopard), but I'm only using Standard Library functions, so it shouldn't make a difference. Thanks!
Pseudorandom numbers are generated as a chaotic sequence derived from an initial seed. srand initializes the randomness by setting this seed. Apparently, the first random number in the sequence is the seed itself - which is the time() value you set.
This is the reason, why the right way to generate a random sequence is to call srand() only once at the beginning of the program, and then only call rand() (well, maybe until the sequence starts looping, which shouldn't happen too soon, but that depends on the generating function). Calling srand() too often will, as you have seen, deteriorate the randomness.
The random number generator differs widely, so this will be difficult to reproduce on other machines. It looks like the first number from your implementation is just the seed value. On mine, for example, the first number appears to be linearly related to the seed. Generally, you will call srand once in a program, and rand many times, and successive calls will get more random-looking results. If you want to avoid this problem, it would be reasonable to do:
srand(time(NULL));
rand();
int r = rand();
printf("%d\n", r);
The first rand call makes sure the seed doesn't get returned, and the next one should pick up something that appears more random. Note that if you run the program twice in a short enough time span (such that time(NULL) is the same in both runs) you will get exactly the same results. This is definitely to be expected - use a different seed value (pid + time might be a good start, or just a higher-resolution time) if this is a problem.
When I run this code snippet repeatedly in the space of a few seconds,
I get an increasing series of number such as 213252683, 213975384,
214193875, 214445980.
I cannot reproduce this. On my system (Debian Linux) I get numbers that are not ordered. Also, the results are not the same as what you get when you print time(NULL).
This is as it should be: You are seeding the random number generator with the current time (in seconds). Thus as long as the time (down to seconds) is the same, your program will print the same result.
What am I doing wrong?
Well, that depends on what you want. If you want random numbers for every run, you need a better source of randomness. You could try functions like gettimeofday, which have higher resolution (typically ms, I believe). Also, mix in other sources of randomness, like the ID of your process.
In most programs, the effect you see is no problem, because typically srand() is only called at the start, and then rand() returns a different number on every call.
If you want "secure" (i.e. unpredictable) random numbers, that's a whole other game. See e.g. Wikipedia for an overview.
In case it helps I generally use it that way:
int rand_between(int min, int max)
{
static int flag = 1;
FILE *urandom;
unsigned int seed;
if (flag)
{
flag = 0;
if (!(urandom = fopen ("/dev/urandom", "r")))
fprintf(stderr, "Cannot open /dev/urandom!\n");
fread(&seed, sizeof(seed), 1, urandom);
srand(seed);
}
return ((int)rand() % (max - min)) + min;
}
To get a random uppercase letter:
char letter = (char)rand_between('A', 'Z');
You should use random() instead of rand(). It is superior to rand() in every way, and it is also included in stdlib.
Try the following code:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
int r = random();
printf("%d\n", r);
return (EXIT_SUCCESS);
}
For the following piece of code:
#include<stdlib.h>
#include<stdio.h>
int main()
{
int x;
x = rand()%100;
printf("The Random Number is: %i", x);
return 0;
}
It always seems to print the random number as 83. Why is this?
Most random number generators are repeatable. You need to seed the generator before using it which you typically do using the system time.
#include <time.h>
srand(time(NULL));
Obligatory XKCD reference:
As people have said, you need to seed the pseudo random number generator properly.
The trouble is, it still only generates pseudo random numbers. Most "true" random number generators require access to some physical phenomenon that is random in nature (for example, clock skews or temperature fluctuations).
Otherwise, the XKCD reference is not too far from the truth. Nor is Dilbert.
Because the pseudo-random number generator used by rand is always initialized with the same seed.
In order to initialize it with a different seed, you can use the srand function, and initialize it as, say, srand(time(NULL)).
Because 83 is a random number, isn't it ?
More seriously, it is useful to have programs providing a repeatable behavior so by default, rand always returns the same sequence of numbers if you don't change the seed.
Seed the random number generator by including <time.h> and calling srand(time(0)); (edited thanks to my commenters)
You can not generate a random number which is truly random until and unless your random number generator has access to a truly random physical phenomenon as quoted earlier by peter. But for a general use you can use C's standard library functions for generating random numbers. Here is a sample code for generating random number between two limits(max and min):
#include<stdio.h>
#include<stdlib.h>
#define MIN 1
#define MAX 5
#define QUANTITY 5
int main()
{
int i;
//stores the time in seconds
time_t seconds;
//getting the system time
time(&seconds);
//initializing the random generator with system time
//as the seed value
srand((long)seconds);
for(i = 0; i < QUANTITY; i++)
{
printf("%f\t",((float)rand())/RAND_MAX*(MAX-MIN)+MIN);
}
printf("\n");
return 0;
}