random number including 1 - i.e. [0,1]

E

Esmail

Hi,

random.random() will generate a random value in the range [0, 1).

Is there an easy way to generate random values in the range [0, 1]?
I.e., including 1?

I am implementing an algorithm and want to stay as true to the
original design specifications as possible though I suppose the
difference between the two max values might be minimal.

Thanks,
Esmail

ps: I'm confused by the docs for uniform():

random.uniform(a, b)
Return a random floating point number N such that a <= N <= b for a <= b

this seems to imply an inclusive range, ie. [a,b]

but this seems to contradict it:

In [3]: random.uniform?
Type: instancemethod
Base Class: <type 'instancemethod'>
String Form: <bound method Random.uniform of <random.Random object at 0x8c50754>>
Namespace: Interactive
File: /usr/lib/python2.6/random.py
Definition: random.uniform(self, a, b)
Docstring:
Get a random number in the range [a, b).
 
M

Mensanator

Hi,

random.random() will generate a random value in the range [0, 1).

Is there an easy way to generate random values in the range [0, 1]?
I.e., including 1?

I am implementing an algorithm and want to stay as true to the
original design specifications as possible though I suppose the
difference between the two max values might be minimal.

Thanks,
Esmail

ps: I'm confused by the docs for uniform():

random.uniform(a, b)
     Return a random floating point number N such that a <= N <= b for a <= b

That's wrong. Where did you get it?
Help on method uniform in module random:

uniform(self, a, b) method of random.Random instance
Get a random number in the range [a, b).

this seems to imply an inclusive range, ie. [a,b]

but this seems to contradict it:

In [3]: random.uniform?
Type:           instancemethod
Base Class:     <type 'instancemethod'>
String Form:    <bound method Random.uniform of <random.Random object at 0x8c50754>>
Namespace:      Interactive
File:           /usr/lib/python2.6/random.py
Definition:     random.uniform(self, a, b)
Docstring:
     Get a random number in the range [a, b).
 
R

Robert Kern

Hi,

random.random() will generate a random value in the range [0, 1).

Is there an easy way to generate random values in the range [0, 1]?
I.e., including 1?

I am implementing an algorithm and want to stay as true to the
original design specifications as possible though I suppose the
difference between the two max values might be minimal.

Thanks,
Esmail

ps: I'm confused by the docs for uniform():

random.uniform(a, b)
Return a random floating point number N such that a<= N<= b for a<= b

That's wrong. Where did you get it?

http://docs.python.org/library/random

--
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
 
M

Miles Kaufmann

Hi,

random.random() will generate a random value in the range [0, 1).

Is there an easy way to generate random values in the range [0, 1]?
I.e., including 1?

I am implementing an algorithm and want to stay as true to the
original design specifications as possible though I suppose the
difference between the two max values might be minimal.

I'm curious what algorithm calls for random numbers on a closed
interval.
That's wrong. Where did you get it?

http://docs.python.org/library/random.html

-Miles
 
E

Esmail

Miles said:
I'm curious what algorithm calls for random numbers on a closed interval.

I'm implementing a Particle Swarm Optimizer. Depending on what paper you
read you'll see mention of required random values "between 0 and 1"
which is somewhat ambiguous. I came across one paper that specified
the range [0,1], so inclusive 1, which was the reason for my question.
(I'm still looking for other papers to see if I can get more information
exactly on the range)

I think in the end it probably doesn't matter if it's [0, 1) or
[0, 1] as the max values for each will probably be very close.

Esmail
 
M

Mensanator

Hi,
random.random() will generate a random value in the range [0, 1).
Is there an easy way to generate random values in the range [0, 1]?
I.e., including 1?
I am implementing an algorithm and want to stay as true to the
original design specifications as possible though I suppose the
difference between the two max values might be minimal.
Thanks,
Esmail
ps: I'm confused by the docs for uniform():
random.uniform(a, b)
      Return a random floating point number N such that a<= N<= b for a<= b
That's wrong. Where did you get it?

http://docs.python.org/library/random

Ok, but the 2.6.1 docs say

random.uniform(a, b)
Return a random floating point number N such that a <= N < b
for a <= b and b <= N < a for b < a.

Is that a new feature of 2.6.2?
 
P

Paul McGuire

Hi,

random.random() will generate a random value in the range [0, 1).

Is there an easy way to generate random values in the range [0, 1]?
I.e., including 1?

