Suppose I want to draw a random number in the range [10^-20, 0.1], how do I do that?
If I use numpy.random.uniform, I don't seem to go lower than 10^-2:
In [2]: np.random.uniform(0.1, 10**(-20))
Out[2]: 0.02506361878539856
In [3]: np.random.uniform(0.1, 10**(-20))
Out[3]: 0.04035553250149768
In [4]: np.random.uniform(0.1, 10**(-20))
Out[4]: 0.09801074888377342
In [5]: np.random.uniform(0.1, 10**(-20))
Out[5]: 0.09778150831277296
In [6]: np.random.uniform(0.1, 10**(-20))
Out[6]: 0.08486347093110456
In [7]: np.random.uniform(0.1, 10**(-20))
Out[7]: 0.04206753781952958
Alternatively I could generate an array instead like:
In [44]: fac = np.linspace(10**(-20),10**(-1),100)
In [45]: fac
Out[45]:
array([ 1.00000000e-20, 1.01010101e-03, 2.02020202e-03,
3.03030303e-03, 4.04040404e-03, 5.05050505e-03,
6.06060606e-03, 7.07070707e-03, 8.08080808e-03,
9.09090909e-03, 1.01010101e-02, 1.11111111e-02,
1.21212121e-02, 1.31313131e-02, 1.41414141e-02,
1.51515152e-02, 1.61616162e-02, 1.71717172e-02,
1.81818182e-02, 1.91919192e-02, 2.02020202e-02,
2.12121212e-02, 2.22222222e-02, 2.32323232e-02,
2.42424242e-02, 2.52525253e-02, 2.62626263e-02,
2.72727273e-02, 2.82828283e-02, 2.92929293e-02,
3.03030303e-02, 3.13131313e-02, 3.23232323e-02,
3.33333333e-02, 3.43434343e-02, 3.53535354e-02,
3.63636364e-02, 3.73737374e-02, 3.83838384e-02,
3.93939394e-02, 4.04040404e-02, 4.14141414e-02,
4.24242424e-02, 4.34343434e-02, 4.44444444e-02,
4.54545455e-02, 4.64646465e-02, 4.74747475e-02,
4.84848485e-02, 4.94949495e-02, 5.05050505e-02,
5.15151515e-02, 5.25252525e-02, 5.35353535e-02,
5.45454545e-02, 5.55555556e-02, 5.65656566e-02,
5.75757576e-02, 5.85858586e-02, 5.95959596e-02,
6.06060606e-02, 6.16161616e-02, 6.26262626e-02,
6.36363636e-02, 6.46464646e-02, 6.56565657e-02,
6.66666667e-02, 6.76767677e-02, 6.86868687e-02,
6.96969697e-02, 7.07070707e-02, 7.17171717e-02,
7.27272727e-02, 7.37373737e-02, 7.47474747e-02,
7.57575758e-02, 7.67676768e-02, 7.77777778e-02,
7.87878788e-02, 7.97979798e-02, 8.08080808e-02,
8.18181818e-02, 8.28282828e-02, 8.38383838e-02,
8.48484848e-02, 8.58585859e-02, 8.68686869e-02,
8.78787879e-02, 8.88888889e-02, 8.98989899e-02,
9.09090909e-02, 9.19191919e-02, 9.29292929e-02,
9.39393939e-02, 9.49494949e-02, 9.59595960e-02,
9.69696970e-02, 9.79797980e-02, 9.89898990e-02,
1.00000000e-01])
and pick a random element from that array, but wanted to clarify anyway if the first option is possible since I could be probably missing something obvious.
There are two main methods that a computer generates a random number: true random number generators (TRNGs) and pseudo-random number generators (PRNGs). The former uses some phenomenon outside the computer for its number generation, whereas the latter relies on pre-set algorithms to emulate randomness².
Random integer values can be generated with the randint() function. This function takes two arguments: the start and the end of the range for the generated integer values. Random integers are generated within and including the start and end of range values, specifically in the interval [start, end].
Seventeen is: Described at MIT as 'the least random number', according to the Jargon File. This is supposedly because in a study where respondents were asked to choose a random number from 1 to 20, 17 was the most common choice. This study has been repeated a number of times.
You need to think closely about what you're doing. You're asking for a uniform distribution between almost 0.0 and 0.1. The average result would be 0.05. Which is exactly what you're getting. It seems you want a random distribution of the exponents.
The following might do what you want:
import random
def rnd():
exp = random.randint(-19, -1)
significand = 0.9 * random.random() + 0.1
return significand * 10**exp
[rnd() for _ in range(20)]
The lowest possible value is when exp=-19
and significand=0.1
giving 0.1*10**-19 = 1**-20
. And the highest possible value is when exp=-1
and significand=1.0
giving 1.0*10**-1 = 0.1
.
Note: Technically, the significand
can only aprach 1.0 as random()
is bounded to [0.0, 1.0), i.e., including 0.0, but excluding 1.0.
Output:
[2.3038280595190108e-11,
0.02658855644891981,
4.104572641101877e-11,
3.638231824527544e-19,
6.220040206106022e-17,
7.207472203268789e-06,
6.244626749598619e-17,
2.299282102612733e-18,
0.0013251357609258432,
3.118805901868378e-06,
6.585606992344938e-05,
0.005955900790586139,
1.72779538837876e-08,
7.556972406280229e-13,
3.887023124444594e-15,
0.0019965330694999488,
1.7732147730252207e-08,
8.920398286274208e-17,
4.4422869312622194e-08,
2.4815949527034027e-18]
See "scientific notation" on wikipedia for definition of significand and exponent.
As per the numpy documentation:
low : float or array_like of floats, optional Lower boundary of the output interval. All values generated will be greater than or equal to low. The default value is 0.
With that in mind, decreasing the value of low
will produce lower numbers
>>> np.random.uniform(0.00001, 10**(-20))
6.390804027773046e-06
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With