question about random generator

M

Marc Dansereau

Hi all

I am new to this forum and to the c programming language.
If I understand, the random() function in C return numbers that follow a
uniform distribution U(0,1). Can somebody know how to generate a set of
random number that follow a normal distribution N(0,1) ? I am develloping
on power4 machine running AIX.

Thank you for your help
 
M

Martin Ambuhl

Marc said:
Hi all

I am new to this forum and to the c programming language.
If I understand, the random() function in C return numbers that follow a
uniform distribution U(0,1).

There is no standard function in C called random(). The standard
pseudo-random function is rand(). The values it returns are not U(0,1).
It returns pseudo-random numbers (no distribution specified) in the
range 0 to RAND_MAX, where RAND_MAX must be at least 32767.
Can somebody know how to generate a set of
random number that follow a normal distribution N(0,1) ?

You should *always* check a newsgroup's FAQ before posting a question.
The core list of random-number questions are 13.15 through 13.20. In
particular, see question 13.20 "How can I generate random numbers with a
normal or Gaussian distribution?"
<http://www.eskimo.com/~scs/C-faq/q13.20.html>
 
E

Eric Sosman

Marc said:
Hi all

I am new to this forum and to the c programming language.
If I understand, the random() function in C return numbers that follow a
uniform distribution U(0,1). Can somebody know how to generate a set of
random number that follow a normal distribution N(0,1) ? I am develloping
on power4 machine running AIX.

First, there is no random() function in the Standard C
library. If your system offers such a function, it is an
extra, bonus, add-on extension to C, not part of C itself.