Are you trying to generate a number in the range [0,n] by multiplying
a random function that returns [0,1] * n? If so, then you want to do
this using: int(random.random()*(n+1)) This will give equal chance of
getting any number from 0 to n.

If you had a function that returned a random in the range [0,1], then
multiplying by n and then truncating would give only the barest sliver
of a chance of giving the value n. You could try rounding, but then
you get this skew:

0 for values [0, 0.5) (width of 0.5)
1 for value [0.5, 1.5) (width of 1)
....
n for value [n-0.5, n] (width of ~0.50000000000000001)

Still not a uniform die roll. You have only about 1/2 the probability
of getting 0 or n as any other value.

If you want to perform a fair roll of a 6-sided die, you would start
with int(random.random() * 6). This gives a random number in the
range [0,5], with each value of the same probability. How to get our
die roll that goes from 1 to 6? Add 1. Thus:

die_roll = lambda : int(random.random() * 6) + 1

Or for a n-sided die:

die_roll = lambda n : int(random.random() * n) + 1

This is just guessing on my part, but otherwise, I don't know why you
would care if random.random() returned values in the range [0,1) or
[0,1].

-- Paul
 
J

John Yeung

Are you trying to generate a number in the
range [0,n] by multiplying a random function that
returns [0,1] * n?  If so, then you want to do
this using: int(random.random()*(n+1))  This will
give equal chance of getting any number from 0 to n.

Better still is simply

random.randint(0, n)

For other discrete random choices, you may find randrange() or choice
() useful.

John
 
A

alex23

Are you trying to generate a number in the
range [0,n] by multiplying a random function that
returns [0,1] * n?  If so, then you want to do
this using: int(random.random()*(n+1))  This will
give equal chance of getting any number from 0 to n.

Better still is simply

  random.randint(0, n)

There's a big difference between randint - which generates _integers_
in the range 0 & n - and the OPs request for generating random
floating point values between & inclusive of 0 & n.
 
A

AggieDan04

Hi,

random.random() will generate a random value in the range [0, 1).

Is there an easy way to generate random values in the range [0, 1]?
I.e., including 1?

You could do random.uniform(0, 1.0000000000000002). Due to floating-
point rounding, there are TWO original values that would return 1.0:
0.99999999999999978 or 0.99999999999999989; this may give you more
1.0's than you expected, and that's not even considering that Python's
PRNG could be non-uniformly-distributed over the 53-bit fractions. If
you're nit-picky enough to care about the less-than-winning-the-
lottery chance of getting the maximum random value in the first place,
this might be a problem.
 
J

John Yeung

Are you trying to generate a number in the
range [0,n] by multiplying a random function that
returns [0,1] * n?  If so, then you want to do
this using: int(random.random()*(n+1))  This will
give equal chance of getting any number from 0 to n.
Better still is simply
  random.randint(0, n)

There's a big difference between randint - which generates _integers_
in the range 0 & n - and the OPs request for generating random
floating point values between & inclusive of 0 & n.

Alex, did you bother to read what I quoted? Paul McGuire suggested an
alternative in case the OP was choosing integers in a roundabout way.
I was merely pointing out that Paul's solution can be more simply
achieved using a library function.

John
 
J

Jussi Piitulainen

Miles Kaufmann writes:
[...]
I'm curious what algorithm calls for random numbers on a closed
interval.

The Box-Muller transform, polar form. At least Wikipedia says so.
 
A

alex23

Alex, did you bother to read what I quoted?  Paul McGuire suggested an
alternative in case the OP was choosing integers in a roundabout way.
I was merely pointing out that Paul's solution can be more simply
achieved using a library function.

My apologies, John. I *did* read the quote, my brain just didn't parse
it correctly.

Sorry about that :)
 
J

Jussi Piitulainen

Esmail said:
random.random() will generate a random value in the range [0, 1).

Is there an easy way to generate random values in the range [0, 1]?
I.e., including 1?

I am implementing an algorithm and want to stay as true to the
original design specifications as possible though I suppose the
difference between the two max values might be minimal.

You could generate from a larger range and reject the values that
you do not want: generate from [0, 2), say, until you get a value
in [0, 1].

If you generate from [0, 1 + epsilon) with small epsilon,
rejections will be rare.

