Skip to content

Commit

Permalink
rebuilding site Sunday 25 February 2024 10:22:32 PM IST
Browse files Browse the repository at this point in the history
  • Loading branch information
animesh-chouhan committed Feb 25, 2024
1 parent 6b2f3fa commit cdcc5e3
Show file tree
Hide file tree
Showing 42 changed files with 809 additions and 70 deletions.
4 changes: 2 additions & 2 deletions 404.html
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ <h1 class="title is-2">HTTP 404</h1>
<img class="is-rounded" src="images&#x2F;avatar.jpg" style="max-width: 192px" />
</figure>
-->
<!--

<p>


Expand Down Expand Up @@ -213,7 +213,7 @@ <h1 class="title is-2">HTTP 404</h1>


</p>
-->

<p class="my-6">
<a href='/'>
<span class="icon">
Expand Down
202 changes: 192 additions & 10 deletions DeepThought/content/posts/circle-random.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
+++
title="Generate Random Point in a Circle"
title="Generate Random Points in a Circle"
extra.featured="/images/posts/circle-random.png"
date=2024-02-20
date=2024-02-24
extra.status="Done"

[taxonomies]
categories = ["Maths"]
categories = ["Maths", "Python"]
tags = ["python", "visualization"]

+++
Expand All @@ -15,17 +15,199 @@ tags = ["python", "visualization"]
<!-- more -->

<p align="center">
<img src="/images/posts/circle-random.png" alt="circle-random" style="max-width:80%"/>
<img src="/images/posts/circle-random/circle-random.png" alt="circle-random" style="max-width:80%"/>
</p>