The rand() function generates uniformly distributed
integers in the range 0 <= rand() <= RAND_MAX <= 32767.
From this source, you can generate floating-point numbers in
the range 0 <= y < 1: `rand() / (RAND_MAX + 1.0)'. Note
that these values may have as little as fifteen bits'
"precision;" if you need more, you may need to combine
the results of multiple rand() calls as in

(rand() + (rand() / (RAND_MAX + 1.0))) / (RAND_MAX + 1.0)

(Pedants take note: The ambiguity in the above expression
may be considered a benefit, under the circumstances.)

Now that you've got a source of (approximately) uniformly-
distributed numbers in [0,1), there are several ways to produce
normally-distributed numbers. The easiest to program is surely
the "polar method" (Google is your friend); faster methods
exist if you're willing to do the extra work. See Knuth
"The Art of Computer Programming, Volume II: Seminumerical
Algorithms." (In fact, see Knuth anyhow: the Standard makes
almost no guarantees about the statistical "goodness" of the
rand() function, and if you're doing high-precision work you
should substitute a source whose characteristics you can
count on.)
 
F

Free Bird

Marc said:
If I understand, the random() function in C return numbers that follow a
uniform distribution U(0,1). Can somebody know how to generate a set of
random number that follow a normal distribution N(0,1) ? I am develloping
on power4 machine running AIX.

The random() function does not exist in ISO C. It does, however, include the
rand() function which returns an int ranging from 0 to RAND_MAX. There are
no random number functions in ISO C which return a floating point value. My
advice would be to use rand() and a function which implements a suitable
normal distribution curve.
 
P

Peter Nilsson

Eric said:
...
The rand() function generates uniformly distributed
integers in the range 0 <= rand() <= RAND_MAX <= 32767.

ITYM: 0 <= rand() <= RAND_MAX, where RAND_MAX >= 32767
 
M

Marc Dansereau

Peter said:

Thank you for pointing these sites !

I am trying this code. The problem is that the

for (;;)
{
double u1 = prng_get_double ();
double u2 = prng_get_double ();
v1 = 2.0 * u1 - 1.0;
v2 = 2.0 * u2 - 1.0;
s = v1 * v1 + v2 * v2;
if (s > limit && s < 1)
break;
}

might end after a long time if u1 and u2 are very small, this loop might
take a time that is too long for my application (fluid simulation).
 
E

Eric Sosman

Peter said:
ITYM: 0 <= rand() <= RAND_MAX, where RAND_MAX >= 32767

Indeed, yes, that is exactly and precisely what I,
of course, meant. (Blbbbpppfft -- I *hate* when I do that.)
 
M

Marc Dansereau

Marc said:
Thank you for pointing these sites !

I am trying this code. The problem is that the

for (;;)
{
double u1 = prng_get_double ();
double u2 = prng_get_double ();
v1 = 2.0 * u1 - 1.0;
v2 = 2.0 * u2 - 1.0;
s = v1 * v1 + v2 * v2;
if (s > limit && s < 1)
break;
}

might end after a long time if u1 and u2 are very small, this loop might
take a time that is too long for my application (fluid simulation).

humm ... according to Knuth, this loop will be executed "1.27 times on the
average, with a standard deviation of 0.587" (Art of computer programming
2, p 117), wich is probably not bad. I beleve him, but still wonder if
there is a way to avoid performance degradation when the values of u1 and
u2 are very small.
 
C

CBFalconer

Marc said:
If I understand, the random() function in C return numbers that
follow a uniform distribution U(0,1). Can somebody know how to
generate a set of random number that follow a normal distribution
N(0,1) ? I am develloping on power4 machine running AIX.

Wrong newsgroup. Try comp.programming, which deals with
algorithms. Somebody is very likely to show you how to create a
gaussian. I thought the C FAQ also had a method, but I guess not,
since you would have looked there before asking.
 
K

Keith Thompson

Free Bird said:
The random() function does not exist in ISO C. It does, however, include the
rand() function which returns an int ranging from 0 to RAND_MAX. There are
no random number functions in ISO C which return a floating point value. My
advice would be to use rand() and a function which implements a suitable
normal distribution curve.

If you care about the quality of your random numbers, my advice would
be to avoid the rand() function. Many C implementations have rand()
functions that aren't particularly good.
 
P

pete

Eric said:
Indeed, yes, that is exactly and precisely what I,
of course, meant. (Blbbbpppfft -- I *hate* when I do that.

Does "pseudo-random" mean the same thing as "uniformly distributed" ?
 
A

Antonio

pete said:
Does "pseudo-random" mean the same thing as "uniformly distributed" ?

Completely OT, but anyway... No, pseudo-random means that it looks like
it's random but it really isn't. There is no way to generate trully
random numbers with a computer, everything you do is deterministic, but
you can generate sequences that look like they're random but that
aren't. Hence the term _pseudo_-random.
 
R

Robert Gamble

Antonio said:
Completely OT, but anyway... No, pseudo-random means that it looks like
it's random but it really isn't. There is no way to generate trully
random numbers with a computer, everything you do is deterministic, but
you can generate sequences that look like they're random but that
aren't. Hence the term _pseudo_-random.

Yes, we know, you didn't say anything that wasn't completely obvious.
The C Standard specifies that rand() generates pseudo-random numbers,
the questions is whether a conforming implementation could generate a
series of normal distributed numbers via the rand() function or if the
term pseudo-random implies that the numbers must be generated with a
uniform distribution. I was wondering the same thing myself, I think
the intention is that the numbers be uniform but that may be debatable.

Robert Gamble
 
E

Eric Sosman

Marc said:
Marc Dansereau wrote:



humm ... according to Knuth, this loop will be executed "1.27 times on the
average, with a standard deviation of 0.587" (Art of computer programming
2, p 117), wich is probably not bad. I beleve him, but still wonder if
there is a way to avoid performance degradation when the values of u1 and
u2 are very small.

What is `limit' and why do you test against it? It
looks pointless to me, serving only to increase the
expected number of iterations by reducing the probability
of "acceptance" from pi/4 to (1-limit^2)pi/4. (It may
also perturb the results, making them non-normal; I'm
not sufficiently motivated to work it out.)

Besides: This method was suggested because it's easy
to implement. As I wrote in my earlier response
> [...] faster methods
> exist if you're willing to do the extra work.

.... and since you've apparently got Knuth ready to hand,
you're staring at explicit recipes for at least two other
methods -- even more if you're looking at the third
edition. If it's speed you want, what's stopping you?
 
E

Eric Sosman

pete said:
Does "pseudo-random" mean the same thing as "uniformly distributed" ?

No. The Standard doesn't actually guarantee any particular
distribution from rand(). On the DeathStation 9000, rand()
returns 42 every time you call it.

I've always assumed that the Standard doesn't describe the
distribution because doing so would require a lot of fairly
deep mathematics; Knuth devotes thirty-five pages to the topic
"What is a random sequence?" Developing a useful theory of
the randomness of finite sequences is (it seems) no simple
matter -- certainly not a topic for the Standard to explicate.
So the Standard just says "pseudo-random," and we all understand
that it means "sort of uniform-ish in a sort of hand-waving way,
noodge noodge wink wink."