(I didn't notice this suggestion in the thread, so I'm voicing it
just in case it's not there yet.)
 
D

dickinsm

Esmail said:
Hi,

random.random() will generate a random value in the range [0, 1).

Is there an easy way to generate random values in the range [0, 1]?
I.e., including 1?

[...]

Here are three recipes, each more pedantic than the last. They all
assume that Python floats are IEEE 754 binary64 format (which they
almost certainly are on your machine), and that randrange generates
all values with equal likelihood (which it almost certainly doesn't,
but the assumption should be good enough for government work).


import random

def random1():
"""Random float in [0, 1]. Generates all floats of the form n/2**53,
0 <= n <= 2**53, with equal probability.

"""
return random.randrange(2**53+1)/2.**53

def random2():
"""Random float in [0, 1]. Generates all floats of the forn n/2**53,
0 <= n <= 2**53, with values in (0.0, 1.0) equally likely, and the
endpoints 0.0 and 1.0 occuring with half the probability of any
other value.

This is equivalent to generating a random real number uniformly on
the closed interval [0, 1] and then rounding that real number to the
nearest float of the form n/2**53.

"""
return (random.randrange(2**54)+1)//2/2.**53

def random3():
"""Random float in [0, 1]. Generates *all* floats in the interval
[0.0, 1.0] (including 0.0 and 1.0, but excluding -0.0). Each
float is generated with a probability corresponding to the size of
the subinterval of [0, 1] that rounds to the given float under
round-to-nearest.

This is equivalent to generating a random real number uniformly on
the closed interval [0, 1] and then rounding that real number to
the nearest representable floating-point number.

"""
m = (random.randrange(2**53)+1)//2
e = 1022
while random.randrange(2) and e:
e -= 1
return (m+2**52) * 2.**(e-1075) if e else m*2.**-1074
 
R

Robert Kern

Hi,
random.random() will generate a random value in the range [0, 1).
Is there an easy way to generate random values in the range [0, 1]?
I.e., including 1?
I am implementing an algorithm and want to stay as true to the
original design specifications as possible though I suppose the
difference between the two max values might be minimal.
Thanks,
Esmail
ps: I'm confused by the docs for uniform():
random.uniform(a, b)
Return a random floating point number N such that a<= N<= b for a<= b
That's wrong. Where did you get it?
http://docs.python.org/library/random

Ok, but the 2.6.1 docs say

random.uniform(a, b)
Return a random floating point number N such that a<= N< b
for a<= b and b<= N< a for b< a.

Is that a new feature of 2.6.2?

As already pointed out, it's not really a new feature of the method, but rather
a fix for the buggy documentation. Because of floating point arithmetic, one
cannot guarantee that a+(b-a)*u is strictly in [a,b) even though u is strictly
in [0,1).

--
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
 
C

Carl Banks

Hi,

random.random() will generate a random value in the range [0, 1).

Is there an easy way to generate random values in the range [0, 1]?
I.e., including 1?

I am implementing an algorithm and want to stay as true to the
original design specifications as possible though I suppose the
difference between the two max values might be minimal.

Well, I guess someone should actually describe a solution to this
rather than debate the necessity, if only for academic interest.

So, in order to do this for real:

Generate a random integer the range [0,2**53+1), probably the easiest
thing is to get a 64 bit integer and scale it using integer division
(which will also help to minimize selection bias). random.randrange
probably does something like this already.

If the number is exactly 2**53, return 1.0. Else stuff the bits of
the number into the mantissa of a double, along with -1 as the
exponent, and return that.

Implementation left as exercise, mostly because it really won't make a
difference.


Carl Banks
 
E

Esmail

Thanks everyone, I learned more than I expected about
floats :) and got some good explanations and ideas about
all of this.

Esmail
 
L

Lawrence D'Oliveiro

The Box-Muller transform, polar form. At least Wikipedia says so.

Doesn't seem to be necessary, if I interpret the following correctly
<http://en.wikipedia.org/wiki/Box-Muller_transform#Polar_form>:

Given u and v, independent and uniformly distributed in the closed
interval [−1, +1], set s = R2 = u2 + v2. (Clearly \scriptstyle R =
\sqrt{s}.) If s = 0 or s > 1, throw u and v away and try another pair
(u, v). Continue until a pair with s in the open interval (0, 1) is
found.

Since s is supposed to be in an open interval, I don't see how it makes any
difference if u and v are chosen from an open or semiopen interval. The
probability of hitting the exact endpoints is 0, after all.
 

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
474,262
Messages
2,571,056
Members
48,769
Latest member
Clifft

Latest Threads

Top