how to generate random numbers that satisfy certain distribution

T

thinke365

such as uniform distribution, Normal distribution or poisson distribution.
is there any package that can be used to generate such random numbers.
 
R

Ravi

such as uniform distribution, Normal distribution or poisson distribution..
is there any package that can be used to generate such random numbers.

Did you try random package?
 
T

thinke365

Bugzilla said:
Did you try random package?

of course i have tried random package, but can this package generate random
sequence that satisfy possion distribution , normal distribution and uniform
distribution
 
P

Peter Chant

thinke365 said:
such as uniform distribution, Normal distribution or poisson distribution.
is there any package that can be used to generate such random numbers.

I remeber being told that adding up 12 random numbers in the range 0-1
(which is what most computer random number genertors at the time chucked
out) and subtracted 6 gives a pretty good normal distribution. I think I
did try it once and it failed, but I must have done something odd.
 
A

Arnaud Delobelle

thinke365 said:
such as uniform distribution, Normal distribution or poisson distribution.
is there any package that can be used to generate such random numbers.

It's all in the standard library, the module is called -surprisingly-
'random'.

- use random.uniform for the uniform distributions
- use random normalvariate for normal distributions

There isn't a Poisson distribution function, but there is a expovariate
function. I think you can get poisson like this, but take it with a
grain of salt because my probability skills are very rusty!

import random
import itertools

def poisson(l):
e = random.expovariate
acc = 0.0
for n in itertools.count():
acc += e(l)
if acc >= 1.0:
return n
 
P

Paul Rubin

thinke365 said:
of course i have tried random package, but can this package generate random
sequence that satisfy possion distribution , normal distribution and uniform
distribution

Did you look at the documentation?
 
P

Paul Rubin

Peter Chant said:
I remeber being told that adding up 12 random numbers in the range 0-1
(which is what most computer random number genertors at the time chucked
out) and subtracted 6 gives a pretty good normal distribution. I think I
did try it once and it failed, but I must have done something odd.

That gives you a binomial distribution on 12 trials, which approximates
a normal distribution when the number of trials is large. 12 isn't too
bad. But there's a simpler way, the Box-Muller transform, that gives
you a pair drawn from a precisely normal distribution from two uniform
random samples:

http://en.wikipedia.org/wiki/Box-Muller_transform
 
S

Steven D'Aprano

of course i have tried random package, but can this package generate
random sequence that satisfy possion distribution , normal distribution
and uniform distribution

Please don't talk garbage. If you had really tried the random module, you
would know the answer. What do you think random.uniform does?

In an interactive Python session:

and read. When you've done that, if you still have any specific
questions, please ask.
 
S

Steven D'Aprano

That gives you a binomial distribution on 12 trials, which approximates
a normal distribution when the number of trials is large. 12 isn't too
bad. But there's a simpler way, the Box-Muller transform, that gives
you a pair drawn from a precisely normal distribution from two uniform
random samples:

http://en.wikipedia.org/wiki/Box-Muller_transform


The Box-Muller transform is reasonably simple, but you can't be serious
that it is simpler than adding twelve random numbers and subtracting six!

def almost_normal():
return sum([random.random() for _ in xrange(12)], -6)


Not that I'm recommending that anyone use this binomial approximation for
anything but the quickest and dirtiest uses, particularly since the
random module already has two excellent normal distributions (gauss and
normalvariate).
 
P

Paul Rubin

Steven D'Aprano said:
The Box-Muller transform is reasonably simple, but you can't be serious
that it is simpler than adding twelve random numbers and subtracting six!

If you want a normal distribution, using the Box-Muller transform is
simpler because it spares you the complication of figuring out whether
the 12-trial binomial approximation is close enough to produce reliable
results for your specific application, which you obviously have to do if
you are using the approximation for anything serious. It also involves
writing less code than that list comprehension, since it is already
implemented in the random module so you can just call it directly.
 
S

Steven D'Aprano

If you want a normal distribution, using the Box-Muller transform is
simpler because it spares you the complication of figuring out whether
the 12-trial binomial approximation is close enough to produce reliable
results for your specific application, which you obviously have to do if
you are using the approximation for anything serious.

But using Box-Miller gives you the complication of figuring out whether
you care about being thread safety, which you have to do if you're doing
anything serious. (See the comments in the random module for the gauss
method).

It also involves
writing less code than that list comprehension, since it is already
implemented in the random module so you can just call it directly.

By that logic, the Linux kernel is simpler than a function to add one to
the argument, because the Linux kernel has already been implemented but
you have to write your own add_one function.

(Except in Forth, which usually comes with a word to add one to the
number at the top of the stack.)

We can agree that, given that the random module already has two normal
distributions, there's no real point in using the binomial approximation.
Everything else is quibbling.

By the way, does anyone know why there is no Poisson random numbers in
the module? The implementation is quite simple (but not as simple as the
Linux kernel *wink*):


def poisson(lambda_=1):
L = math.exp(-lambda_)
k = 0
p = 1
while 1:
k += 1
p *= random.random()
if p <= L:
break
return k-1


although this can be improved upon for large values of lambda_.
 
R

Robert Kern

But using Box-Miller gives you the complication of figuring out whether
you care about being thread safety, which you have to do if you're doing
anything serious. (See the comments in the random module for the gauss
method).

If you care about thread-safety, each thread should get its own Random instance
anyways.
By the way, does anyone know why there is no Poisson random numbers in
the module? The implementation is quite simple (but not as simple as the
Linux kernel *wink*):


def poisson(lambda_=1):
L = math.exp(-lambda_)
k = 0
p = 1
while 1:
k += 1
p *= random.random()
if p<= L:
break
return k-1


although this can be improved upon for large values of lambda_.

Where large is about 10. That's where my implementation in numpy.random switches
over to a more complicated, but more efficient implementation. It does require a
log-gamma special function implementation, though.

#define LS2PI 0.91893853320467267
#define TWELFTH 0.083333333333333333333333
long rk_poisson_ptrs(rk_state *state, double lam)
{
long k;
double U, V, slam, loglam, a, b, invalpha, vr, us;

slam = sqrt(lam);
loglam = log(lam);
b = 0.931 + 2.53*slam;
a = -0.059 + 0.02483*b;
invalpha = 1.1239 + 1.1328/(b-3.4);
vr = 0.9277 - 3.6224/(b-2);

while (1)
{
U = rk_double(state) - 0.5;
V = rk_double(state);
us = 0.5 - fabs(U);
k = (long)floor((2*a/us + b)*U + lam + 0.43);
if ((us >= 0.07) && (V <= vr))
{
return k;
}
if ((k < 0) ||
((us < 0.013) && (V > us)))
{
continue;
}
if ((log(V) + log(invalpha) - log(a/(us*us)+b)) <=
(-lam + k*loglam - loggam(k+1)))
{
return k;
}


}

}

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
 

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top