Uniform Random Points Generation
Some intriguing stuff about generating uniformly distributed random points in a circle.
Ever thought about generating uniformly distributed random points in a circle? 🤔 Wow, what a question to ask. Why would a completely sane person think about generating random points in a circle out of nowhere? But hey, I'm not completely sane. 😅
Jokes apart, intially I thought there might be one or two ways to do this, which pretty much I've already guessed. But as I started to dig deeper, I fell in a deep rabbit hole of mathematics & algorithms.
TL;DR (The python code used to generate the gifs used in this dump)
Rejection Sampling
The most trivial method one could think of is to generate random points in a square (well because it's easy as hell : just pick a random value for x
& y
in the desired range) & then check if the point lies inside the circle or not.
If it does, then we keep it/plot it, else we reject it. Hence the name Rejection Sampling
.
The Algorithm
The function simply generates 2 random points, each in the range [-1, 1]
& then checks if the point lies inside the circle or not.
Which is done by finding the distance of the point from the origin i.e. D(x, y) = √(x^2 + y^2)
& checking if it is less than or equal to the radius of the circle, which would mean that the point lies within the bounds of the circle.
Efficiency
This method is quite simple and does a pretty decent job. But the problem with this approach is that we are generating a lot of points which are getting rejected. So, the efficiency of this method reduces a lot. Upto what extent you ask? Well, let's find out.
Efficiency = Correct Points / Total Points
So, the efficiency of this method is π / 4 ≈ 0.785 ≈ 78.5%.
Polar Coordinates
In the previous method, we were limiting ourself to the cartesian coordinates. But, since we are dealing with a circle, why not switch to something suited for circles, right?
So, we switch to Polar Coordinates
. I'll do a quick recap of polar coordinates, don't worry 😅.
Polar Coordinates
Instead of representing a point in a plane using x
& y
coordinates, we represent it using r
& θ
coordinates.
Where, r
is the distance of the point from the origin & θ
is the angle made by the point with the positive x-axis.
So, basically, we fix a circle of radius r
& then move the point along the circle by chaning the angle θ
.
Since, we are guaranteed that the point lies within the circle, we can generate the points directly in the polar coordinates without any need of rejection.
So, what do we do? We generate a random value for r
in the range [0, 1]
& θ
in the range [0, 2π]
, which can be converted back to cartesian coordinates using the formulae:
The Algorithm
The function simply generates a random value for r
in the range [0, 1]
& θ
in the range [0, 2π]
.
Then, it converts these polar coordinates to cartesian coordinates using the formulae mentioned above.
Problem, Problem, Problem
Are the points generated uniformly distributed in the circle? 🤔. Clearly, as we can see in the animation, it isn't.
The centre of the circle seems to have more points for some reason.
So, what went wrong? We know that θ
is uniformly distributed in the range [0, 2π]
, but what about r
?
The random generation of r
is uniform, not a question about that. But the problem lies with the density of points.
Since we are following the fact that on average each radius would have same number of points chosen, the points gets sparsely distributed as we increase the size of the circle.
So, the points are not getting uniformly scattered around the circle.
Inverse Transform Sampling
So, what we need to do is somehow manage the density of points in the circle. How do we do that? 🤔
Well, we have something called Probability Density Function (PDF)
which can help us with this.
A Probability Density Function (PDF) is a function that describes the likelihood of a random variable taking on a particular value. It is used to specify the probability of the random variable falling within a particular range of values. i.e.
f(x) = P(a <= X <= b)
Now, we have to find the PDF for this.
Before we proceed, we need some mechanism to add to our previous uniform random number generator to generate points with a probability of 2 * r
.
Here comes the Inverse Transform Sampling
to the rescue.
Inverse Transform Sampling is a method which takes a uniform distribution & transforms it into a non-uniform distribution based on the CDF of the non-uniform distribution.
CDF ??? What's that? 🤔
A Cumulative Distribution Function (CDF) is a function that describes the probability that a real-valued random variable X with a given probability distribution will be found at a value less than or equal to x. i.e.
F(x) = P(X <= x)
It's basically the integral of the PDF from -∞
to x
.
So, we can now get to the Inverse Transform Sampling.
So, we need to do the following modification:
And there we go, we have our uniformly distributed random points in the circle. 😎
Infinite Triangles
Now, let's do something interesting. Open up your mind for some visualization. Would it be wrong to say that circle is made up of infinitely many small triangles? No, right? On top of that, the triangles are isosceles triangles (since 2 sides are equal i.e. radius of the circle).
This would act as a base for our next approach. What we need to do is to generate random points in an isosceles triangle. How do we do that? 🤔 If we look at a Rhombus, isn't it a skewed square which can be broken down into 2 isosceles triangles? If it is similar to a square, we can use our previous approach of choosing 2 random points to generate a point here.
There is one thing we need to take care of. There are 2 triangles, one of which is in the bounds of the circle & the other one is lying just in the mirrored opposite direction. So, while generating the points, if the point get out of the bounds, we can simply take the mirror image of the point with respect to the circle.
The Algorithm
The function generates 2 random points a
& b
in the range [-1, 1]
& θ
in the range [0, 2π]
.
It then checks if the point lies within the bounds of the circle or not. If not, it takes the mirror image of the point.
Everything after that is the same as Polar Coordinates
.
What did I just do?
Why r = a + b
?
It's because of probability distribution. I could have taken r = a * 2
as well. But that would have generated an uniform distribution of points.
To understand this better, let's consider the example of die: Rolling a die and mutiplying the outcome by 2 would give 2, 4, 6, 8, 10, 12 with equal probability. But, rolling 2 dice (or a die twice) and adding the outcomes would give 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 with different probabilities. And the probability distribution is fascinating too.
How to prove that the points generated are uniformly distributed in the circle?
This can be done by using Irwin Hall Distribution
.
The Irwin-Hall distribution is the distribution of the sum of n independent random variables, each uniformly distributed on the interval [0, 1].
Once again, we need to get the PDF & CDF for this distribution. Well, I'm not going to type all that formula down. Here is a snapshot of the formulae:
Pluggin in the values, we get the same PDF & CDF as the previous case. So, the points generated are uniformly distributed in the circle.
Voilla, we have our uniformly distributed random points in the circle in yet another method. 😎
More Interesting Methods
There are more interesting methods to generate uniformly distributed random points in a circle.
Even if you take the above example & tweak the selection of a
& b
a bit, you can come up with a new method.
Who would have thought that generating random points in a circle would be so intriguing & fun. I hope you enjoyed reading this as much as I enjoyed reading & writing about it.
For Some Other Night
Yeah about the Task Management Application in C, I got busy with some other stuffs & couldn't get myself ready to start it. I'll try to start it as soon as possible. I don't know what would be up for the next sleepless nights, keep guessing the topics 💁.