## A Really Clever Subtitle
## Motivation

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla ac iaculis libero. Suspendisse et sodales tellus, ut sodales mi. Proin scelerisque est nec laoreet aliquet. Aenean et nunc at mi efficitur sollicitudin at quis diam. Aenean mi massa, sollicitudin eu condimentum sed, sodales ut nisi. Aenean iaculis ante id gravida hendrerit. Nulla nisi neque, facilisis vitae viverra ac, interdum malesuada quam. Quisque laoreet leo nec lectus lacinia, in lacinia enim tempor.
I found this problem on [Leetcode](https://leetcode.com/problems/generate-random-point-in-a-circle/description/) while going through Geometry problems.
So my first intuition was the most simple one, which everyone would get upon reading the problem for the first time. Unfortunately, that didn't work out,
and I had no idea why. So I went on to extend the program to visualize my solution. Check out the source code [here](https://github.com/animesh-chouhan/awesome-pyviz/tree/main/uniform-circle).

Nulla facilisi. Aenean urna metus, egestas quis mauris non, dignissim vestibulum risus. Mauris posuere nisl a massa commodo rhoncus. Fusce sed euismod dui, eget aliquet sem. Aenean quam est, iaculis quis aliquet at, semper id tellus. Suspendisse fringilla ipsum diam, suscipit commodo neque varius ac. Maecenas commodo orci vitae massa dapibus, interdum ultricies ex scelerisque. Nullam volutpat mollis aliquam. Donec fringilla interdum urna, nec posuere est tincidunt a.
Try it out with your own ideas before checking out the correct approach!

Morbi molestie aliquam congue. Sed pulvinar id lectus eget luctus. Fusce non augue efficitur, posuere dolor et, gravida enim. In ullamcorper lorem turpis, in finibus eros posuere id. Maecenas vulputate dapibus risus vel tempor. In pulvinar commodo dui eu mattis. Duis fringilla dictum elit, et dictum nisi sollicitudin non. Vestibulum fermentum ligula id augue ullamcorper, a bibendum neque ultrices.
## Problem Statement

Vivamus at volutpat dolor, vitae interdum nulla. Morbi vitae sagittis mi, a pulvinar ex. Fusce convallis diam quis turpis tristique, sodales euismod nunc ullamcorper. Aenean id nulla et leo sodales aliquam. Donec a felis vel ipsum fringilla volutpat. Praesent luctus nisl sit amet est interdum elementum. Etiam tincidunt malesuada sapien, quis tincidunt urna faucibus sed. Aliquam iaculis ex at felis sodales iaculis. Sed quis mauris finibus, consequat risus rutrum, ornare libero. Maecenas ultrices mollis nibh in interdum. Cras molestie quis velit quis dictum. Cras vehicula neque id turpis facilisis fringilla. Quisque sit amet tincidunt lectus, vel feugiat diam. Nullam euismod lacinia mi non facilisis.
So the problem requires you to write a function that generates random points that are evenly distributed inside a circle of a given radius.

Sed tempus odio vel tellus tempor laoreet. Sed finibus nulla quis velit molestie dictum. Donec efficitur sollicitudin enim in vestibulum. Etiam porta urna ut nisl scelerisque sagittis. Quisque turpis neque, vulputate nec dui ornare, dignissim aliquet mi. Proin vel scelerisque tellus. Nunc laoreet rutrum luctus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam quis diam tellus.
Suppose you are given a circle of radius **R** and the the center of the circle is **(x_center, y_center)**. Your objective is to write a function `randPoint` which
returns **[random_x, random_y]** when invoked and is then used to generate **N** points inside the circle which are distributed evenly.

You can try solving and visualizing this in a programming language of your choice but I would recommend Python given the availability of the Matplotlib library.
If using Python you can use this template if you want to use my program to visualize your solution.

Just edit the `randPoint` function with your logic to generate the coordinates. The `plot` function is already written and the source code can be found [here](https://github.com/animesh-chouhan/awesome-pyviz/blob/main/uniform-circle/circle.py#L30).

```python
class Solution:
def __init__(self, radius: float, x_center: float, y_center: float):
self.radius = radius
self.x_center = x_center
self.y_center = y_center

def randPoint(self) -> list[float]:
x = "Expression to generate x coordinate"
y = "Expression to generate y coordinate"
return [x, y]

def plot(self, description):
# Calls randPoint func and plots your solution
pass
```

You can use the following code to instantiate this class and generate the plot:

```python
radius = 5
s = Solution(radius, 0, 0)
s.plot("• Plot description")
```

After you are done writing the logic you can run the script. Before running make sure you install the dependencies.

```bash
pip3 install numpy matplotlib
python3 circle.py
```

This is what a uniform distribution looks like:

<p align="center">
<img src="/images/posts/circle-random/sqrt.png" alt="circle-random" style="max-width:min(85%, 600px)"/>
</p>

**Give this a try before heading over to the solution.**

## Solution

So after reading this problem, my naive first thought was to select a random angle **θ** between **[0, 2π]** and
then choose a distance **r** between **[0, R]**. That would give a random point on the circle.

Here's an illustration of the approach:

<p align="center">
<img src="/images/posts/circle-random/circle-random-approach.png" alt="circle-random" style="max-width:min(85%, 500px)"/>
</p>

Let's code up this approach:

```python
def randPoint(self) -> list[float]:
r = random.uniform(0, self.radius)
theta = 2 * math.pi * random.uniform(0, 1)
x = self.x_center + r * math.cos(theta)
y = self.y_center + r * math.sin(theta)
return [x, y]
```

The position of a chosen point relative to the center of the circle is **(rcos(θ),rsin(θ))**. Here **(x,y)** is returned
relative to the origin.

Now let's try to plot the points generated this way:

<p align="center">
<img src="/images/posts/circle-random/naive.png" alt="naive-approach" style="max-width:min(98%, 800px)"/>
</p>

We can already make out that this distribution isn't uniform. But what went wrong?

The second sub-figure shows the distribution of points with radius. We can see that this distribution is uniform which means that
the density of points is same for all **r** from **[0, R]**. This is why we got more points near the center as illustrated in this figure:

<p align="center">
<img src="/images/posts/circle-random/points-illustration.png" alt="points-illustration" style="max-width:min(95%, 600px)"/>
</p>

So this approach didn't work out, which made me think of a totally different approach.

Let's start with what we can generate randomly. So I looked up the Python documentation for the [random](https://docs.python.org/3/library/random.html) module and
came across a function of interest:

> `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**.
So geometrically we can generate a random point on a line segment of length **l** using:

```python
x = l * random.uniform(0, 1)
```

We can extend this to generate a point inside a square of length **l** just by adding a `y dimension`:

```python
x = l * random.uniform(0, 1)
y = l * random.uniform(0, 1)
```

<p align="center">
<img src="/images/posts/circle-random/random-square.png" alt="random-square" style="max-width:min(95%, 600px)"/>
</p>

Now, how can we use this to solve the original problem?

Let's generate points inside a square that encloses the circle of radius **R**. The side of this
square will be **2R**. You can already sense where we are trying to go with this. So after we generate a random point inside the enclosing square, we just
check if it lies inside the circle. If it does, well and good. Otherwise, we keep generating new points until we get a valid point.

Let's code this up:

```python
def randPoint(self) -> list[float]:
while True:
rand_y = random.uniform(-self.radius, self.radius)
rand_x = random.uniform(-self.radius, self.radius)
if rand_x**2 + rand_y**2 <= self.radius**2:
break
x = self.x_center + rand_x
y = self.y_center + rand_y
return [x, y]
```

The code is self-explanatory, we keep generating points unless it lies inside the circle. We check if a point is inside a circle by checking if the distance
of that point from the center is less than or equal to the radius.

Now you must be wondering why this works. The answer lies in the previous diagram itself,
we can see that if we select any smaller area than the square, the points that are uniformly distributed inside the square will be uniformly distributed
over the smaller area provided that point lies within the smaller area.

Let's see how the plot looks now:

<p align="center">
<img src="/images/posts/circle-random/rejection-sampling.png" alt="rejection-sampling" style="max-width:min(98%, 800px)"/>
</p>

**Perfect!**

When I first came up with this solution I thought this was just a hack, but turns out it is an established statistical concept known as
[rejection sampling](https://towardsdatascience.com/what-is-rejection-sampling-1f6aff92330d).

> Rejection sampling is a Monte Carlo algorithm to sample data from a sophisticated (“difficult to sample from”) distribution with the help of a proxy distribution.
Now back to the generated plot, we can notice that the number of points grows linearly with radius. This confirms our hypothesis that the number of points should
scale **linearly** with the circumference **2πr**.

Turns out we could have used this knowledge to define a distribution function using a method called [inverse transform sampling](https://en.wikipedia.org/wiki/Inverse_transform_sampling). This requires an intermediate knowledge of statistics and is thus kept out of the scope of this article. But you can read more about this approach [here](https://itecnote.com/tecnote/r-generate-a-random-point-within-a-circle-uniformly/).

The code for this approach looks like this:

```python
def randPoint(self) -> list[float]:
theta = random.uniform(0, 2 * math.pi)
R = math.sqrt(random.uniform(0, self.radius**2))
return [
self.x_center + R * math.cos(theta),
self.y_center + R * math.sin(theta),
]
```

We get the same uniform plot:

<p align="center">
<img src="/images/posts/circle-random/pdf-approach.png" alt="pdf-approach" style="max-width:min(98%, 800px)"/>
</p>

## Conclusion

We went over two different approaches on how to solve this problem. While the rejection sampling method was more intuitive, it is not as performant as
the distribution function approach. Let me know which one you liked more. If you’ve got a comment to share, reach out to me on any social media platform or email.

If you found this article valuable, share it with your friends. Stay curious!
5 changes: 2 additions & 3 deletions DeepThought/content/posts/dotfiles.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,8 @@ Here are the steps:

## Use my dotfiles

{{% alert note %}}
Warning: If you want to give these dotfiles a try, you should first fork this repository, review the code, and remove things you don’t want or need. Don’t blindly use my settings unless you know what that entails. Use at your own risk!
{{% /alert %}}
> ⚠️ **Warning**:
> If you want to give these dotfiles a try, you should first fork this repository, review the code, and remove things you don’t want or need. Don’t blindly use my settings unless you know what that entails. Use at your own risk!
Link to the repository: [dotfiles](https://github.com/animesh-chouhan/dotfiles)

Expand Down
9 changes: 6 additions & 3 deletions DeepThought/sass/base/_generic.sass
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,14 @@ a
color: $link-hover

code
background-color: $code-background
// background-color: $code-background
background-color: #cacaca
color: $code
font-size: $code-size
font-size: 85%
font-weight: $code-weight
padding: $code-padding
// padding: $code-padding
padding: .2em .4em
border-radius: 6px

hr
background-color: $hr-background-color
Expand Down
Binary file modified DeepThought/static/files/resume-animesh-public.pdf
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion DeepThought/templates/404.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ <h1 class="title is-2">HTTP 404</h1>
<img class="is-rounded" src="{{ config.extra.author.avatar }}" style="max-width: 192px" />
</figure>
{% endif %} -->
<!-- {{ macros:: social_links( social_config=config.extra.social) }} -->
{{ macros:: social_links( social_config=config.extra.social) }}
<p class="my-6">
<a href='/'>
<span class="icon">
Expand Down
2 changes: 1 addition & 1 deletion categories/dotfiles/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ <h2 class="title">
<span class="icon">
<i class="fas fa-pencil-alt"></i>
</span>
<span>323 words</span>
<span>320 words</span>
</span>

</div>
Expand Down
9 changes: 8 additions & 1 deletion categories/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ <h1 class="title is-2">
</span>
Categories
</h1>
<p class='subtitle is-4'>7 categories in total</p>
<p class='subtitle is-4'>8 categories in total</p>
<p>

<a href="https://animeshchouhan.com/categories/c/" class="mr-4">
Expand Down Expand Up @@ -156,6 +156,13 @@ <h1 class="title is-2">
<span>Maths <sup>1</sup></span>
</a>

<a href="https://animeshchouhan.com/categories/python/" class="mr-4">
<span class="icon">
<i class="fas fa-cube"></i>
</span>
<span>Python <sup>1</sup></span>
</a>

<a href="https://animeshchouhan.com/categories/vcf/" class="mr-4">
<span class="icon">
<i class="fas fa-cube"></i>
Expand Down
17 changes: 13 additions & 4 deletions categories/maths/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ <h1 class="title">
<article class="box">
<h2 class="title">
<a href='https:&#x2F;&#x2F;animeshchouhan.com&#x2F;posts&#x2F;circle-random&#x2F;'>
Generate Random Point in a Circle
Generate Random Points in a Circle
</a>
</h2>
<p class="subtitle"></p>
Expand All @@ -159,7 +159,7 @@ <h2 class="title">
<span class="icon">
<i class="far fa-calendar-alt"></i>
</span>
<span><time datetime="2024-02-20">February 20, 2024</time></span>
<span><time datetime="2024-02-24">February 24, 2024</time></span>
</span>

</div>
Expand All @@ -169,11 +169,11 @@ <h2 class="title">
<span class="icon">
<i class="far fa-clock"></i>
</span>
<span>2 min,</span>
<span>7 min,</span>
<span class="icon">
<i class="fas fa-pencil-alt"></i>
</span>
<span>389 words</span>
<span>1327 words</span>
</span>

</div>
Expand Down Expand Up @@ -204,6 +204,15 @@ <h2 class="title">
</span>
</a>

<a class="has-text-info-dark has-text-weight-semibold" href="https://animeshchouhan.com/categories/python/">
<span class="icon-text">
<span class="icon">
<i class="fas fa-cube"></i>
</span>
<span>Python</span>
</span>
</a>

</p>


Expand Down
6 changes: 3 additions & 3 deletions categories/maths/rss.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
<generator>Zola</generator>
<language>en</language>
<atom:link href="https://animeshchouhan.com/categories/maths/rss.xml" rel="self" type="application/rss+xml"/>
<lastBuildDate>Tue, 20 Feb 2024 00:00:00 +0000</lastBuildDate>
<lastBuildDate>Sat, 24 Feb 2024 00:00:00 +0000</lastBuildDate>
<item>
<title>Generate Random Point in a Circle</title>
<pubDate>Tue, 20 Feb 2024 00:00:00 +0000</pubDate>
<title>Generate Random Points in a Circle</title>
<pubDate>Sat, 24 Feb 2024 00:00:00 +0000</pubDate>
<author>Unknown</author>
<link>https://animeshchouhan.com/posts/circle-random/</link>
<guid>https://animeshchouhan.com/posts/circle-random/</guid>
Expand Down
Loading

0 comments on commit cdcc5e3

Please sign in to comment.