Anyhow, that's how I've imagined the committee's intent.
The Rationale sheds no further light on the matter, either.
 
S

Sensei

Hi all

I am new to this forum and to the c programming language.
If I understand, the random() function in C return numbers that follow a
uniform distribution U(0,1). Can somebody know how to generate a set of
random number that follow a normal distribution N(0,1) ? I am develloping
on power4 machine running AIX.

Thank you for your help

If by normal you mean Gaussian, remember that a sum of white
distributions tends to a gaussian. Many other methods you can choose,
less naive than this.
 
A

Antonio

Robert said:
Yes, we know, you didn't say anything that wasn't completely obvious.
The C Standard specifies that rand() generates pseudo-random numbers,
the questions is whether a conforming implementation could generate a
series of normal distributed numbers via the rand() function or if the
term pseudo-random implies that the numbers must be generated with a
uniform distribution. I was wondering the same thing myself, I think
the intention is that the numbers be uniform but that may be debatable.

It may be completely obvious to you, and to many people (including
myself), but it doesn't seem to be obvious to "pete", since he asked.
What I was trying to explain is that pseudo-random does not imply
anything about the distribution of the numbers. You may get
pseudo-random numbers that look like a uniform distribution, or
pseudo-random numbers that look like a poisson distribution, or a
gaussian distribution, or anything you want. In fact if you are able to
generate pseudo-random numbers with any distribution, you can operate
with them to obtain any other distribution you want.

On the topic of wether the standard requires the distribution to be
uniform. Well I don't know the standard by hard, but many people here
seem to have a copy of it, so it should be a simple matter to check it.
Every implementation I've seen of C and almost any other language/tool
generates pseudo-random number using a multiplicative seed, simply
becase it's a good enough method and requires relatively few
operations.

And finally, I don't know if an implementation that generated normally
distributed numbers with the rand() function would conform to the
standard, but it would be beyond foolish.
 
R

Robert Gamble

Antonio said:
It may be completely obvious to you, and to many people (including
myself), but it doesn't seem to be obvious to "pete", since he asked.
What I was trying to explain is that pseudo-random does not imply
anything about the distribution of the numbers. You may get
pseudo-random numbers that look like a uniform distribution, or
pseudo-random numbers that look like a poisson distribution, or a
gaussian distribution, or anything you want. In fact if you are able to
generate pseudo-random numbers with any distribution, you can operate
with them to obtain any other distribution you want.

On the topic of wether the standard requires the distribution to be
uniform. Well I don't know the standard by hard, but many people here
seem to have a copy of it, so it should be a simple matter to check it.
Every implementation I've seen of C and almost any other language/tool
generates pseudo-random number using a multiplicative seed, simply
becase it's a good enough method and requires relatively few
operations.

And finally, I don't know if an implementation that generated normally
distributed numbers with the rand() function would conform to the
standard, but it would be beyond foolish.

You are missing the point. The standard only states that the numbers
generated are "pseudo-random", pete knows this, I know this, anyone who
has a copy of the Standard knows this. He was specifically refering to
this wording in the Standard and asking if this requirement alone
implied a uniform disribution since the Standard does not discuss
distribution requirements.

Robert Gamble
 
A

Antonio

Robert said:
You are missing the point. The standard only states that the numbers
generated are "pseudo-random", pete knows this, I know this, anyone who
has a copy of the Standard knows this. He was specifically refering to
this wording in the Standard and asking if this requirement alone
implied a uniform disribution since the Standard does not discuss
distribution requirements.


Then I have already answered your question. No, in no way pseudo-random
implies a uniform distribution. If the point is wether the creators of
the standard had a uniform distribution in mind when they phrased the
standard, well I wasn't one of them and AFAIK neither were you, so we
could talk for ages and still get to no conclusion.

If the standard just says that rand() generates pseudo-random integer
numbers between 0 and RAND_MAX >= 32767, then it says that, and only
that. If no reference to a certain distribution is made any
distribuiton would be valid. Of course the requirement that the values
must be within a certain range rules out lots of distributions
(poisson, gauss, Student-t, chi^2, cauchy...). So, from my POV, a
rand() function that returned 0 with p probability and 32767 with (1 -
p) probability would conform to the standard... while beeing almost
totally useless.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top