Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create random number within an annulus

Tags:

python

random

I am trying generate a random number that is within an annulus, i.e. we have a max and min radius. I tried doing:

while True:
    x=random.uniform(-maxR, maxR)
    y=random.uniform(-maxR, maxR)
    R=math.sqrt(x**2 + y**2)
    if R <= maxRadius and R >= minRadius:
        if x>= -maxRadius and x <= maxRadius and x<=-minRadius and x>= minRadius:
            print "passed x"
            if y>= -maxRadius and y <= maxRadius and y<=-minRadius and y>= minRadius: 
                break

But this is very slow. Is it possible to feed more contraints into random.uniform or is there another method?

like image 511
madtowneast Avatar asked Jan 28 '12 19:01

madtowneast


People also ask

How do you generate a random number from a list of numbers?

Note: If you want to generate random number based on a list, you can use this formula =INDEX($I$2:$I$7, RANDBETWEEN(1, 6)), and press Enter key.

How do you generate random values?

Computers can generate truly random numbers by observing some outside data, like mouse movements or fan noise, which is not predictable, and creating data from it. This is known as entropy. Other times, they generate “pseudorandom” numbers by using an algorithm so the results appear random, even though they aren't.

How do you generate random numbers with random modules?

Use a random. rand(d0, d1, …, dn) function to generate an n-dimensional array of random float numbers in the range of [0.0, 1.0) . Use a random. uniform(low=0.0, high=1.0, size=None) function to generate an n-dimensional array of random float numbers in the range of [low, high) .

How do you generate a random number between 0 and 1?

Using the random.The random. uniform() function is perfectly suited to generate a random number between the numbers 0 and 1, as it is utilized to return a random floating-point number between two given numbers specified as the parameters for the function.


1 Answers

In general you can either draw the correct distribution directly or use rejection.

To draw directly use

  • draw theta uniformly on [0,2pi): theta = random.uniform(0,2*pi)
  • draw r from the power-law distribution r^1.

    The only complexity compared to doing this for a circle is that you PDF runs from [r_min,r_max] not [0,r_max]. This leads to

    CDF = A \int_{r_min}^{r} r' dr' = A (r^2 - r_min^2)/2

    for A the normalizing constant

    A = 2/(r_max*r_max - r_min*r_min)
    

    implying that

    r = sqrt(2*random.uniform(0,1)/A + r_min*r_min)
    

    and you can simplify slightly.

  • then compute (x,y) by the usual transformation from radial coordinates
    x = r * cos(theta)
    y = r * sin(theta)

This method of integrating the PDF, normalizing the CDF and inverting is general and is sometimes called the "Fundamental Theorem of Sampling".

Rejection

Draw (x,y) on a box big enough to contain the annulus, then reject all cases where `r = sqrt(xx + yy) exceeds r_max or is less than r_min.

This is reasonably efficient if the hole in the middle is small, and very inefficient if the hole is large.

like image 96
dmckee --- ex-moderator kitten Avatar answered Sep 29 '22 03:09

dmckee --- ex-moderator kitten