<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
        <title><![CDATA[fuzzymusings]]></title>
        <description><![CDATA[A space for my two cents, musings, and insights.]]></description>
        <link>https://anubhavp.dev</link>
        <generator>RSS for Node</generator>
        <lastBuildDate>Wed, 01 Apr 2026 20:50:54 GMT</lastBuildDate>
        <atom:link href="https://anubhavp.dev/feed.xml" rel="self" type="application/rss+xml"/>
        <author><![CDATA[Anubhab Patnaik]]></author>
        <atom:link href="https://anubhavp.dev/feed.xml" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[2023, A Year in Review]]></title>
            <description><![CDATA[The daunting realm of adulthood; a year of growth, challenges, and new beginnings.]]></description>
            <link>https://anubhavp.dev/blog/23.html</link>
            <guid isPermaLink="true">https://anubhavp.dev/blog/23.html</guid>
            <dc:creator><![CDATA[Anubhab Patnaik]]></dc:creator>
            <pubDate>Sun, 31 Dec 2023 00:00:00 GMT</pubDate>
            <content:encoded>
          &lt;div class=&quot;content custom&quot;&gt;
            &lt;div class=&quot;search-container&quot;&gt;&lt;/div&gt;
            &lt;h6 id=&quot;december&quot; tabindex=&quot;-1&quot;&gt;December&lt;/h6&gt;
&lt;p&gt;The new year begins with a new job and a new hustle. I am looking forward to the next year, and I am excited to see what it has in store for me.&lt;/p&gt;
&lt;p&gt;The rollercoaster of the year 2023 is coming to an end. I am glad to be back at home taking a break. Looking back, I am proud of myself for having come this far. This year has been a crucible of growth, and I am grateful for the opportunities that I have had. Life is not a fairy tale, and I have had my fair share of ups and downs. But, with enough grit, effort, and love, you can make it the kind of movie you want it to be.&lt;/p&gt;
&lt;p&gt;Here are some of the things that I have learnt this year, and wanted to share with you:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Work harder. Your success is almost directly proportional to the amount of work you put in.&lt;/li&gt;
&lt;li&gt;Keep building. There is no end to learning. Growth doesn’t foster in a comfort zone.&lt;/li&gt;
&lt;li&gt;Be kinder. You never know what someone is going through.&lt;/li&gt;
&lt;li&gt;Save. You never know when you might need it.&lt;/li&gt;
&lt;li&gt;Don’t forget to roam around. Travel. See the world. There aren’t enough places to see!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Happy New Year! 🎉&lt;/p&gt;
&lt;p&gt;December brought forth a lot of major life changes. As with every good journey, there comes an end. I’ve wrapped up my tenure at StackIt after six fulfilling months. December serves as the last month of my journey at StackIt. I’ve had a great time working at StackIt. This team is the most hard-working, and the most talented team that I have worked with. Leaving StackIt with a heavy heart full of gratitude and memories. Meanwhile, looking forward to the next step in my career.&lt;/p&gt;
&lt;p&gt;A couple of interns are also leaving, so we decided to go on a company trip to Gokarna. We had a great time at the beach. We went on a trek, had tons of food, and partied a lot on the beach. The past six months have been extremely fulfilling; made a lot of friends, learned a lot, and built a lot of stuff. Here are the &lt;a href=&quot;https://www.instagram.com/stories/highlights/17910685385785563/&quot;&gt;pics of the trip&lt;/a&gt;. The journey ended with Go-karting and gaming.&lt;/p&gt;
&lt;p&gt;Now, I’m in transition, on the lookout for the next step in my career. The excitement and dread of embarking on a new professional journey is overwhelming. Meanwhile, I have uncovered a new pain point in the developer tooling market, and I’m working on a solution. I am planning to build something of my own.&lt;/p&gt;
&lt;h6 id=&quot;november&quot; tabindex=&quot;-1&quot;&gt;November&lt;/h6&gt;
&lt;p&gt;As November came to an end; with merely a month left, I looked at my resolutions for this year and wondered if I even came close to starting them. Contemplating the decisions that I took in these past eleven months, I pondered on how much I had progressed.&lt;/p&gt;
&lt;p&gt;This year, I&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Graduated College&lt;/li&gt;
&lt;li&gt;Got a Job/ started my entrepreneurial journey&lt;/li&gt;
&lt;li&gt;Moved to Bangalore; started living away from home&lt;/li&gt;
&lt;li&gt;Somehow managed to make money, and send some back home; started paying my bills&lt;/li&gt;
&lt;li&gt;Started paying taxes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By the end of this year, I want to have&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;built more projects&lt;/li&gt;
&lt;li&gt;read and written more&lt;/li&gt;
&lt;li&gt;become more fit than I was in January&lt;/li&gt;
&lt;li&gt;built a solid plan for the next two to three years&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Before beginning 2024, I want to have grown to look back at 2023 and be proud of myself; thus, I will be working on myself for the next month.&lt;/p&gt;
&lt;p&gt;The festive season in Nov is always a busy time for us Indians. It brings forth long weekends, leaves, and holidays. Corporate folks save up leaves and vacation days to go back home and cherish the season with friends and family. I, too, went back home for this Diwali. We had a Puja at home, and I met my extended family. It was a weekend of fun and a break from my work life. Both my sisters had their birthdays in the beginning of November, and I had to get both of them gifts.&lt;/p&gt;
&lt;p&gt;Returning from home is always a challenge. The dreaded steps that I take on mornings when I know I have a flight to catch are the worst. This time too, I did not want to return and with each breath that I took, I wished somehow magically I wouldn’t have to leave my home, and yet I would be employed and earning a living. I had to leave, and with a heavy heart I mustered all courage inside me, and I did. Rio never gets why I have to leave. He is always by my side whenever I am in my home and tries his best to not let me leave my room. There are things that humans do that dogs do not understand, like leaving. I wish I could explain to him that I have to leave, and I will be back soon. While he knows that I will be back someday, he still makes those puppy eyes, unable to speak up or do anything, just looks at me leave. If only I could explain that leaving is a transient inevitability!&lt;/p&gt;
&lt;p&gt;The following week was a stressful one. At Stackit, I had a lot of pending tasks on the backlog. While back at home I had to prepare for an important test. The highlight of the week was watching India go into finals in the ICC Men’s Cricket World Cup. Even though I am not a sports fan, looking at my country at the top of the leaderboard, undefeated, making its way to win the finals made me proud.&lt;/p&gt;
&lt;p&gt;Tech:&lt;/p&gt;
&lt;p&gt;Currently working on building an Nl2SQL engine for StackIt. A platform that can effortlessly translate natural language queries into SQL, automating the entire data extraction and analysis process. The tech behind this would involve vectorizing SQL schemas and using a multi-query engine to find the appropriate schema-embedding section to send to the LLM to generate SQL queries.&lt;/p&gt;
&lt;p&gt;At StackIt, we have decided to have a &lt;code&gt;demo pitch round&lt;/code&gt; each Saturday. We make presentations to show what we’ve built in the entire week. Inspired by this, a zeal to build my own presentation came rushing. Thus, I started &lt;a href=&quot;https://github.com/anubhavpgit/dough&quot;&gt;Dough&lt;/a&gt;: a rich, modular, command-line tool to generate presentations written in Rust.&lt;/p&gt;
&lt;p&gt;Meanwhile, I am planning to pick back up &lt;a href=&quot;https://github.com/anubhavpgit/b&quot;&gt;Bee&lt;/a&gt;: a command-line bit-torrent client to download torrents written in Rust. I am looking to explore esoteric programming languages and look into the interpreters. Curious about game dev, I am also looking to get my hands dirty with tactical FPS/ open-world games.&lt;/p&gt;
&lt;p&gt;Research:&lt;/p&gt;
&lt;p&gt;I am diving deeper into the world of AI, prompt engineering and fine-tuning LLMs to convert natural language to SQL queries. The impetus for this exploration stemmed from the shortcomings of an NL2SQL generator at StackIt, prompting a quest for a robust platform automating SQL generation from natural language queries. The model was not able to generate SQL queries for complex questions. Thus, I am trying to understand the prompt engineering behind the entire infrastructure of Lookup AI. Our strategic plan involves developing a platform that can effortlessly translate natural language queries into SQL, automating the entire data extraction and analysis process.&lt;/p&gt;
&lt;h6 id=&quot;october&quot; tabindex=&quot;-1&quot;&gt;October&lt;/h6&gt;
&lt;p&gt;October began with a bang. I had a lot of trips planned out. I went to a trip in Dubai! Meanwhile, my childhood friends and I had a week-long trek planned to Kedarnath, UK. Four of us, Mukul, Hritik, Hemant, and I were going to meet in Delhi and then head to Haridwar. Read more about the trip &lt;a href=&quot;/blog/fall23.html&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I am diving deeper into the world of AI, prompt engineering and fine-tuning LLMs to convert natural language to SQL queries. The impetus for this exploration stemmed from the shortcomings of an NL2SQL generator at StackIt, prompting a quest for a robust platform automating SQL generation from natural language queries. The model was not able to generate SQL queries for complex questions. Thus, I am trying to understand the prompt engineering behind the entire infrastructure of Lookup AI. Our strategic plan involves developing a platform that can effortlessly translate natural language queries into SQL, automating the entire data extraction and analysis process.&lt;/p&gt;
&lt;h6 id=&quot;september&quot; tabindex=&quot;-1&quot;&gt;September&lt;/h6&gt;
&lt;p&gt;&lt;a href=&quot;/blog/lifeinametro.html&quot;&gt;Settling down in Bangalore&lt;/a&gt; and looking forward to a new, competitive and exciting software engineering life here. The new house is lovely and living with my best friends solves more problems than I anticipated. I am trying to make out time of my schedule to play the guitar more, write more, work on my projects, and also polish up my data structures and algorithms as well. For a good part of my adulthood, I tried to avoid investments and always had my dad take care of them. Now, I have decided to learn more about stocks, investments and the pile of cash surrounding it. I aspire to be physically fit, but my appetite for junk food has spread like wildfire. I am trying to get into a routine and lose a considerable amount of weight before hitting the gym.&lt;/p&gt;
&lt;p&gt;My current endeavours encompass a broad spectrum of technical challenges and innovations, ranging from plugin development and deployment optimization to AI-driven solutions that promise to transform the way we interact with data.&lt;/p&gt;
&lt;p&gt;Engaged with &lt;a href=&quot;https://nowstackit.com&quot;&gt;StackIt&lt;/a&gt;, I am working with Google AppScript, React, and Nodejs to build the StackIt Plugin. Our primary focus is on seamlessly integrating a payment infrastructure into the plugin.&lt;/p&gt;
&lt;p&gt;Dealing with Google AppScript has proven somewhat challenging. The documentation is not that great and the community is not active. Meanwhile, within the cloud platform, our objective is to establish a clear demarcation between production, pre-production, and development environments for our plugin. We use Docker to create containers for each of us developers and separate virtual machines for each of the environments. Our current hurdle revolves around mapping multiple host ports to corresponding container ports, further complicated by our SSL certificate setup.&lt;/p&gt;
&lt;p&gt;To streamline the Node.js and Docker deployment process, I’ve been experimenting with bash scripts, aiming to automate these tasks efficiently. For the React Project, I’ve successfully established a Continuous Deployment (CD) pipeline, facilitating deployments into the Google AppScript environment through Clasp. All of this is being built leveraging Github Actions. I am also working on refactoring the code base to make it more robust, modular and readable.&lt;/p&gt;
&lt;p&gt;While working on the AI vertical of StackIt I am planning to invest time to understand the prompt engineering behind the entire infrastructure of Lookup AI. Our strategic plan involves developing a platform that can effortlessly translate natural language queries into SQL, automating the entire data extraction and analysis process.&lt;/p&gt;
&lt;h6 id=&quot;august&quot; tabindex=&quot;-1&quot;&gt;August&lt;/h6&gt;
&lt;p&gt;In between all this chaos, A friend visited me in Bangalore. An entire weekend of fun and frolic ensued, as we explored the city and met with friends. It was a much-needed break from the stress of the past few weeks. Two days felt like what was a few hours, and I cherished every moment of it. There are times when I just sit back and wonder how much life has given me and amongst a busy schedule, tough job, less money, and hundreds of whatnots, I have a thousand reasons to be grateful and happy.&lt;/p&gt;
&lt;p&gt;Whilst I want to go back to my home, I also love the hustle and bustle of the city and want to build something here. This eternal dilemma is killing me. I am trying to find a balance between the two. Bangalore brings out hope, and discomfort, moulding and shaping me in different forms, challenging me while providing me with growth and success. On the other hand, my home is a place of comfort, love, and familiarity, and provides a sense of belonging.&lt;/p&gt;
&lt;h6 id=&quot;july&quot; tabindex=&quot;-1&quot;&gt;July&lt;/h6&gt;
&lt;p&gt;The past few months have been a whirlwind of new experiences for me. Navigating a new city, a fresh job, and an unfamiliar way of life has certainly kept me on my toes. I have been trying to get a hang of the new city, the new job and the new life. I got to attend a lot of networking events in Bangalore.&lt;/p&gt;
&lt;p&gt;At StackIt, we meet a lot of startups and enterprises and try to see if our product solves their problem. We went to Chargebee’s Finance and Ops conference, Google IO Connect, and The Magic Ball event. Each of these experiences provided valuable insights into the industry landscape and allowed us to make meaningful connections. Moreover, our recent involvement in YC’s Startup School, focusing specifically on the AI domain, proved to be a significant milestone. This platform served as the launch pad for our AI vertical, marking a successful endeavour in this direction.&lt;/p&gt;
&lt;p&gt;However, life threw me a curveball when I fell ill just last month. The diagnosis was a combination of dengue and a stomach ulcer, which necessitated a week-long hiatus to recover back home. My return to Bangalore revealed a turbulent living situation. I had to shift from where I was staying since the rent and overall expenses of the place shot up. There were a lot of unknowns and a ton of expenses that kept on piling up. My roommates did not inform me earlier about this and as soon as I paid the deposit,  I was confronted with a daunting list of a shitload of bills that I needed to clear. As I refused to pay, they asked me to find a replacement, or else I would not get back the deposit.&lt;/p&gt;
&lt;p&gt;Meanwhile, &lt;a href=&quot;https://injuly.in&quot;&gt;Srijan&lt;/a&gt; encountered his housing predicament. His landlord’s strict no-visitor policy left us with no option but to consider securing a place of our own. Amidst these challenges, my mother stepped in admirably, caring for me during my illness and remaining by my side upon my return to Bangalore.&lt;/p&gt;
&lt;h6 id=&quot;june&quot; tabindex=&quot;-1&quot;&gt;June&lt;/h6&gt;
&lt;p&gt;Moving to Bangalore has been tough. The sheer number of people and the traffic is overwhelming. Coming from a place where I had my room, spent a ton of time with my friends, and had a lot of time to myself, it’s been a bit of a challenge to settle down here. I have been trying to get used to the city, and it’s been almost a month since I moved here, and &lt;a href=&quot;/blog/lifeinametro.html&quot;&gt;here’s what it’s like&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;While adapting to this new environment, at StackIt things have been going great. The product is in a very early stage, so the sheer amount of effort that goes into building the product is immense. The workload is a lot, and it’s difficult to figure out where time passes by. Looking back, I see that it’s already July, and it feels as if I had just joined a few days back!&lt;/p&gt;
&lt;p&gt;I have been actively engaged in client-side development using React and Google App Script while waiting for the setup of the development environment. The backend is built in NodeJs. Though I have been enjoying working with React, the client-side development env is wrecked, and it takes a lot of time; to render changes I always need to do a test deployment. The code is written by someone before me, and it’s challenging to understand the workflow, I have been trying to get a hang of it since I joined.&lt;/p&gt;
&lt;p&gt;The best part of June is also getting a side gig as a full-stack developer at Asymmetri, working on a PDF generator.&lt;/p&gt;
&lt;h6 id=&quot;may&quot; tabindex=&quot;-1&quot;&gt;May&lt;/h6&gt;
&lt;p&gt;As I near the end of my four-not-so-long-year college journey, it feels like the end of an era. Looking back, I am filled with immense gratitude for the incredible experiences and memories that I have garnered throughout my college life. I made lifelong friends, discovered new passions, and grew both personally and professionally. &lt;a href=&quot;/blog/teasquared.html&quot;&gt;Teasquared&lt;/a&gt; is an ode to my alma mater.&lt;/p&gt;
&lt;p&gt;Reflecting on my journey, I recently bid adieu to the IEEE Students’ Chapter, where I served as the President (Chairperson) for the past year. &lt;a href=&quot;https://www.linkedin.com/in/aditya-viswabhusan/&quot;&gt;Aditya&lt;/a&gt; passed on the torch and I did my best to keep it lit. I am proud of the accomplishments of the chapter and the team that I worked with, and I hope that the chapter continues to grow and thrive in the years to come. I still remember the day &lt;a href=&quot;https://www.linkedin.com/in/saurav-jha-4a01341b1/&quot;&gt;Saurav&lt;/a&gt; sir and I established SWITCH, the official coding club of the college. We wanted to establish a coding community for students by conducting workshops, hackathons, and coding competitions. I wish SWITCH all the best with its new management and hope it continues to thrive. I wanted to accomplish a lot with &lt;a href=&quot;https://cbrtl.github.io/&quot;&gt;CBRTL&lt;/a&gt; but maybe the timing wasn’t right. &lt;a href=&quot;https://injuly.in&quot;&gt;Srijan&lt;/a&gt; and I started cbrtl, a small, tight-knit group of programmers and open-source sorcerers who like to craft fun projects together and build a community. The Social Media Cell was a fun experience. I worked as a photographer, and I was responsible for capturing the moments and memories of the college. We recently had a hearty farewell organized by the whole SSMC team, and hope to stay connected with each other.&lt;/p&gt;
&lt;p&gt;While it is bittersweet to say goodbye to this phase of my life, I am eagerly looking forward to embarking on a new chapter. With my sights set on new horizons, I am excited to see where life takes me and to see what the future holds. I am exploring my options and scouring for opportunities. I intend to work with the biggest tech companies, building products and creating differences.&lt;/p&gt;
&lt;p&gt;I got an internship at &lt;a href=&quot;https://nowstackit.com&quot;&gt;StackIt&lt;/a&gt;. I intend to work with web applications and set up CI/CD and data pipelines.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;“At StackIt, we wish to take Spreadsheets into a new era. We are building the next-generation spreadsheet automation platform that will empower 1 billion+ business users to use spreadsheets as their business OS. StackIt is a Google Sheets Editor Plugin. Business teams can rely on StackIt to pull data from popular SaaS tools &amp;amp; internal databases like Chargebee, PostgreSQL, MySQL, etc regularly on spreadsheets. They can further analyze and build workflows &amp;amp; dashboards on top of it using StackIt.”&lt;/em&gt;&lt;/p&gt;
&lt;h6 id=&quot;april&quot; tabindex=&quot;-1&quot;&gt;April&lt;/h6&gt;
&lt;p&gt;I hosted &lt;a href=&quot;https://www.linkedin.com/posts/anubhabpatnaik0530_git-groove-getting-into-the-rhythm-of-version-activity-7050527332519862272-jniz?utm_source=share&amp;amp;utm_medium=member_desktop&quot;&gt;Git Groove&lt;/a&gt;: Getting into the rhythm of version control with Git &amp;amp; GitHub, with the UnStop Chapter of SIT, BBS and it was a huge success. We are planning to host a more advanced session on Git and GitHub shortly. There’s also a web development workshop coming up.&lt;/p&gt;
&lt;p&gt;Meanwhile, at IEEE, we arranged a talk show that focused on getting to know IEEE and its benefits. The IEEE Students Chapter is dedicated to promoting knowledge and understanding of engineering.&lt;/p&gt;
&lt;p&gt;Lately, I’ve been working on a custom bit-torrent client to download files and movies based on recommendations from my &lt;a href=&quot;https://github.com/anubhavpgit/Movie-recommendation&quot;&gt;movie recommendation system&lt;/a&gt; and a &lt;a href=&quot;https://github.com/anubhavpgit/Movie-rating-prediction&quot;&gt;movie rating prediction system&lt;/a&gt;. The goal is to integrate both these systems to work with this bit-torrent client I have been building to download movies based on recommendations.&lt;/p&gt;
&lt;p&gt;I recently visited Bangalore and met with my friends; to explore and pursue a new idea. We had a great time, and I look forward to meeting them again. My primary priority remains the same, to work with one of the top tech companies and work on projects I am passionate about. While I go and hunt, &lt;a href=&quot;https://injuly.in&quot;&gt;Srijan&lt;/a&gt; and I have planned to start something of our own! The egg has just been laid, and we have a lot of figuring out to do, but I am excited about it.&lt;/p&gt;
&lt;h6 id=&quot;march&quot; tabindex=&quot;-1&quot;&gt;March&lt;/h6&gt;
&lt;p&gt;March had mid-semester exams in stock for me. I thought I wouldn’t pull through and fail miserably. (Chill. That didn’t happen xD). But as I geared towards preparing for the exams, desperately trying to collect notes, a sense of responsibility dawned upon me. A friend reminded me that we were supposed to build the half-baked project together that makes notes and academic materials accessible for free and I started on the first day of my exam and completed it &lt;a href=&quot;https://resoc.in/&quot;&gt;Resoc&lt;/a&gt; on the last day of the exam. (Funny how I managed to find a way not to study enough xD). You can read more about it &lt;a href=&quot;https://anubhavp.dev/blog/resoc.html&quot;&gt;here&lt;/a&gt;. We acquired a user base of 96 with an average engagement time of 3m14s and more than 2980 reads within a week of launch! We are looking for active contributors interested in contributing their notes.&lt;/p&gt;
&lt;p&gt;With the end of the semester approaching, I am looking forward to a much-needed break. However, this impending respite also brings with it the realization that my time in college, particularly with my friends, is dwindling. My mind races back to those initial days when I struggled to introduce myself to seniors and make friends. Those moments, in retrospect, were the extent of my worries back then!&lt;/p&gt;
&lt;p&gt;Today, the landscape of my concerns has transformed exponentially. Each morning, as I wake up, a whirlwind of thoughts engulfs my mind. I become aware that there is an overwhelming number of challenges and dilemmas that I may never fully resolve. Now, standing at the crossroads between the present and the future, I’m confronted with the weight of responsibilities and uncertainties. The path to adulthood feels daunting, and the magnitude of the challenges can be overwhelming.&lt;/p&gt;
&lt;p&gt;As the days of college slip away, I’m determined to make the most of the time I have left. I cherish the friendships I’ve formed and know that they may change but will always hold a special place in my heart.&lt;/p&gt;
&lt;p&gt;Furthermore, as I gear up to graduate this year, I am actively scouring the web for compelling summer internship opportunities, and well, jobs.&lt;/p&gt;
&lt;h6 id=&quot;february&quot; tabindex=&quot;-1&quot;&gt;February&lt;/h6&gt;
&lt;p&gt;I am thrilled to have bagged the &lt;a href=&quot;https://drive.google.com/file/d/1vTZl3K2kRTJgDgFr3lN5mxSaz7pnwvc2/view?usp=share_link&quot;&gt;Best Delegate&lt;/a&gt; award in the XIMUN 2023, the annual Model United Nations conference hosted by XIM University, with my go-to co-delegate, &lt;a href=&quot;https://www.linkedin.com/in/avinashprasad-2001/&quot;&gt;Avinash&lt;/a&gt;. Our team represented Pakistan in the Disarmament and International Security Committee (DISEC). We decided to go with Pakistan because representing any other nation or a P5/ NATO nation is relatively more straightforward because there are fewer fingers pointed at you and Pakistan presented a unique challenge due to its reputation for alleged notorious activities. Overall, it was a satisfying victory, and I am grateful for the opportunity to have participated.&lt;/p&gt;
&lt;p&gt;I am modifying zuzu to port my &lt;a href=&quot;https://anubhavp.dev/paperblog&quot;&gt;blog&lt;/a&gt; (written in Hugo) to &lt;a href=&quot;https://anubhavp.dev/zuzu&quot;&gt;zuzu&lt;/a&gt;. This entire site and the blog are now built using zuzu. Zuzu is a custom static site generator written in JavaScript. It includes static file compilation, dynamic search, and an RSS feed generator. You can find the source code &lt;a href=&quot;https://github.com/anubhavpgit/zuzu&quot;&gt;here&lt;/a&gt;. Currently, it is in a very early stage of development, and it is designed to work like a basic static site generator. But it can be modified to cater to your needs easily.&lt;/p&gt;
&lt;h6 id=&quot;january&quot; tabindex=&quot;-1&quot;&gt;January&lt;/h6&gt;
&lt;p&gt;My time as &lt;a href=&quot;https://github.com/anubhab-patnaik&quot;&gt;a full-stack engineering intern&lt;/a&gt; at &lt;a href=&quot;https://squbix.in&quot;&gt;Squbix Digital&lt;/a&gt; had to come to an end. I’m grateful for the opportunity. During this stint, I was tasked with building web and mobile apps to integrate with the spinal blockchain. My work included but was not limited to, TypeScript, NodeJs, ReactJs, React Native, Substrate, and Rust which was primarily focused on Web-3 dev; cryptocurrencies, decentralized applications, blockchains, and NFTs. I was also responsible for refactoring React-Native applications with better UI, building offline consistent storage services, push notifications, and an internal ERP system to monitor the attendance and tasks of employees, modifying the existing NodeJs code configuring optional parameters to switch between blockchains, refactoring the JS-based SDK to TypeScript. We also had to build a browser extension, and a PWA for the wallet-to-wallet transactions. The challenging part was the Polkadtot chain, where I messed up the existing DID (identity) pallet using Rust and Substrate to store ID information in the blockchain.&lt;/p&gt;
&lt;p&gt;The other part of the month was an exhilarating trip to two of India’s most bustling cities, Mumbai and New Delhi. The highlight of my visit was attending Mood Indigo 2023, the annual cultural extravaganza hosted by IIT Bombay. The entire trip and the experience left me in awe- exploring old forts, indulging in street food, and immersing myself in the vibrant culture of these cities.&lt;/p&gt;

            &lt;hr&gt;
            &lt;div class=&quot;footer&quot;&gt;
              &lt;i&gt;Feedback, Suggestions, Comments - &lt;/i&gt;
              &lt;div class=&quot;giscus-div&quot; id=&quot;comments&quot;&gt;
                &lt;script src=&quot;https://giscus.app/client.js&quot; data-repo=&quot;anubhavpgit/anubhavpgit.github.io&quot; data-repo-id=&quot;MDEwOlJlcG9zaXRvcnk0MDQ1ODEzMjc=&quot; data-category-id=&quot;DIC_kwDOGB1rz84Cer0j&quot; data-mapping=&quot;title&quot; data-strict=&quot;0&quot; data-reactions-enabled=&quot;1&quot; data-emit-metadata=&quot;0&quot; data-input-position=&quot;bottom&quot; data-theme=&quot;noborder_light&quot; data-lang=&quot;en&quot; data-loading=&quot;lazy&quot; crossorigin=&quot;anonymous&quot; async=&quot;&quot;&gt;&lt;/script&gt;
              &lt;/div&gt;
              Feel free to
              &lt;a id=&quot;mailtoLink&quot; href=&quot;mailto:anubhavp@duck.com?subject=Here&apos;s%20a%20suggestion/feedback!&quot;&gt;send
                me an email&lt;/a&gt;.
            &lt;/div&gt;
          &lt;/div&gt;
        </content:encoded>
            <subtitle>The daunting realm of adulthood; a year of growth, challenges, and new beginnings.</subtitle>
        </item>
        <item>
            <title><![CDATA[2024, A Year in Review]]></title>
            <description><![CDATA[The magic and the storms that shaped my 2024]]></description>
            <link>https://anubhavp.dev/blog/24.html</link>
            <guid isPermaLink="true">https://anubhavp.dev/blog/24.html</guid>
            <dc:creator><![CDATA[Anubhab Patnaik]]></dc:creator>
            <pubDate>Tue, 31 Dec 2024 00:00:00 GMT</pubDate>
            <content:encoded>
          &lt;div class=&quot;content custom&quot;&gt;
            &lt;div class=&quot;search-container&quot;&gt;&lt;/div&gt;
            &lt;h6 id=&quot;december&quot; tabindex=&quot;-1&quot;&gt;December&lt;/h6&gt;
&lt;p&gt;2024 comes to an end. A year full of growth. 2024 has been a year of immense growth for me, both personally and professionally. I embarked on numerous journeys, traveled to a lot of new places, so much so that I moved from India to the US. Mentally exhausting, but extremely satisfying. New York City is as beautiful as ever. The streets are filled with lights, and the air is filled with the sound of Christmas carols. The city is bustling with magic, love and happiness, and the festive season is in full swing. With the onset of 2025, I plan on taking a break from everything and visiting home, back in Bhubaneswar.&lt;/p&gt;
&lt;p&gt;Ever tried to convert a PNG to SVG? Here’s why it is difficult to achieve this: the two formats fundamentally differ in how they represent images. PNG images are pixel-based, meaning they store visual information as a grid of colored pixels, whereas SVG images are path-based, relying on mathematical equations to describe shapes, lines, and curves. The challenge lies in translating the discrete, resolution-dependent data of a PNG into smooth, resolution-independent vector paths.&lt;/p&gt;
&lt;p&gt;I was experimenting with pixel-art; trying to convert PNG and SVG formats to pixel art and stumbled across this issue above. To solve this, I am spending the next couple of weeks working on a application of Fourier series, a mathematical tool for approximating complex shapes with sums of sine and cosine functions. A Fourier series represents a periodic function as a sum of sine and cosine waves, each with specific frequencies, amplitudes, and phases, allowing complex patterns to be broken into simpler components. This might not be the best, most efficient solution, but a fun, educational exercise nonetheless.&lt;/p&gt;
&lt;p&gt;Meanwhile, here’s a small pixel-art generator for SVGs and PNGs written in Rust: &lt;a href=&quot;https://github.com/anubhavpgit/pixlr&quot;&gt;pixlr&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Yatch, the RISCV simulator, is shaping up well. The forward pass and stalling work well with the current nop setup and bubble implementation. I am currently focused on fixing minor issues in the hazard detection pipeline and am yet to implement multiplexers for forwarding, branch prediction, and control mechanisms.&lt;/p&gt;
&lt;h6 id=&quot;november&quot; tabindex=&quot;-1&quot;&gt;November&lt;/h6&gt;
&lt;p&gt;I finally built that 32-bit machine code simulator for RISCV in C++, &lt;a href=&quot;https://anubhavp.dev/blog/hacktoberfest.html&quot;&gt;Yatch&lt;/a&gt; which I was supposed to, do for Hacktoberfest. It took me a longer time due to my mid-semester in between. It supports a realistic five-stage pipeline for processing multiple instructions concurrently with measures for avoiding control and data hazards. It is currently capable of executing RV32I instructions, and I am planning to extend it to support RV32M, RV32A, and RV32F instructions. The project is still in its early stages, and I am looking for contributors. If you are interested in contributing, feel free to reach out to me.&lt;/p&gt;
&lt;p&gt;Debugging Yatch inspired me to build a machine code decoder to analyze RV32I instructions and translate them to assembly. A standalone version is in the works which would be capable of encoding assembly to machine code as well. Check it out here: &lt;a href=&quot;https://anubhavp.dev/barney/&quot;&gt;Barney&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Researching more on designing compilers and automata theory, I came across Conway’s Game of Life, a fascinating 0-player cellular automaton that follows simple rules to create complex patterns and is turning complete. Here’s my implementation of the Game of Life: &lt;a href=&quot;https://anubhavp.dev/blog/gameoflife.html&quot;&gt;Conway’s Game of Life&lt;/a&gt;. It’s exciting to see how the four rules are capable of creating such complex patterns, such that you can build a computer using them.&lt;/p&gt;
&lt;p&gt;Back home, November ushers in the festive season, where the celebrations typically begin in September- October with Ganesh Puja, Navratri, Durga Puja, and Dussehra leading up to Diwali in November. Now, I am used to a different energy of festivities and celebrations. I lived my whole life in central-eastern India, and here in Odisha, West Bengal, and Jharkhand, the Navratri- Durga puja celebrations are the grandest, leading up to Diwali and Chhath Puja. The streets are filled with lights, and the air is filled with the sound of crackers. The houses are decorated with lights, and the markets are filled with people buying clothes, sweets, and gifts. We roam around days and nights, tuitions are shut down, school has a different energy, and the entire city is filled with love and happiniess.&lt;/p&gt;
&lt;p&gt;Diwali is usually spent in phases. The first phase is when Diwali hasn’t begun, but the sale of crackers has started, and we cannot wait and get a bunch. We spend the next two days bursting crackers, and the challenge is to save enough to celebrate properly on the main Diwali Day. The Diwali Day is filled with love, laughter and happiness. New clothes, sweets, and family get-togethers are musts. The next day is spent visiting friends, bursting crackers with family, and playing cards. Now that I am not home, I feel that I am old enough to be let into the room that elders lock because they drink and gamble. I miss the fun, the laughter, the food, and the love.&lt;/p&gt;
&lt;p&gt;Dealing with post-Diwali blues is morbid. The house is a mess, the lights are off, the sweets are over, and the crackers are burnt. The house is empty, and the silence is deafening. The only thing that remains is the memories of the fun we had and the love we shared.&lt;/p&gt;
&lt;p&gt;Two months later, in December, we look back at the memories we’ve made, surprised at how quickly another year has gone by. I still sometimes do not fully understand how have I managed to get by, this year.&lt;/p&gt;
&lt;p&gt;It’s hard not being at home. New York is lovely and feels just like home, but it’s not. To you, alone, in a different place, not being able to come home on Diwali, I wish it gets better. Happy Diwali, everyone!&lt;/p&gt;
&lt;h6 id=&quot;october&quot; tabindex=&quot;-1&quot;&gt;October&lt;/h6&gt;
&lt;p&gt;Halloween is here, and fall in NYC is as beautiful as ever. The leaves are changing colours, and the days are getting cooler. Sunny days are the best. I’m adapting to the colder weather, the daily commute, and the steady stream of assignments. The workload is getting tougher, and my motivation to study is wearing thin. October has been full of learning and growth. I’m back to grinding on Leetcode, polishing my skills and trying to stay consistent. I’ve started cooking daily, adjusted my lifestyle, focused on eating healthier, and even lost 5 kg in a month through consistent workouts.&lt;/p&gt;
&lt;p&gt;For the Hacktober fest, I wanted to take up  &lt;a href=&quot;https://github.com/anubhavpgit/yatch&quot;&gt;Yatch&lt;/a&gt;: a machine code interpreter for RISC-V in Python/C++. The aim here is to learn more about compilers, the workings of CPUs, and computer systems architecture. This a great project to get started with if you’re keen to learn about low-level programming. I’d love to collaborate with others who share similar interests.&lt;/p&gt;
&lt;p&gt;The academic pressure was so huge that I had zero time to take out from my schedule to work on any of these. I was heavily occupied with assignments, Leetcode practice, and staying on top of my fitness goals. I aim to wrap up these projects by the first week of November.&lt;/p&gt;
&lt;p&gt;October’s highlight? Spending time with my cousin, a serial entrepreneur with multiple outlets of a popular mobile carrier provider here in Manhattan. Half the month was a first-hand crash course in consumer business as I watched him engage customers, close sales, and manage operations. I learned more about sales, customer acquisition and service than any book or course could have taught me.&lt;/p&gt;
&lt;p&gt;I saw what makes customers want to spend, what makes them ick, and what they’re usually willing to pay. Confidence is essential. If they have a sniff that they are being charged extra, you’re done. You need smooth communication skills. I also realized how empathy can drive sales, and that upselling is a skill. Selling a $300 item for something valued at $100 requires finesse. People here often don’t negotiate; they prefer to pay for convenience and quality without haggling. India is a different ballgame. People there are more price-sensitive. Network providers cannot take the same approach in India as they do here.&lt;/p&gt;
&lt;p&gt;Here’s the thing about the US: people are willing to pay for convenience. They don’t mind paying extra for a service that makes their life easier. In fact, they want to pay more for the latest iPhone, which has the best cameras, the best display, and all the new AI features, etc. India is entirely different; people there are more price-sensitive. They want the best deal and the best price, and they’re willing to haggle for it.&lt;/p&gt;
&lt;p&gt;Here is a better understanding of how this business model works: &lt;a href=&quot;/blog/freeiphone.html&quot;&gt;iPhone on the house&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This has given me insane insights into what it takes to run a consumer business, and how to sell. I’m still uncertain about how well these lessons will translate to tech, but I’m excited to try them out.&lt;/p&gt;
&lt;h6 id=&quot;september&quot; tabindex=&quot;-1&quot;&gt;September&lt;/h6&gt;
&lt;p&gt;Settling in here, in New York City, has been fun and growthful. The worst part of staying away from India is not having access to a myriad of cheap labour. I have to do everything myself now. I must cook, clean, do laundry, commute using public transport, and manage my finances until I find some form of employment.&lt;/p&gt;
&lt;p&gt;Living in Jersey City gives me access to bigger, wider rooms with amazing skyline views, and a lot of greenery. The rent is cheaper, and the cost of living is lower. Jersey City is very clean and quiet, away from the hustle and bustle of NYC, and has a lot of parks and greenery. I stay on the bank of the Hudson River, and the view is amazing. I can see the entire skyline of Manhattan from my window. The state taxes are lower, and access to Indian communities is easier. There are a &lt;strong&gt;LOT&lt;/strong&gt; of Indians staying in New Jersey, and I can find Indian groceries and restaurants easily.&lt;/p&gt;
&lt;p&gt;The only downside is that I have to take a subway to reach NYC, and then transfer to another subway to Brooklyn. Midtown Manhattan is a 5-minute ride across the river, and Brooklyn is a 30-minute subway ride. The commute can be a bit overwhelming at times. The peace, the size of my room for the rent, the views from the window, and the facilities in the locality make up for it.&lt;/p&gt;
&lt;p&gt;September begins with my first semester at NYU. The culture here is very diverse. The classes are long, the assignments are overwhelming, and the professors are very knowledgeable. Most are part-time lecturers with a full-time job at multi-national tech companies. Although, there is an “accent” problem; it is difficult to understand some of them at times, but it is a learning curve.&lt;/p&gt;
&lt;p&gt;I have taken up three courses this semester: &lt;em&gt;Data Structures and Algorithms(the same old kingmaker terrorizing SEs all across the world xD)&lt;/em&gt;, &lt;em&gt;Computer Systems Architecture( an advanced version of COA from bachelor)&lt;/em&gt;, and &lt;em&gt;Internet Architecture and Protocols( focusing on Internet architecture from CN in bachelors)&lt;/em&gt;. The subjects are interesting but the assignment overload is intense.&lt;/p&gt;
&lt;p&gt;Meanwhile, I am planning to restart a couple of projects that align with the subjects I have taken up, the distributed file system, and the compiler.&lt;/p&gt;
&lt;p&gt;Looking forward to an amazing Semester here at NYU, New York City.&lt;/p&gt;
&lt;h6 id=&quot;august&quot; tabindex=&quot;-1&quot;&gt;August&lt;/h6&gt;
&lt;p&gt;Moving to a new country is tough. The past couple of weeks have been really busy and exciting; arranging funds, exploring scholarships, looking for housing, and overall planning the move. Rachna and I are leaving together for NY, and this makes the transition a little bit easier. The other difficult part of living this dream is leaving my family and friends behind. I have been feeling extremely homesick since I arrived here, and I miss my friends and family a lot.&lt;/p&gt;
&lt;h6 id=&quot;july&quot; tabindex=&quot;-1&quot;&gt;July&lt;/h6&gt;
&lt;p&gt;Three biggest updates:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I got accepted into NYU( &lt;em&gt;New York University&lt;/em&gt; ) for Masters in Computer Engineering in the Tandon School of Engineering. I am moving to NYC!&lt;/li&gt;
&lt;li&gt;Back to the startup life; building &lt;a href=&quot;http://datingai.pro&quot;&gt;datingai.pro&lt;/a&gt;, your perfect wingman.&lt;/li&gt;
&lt;li&gt;With all good things, comes an end. I am leaving RadiusAI, and India.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I am back to the startup drill. Staying up late, shipping features, building, failing, talking to customers, discussing our GTM strategy, and building the product, have been the highlights of the past month. I am excited to be a part of the founding team at &lt;em&gt;&lt;a href=&quot;http://datingai.pro&quot;&gt;datingai.pro&lt;/a&gt;&lt;/em&gt;. Including me, there are five of us in the team now.&lt;/p&gt;
&lt;p&gt;A sad part of all of this is leaving RadiusAI. I have been with the company for seven months and have loved it here. In the end, difficult decisions have to be taken, and while this was an amazing learning experience and a great place for growth, it’s time for me to leave, take flight, and build my own nest.&lt;/p&gt;
&lt;p&gt;I am going to miss my team and the office. The weekend get-togethers at pubs and breweries, and me coaxing everyone to come out for lunch and play carrom have been the highlights of my time here. From GitHub actions deployment failures and optimising memory in my Rust applications to compiling cross-platform binaries and multi-threaded applications and fixing Kafka and RedPanda issues, I have learnt and grown a lot as a software engineer. I will be forever grateful to Rachna and indebted to Ram for getting me into the team and making this happen.&lt;/p&gt;
&lt;p&gt;To the team, I will miss you guys, and I hope we cross paths again. Here’s to the good times and the memories we made. 🥂!&lt;/p&gt;
&lt;p&gt;The end of June and the beginning of this month was an extremely emotional goodbye, as:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;I met with my childhood best friends from all phases of my life, toghether, had an amazing weekend in Mumbai, and bid adeiu to them. It was a nostalgia trip, and it felt very content to see them become friends.&lt;/p&gt;
&lt;p&gt;We reminisced about our school days, gossiped about who dated whom, and laughed about the stupid things we and our teachers used to do. We talked about our JEE preparation days, locked our home, unable to fous with all the pressure surmounting us and finally giving up and buying a gaming console instead of shutting down TV. Our college days, and how we used to bunk classes, and go to the beach, and how we used to get drunk and watch movies.&lt;/p&gt;
&lt;p&gt;I have been friends with Ankit since 2012 now, with Vishnu since 2016, and with Abinash since 2019 now. Getting together, drinking and talking about our lives, our dreams, and our future, was an extremely heartfelt and emotional experience. Goodbyes are tough. This is the best farewell gift I could have ever asked for; them, just being there, and being my friends.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I went to Goa with my college friends, Tushar and Mahak, and it was amazing! It was a road trip from Bangalore, and it took us 10-11 hours to reach there. We stayed at a AirBnb, spent three and a half amazing days there before returning back to Bangalore.&lt;/p&gt;
&lt;p&gt;The first day was tiring, we just hung out in the Bnb room, had amazing seafood in a beach shacks and just sat and chilled on the beach. The second day was exploring North, and Old Goa. We webt to forts, beaches, lighthouses, trekked, and found cliffs from where we could see the entire Goa, and in the evening, we explored the old city, monuments and architecture. The third day was spent in South Goa, exploring the rocky beaches, hidden beaches, and the best sunsets. We kayaked on the backwaters, and had lunches in beach shacks.&lt;/p&gt;
&lt;p&gt;The last day was churches, and shopping, and we returned back to Bangalore. We had amazing food, and drinks, and we danced, and sang, and laughed, and had the best time of our lives.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I went on a major road trip with my dad from Bangalore to Bhubaneswar. We travelled through 1500 kms, and it took us a day and a half with a small halt near Nellore. I was shifting, and I returned home with a bunch of stuff that I wanted to keep. The most important on my bucket list was attending &lt;em&gt;Ratha Jaatra&lt;/em&gt; before leaving, and I also had to sell my car. I had to meet my family, and friends, and say goodbye to them. I had to pack, and plan, and prepare for the move. I had to get my visa, and my tickets, and my insurance, and my housing, and my bank accounts, and my sim cards, and my luggage, and my documents, and everything.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The entire shifting from Bangalore journey ends with me and mom in a TN tour. We visited Pondicherry, Rameswaram, Madurai and other places.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;June and July had me cover entire western to eastern India, from beaches to ghats, the road trips were dreamy, magical, and I would cherish them for a lifetime.&lt;/p&gt;
&lt;h6 id=&quot;june&quot; tabindex=&quot;-1&quot;&gt;June&lt;/h6&gt;
&lt;p&gt;May was hectic. I turned 24, went back to home for a week, and spent an amazing time with family and friends. I am back in Bangalore now, and life is busy.&lt;/p&gt;
&lt;p&gt;Back in Bangalore, I finally got to building my own budget gaming PC with Akash, a senior from office. Coming from a PS5, a gaming PC did not make sense initially. I wanted to play competitive FPS( first-person shooting ) games with my mates but Valorant and CS2 are not cross-play compatible or present on PS, yet. A minimum budget windows CPU build seemed apt.&lt;/p&gt;
&lt;p&gt;I went with the AMD Ryzen 5 3400G with Radeon RX Vega 11 because it has &lt;a href=&quot;https://www.cpubenchmark.net/cpu.php?cpu=AMD+Ryzen+5+3400G&quot;&gt;decent benchmarks&lt;/a&gt; and has a built in GPU and I did not want to spend on an additional GPU &lt;strong&gt;now&lt;/strong&gt;. This CPU is powered by two &lt;a href=&quot;https://www.amazon.in/G-SKILL-F4-3200C16S-8GVKB-Ripjaws-DDR4-3200MHz-CL16-18-18-38/dp/B01J6OA8RU?th=1&quot;&gt;8GB DDR4 RAM&lt;/a&gt; and the xmp profile set in BIOS to make them run at 1600 Mhz( max capacity ) each. The build is powered by a &lt;a href=&quot;https://www.gigabyte.com/Motherboard/B450M-DS3H-V2-rev-1x#kf&quot;&gt;Gigabyte B450M DS3H V2&lt;/a&gt; motherboard, without a wireless module, and a MSI cabinet with 6 fans. I am yet to achieve the maximum performance out of this build, and will update here soon.&lt;/p&gt;
&lt;p&gt;I am looking to hire a SE intern at my office, RadiusAI. Feel free to &lt;a href=&quot;mailto:anubhavp@duck.com&quot;&gt;reach out&lt;/a&gt; if you are interested.&lt;/p&gt;
&lt;p&gt;My current endeavours keep me occupied, and don’t leave me with much time to work on personal projects. I am currently working on a couple of projects at RadiusAI. These include building a developer tooling platform in Python for RadiusAI, and a multi-process simulator in Rust to read, sync simulate and handle messages from Kafka and RedPanda. The last project is insanely complex and exciting.&lt;/p&gt;
&lt;h6 id=&quot;may&quot; tabindex=&quot;-1&quot;&gt;May&lt;/h6&gt;
&lt;p&gt;My family visiting me returned back home. The most dreaded feeling is when you have to say goodbye. I have always been a lot attached, and it was painful. Before leaving, we decided to get matching tattoos! Here are mama and baby dinausors on our wrists.&lt;/p&gt;
&lt;figure style=&quot;justify-content: center; align-items: center; display: flex;flex-direction: column;&quot;&gt;
&lt;img alt=&quot;introduction&quot; src=&quot;../assets/img/24/dinos.png&quot; class=&quot;h-75 w-75&quot; loading=&quot;lazy&quot;&gt;
&lt;/figure&gt;
&lt;h6 id=&quot;april&quot; tabindex=&quot;-1&quot;&gt;April&lt;/h6&gt;
&lt;p&gt;I bid my best friend a final goodbye as he left Bangalore permanently. He decided to quit his job and follow his passion. The current economic climate is not conducive to his interests, and the job market is extremely rough. A sense of this weird melancholy prevails over me. While I applaud his courage, a part of me wants him to stay and hunt for jobs here. I am going to miss our late-night conversations, our shared interests, and our shared dreams. We started off watching stand-up comedy in the first year of college. From college politics and friendships to getting drunk and watching Rockstar. From walking Rio to getting high and watching Batman. From internships and long car rides to getting jobs and going on trips to Mumbai, Mangalore, Pondicherry, and where the hell not. We have been through a lot together. I am going to miss him a lot. Before leaving for the airport we decided to get something together and have one last meal in Bangalore; and so we went into the Apple store to get something together, and for the restaurant I chose KFC considering that he is a vegan xD. We plan on getting the WWE2k24 and playing it together. A blue summer awaits.&lt;/p&gt;
&lt;p&gt;April is all about spending time with my family visiting me in Bangalore. We had to visit some collges, thus we had to travel a lot. A fast-paced, exciting adventure to &lt;em&gt;Gujrat&lt;/em&gt; and &lt;em&gt;Uttarakhand&lt;/em&gt; ends this fortnight.&lt;/p&gt;
&lt;p&gt;We went to &lt;em&gt;Ahmedabad&lt;/em&gt;, &lt;em&gt;Dwarka&lt;/em&gt;, &lt;em&gt;Somnath&lt;/em&gt;, &lt;em&gt;Rishikesh&lt;/em&gt;, &lt;em&gt;Haridwar&lt;/em&gt;, and &lt;em&gt;Dehradun&lt;/em&gt;. The trip was a mix of adventure, culture, and spirituality. The best parts were the &lt;em&gt;river rafting&lt;/em&gt;, and &lt;em&gt;Ganga Aarti&lt;/em&gt; in Rishikesh, and the visit to the old city, &lt;em&gt;Dwarka&lt;/em&gt;, the residence of Lord Krishna. Back in bangalore, looking forward to the same old monotony.&lt;/p&gt;
&lt;p&gt;I am not planning to build anything new as of yet. Work consumes most of my time. Mostly invested in research, I spend time exploring business, product, and tech ideas. The ultimate goal is to build something bigger, unique, and sell it, or build a company around it. Here’s an amazing article that I recetly came across by Paul Graham about how &lt;a href=&quot;https://www.ycombinator.com/blog/the-reddits&quot;&gt;Reddit got started&lt;/a&gt;. He says, &lt;em&gt;“Reddit the site (and now app) is such a fundamentally useful thing that it’s almost unkillable.”&lt;/em&gt;. I am looking for something like that. Something that is fundamentally useful, and unkillable.&lt;/p&gt;
&lt;h6 id=&quot;march&quot; tabindex=&quot;-1&quot;&gt;March&lt;/h6&gt;
&lt;p&gt;An hectic beginning to the month; I just returned, and had a terrific week back at home. All of my best friends were back, together, and we meandered through familiar haunts, roaming around, exploring places, and restaurants, and talking about our current lives. The weekend after that was spent in Pondicherry, with Abinash. We explore bakeries, french architecture, &lt;em&gt;Auroville&lt;/em&gt;, the beach, and the city. After a week-long hiatus with friends and family, and an excruciatingly tiring trip to Pondi, I am back in Bangalore, looking forward to a productive month.&lt;/p&gt;
&lt;p&gt;Not planning on taking up much work, I have thought of taking an hour of my day to figure out where this is all going. March is supposed to be an interlude, a time to reflect and recharge. I have long-term goals, and to be able to accomplish them, I need to be more disciplined and focused. The path must be streamlined. This daily routine will help me to stay on track and keep my goals in sight. This month would be spent planning out the next four odd years. My short-term goals would be to focus on my fitness journey and improve my writing. Writing has always been a passion of mine, serving as a conduit for connecting with others and sharing my insights. Lately, I’ve been particularly prolific, and I have been writing a lot.&lt;/p&gt;
&lt;p&gt;March ends exciting. I finished up with &lt;a href=&quot;https://anubhavp.dev/blog/nicedear.html&quot;&gt;NiceDear&lt;/a&gt;, a dynamic open-source avatar generator that crafts unique avatars based on user input. Looking to upgrade my desk setup, I finally made the switch to a fully customisable mechanical keyboard, and an ergonomic mouse. I initially planned on going with linear switches, but I ended up with tactile ones. They are pre-lubed, and the PCB is covered with a layer of foam. I am using the fully hot-swapable Keychron K2 Pro, with banana switches, aluminium casing, south-facing RGB lights, and a custom keycap set. The mouse is the Logitech MX Master 3s Mac, white. It has an 8,000 DPI optical sensor that can track on virtually any surface, including glass. I have mapped the horizontal scroll-wheel, and the back, and forward buttons to custom schortcuts. The next step would be upgrading my desk mat.&lt;/p&gt;
&lt;h6 id=&quot;feb&quot; tabindex=&quot;-1&quot;&gt;Feb&lt;/h6&gt;
&lt;p&gt;I went on a trip to Mangalore with Abinash for a night. I had been occupied with a lot of things lately and this was a much-needed escape. Back in Bangalore life is slow and boring. A few friends came over on the weekend and we had a ton of fun. This new place at HSR Layout, Plan B, is my go-to hangout destination. They serve the best damn chicken wings in town. Looking towards to chilling out with my friends and family, back home this last week.&lt;/p&gt;
&lt;p&gt;Here’s how Dough is shaping up:&lt;/p&gt;
&lt;figure style=&quot;justify-content: center; align-items: center; display: flex;flex-direction: column;&quot;&gt;
&lt;img alt=&quot;introduction&quot; src=&quot;https://anubhavp.dev/assets/img/dough/simple-presentation.gif&quot; class=&quot;h-100 w-100&quot; loading=&quot;lazy&quot;&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;a href=&quot;https://anubhavp.dev/blog/dough.html&quot;&gt;Here’s everything about Dough&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you’re eager to dive into the world of Rust and looking for a project to contribute to, Dough presents an exciting opportunity. Here’s a breakdown of what’s currently not working and areas that could benefit from your expertise:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fix scrolling issue in highlight mode:
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;bug&lt;/em&gt; Over Scroll in infinite scrolling&lt;/li&gt;
&lt;li&gt;&lt;em&gt;feat&lt;/em&gt; Skip empty lines in highlight mode&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;bug&lt;/em&gt; custom aligner adds empty lines after text-block alignment&lt;/li&gt;
&lt;li&gt;&lt;em&gt;feat.&lt;/em&gt; Hot Module Reload&lt;/li&gt;
&lt;li&gt;&lt;em&gt;feat.&lt;/em&gt; Add support for the maximum width and height of the terminal. (Write a word wrapper)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;feat.&lt;/em&gt; Add comprehensive support for common Markdown elements.
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;feat.&lt;/em&gt; Enhance rendering for complex markdown elements like links within headings or lists, blockquotes, and tables.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I am looking for contributions from peers regarding the pending issues, making this a more robust open-source project.&lt;/p&gt;
&lt;p&gt;At Radius AI I am involved in building an async uptime monitoring service using Rust, and also a concurrent heartbeat service in Python. I will update this page with more details soon.&lt;/p&gt;
&lt;p&gt;Got a new idea about a content summarization and accessibility tool. Still in the early stages of the idea, I might share more details soon. Mostly, it would be:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;content aggregation; recommendation engine&lt;/li&gt;
&lt;li&gt;search engine&lt;/li&gt;
&lt;li&gt;bookmarks, and TL;DR, summarization&lt;/li&gt;
&lt;/ul&gt;
&lt;h6 id=&quot;jan&quot; tabindex=&quot;-1&quot;&gt;Jan&lt;/h6&gt;
&lt;p&gt;Happy New Year, muchachos! I hope you had a good one. I just returned to Bangalore after a much-needed break in my hometown. Leaving home and returning to the city was a bit of a bummer, but such is life! The dreaded omicron variant is wreaking havoc in the city. I am starting a new career at RadiusAI as a Software Engineer, and I am pretty stoked :D&lt;/p&gt;
&lt;p&gt;Here’s an improved version of Llama Index’s sub-querying engine used to generate SQL from Natural Language: &lt;a href=&quot;/blog/neak.html&quot;&gt;Neak&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Coming onto Dough: a rich, modular, and customisable content generator, crafted in Rust, &lt;a href=&quot;https://anubhavp.dev/blog/dough.html&quot;&gt;here’s everything&lt;/a&gt; you need to know.
This is a breakdown of the tasks I was working on:&lt;/p&gt;
&lt;p&gt;v2:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Improving the rendering engine:
&lt;ul&gt;
&lt;li&gt;&lt;s&gt;Add a refresh feature while rendering slides&lt;/s&gt;
&lt;ul&gt;
&lt;li&gt;Hot Module Reload( FIX )&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;s&gt;Add support for rendering &lt;strong&gt;nested syntax&lt;/strong&gt;&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;Add support for the maximum width and height of the terminal. Write a word wrapper.&lt;/li&gt;
&lt;li&gt;&lt;s&gt;Address the color storage issue for multiline elements, ensuring ANSI escape sequences are properly stripped: Refine color correction post-alignment&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;Enhance rendering for complex markdown elements like links within headings or lists.
&lt;ul&gt;
&lt;li&gt;&lt;s&gt;lists.&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;blockquotes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Provide comprehensive support for common Markdown elements.
&lt;ul&gt;
&lt;li&gt;&lt;s&gt;Improve the rendering of thematic breaks&lt;/s&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;s&gt;Improve the design language.&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;Image support for terminals with image capabilities is pending. &lt;em&gt;(Kitty, iTerm2, etc.)&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;s&gt;Syntax Highlighting in code blocks&lt;/s&gt;
&lt;ul&gt;
&lt;li&gt;&lt;s&gt;Improve the performance of syntax highlighting. The current implementation is CPU intensive. Use a different library for syntax highlighting, or parallel threads to improve performance.&lt;/s&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;s&gt;Custom text alignment: A regex match for individual text alignment&lt;/s&gt;
&lt;ul&gt;
&lt;li&gt;&lt;s&gt;Improve the alignment of segments of text.&lt;/s&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;s&gt;Implement running code blocks on separate threads and displaying results in the current console.&lt;/s&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;a href=&quot;/blog/23.html&quot;&gt;2023&lt;/a&gt;&lt;/p&gt;

            &lt;hr&gt;
            &lt;div class=&quot;footer&quot;&gt;
              &lt;i&gt;Feedback, Suggestions, Comments - &lt;/i&gt;
              &lt;div class=&quot;giscus-div&quot; id=&quot;comments&quot;&gt;
                &lt;script src=&quot;https://giscus.app/client.js&quot; data-repo=&quot;anubhavpgit/anubhavpgit.github.io&quot; data-repo-id=&quot;MDEwOlJlcG9zaXRvcnk0MDQ1ODEzMjc=&quot; data-category-id=&quot;DIC_kwDOGB1rz84Cer0j&quot; data-mapping=&quot;title&quot; data-strict=&quot;0&quot; data-reactions-enabled=&quot;1&quot; data-emit-metadata=&quot;0&quot; data-input-position=&quot;bottom&quot; data-theme=&quot;noborder_light&quot; data-lang=&quot;en&quot; data-loading=&quot;lazy&quot; crossorigin=&quot;anonymous&quot; async=&quot;&quot;&gt;&lt;/script&gt;
              &lt;/div&gt;
              Feel free to
              &lt;a id=&quot;mailtoLink&quot; href=&quot;mailto:anubhavp@duck.com?subject=Here&apos;s%20a%20suggestion/feedback!&quot;&gt;send
                me an email&lt;/a&gt;.
            &lt;/div&gt;
          &lt;/div&gt;
        </content:encoded>
            <subtitle>The magic and the storms that shaped my 2024</subtitle>
        </item>
        <item>
            <title><![CDATA[2025, A Year in Review]]></title>
            <description><![CDATA[Nomadic battles and adventures around the world]]></description>
            <link>https://anubhavp.dev/blog/25.html</link>
            <guid isPermaLink="true">https://anubhavp.dev/blog/25.html</guid>
            <dc:creator><![CDATA[Anubhab Patnaik]]></dc:creator>
            <pubDate>Tue, 23 Dec 2025 00:00:00 GMT</pubDate>
            <content:encoded>
          &lt;div class=&quot;content custom&quot;&gt;
            &lt;div class=&quot;search-container&quot;&gt;&lt;/div&gt;
            &lt;h6 id=&quot;december&quot; tabindex=&quot;-1&quot;&gt;December&lt;/h6&gt;
&lt;p&gt;It’s that time of the year again. A whole year went by? This one was full of growth, learning, and perseverance. Mostly quiet, unlike 2024. This year was fewer friends and family, more work and self-discovery. The nomadic life, the adventure continues.&lt;/p&gt;
&lt;p&gt;Highlight would have to be the summer this year. Spent May and June winning World Builder Residency at Edge Esmeralda and SF, California. The experience was surreal, to say the least. Meeting amazing founders, builders, and creators from all over the world, exchanging ideas, and building cool stuff in the beautiful vineyards of Healdsburg is where I want my life to be heading. Next up would be Seoul, for another month, in August. South Korea for a month was a life-changing experience. Exploring Seoul, working with an amazing team at Authentic, and experiencing a new culture was refreshing.&lt;/p&gt;
&lt;p&gt;My formal education for this lifetime seems to have come to an end, and I couldn’t be happier about it. Graduated this December with a major in Computer Engineering from NYU Tandon. Also, started my own company :) (&lt;em&gt;More on that soon&lt;/em&gt;)&lt;/p&gt;
&lt;p&gt;2026 looks promising and full of hope. Taking some time off from this site, will be back in Jan! Wishing you a merry Christmas, and a Happy New Year. Happy Holidays!&lt;/p&gt;
&lt;h6 id=&quot;november&quot; tabindex=&quot;-1&quot;&gt;November&lt;/h6&gt;
&lt;p&gt;Mostly occupied in work and wrapping up college work for the semester. New York is chilly now, with temperatures ranging from 5 to 15 C. The city is beautiful in the fall, with the leaves changing colours and the air crisp and cool. The most annoying thing now is going back to standard time from daylight saving time.&lt;/p&gt;
&lt;p&gt;A couple of projects are pending. My coursework requirements include a few projects; an application on Fourier-series analysis: transforming signals from time-domain to frequency domain and vice-versa, a small GPU Kernel for LLM inference, and an algorithmic trading bot and stock pricing option pricing using Monte Carlo simulations. Expecting to finish these in the next couple of weeks and write more soon. Authentic is going well. Launched, live on the &lt;a href=&quot;https://apps.apple.com/us/app/authentic/id6748682732&quot;&gt;App Store&lt;/a&gt; now.&lt;/p&gt;
&lt;h6 id=&quot;october&quot; tabindex=&quot;-1&quot;&gt;October 🎃&lt;/h6&gt;
&lt;p&gt;This weekend was exhausting. Participated in a 24-hour hackathon, NASA Space Apps Challenge, and built Lighthouse - an air quality monitoring app using NASA’s open APIs and some ML magic.&lt;/p&gt;
&lt;p&gt;The task was pretty laid out, straightforward; NASA’s site mentions on the page exactly what to do - build an air quality monitoring app that caters to different user groups. I remember starting to work on it on a Saturday morning, and now it is early Monday morning, just about submitted it, tired but ready to face Monday. Standups, meetings, sprint planning, and all that jazz. Also, some college work to do. (&lt;em&gt;2 more months to graduation!&lt;/em&gt;)&lt;/p&gt;
&lt;p&gt;The challenge for me here was not the tech - a React-native + Flask app, deployed on Railway and TestFlight. The hard work was the &lt;em&gt;product&lt;/em&gt;. How do I sell this? How do I compete with years of polished app experiences/ ecosystem tie-ups, alert mechanisms for Wildfire alerts, heavy thunderstorm warnings, umbrella suggestions, etc, which were all extremely doable, but what could be my moat? Spent some time thinking about product development and PMF.&lt;/p&gt;
&lt;p&gt;The Oct - Nov period is usually the most happening time of the year for me. Growing up in Eastern India, Durga Puja/Dussehra marks the onset of the festive season. The city is decorated with lights, and the atmosphere is vibrant. We visit friends and family, do not bother about getting up and going to college/ work the next day, and just enjoy the food and celebrations. Most weeks have some holiday going on, Diwali not far away. All of us living in other parts of the country come back home, and we all meet up, eat out, and have fun. October looks like I’ll be living in nostalgia for a while now. At times, I wish I could just leave everything behind and go back to India.&lt;/p&gt;
&lt;h6 id=&quot;september&quot; tabindex=&quot;-1&quot;&gt;September&lt;/h6&gt;
&lt;p&gt;Authentic is going well and is almost ready for launch. The app is now a functional, Instagram-story-like app with ephemeral posts. Current versions focus on perfecting the iOS builds before moving on to Android. I am currently working on optimising the runtime performance of the app, reducing the bundle size, mostly improving the overall user experience - better error handling, reducing response times in posting, improving UI feedback, etc. The aim here is to make it ready for App Store submission. The app is invite-only for now, and we are working on building a waitlist for the app. &lt;a href=&quot;mailto:anubhav@authentic.tech&quot;&gt;Email me here&lt;/a&gt; if you want in.&lt;/p&gt;
&lt;p&gt;The last week of August was all about helping friends pack, move, settle into new routines and preparing for the upcoming fall semester. Back to school now. The last ride; graduating this December.&lt;/p&gt;
&lt;h6 id=&quot;august&quot; tabindex=&quot;-1&quot;&gt;August&lt;/h6&gt;
&lt;p&gt;August 16 marks one whole year of my life in the US. Feels happy, nostalgic and content; eudaimonic in ways, looking back at all that I have achieved so far in this past year, having made a whole year alone as an adult in a foreign land. Celebrated last year’s Independence Day with a couple of friends from work and college, playing paintball, eating out and watching patriotic movies. This year, on 15th August, spent the day roaming around in scorching 35 degrees in NY with friends, and sat down by the river to look at my tricolour on the Empire State and World Trade Centre. Looking forward to another year.&lt;/p&gt;
&lt;figure style=&quot;justify-content: center; align-items: center; display: flex; flex-direction: column; gap: 10px;&quot;&gt;
	&lt;img alt=&quot;New York landscape&quot; src=&quot;../assets/img/25/79.webp&quot; style=&quot;max-width: 75%;&quot; loading=&quot;lazy&quot;&gt;
	&lt;figcaption style=&quot;text-align: center; font-size: 0.8em;&quot;&gt; New York City celebrating India&apos;s 79th Independence Day&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Leaving for New York in mid-August. Happy to be finally back, properly, but I will miss Seoul. The last time I was living in New York was back in April. These four months have been a whirlwind of experiences, from Healdsburg to Seoul, and now back to New York.&lt;/p&gt;
&lt;p&gt;Life in Seoul is amazing. Seoul is vibrant, rich in culture, and has a fantastic food scene. I spend most of my time working on Authentic and remaining focused on exploring the city. The weather is warm, with temperatures ranging from 28 to 40 degrees Celsius.&lt;/p&gt;
&lt;p&gt;Built on top of Next.js &amp;amp; Vercel (Migrating to Express + Railway), and React Native, Authentic is now live on the testflights on app stores. Think of it as a privacy-focused, ephemeral social media app- a Snapchat/ Instagram of sorts without ads or doomscrolling. The primary motivation behind the app is to create a non-infinite space where people can share their thoughts and experiences without having to apply filters to fit in or worrying about the permanence of their posts. We fight doomscrolling, ads targeting, and the constant pressure to curate a perfect online persona.&lt;/p&gt;
&lt;p&gt;Here’s a fun little hack that I built for the Authentic Office in Korea: blink all the lights in the office on a PR merge to celebrate a new feature shipment. So, we had these ‘Sunset Lamps’ that would change colours and create a nice ambience during our late-night coding sessions. They operated either manually using the physical switch or through their proprietary app. The actual challenge here was to figure out the exact set of commands used for each action.&lt;/p&gt;
&lt;p&gt;I installed a Bluetooth profile on the iOS device and used the packet logger on my Mac to track all the packets being sent out over a time frame of 10 seconds. Turns out some devices advertise manufacturer-specific data on a new connection. This helped me get the UUIDs of the devices. So, I spammed different light options in the app within ~10 seconds and added filters in the packet logger using the manufacturer-specific data and the time window to find a bunch of commands being sent out to one specific UUID that I had identified. Once done, created a flask server with bleak to scan for devices, match the UUIDs, connect, and brute-forced all recorded commands, until one command worked—the light turned off. Then GPT-4o helped me flip the hex command into the “ON” version. Success.&lt;/p&gt;
&lt;p&gt;The rest of it was simple; a Github webhook call to the Flask server via ngrok, and a trigger that blinked the lights thrice on a successful merge of a feature branch. Later, I added a cron job to periodically check the status of the lights and ensure they were responsive. The final touch was a Siri Shortcut on all our laptops that just did a GET call to the Flask server via ngrok tunnel. Anyone could yell: “Hey Siri, Authentic Party!” → instant disco mode.&lt;/p&gt;
&lt;p&gt;Fun times.&lt;/p&gt;
&lt;figure style=&quot;justify-content: center; align-items: center; display: flex; flex-direction: column; gap: 10px;&quot;&gt;
	&lt;img alt=&quot;Lights&quot; src=&quot;../assets/img/25/aut1.webp&quot; style=&quot;max-width: 75%;&quot; loading=&quot;lazy&quot;&gt;
	&lt;figcaption style=&quot;text-align: center; font-size: 0.8em;&quot;&gt;The office and disco lights&lt;/figcaption&gt;
	&lt;div style=&quot;display: flex; flex-direction: row; justify-content: center; gap: 10px; width: 100%;&quot;&gt;
		&lt;img alt=&quot;Office&quot; src=&quot;../assets/img/25/aut2.webp&quot; style=&quot;max-width: 35%;&quot; loading=&quot;lazy&quot;&gt;
		&lt;img alt=&quot;Photobooth&quot; src=&quot;../assets/img/25/aut3.webp&quot; style=&quot;max-width: 35%;&quot; loading=&quot;lazy&quot;&gt;
	&lt;/div&gt;
	&lt;figcaption style=&quot;text-align: center; font-size: 0.8em;&quot;&gt;Office and photobooth&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;We ultimately decided to build the app using React Native. Choosing a mobile framework just makes more sense as a developer and from a UX perspective. The first week of August would be spent doing Coffee Chats with end users, testing and gathering feedback on the app on the alpha build. The app will be out on beta soon. Migrating from Next.js to React Native was a challenge, but a week of toil and badgering Claude 4 Opus APIs and exhaustion later, we have a working app. The app, for all intents and purposes, is now a cute-looking, functional app that works on both iOS and Android. Excited to share more soon.&lt;/p&gt;
&lt;h6 id=&quot;july&quot; tabindex=&quot;-1&quot;&gt;July&lt;/h6&gt;
&lt;p&gt;A lot of updates this month. The h011yw00d internship comes to an end. Had an amazing experience in California building a user-centric social media app with tens of thousands of users. CA led me to some other awesome teams working in similar spaces. Thus, a new life update: spending the summer in Seoul, working for &lt;a href=&quot;https://authentic.tech/&quot;&gt;Authentic&lt;/a&gt; as a mobile software engineer. My aim here is to take the web-app mobile, building a Capacitor app based on the Next.js app and ship it on the app stores as the first MVP version.&lt;/p&gt;
&lt;p&gt;Relocated to Seoul, South Korea, for a month. Authentic is currently operating out of Seoul. Excited to be here, exploring the city, and working with an amazing team of engineers and designers. The culture is vibrant, the food is delicious, and the people are friendly. Looking forward to experiencing the local culture and learning more about the tech scene here.&lt;/p&gt;
&lt;p&gt;The worst part of all of this is the jet lag. I have been struggling with it for the past few months now. In the last 2 months, I have travelled across 3 continents, and the time zone changes have been brutal- more than 4 different time zones in the last 2 months. Still trying to adjust to the new time zone here in Seoul, which is 3.5 hours ahead of India, 13 hours ahead of New York, and 16 hours ahead of California. Hoping that spending some time in the sun and getting some fresh air will help adjust. The curse of living the &lt;em&gt;Jajabara&lt;/em&gt; (nomadic) life! Crazy how life has always been, for as long as I can remember now. Twenty-five years, packing up and moving to a new place every few years, and now, months. Will write more about this in a &lt;a href=&quot;https://anubhavp.dev/blog/jajabara&quot;&gt;separate post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;July starts with a trip back home to India until the fall. &lt;em&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Ratha_Yatra_(Puri)&quot;&gt;Ratha Jaatra&lt;/a&gt;&lt;/em&gt;, the chariot festival in Puri, is the one event I try hard to make it to every year.&lt;/p&gt;
&lt;p&gt;Taking a break from the project-building phase was a mindful call. I spend most of my energy on actual work, focusing on my internships. Currently working with distributed computing - scaling, maintaining, deploying, and managing the video generation app at h011yw00d. The aim would be to keep hunting for technical founding staff/ founding engineer roles for when I graduate, which will probably be at the end of this semester/ year. Excited for what’s next.&lt;/p&gt;
&lt;h6 id=&quot;june&quot; tabindex=&quot;-1&quot;&gt;June&lt;/h6&gt;
&lt;p&gt;Won the &lt;a href=&quot;https://edgeesmeralda2025.substack.com/p/world-builder-residency-2025&quot;&gt;World Builder Residency&lt;/a&gt;! :) LFG&lt;/p&gt;
&lt;figure style=&quot;justify-content: center; align-items: center; display: flex; flex-direction: column; gap: 10px;&quot;&gt;
	&lt;img alt=&quot;Edge Esmeralda&quot; src=&quot;../assets/img/25/cali1.webp&quot; style=&quot;max-width: 75%;&quot; loading=&quot;lazy&quot;&gt;
	&lt;figcaption style=&quot;text-align: center; font-size: 0.8em;&quot;&gt;Worldcoin builder residency, summer, Edge Esmeralda, 2025&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Summer in California is beautiful. Healdsburg is a small town in Sonoma County, known for its picturesque vineyards and wineries. The weather is warm, with temperatures ranging from 25 to 30 degrees Celsius. The town has a charming vibe with boutique shops, restaurants, and cafes. Currently, it’s filled with tourists/ people attending Edge City, a tech pop-up village, which is more like a tech summer camp, where people can come together to share ideas and collaborate on projects. I am part of the &lt;a href=&quot;https://www.edgecity.live/world-builder-residency&quot;&gt;World Residency program&lt;/a&gt;, where we build and deploy a mini app that runs on the World ecosystem.&lt;/p&gt;
&lt;p&gt;Now, while I am here, I did decide to ship &lt;a href=&quot;https://anubhavp.dev/fireside/&quot;&gt;fireside&lt;/a&gt;, a decentralised encrypted chat app I built some years ago, on &lt;a href=&quot;https://worldcoin.org/mini-app?app_id=app_7501435523cb7805cb06ca6918973726&quot;&gt;worldcoin&lt;/a&gt;. I was anyway working on shipping h011yw00d, thought I might as well try to ship something of my own. This blew up! Acquired 500 users in a day and was in the top 10% of the apps without any marketing.&lt;/p&gt;
&lt;p&gt;Here are the metrics after a day of launch :) -&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../assets/img/25/fireside-metrics.webp&quot; alt=&quot;fireside metrics&quot; loading=&quot;lazy&quot;&gt;&lt;/p&gt;
&lt;p&gt;The rest of the time, when I am not working, I spend exploring California, visiting San Francisco, Redwood National Park, and the beautiful beaches along the coast.&lt;/p&gt;
&lt;p&gt;San Francisco is a vibrant, beautiful city, known for its diverse culture, tech scene, and absolutely stunning views. The weather is mild/ cold, with temperatures ranging from 12 to 20 degrees Celsius. California has microclimates, so the weather can vary significantly from one part of the city to another. I halted in Presidio for a couple of days, a Bay Area neighbourhood, also a former naval base turned into a national park. Worked out of the &lt;a href=&quot;https://www.edgeandnode.com/thehouse&quot;&gt;House of Web3&lt;/a&gt;, with beautiful views of the Golden Gate Bridge and the bay, with hiking trails and picnic areas. Presidio also has this amazing trail, Lands End, which offers breathtaking views of the Pacific Ocean from the cliffs. This is hands down my favourite place in SF, and my favourite hike so far.&lt;/p&gt;
&lt;figure style=&quot;justify-content: center; align-items: center; display: flex; flex-direction: column; gap: 10px;&quot;&gt;
	&lt;img alt=&quot;Lands End&quot; src=&quot;../assets/img/25/cali3.webp&quot; style=&quot;max-width: 75%;&quot; loading=&quot;lazy&quot;&gt;
	&lt;div style=&quot;display: flex; flex-direction: row; justify-content: center; gap: 10px; width: 100%;&quot;&gt;
		&lt;img alt=&quot;Redwood National Park&quot; src=&quot;../assets/img/25/cali2.webp&quot; style=&quot;max-width: 35%;&quot; loading=&quot;lazy&quot;&gt;
		&lt;img alt=&quot;Lands End, sun over Pacific&quot; src=&quot;../assets/img/25/cali4.webp&quot; style=&quot;max-width: 35%;&quot; loading=&quot;lazy&quot;&gt;
	&lt;/div&gt;
	&lt;figcaption style=&quot;text-align: center; font-size: 0.8em;&quot;&gt;Scattered clouds over San Francisco, hiking in the redwoods, and gazing at the sun over the Pacific from Lands End&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The city has a rich cultural scene, with museums, galleries, theatres, and amazing culinary experiences. The food here is probably the best I have had in the US so far. I attended a few meetups and events and got to meet some amazing founders. SF inspires me to move here someday. If I ever do decide to move out of New York, I think SF would be the place.&lt;/p&gt;
&lt;h6 id=&quot;may&quot; tabindex=&quot;-1&quot;&gt;May&lt;/h6&gt;
&lt;p&gt;Moving to SF for the summer. Summer internship as an AI Research Engineer at an AI/Web3 startup, h011yw00d - an AI agent that generates autonomous cinematic videos, currently active on &lt;a href=&quot;https://x.com/h011yw00dAgent/&quot;&gt;Twitter&lt;/a&gt;. My role involves working on the apps that run on this AI engine - the underlying distributed computing infrastructure, deploying and maintaining it.&lt;/p&gt;
&lt;p&gt;My speculations about the Web3 world aside, and the fact that crypto is 99% a scam, innovation and profitability are two separate things. Businesses don’t need useful technology to make money. A few are financially successful businesses, although built on technically questionable foundations, not meaningful innovations solving real problems. Examples include Coinbase, OpenSea, etc. The bottom line is, &lt;strong&gt;distribution trumps innovation&lt;/strong&gt;. Not that I see myself working in the web3 space, but this stint feels like a decent opportunity to network and explore more.&lt;/p&gt;
&lt;p&gt;The semester is over. I feel I am done with building projects now. They still excite me, but the monetary aspect of it is more appealing now. I’d like to focus on building and solving more business-oriented problems. The Summer internship starts in a few days. At 24 °C, New York feels warmer now. People are out and about, and the city is alive. I’d like to save up for a few trips this summer, mostly exploring places around the Bay Area.&lt;/p&gt;
&lt;p&gt;Orion is going well. The device is currently capable of recording various muscle signals based on activity, and the data shows distinguishable patterns between relaxed, fist, index, and index-middle finger positions. It conditions signals using moving average filtering, rectification and envelope signals with additional raw signals for improved accuracy. The challenge here is improving the deep learning model that has a terrible accuracy of around 60-70% for the current dataset. The annoying part about this is that the data is terrible. Primarily, because the jumper wires kept falling off, and the electrodes were not placed properly. Also, the muscles get fatigued after a while.&lt;/p&gt;
&lt;figure style=&quot;justify-content: center; align-items: center; display: flex; flex-direction: column; gap: 10px;&quot;&gt;
&lt;img alt=&quot;Orion EMG signal gif&quot; src=&quot;../assets/img/25/orion_emg.gif&quot; style=&quot;max-width: 75%;&quot; loading=&quot;lazy&quot;&gt;
&lt;/figure&gt;
&lt;figcaption style=&quot;text-align: center; font-size: 0.8em;&quot;&gt;Recording muscle data fluctuations which will be later used for analysis and model training.&lt;/figcaption&gt;
&lt;figure style=&quot;justify-content: center; align-items: center; display: flex; flex-direction: row; gap: 10px;&quot;&gt;
	&lt;img alt=&quot;arm&quot; src=&quot;../assets/img/25/arm_two.webp&quot; style=&quot;max-width: 30%;&quot; loading=&quot;lazy&quot;&gt;
	&lt;img alt=&quot;arm&quot; src=&quot;../assets/img/25/arm_two_mcu.webp&quot; style=&quot;max-width: 30%;&quot; loading=&quot;lazy&quot;&gt;
	&lt;!-- &lt;img alt=&apos;arm&apos; src=&quot;../assets/img/25/orion_mcu.webp&quot; style=&quot;max-width: 30%;&quot; loading=&quot;lazy&quot;&gt; --&gt;
&lt;/figure&gt;
&lt;figcaption style=&quot;text-align: center; font-size: 0.8em;&quot;&gt;Left, Mid: Arm with electrodes and sensors, Right: MCU with electrodes and sensors live&lt;/figcaption&gt;
&lt;p&gt;Further, in the next semester, I am planning to integrate a language recognition model that will be used to convert the signals into text. This has a lot of potential applications, including controlling devices, typing (air keyboard), and even hand-gesture-to-speech conversion.&lt;/p&gt;
&lt;p&gt;New York in spring is as beautiful as ever. The highs are around 20-24, and the lows are around 12-14, the sweet spot. The cherry blossoms are in full bloom, and the city feels lively. Charting out a few short trip plans for the summer. The East Coast isn’t as scenic as the West Coast, but let’s see how it goes.&lt;/p&gt;
&lt;p&gt;Currently watching &lt;em&gt;When Life Gives You Tangerines&lt;/em&gt;, a Korean series that beautifully explores themes of love, loss, and self-discovery. The story follows a young woman as she navigates the complexities of relationships and personal growth. Stunning cinematography and heartfelt narrative. Also, &lt;em&gt;You&lt;/em&gt;, a psychological thriller series that follows Joe Goldberg, a charming yet dangerous psychopath who becomes obsessed with the people he loves.&lt;/p&gt;
&lt;p&gt;The last ten-odd days were disturbing and I was glued to the news. The situation back home is heartbreaking. What is more annoying is that all of the news channels are too polarised; thus, instead of providing information, they spend more time on sensationalism. I have faith that India will have a response ready. &lt;a href=&quot;https://x.com/adgpi/status/1919850036596199492&quot;&gt;Vengeance is coming&lt;/a&gt;. &lt;a href=&quot;https://x.com/adgpi/status/1919850036596199492&quot;&gt;Jai Hind&lt;/a&gt;.&lt;/p&gt;
&lt;h6 id=&quot;april&quot; tabindex=&quot;-1&quot;&gt;April&lt;/h6&gt;
&lt;p&gt;Too many projects and short stints; dropping all projects for now. Planning to slow down a bit and try to focus on one clear domain to build something tangible. Let’s see how this turns out. I’d still have to finish Orion, for it is part of my academics. New York life is beautiful. Spring is starting, and the city looks lovely! Also got a new gig that I am pretty excited about. I got a Tech Product Engineering internship for this summer at &lt;a href=&quot;https://yourmove.ai/&quot;&gt;YourMove.ai&lt;/a&gt;, an AI-based product that helps you in your dating life.&lt;/p&gt;
&lt;p&gt;College life is slow but more meaningful. Formal education and I seem to be done with each other. Thus, this semester, almost half of my credits are just projects. Ferry is almost done, and I am focused on wrapping up Orion. (More details &lt;a href=&quot;https://github.com/anubhavpgit&quot;&gt;&lt;em&gt;here&lt;/em&gt;&lt;/a&gt;). Will try to keep up the pace next semester as well and graduate early. Spending most of my time on product strategies, design, architecture and case studies: product market fits.&lt;/p&gt;
&lt;p&gt;Helped out a friend this weekend build an &lt;a href=&quot;https://github.com/anubhavpgit/accelerator/&quot;&gt;AI-accelerated hardware simulator&lt;/a&gt; in ‘C’ and Verilog to demonstrate vector multiplications and speedup in hardware. The benchmarks show massive speedup in TPUs and NPUs: O(1) vs O(n) in CPUs by running the multiplication in parallel.&lt;/p&gt;
&lt;p&gt;This weekend was productive. Decided to revisit an old decentralised, encrypted chat app I built three years ago, and here is the v2: &lt;a href=&quot;https://anubhavp.dev/fireside/&quot;&gt;https://anubhavp.dev/fireside/&lt;/a&gt;. Also, implemented a global search feature in this blog. Search for any content in the blog on any page, using the search icon, or &lt;code&gt;ctrl&lt;/code&gt;/ &lt;code&gt;cmd&lt;/code&gt; + &lt;code&gt;k&lt;/code&gt; or &lt;code&gt;/&lt;/code&gt;. The search is implemented using a custom prefix-matching plus a fuzzy search engine that uses the BM25 ranking algorithm. At times, there are these one or two out of a thousand scenarios where I sometimes contemplate that maybe Leetcode has had some value in my software engineering journey.&lt;/p&gt;
&lt;p&gt;F-ed up my PC for a day. Ferry is not programmed to handle malformed code, and the IR-assembly code generation missed adding &lt;code&gt;epilogue&lt;/code&gt; to this one for-loop in a test.c file. Ferry uses &lt;code&gt;spike&lt;/code&gt; to emulate the RISC-V assembly code, and it started an infinite loop with seg faults and stack overflows. I quit the emulator (&lt;code&gt;ctrl&lt;/code&gt; + &lt;code&gt;c&lt;/code&gt;) and was on my way, but &lt;code&gt;spike&lt;/code&gt; was silently running in the background. A day later, my CPU Fan started roaring, and the laptop was heating up. Initially, I ignored it, but later, upon inspection, it was clear today why tests are important in your code. Spike was hogging 99.5% CPU usage.&lt;/p&gt;
&lt;p&gt;Gemini-2.5-pro is the new hot thing in the AI space. Reddit users are reportedly reporting massive &lt;a href=&quot;https://www.reddit.com/r/singularity/comments/1jl1eti/man_the_new_gemini_25_pro_0325_is_a_breakthrough/&quot;&gt;performance differences from Claude 3.7-sonnet&lt;/a&gt;. On the contrary, my experience has not been quite the same. When I asked it to analyse Ferry, my C compiler project, it did successfully analyse it in one shot, identify bugs and suggest improvements. But the code generated by Gemini 2.5-pro was buggy, with unreadable characters (this one time it generated a weird character which I hadn’t seen in ASCII before xD), and a lot of unused variables, amongst others. The code also didn’t solve the problem.&lt;/p&gt;
&lt;p&gt;Currently, Ferry is riddled with bugs, primarily in the IR to Assembly space, mainly because I mostly wrote all the template code myself and asked Claude to fill in the rest.&lt;/p&gt;
&lt;h6 id=&quot;march&quot; tabindex=&quot;-1&quot;&gt;March&lt;/h6&gt;
&lt;p&gt;Claude finally has a web search feature; I can finally let my ChatGPT+ rest in peace now. Well done, soldier. You did well. (&lt;em&gt;Immediately regrets after looking at the Ghibli art images everyone is generating&lt;/em&gt;) :(&lt;/p&gt;
&lt;p&gt;Happy Holi, folks! I had a lovely Holi celebration here this weekend. Currently wrapping up Ferry, &lt;a href=&quot;/blog/ferryman.html&quot;&gt;a C compiler in Rust&lt;/a&gt;. The compiler is currently capable of parsing, tokenising, generating an AST and an optimised intermediate representation of the code for a subset of the C language. The following steps would be to compile IR to RISC-V assembly.&lt;/p&gt;
&lt;p&gt;Compiled languages are always faster than interpreted languages, which is why ​Microsoft has also announced a &lt;a href=&quot;https://devblogs.microsoft.com/typescript/typescript-native-port/&quot;&gt;native port of the TypeScript compiler to Go&lt;/a&gt;, which was earlier written in TypeScript.&lt;/p&gt;
&lt;p&gt;I am also contributing to a process isolation sandbox project, &lt;a href=&quot;https://github.com/Lind-Project&quot;&gt;LIND&lt;/a&gt;, at the Secure Systems Lab at NYU and in some research about Meta’s Orion Glasses, particularly focusing on hand-gestured controllers.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://www.reddit.com/r/ClaudeAI/comments/1ixisq1/just_tried_claude_37_sonnet_what_the_actual_fuck/&quot;&gt;internet is going crazy&lt;/a&gt; since the launch of &lt;em&gt;Claude 3.7 sonnet&lt;/em&gt; and for the right reasons. Claude 3.7 destroyed benchmarks, which is a significant improvement over other models. I tried out Claude, and it’s just insane. For instance, I asked it to review an article I wrote earlier with the default prompt provided by Anthropic (look for the &lt;em&gt;polish your prose&lt;/em&gt; suggestion in Claude), and it just nailed it.&lt;/p&gt;
&lt;p&gt;Now the question is, do I replace my ChatGPT+ subscription with Claude? Claude &lt;strong&gt;doesn’t have a web-search feature&lt;/strong&gt;, yet. But I switched, crossed the line, and made the jump to the dark side. I wish it had a web search feature. It could be a separate entity, like a separate web scraper model, or maybe a separate tab in the app, or something. This would solve all my problems and would be a game-changer. I used ChatGPT for every single thing, from research and coding to analysing the nutritional values of food. For example, every day, I ask ChatGPT to find the nutritional values of a food item, like say a particular branded milk/ oat milk or a coffee from Starbucks, and it still does a great job at it. To maintain a log, I ask it to save all the results in a markdown file and return.&lt;/p&gt;
&lt;p&gt;The other solution now is using Google as usual (Google does a better job than the likes of Perplexity at &lt;strong&gt;finding relevant sources&lt;/strong&gt;, &lt;strong&gt;BUT&lt;/strong&gt;, for summarising, paraphrasing &amp;amp; “how to” queries, an LLM-based search engine is better. Refer &lt;a href=&quot;https://medium.com/codex/perplexity-vs-google-search-a-totally-unscientific-comparison-9a58837d7a69&quot;&gt;to this article&lt;/a&gt;), and then copy-paste the results to Claude.&lt;/p&gt;
&lt;p&gt;Is it March yet? I remember going back home, to India, for a break, like it was yesterday and now two months are already over? Strange. On this side of the world, I am currently building a compiler for a subset of the C language to RISC-V assembly language. It’s a fun project that helps me understand how compilers work. I also joined the SSL (Secure Systems Lab) at NYU, and am involved in a project aimed at building a secure system that aims to isolate processes in a single process sandbox. This helps limit the damage caused by bugs or security flaws in the application. Also, involved in some research about&amp;nbsp;&lt;a href=&quot;https://about.fb.com/news/2024/09/introducing-orion-our-first-true-augmented-reality-glasses/&quot;&gt;Meta’s Orion Glasses&lt;/a&gt; because I found the hand-gestured controllers fascinating. I am planning to work this semester on a controller as such. Excited to see how all these unfold in the coming months.&lt;/p&gt;
&lt;h6 id=&quot;february&quot; tabindex=&quot;-1&quot;&gt;February&lt;/h6&gt;
&lt;p&gt;The highlight has to be HackNYU, a 48-hour hackathon that I participated in last weekend. We built &lt;strong&gt;&lt;a href=&quot;https://github.com/mewtyunjay/neighborly/&quot;&gt;Neighbourly&lt;/a&gt;&lt;/strong&gt;, a hyperlocal community inventory management app for you to donate, borrow, or exchange food and essentials with those in need. We didn’t win, but I am proud of what we accomplished in the given timeframe. Here’s the gist of the project on &lt;a href=&quot;https://devpost.com/software/neighbourly-r7fjz4?ref_content=my-projects-tab&amp;amp;ref_feature=my_projects&quot;&gt;Devpost&lt;/a&gt;. We built the skeleton in a few minutes using tools like &lt;a href=&quot;https://v0.dev&quot;&gt;v0.dev&lt;/a&gt;, &lt;a href=&quot;https://blot.new&quot;&gt;blot.new&lt;/a&gt;, &lt;a href=&quot;https://rollout.site&quot;&gt;rollout.site&lt;/a&gt;, and &lt;a href=&quot;https://presentations.ai/&quot;&gt;presentations.ai&lt;/a&gt;. It’s crazy how AI has changed the landscape of today’s development.&lt;/p&gt;
&lt;p&gt;Tech is a commodity now; anyone with a slight sense of what they are doing can build something. I don’t see the point in hiring a lot of developers to build something that can be done by a few now. I get what FAANG companies mean when they lay off a lot of devs. Not that I support that, but it just makes more fiscal sense. The real challenge is to build something that people want.&lt;/p&gt;
&lt;h6 id=&quot;january&quot; tabindex=&quot;-1&quot;&gt;January&lt;/h6&gt;
&lt;p&gt;Back in action: January was like an amazing, much-needed, magical vacation back home, and now I am back, and it feels good. I met my cousins, family and relatives, ate a bunch of good Indian food, and spent a lot of time with my friends, still unsure how a month went by and if I was ready to get back to work. My sister got married, and I still can’t digest this. She is just six months older than I, and we grew up together, inseparable. I am happy for her, but it feels like a part of me is missing. I can’t wait to finish things here and rush back home.&lt;/p&gt;
&lt;p&gt;Currently reading &lt;a href=&quot;https://youtubetranscriptoptimizer.com/blog/05_the_short_case_for_nvda&quot;&gt;The Short Case for Nvidia Stock&lt;/a&gt; by Jeffrey Emanuel, which explains how Deepseek, an open-source LLM, just killed it in the LLM space. The training of DeepSeek-V3 required less than $6 million worth of computing power with Nvidia H800 chips, which is 20 to 50 times cheaper than the cost of training similar models by OpenAI and Anthropic. On Monday, January 27, 2025, the stock closed at $118.42, marking a 17% drop from the previous close. This decline erased nearly $600 billion from NVIDIA’s market capitalisation, setting a record for the largest single-day loss in U.S. history. The stock’s decline was attributed to a combination of factors, including a broader market sell-off, concerns about the company’s growth prospects, and a downgrade from analysts at Morgan Stanley.&lt;/p&gt;
&lt;p&gt;Taking a break:&lt;/p&gt;
&lt;p&gt;I am going back home this month. If you’re curious, I will be spending more time on my books, PS5, and Netflix in the next few weeks. Red Dead Redemption, Spiderman 2, Pulp Fiction, The Godfather, and a long list await this new year. Hoping to gobble up good food for the rest of the year in this one-month break.&lt;/p&gt;
&lt;p&gt;Here’s to new beginnings and new adventures! 🥂 I hope you have a great year ahead. Merry Christmas, and a happy New Year, everyone! Promise to be back soon. Keep checking :)&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;a href=&quot;/blog/24.html&quot;&gt;2024&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;/blog/23.html&quot;&gt;2023&lt;/a&gt;&lt;/p&gt;

            &lt;hr&gt;
            &lt;div class=&quot;footer&quot;&gt;
              &lt;i&gt;Feedback, Suggestions, Comments - &lt;/i&gt;
              &lt;div class=&quot;giscus-div&quot; id=&quot;comments&quot;&gt;
                &lt;script src=&quot;https://giscus.app/client.js&quot; data-repo=&quot;anubhavpgit/anubhavpgit.github.io&quot; data-repo-id=&quot;MDEwOlJlcG9zaXRvcnk0MDQ1ODEzMjc=&quot; data-category-id=&quot;DIC_kwDOGB1rz84Cer0j&quot; data-mapping=&quot;title&quot; data-strict=&quot;0&quot; data-reactions-enabled=&quot;1&quot; data-emit-metadata=&quot;0&quot; data-input-position=&quot;bottom&quot; data-theme=&quot;noborder_light&quot; data-lang=&quot;en&quot; data-loading=&quot;lazy&quot; crossorigin=&quot;anonymous&quot; async=&quot;&quot;&gt;&lt;/script&gt;
              &lt;/div&gt;
              Feel free to
              &lt;a id=&quot;mailtoLink&quot; href=&quot;mailto:anubhavp@duck.com?subject=Here&apos;s%20a%20suggestion/feedback!&quot;&gt;send
                me an email&lt;/a&gt;.
            &lt;/div&gt;
          &lt;/div&gt;
        </content:encoded>
            <subtitle>Nomadic battles and adventures around the world</subtitle>
        </item>
        <item>
            <title><![CDATA[Dough - A Rich Presentation Tool]]></title>
            <description><![CDATA[A rich presentation tool built in Rust that uses markdown for content generation.]]></description>
            <link>https://anubhavp.dev/blog/dough.html</link>
            <guid isPermaLink="true">https://anubhavp.dev/blog/dough.html</guid>
            <dc:creator><![CDATA[Anubhab Patnaik]]></dc:creator>
            <pubDate>Wed, 31 Jan 2024 00:00:00 GMT</pubDate>
            <content:encoded>
          &lt;div class=&quot;content custom&quot;&gt;
            &lt;div class=&quot;search-container&quot;&gt;&lt;/div&gt;
            &lt;p&gt;Imagine a presentation tool that seamlessly blends simplicity with power. Welcome to Dough – your new favorite presentation companion. Say goodbye to clunky interfaces and hello to a tool that’s as intuitive as it is efficient.&lt;/p&gt;
&lt;h2 id=&quot;why-dough&quot; tabindex=&quot;-1&quot;&gt;Why Dough?&lt;/h2&gt;
&lt;p&gt;(Why, though? - &lt;em&gt;Get it? xD&lt;/em&gt;)&lt;/p&gt;
&lt;p&gt;At StackIt, the team gathers every Saturday for their weekly showcase. Each member presents their progress, showcasing the fruits of their week-long hike. Inspired by this collaborative spirit, I came to the idea of Dough - a presentation generator tool like no other. Built in Rust, &lt;a href=&quot;https://github.com/anubhavpgit/dough&quot;&gt;Dough&lt;/a&gt; is a rich, modular, command-line tool to generate presentations. I found similar tools like &lt;a href=&quot;sli.dev&quot;&gt;slidev&lt;/a&gt; by &lt;a href=&quot;https://antfu.me/&quot;&gt;antfu&lt;/a&gt; and &lt;a href=&quot;https://github.com/mfontanini/presenterm&quot;&gt;presenterm&lt;/a&gt; that inspired me to create Dough.&lt;/p&gt;
&lt;h2 id=&quot;features&quot; tabindex=&quot;-1&quot;&gt;Features&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Dough’s modular design allows for seamless &lt;strong&gt;customization&lt;/strong&gt;. You can customize the color scheme, the alignment, and the syntax highlighting of the code blocks, and even the runtime of the code blocks.&lt;/li&gt;
&lt;li&gt;Align content both horizontally and vertically and also specify the &lt;strong&gt;alignment&lt;/strong&gt; of individual text segments. You can decide between having a margined presentation or one without margin anywhere, in the bottom, left, or centre, of the screen.&lt;/li&gt;
&lt;li&gt;Code blocks have &lt;strong&gt;syntax highlighting&lt;/strong&gt;, and also support code execution. You can run your code and the output will be displayed in the presentation. The code blocks run in a separate thread and the main thread displays the output in the terminal. The code blocks are internally ordered in the order they appear in the markdown file.&lt;/li&gt;
&lt;li&gt;Dough will also be supporting &lt;strong&gt;images&lt;/strong&gt; in the terminal for the ones that have a GPU-enabled terminal like Kitty or iTerm2.&lt;/li&gt;
&lt;li&gt;You can choose to use templates. The optional &lt;code&gt;--template&lt;/code&gt; flag is used to specify the template. The default template is used if not specified. If not, simply spawn a new folder and a markdown file, and you’re good to go. Dough’s intuitive navigation system lets you scroll through slides with ease. You can choose between scrolling top-down or bottom-up. Presentations start from &lt;code&gt;1&lt;/code&gt; to the last slide. Dough supports arrow keys and VIM keybindings to navigate through slides. There are two modes of navigation:&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Highlight&lt;/strong&gt; a line as you scroll through the slides.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scroll&lt;/strong&gt; through the content of the slide.&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;Dough supports &lt;strong&gt;hot reloading&lt;/strong&gt;. You can edit your markdown file and do a &lt;code&gt;ctrl+r&lt;/code&gt; to reflect in the presentation instantly. The auto hot reload is still in the works.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The default style settings are stored in a &lt;code&gt;style.yaml&lt;/code&gt; file which looks like this: &lt;a href=&quot;https://github.com/anubhavpgit/dough/blob/main/templates/default/style.yml&quot;&gt;style.yaml&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;unveiling-the-core&quot; tabindex=&quot;-1&quot;&gt;Unveiling the Core&lt;/h2&gt;
&lt;p&gt;Dough thrives on markdown, transforming simple text files into captivating slides. Leveraging the syntax of &lt;a href=&quot;https://talk.commonmark.org/t/pulldown-cmark-commonmark-in-rust/1205&quot;&gt;pulldown-cmark&lt;/a&gt;, it effortlessly transforms your ideas into visual stories.&lt;/p&gt;
&lt;p&gt;Projects are created by simply writing a markdown file inside a folder. The folder name is the name of the project. Just &lt;code&gt;mkdir my_folder&lt;/code&gt;
and &lt;code&gt;touch my_folder/1.md&lt;/code&gt; and you’re good to go. You can also use &lt;strong&gt;templates&lt;/strong&gt; using the &lt;code&gt;new&lt;/code&gt; command. The slides are presented using the &lt;code&gt;present&lt;/code&gt; command. The optional &lt;code&gt;--template&lt;/code&gt; flag is used to specify the template. The default template is used if not specified.&lt;/p&gt;
&lt;p&gt;At the heart of dough lie two pivotal components:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Renderer&lt;/strong&gt;: This component takes charge of the visual rendering of slides.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Parser&lt;/strong&gt;: Responsible for dissecting markdown files and converting them into a structured format.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;strong&gt;parser&lt;/strong&gt; parses the markdown file, prettifies it, and then passes it to the renderer to render it. The renderer then renders the slide in the &lt;code&gt;terminal&lt;/code&gt; to display it.&lt;/p&gt;
&lt;p&gt;The parser takes in the markdown text and converts it into &lt;code&gt;Nodes&lt;/code&gt; of &lt;code&gt;mdast&lt;/code&gt;(markdown abstract syntax tree). The tree is reccursively traversed and each node is then styled according to the &lt;code&gt;Node&lt;/code&gt; ( Markdown Element ) type. After combining all the nodes, a &lt;code&gt;prettified&lt;/code&gt; version of the text is returned. It then modifies the &lt;code&gt;prettified&lt;/code&gt; content, applies custom alignment, styles, and spacing, and adds a margin to the content to fit the terminal.&lt;/p&gt;
&lt;p&gt;There are two stages of &lt;strong&gt;rendering&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The renderer takes in the &lt;code&gt;prettified&lt;/code&gt; content and renders it in the terminal.&lt;/li&gt;
&lt;li&gt;The renderer then handles the navigation actions, the scrolling mechanism and the keybindings. It controls the flow of the presentation and is responsible for rendering the slides in the terminal. It switches between presentation and highlighting mode and also handles the code execution.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here is the source code of dough - &lt;a href=&quot;https://github.com/anubhavpgit/dough.git&quot;&gt;Dough&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;contributing&quot; tabindex=&quot;-1&quot;&gt;Contributing&lt;/h2&gt;
&lt;p&gt;If you’re eager to dive into the world of Rust and looking for a project to contribute to, Dough presents an exciting opportunity. Here’s a breakdown of what’s currently working and what areas could benefit from your expertise:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What’s working and what’s not?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input type=&quot;checkbox&quot; id=&quot;checkbox0&quot;&gt;&lt;label for=&quot;checkbox0&quot;&gt; Fix scrolling issue in highlight mode:&lt;/label&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input type=&quot;checkbox&quot; id=&quot;checkbox1&quot;&gt;&lt;label for=&quot;checkbox1&quot;&gt; &lt;/label&gt;&lt;em&gt;bug&lt;/em&gt; Over Scroll in infinite scrolling&lt;/li&gt;
&lt;li&gt;&lt;input type=&quot;checkbox&quot; id=&quot;checkbox2&quot;&gt;&lt;label for=&quot;checkbox2&quot;&gt; &lt;/label&gt;&lt;em&gt;feat&lt;/em&gt; Skip empty lines in highlight mode&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;input type=&quot;checkbox&quot; id=&quot;checkbox3&quot;&gt;&lt;label for=&quot;checkbox3&quot;&gt; &lt;/label&gt;&lt;em&gt;bug&lt;/em&gt; custom aligner adds empty lines after text-block alignment&lt;/li&gt;
&lt;li&gt;&lt;input type=&quot;checkbox&quot; id=&quot;checkbox4&quot;&gt;&lt;label for=&quot;checkbox4&quot;&gt; &lt;/label&gt;&lt;em&gt;feat.&lt;/em&gt; Hot Module Reload&lt;/li&gt;
&lt;li&gt;&lt;input type=&quot;checkbox&quot; id=&quot;checkbox5&quot;&gt;&lt;label for=&quot;checkbox5&quot;&gt; &lt;/label&gt;&lt;em&gt;feat.&lt;/em&gt; Add support for the maximum width and height of the presentation. Write a word wrapper.&lt;/li&gt;
&lt;li&gt;&lt;input type=&quot;checkbox&quot; id=&quot;checkbox6&quot;&gt;&lt;label for=&quot;checkbox6&quot;&gt; &lt;/label&gt;&lt;em&gt;feat.&lt;/em&gt; Add comprehensive support for common Markdown elements.&lt;/li&gt;
&lt;li&gt;&lt;input type=&quot;checkbox&quot; id=&quot;checkbox7&quot;&gt;&lt;label for=&quot;checkbox7&quot;&gt; &lt;/label&gt;&lt;em&gt;feat.&lt;/em&gt; Enhance rendering for complex markdown elements like links within headings or lists.
&lt;ul&gt;
&lt;li&gt;&lt;input type=&quot;checkbox&quot; id=&quot;checkbox8&quot;&gt;&lt;label for=&quot;checkbox8&quot;&gt; lists.&lt;/label&gt;&lt;/li&gt;
&lt;li&gt;&lt;input type=&quot;checkbox&quot; id=&quot;checkbox9&quot;&gt;&lt;label for=&quot;checkbox9&quot;&gt; blockquotes.&lt;/label&gt;&lt;/li&gt;
&lt;li&gt;&lt;input type=&quot;checkbox&quot; id=&quot;checkbox10&quot;&gt;&lt;label for=&quot;checkbox10&quot;&gt; tables.&lt;/label&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Feel free to explore these areas, open new issues, or submit pull requests to contribute to Dough’s evolution. Your insights and contributions are highly valued as we strive to make Dough the go-to presentation tool for Rust enthusiasts everywhere.&lt;/p&gt;
&lt;p&gt;Let your presentations shine like never before :)&lt;/p&gt;
&lt;figure style=&quot;justify-content: center; align-items: center; display: flex;flex-direction: column;&quot;&gt;
&lt;video controls=&quot;&quot; style=&quot;height: 100%; width: 100%; object-fit: contain;&quot;&gt;
&lt;source src=&quot;https://anubhavp.dev/assets/img/dough/simple-presentation.mp4&quot; type=&quot;video/mp4&quot;&gt;
  Your browser does not support the video tag.
&lt;/video&gt;
&lt;/figure&gt;

            &lt;hr&gt;
            &lt;div class=&quot;footer&quot;&gt;
              &lt;i&gt;Feedback, Suggestions, Comments - &lt;/i&gt;
              &lt;div class=&quot;giscus-div&quot; id=&quot;comments&quot;&gt;
                &lt;script src=&quot;https://giscus.app/client.js&quot; data-repo=&quot;anubhavpgit/anubhavpgit.github.io&quot; data-repo-id=&quot;MDEwOlJlcG9zaXRvcnk0MDQ1ODEzMjc=&quot; data-category-id=&quot;DIC_kwDOGB1rz84Cer0j&quot; data-mapping=&quot;title&quot; data-strict=&quot;0&quot; data-reactions-enabled=&quot;1&quot; data-emit-metadata=&quot;0&quot; data-input-position=&quot;bottom&quot; data-theme=&quot;noborder_light&quot; data-lang=&quot;en&quot; data-loading=&quot;lazy&quot; crossorigin=&quot;anonymous&quot; async=&quot;&quot;&gt;&lt;/script&gt;
              &lt;/div&gt;
              Feel free to
              &lt;a id=&quot;mailtoLink&quot; href=&quot;mailto:anubhavp@duck.com?subject=Here&apos;s%20a%20suggestion/feedback!&quot;&gt;send
                me an email&lt;/a&gt;.
            &lt;/div&gt;
          &lt;/div&gt;
        </content:encoded>
            <subtitle>A rich presentation tool built in Rust that uses markdown for content generation.</subtitle>
        </item>
        <item>
            <title><![CDATA[Fall, 2023 - Kedarnath & Dubai]]></title>
            <description><![CDATA[Two most glorious weeks of my life, unbothered by the world, one in the mountains, chasing the clouds, looking for Nirvana, and the other in the desert, chasing the sun, looking at greater heights.]]></description>
            <link>https://anubhavp.dev/blog/fall23.html</link>
            <guid isPermaLink="true">https://anubhavp.dev/blog/fall23.html</guid>
            <dc:creator><![CDATA[Anubhab Patnaik]]></dc:creator>
            <pubDate>Mon, 23 Oct 2023 00:00:00 GMT</pubDate>
            <content:encoded>
          &lt;div class=&quot;content custom&quot;&gt;
            &lt;div class=&quot;search-container&quot;&gt;&lt;/div&gt;
            &lt;style&gt;
 .dubai {
	justify-content: center;
	align-items: center;
	display: flex;
	flex-direction: column;
	width: 100%;
	/* Ensure consistent parent width for percentage calculations */
}

 .dubai-group {
	display: flex;
	flex-direction: row;
 }
&lt;/style&gt;
&lt;p&gt;This fall, I spent two of the most glorious weeks of my life, one in the mountains, chasing the clouds, and the other in the desert, tanning under the sun. The journey was filled with love, nostalgia, and a sense of freedom as I explored a part of adulthood.&lt;/p&gt;
&lt;h2 id=&quot;a-trek-to-kedarnath&quot; tabindex=&quot;-1&quot;&gt;A trek to Kedarnath&lt;/h2&gt;
&lt;p&gt;The journey started from Bangalore. Mukul and I live in Bangalore, and we left for Delhi on the 7th of October. We boarded the train and had a great time. We got ourselves an AC coach and settled in. The journey begins!&lt;/p&gt;
&lt;p&gt;Upon reaching Delhi, we stayed with Mukul’s sister for a day. We met the rest of the gang, Hritik and Hemant, who had come from Jamshedpur. We had an evening to kill and thus decided to explore the old city, rich with history and culture. We roamed around the streets of &lt;em&gt;Chandni Chowk&lt;/em&gt; and &lt;em&gt;Chawri Bazar&lt;/em&gt;, looked for flea markets, and ate a ton of fast food which you might guess- I would have regretted later. These places had been bookmarked by me for a long time now, and I finally got to visit them. Our day was filled with visits to iconic landmarks, including the magnificent Jama Masjid and the Red Fort.&lt;/p&gt;
&lt;figure class=&quot;dubai&quot;&gt;
&lt;img alt=&quot;puranidilli&quot; src=&quot;https://anubhavp.dev/assets/img/fall23/purani-dilli.jpeg&quot; class=&quot;h-75 w-75&quot; loading=&quot;lazy&quot;&gt;
&lt;figcaption&gt;
&lt;a href=&quot;https://www.instagram.com/p/CytDfh0PFAw/?utm_source=ig_web_copy_link&amp;amp;igshid=MzRlODBiNWFlZA==&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Purani Dilli&lt;/a&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;We left for Haridwar at midnight and reached there at the break of dawn, around 4 in the morning. We scoured for cabs and found a cheap one right in front of the railway station, and went straight to Sonprayag. En route, we explored numerous river confluences, each referred to as a “Prayag.”&lt;/p&gt;
&lt;p&gt;The literal meaning of &lt;em&gt;Prayag&lt;/em&gt; is “confluence,” and it signifies the meeting point of two or more rivers. The most famous Prayag is &lt;em&gt;Triveni Sangam&lt;/em&gt;, where the &lt;em&gt;Ganga&lt;/em&gt;, &lt;em&gt;Yamuna&lt;/em&gt;, and &lt;em&gt;Saraswati&lt;/em&gt; rivers converge. The &lt;em&gt;Ganga&lt;/em&gt; is considered the most sacred river in Hinduism, while the &lt;em&gt;Yamuna&lt;/em&gt; is associated with Lord Krishna, and the &lt;em&gt;Saraswati&lt;/em&gt; is believed to be a mythical river that no longer exists. There are five major confluences in the region, each with its significance, in Uttarakhand. The &lt;em&gt;Ganga&lt;/em&gt; is formed at a place called &lt;em&gt;Devprayag&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;From Sonprayag, we left for Gaurikund, the starting point of the trek to Kedarnath. During the journey, we spoke about our lives and how life had changed over the years. The 2013-14 teenage years were filled with fun and excitement. We spoke about those kids in those days in Jamshedpur, unbothered and oblivious to the world around them, and now how after 10 years, having grown up, we were all set to explore the world. We talked about what each of us plans to do in the future, and how our lives had changed since we had graduated from high school. It took us 12 odd hours to reach Gaurikund and we were exhausted. Sensibly, we decided to rest and begin the trek the next day.&lt;/p&gt;
&lt;p&gt;Woke up early the next day, freshened up, and prepared for the trek. Hemant and Mukul, exuding fumes of enthusiasm, and energy radiating, looking all tough, shouldered their backpacks and set out for the trek’s starting point. I was a bit sceptical of my skill. I pretty much knew I wouldn’t be able to complete the entire trek on foot. The 22-kilometer, steep journey seemed daunting. Hritik freshened up as well, and we all went ahead to start the trek. Mukul and Hemant were ahead of us. They didn’t wait for me as I was slowing down everyone. Hritik walked with me and tried to push me to cover as much as I could and advised me not to take frequent breaks. Carrying a few extra kilos, I found it extremely cumbersome to trek. I had to pause every 100-200 meters, mustering every ounce of courage and strength to continue. I was not accustomed to such strenuous physical activity, and the steep ascent was taking a toll on me. Plus, I was not in the best shape and was not physically prepared for the trek.&lt;/p&gt;
&lt;p&gt;Somehow, I managed to trek for six and a half km. Hritik, Mukul and Hemant urged me to trek on a mule. The route offered mule transportation for those who found it challenging to ascend on foot. Initially, I was equally excited as the rest and didn’t want to succumb and get on a mule. However, after enduring the gruelling climb of the first 6 kilometres, and considering the unanimous request, I realized that it would be unfair of me to hold back the group.&lt;/p&gt;
&lt;p&gt;With Hritik by my side, we decided to mount mules and proceed with the journey. Upon reaching, we paid an incredibly high price for a plate of Maggie and halted. The Maggie plate and the view were worth it. Mukul and Hemant reached after an hour, tired and looking like their souls were almost ready to succumb to fatigue. Hritik, Mukul, and Hemant set off in search of the campsite to rest and recuperate. Mukul looked as if he was on the brink of exhaustion and was borderline dead. I decided to hang back, explore the hills, and click photos.&lt;/p&gt;
&lt;figure class=&quot;dubai&quot;&gt;
&lt;img alt=&quot;gangotri&quot; src=&quot;../assets/img/fall23/maggie.jpeg&quot; class=&quot;h-75 w-75&quot; loading=&quot;lazy&quot;&gt;
&lt;figcaption&gt;
&lt;a href=&quot;https://www.instagram.com/p/CyQ6wKVP7BV/?utm_source=ig_web_copy_link&amp;amp;igshid=MzRlODBiNWFlZA==&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;
Maggie and the view
&lt;/a&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I came to the tent after having witnessed the magnificent sunset that I saw up on the hill. All of us were exhausted, and we went to sleep quickly and just woke up for dinner. During the night, the temperatures plummeted to -3 degrees Celsius.&lt;/p&gt;
&lt;figure class=&quot;dubai&quot;&gt;
&lt;img alt=&quot;gangotri&quot; src=&quot;https://anubhavp.dev/assets/img/fall23/gangotri.jpeg&quot; class=&quot;h-75 w-100&quot; loading=&quot;lazy&quot;&gt;
&lt;figcaption&gt;
&lt;a href=&quot;https://www.instagram.com/p/CyQ6wKVP7BV/?utm_source=ig_web_copy_link&amp;amp;igshid=MzRlODBiNWFlZA==&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;
Gangotri Range
&lt;/a&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The following morning, we awoke from our snug sleeping bags and prepared to visit the temple, our spirits high. We went near the temple, and the view was breathtaking. The temple was surrounded by snow-capped mountains, and the sun was shining brightly. We were all in awe of the beauty of the place. Hritik decided to buy gifts for his family and friends. We went ahead and bought some stuff for our families as well. After the shopping, we went ahead and stood in the queue for the temple. The queue was long, and it took us 3 hours to reach the temple. We heard that someone from the Ambanis had come to visit the place and the temple was closed for 3 tedious hours.&lt;/p&gt;
&lt;p&gt;Standing there, I eavesdropped on the conversations of the people around me. My mind got busy wandering, travelling to various places in various stories, exploring multiple character arcs and their views of rights and wrongs. I was engrossed in my own thoughts, contemplating morality through the lens of these characters. I was lost in the stories of the people around me, their lives, their struggles, and their aspirations. Until I heard the temple bells ringing.&lt;/p&gt;
&lt;figure class=&quot;dubai&quot;&gt;
&lt;img alt=&quot;gangotri&quot; src=&quot;../assets/img/fall23/gang.jpeg&quot; class=&quot;h-75 w-75&quot; loading=&quot;lazy&quot;&gt;
&lt;figcaption&gt;
&lt;a href=&quot;https://www.instagram.com/p/CyQ6wKVP7BV/?utm_source=ig_web_copy_link&amp;amp;igshid=MzRlODBiNWFlZA==&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;
The Gang and the temple
&lt;/a&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;We went inside the temple, and the atmosphere was serene. After returning to the campsite in Kedarnath, we collected our belongings and I found out that my power bank had been stolen. With a heavy heart, we started our descent. We reached the campsite, and we were all tired. We had our dinner and slept.&lt;/p&gt;
&lt;figure class=&quot;dubai&quot;&gt;
&lt;img alt=&quot;kedarnath&quot; src=&quot;../assets/img/fall23/kedarnath.webp&quot; class=&quot;h-75 w-75&quot; loading=&quot;lazy&quot;&gt;
&lt;figcaption&gt;
&lt;a href=&quot;https://www.instagram.com/p/CytDNnKvQfr/?utm_source=ig_web_copy_link&amp;amp;igshid=MzRlODBiNWFlZA==&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;
Journey back
&lt;/a&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The following day, we embarked on our journey to Haridwar. The return journey was beautiful. We were tired, having successfully completed the trip and were all in high spirits. We reminisced about our childhood days and the memories we had made. We were all happy and content. Hritik told us how hard his breakup was on him, while me and Mukul made fun of him. Hemant told us that he got a quarter where he later found out that someone had died and decided to switch places. Now, he had to live with his brother while he awaited a new quarter. Somehow six hours passed, and we reached Haridwar.&lt;/p&gt;
&lt;p&gt;After reaching Haridwar, we stowed our belongings in a room booked by Hemant. That evening, we roamed the enchanting streets, particularly around the ghats. It was a magical experience. As we explored the bustling markets of Haridwar, we indulged in a variety of food, finally catering to our appetites after being starved for 3 days. Hritik decided to bathe in the &lt;em&gt;Holy Ganga&lt;/em&gt; and I joined him and dipped my feet in the sacred water. We also visited several temples, walking down memory lane. We explored old paintings on the walls, discussing mythology and the stories behind them.&lt;/p&gt;
&lt;p&gt;We had a train to catch at 11:45 p.m., and at 12, we left for Delhi.&lt;/p&gt;
&lt;p&gt;At that point, my journey took a different direction. While the rest of my friends remained in Delhi, I boarded a flight headed for Bhubaneswar, concluding this unforgettable adventure with memories that would last a lifetime.&lt;/p&gt;
&lt;p&gt;Coming back home is always great. Khusi had flown in from Dubai for her fall break, and we had decided to go visit Dubai the next week, together. The day after that, both Khusi and I embarked on our journey to Dubai, ready for the adventures and experiences that awaited us in this vibrant city.&lt;/p&gt;
&lt;h2 id=&quot;marhaba-dubai&quot; tabindex=&quot;-1&quot;&gt;Marhaba, Dubai&lt;/h2&gt;
&lt;p&gt;Dubai proved to be a surreal experience, marking my first international trip outside of India. As I boarded the flight, the first thing that caught my attention was the extended flight time. Our journey spanned 4 hours and 15 minutes from Bhubaneswar to Dubai International Airport.&lt;/p&gt;
&lt;p&gt;Initially, I grappled with homesickness and longed to go back to Bangalore. I was away for more than a week and this feeling was making me uncomfortable. Most of my tension was due to my work. A lot of things were pending, and Stackit has just launched. Being the only senior engineer, I had to make sure everything was in place. Dubai was a new place, and I was apprehensive about how I would adapt. I didn’t know anyone here and felt left out. Dubai was turning out to be a bum. I stayed indoors, did not interact with anyone, and was homesick and worried about going back.&lt;/p&gt;
&lt;p&gt;However, after a few days, I gradually acclimated to the city, and my initial reservations gave way to enjoyment. I was amazed by the cleanliness of the city. The roads were clean, and the people were disciplined. The architecture was magnificent. Dubai is a giant city inside a desert. The city is filled with skyscrapers, and the roads are wide. Moreover, the diversity of its population was striking, with people hailing from all corners of the globe, making Dubai a truly global metropolis.&lt;/p&gt;
&lt;p&gt;During our stay in Dubai, we rented out an apartment near where Khusi lives, for our accommodation. Each morning, as Khusi headed to her office, I would set up my daily standup calls and tackle the day’s tasks and responsibilities. We both would try to finish off our work by pre-evening and would hop on the bus and travel towards the metro to explore the city.&lt;/p&gt;
&lt;div class=&quot;dubai-group&quot;&gt;
&lt;figure class=&quot;dubai&quot;&gt;
&lt;img alt=&quot;room1&quot; src=&quot;https://anubhavp.dev/assets/img/fall23/room-1.jpeg&quot; class=&quot;h-100 w-100 &quot; loading=&quot;lazy&quot;&gt;
&lt;figcaption&gt;
Room -1
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;dubai&quot;&gt;
&lt;img alt=&quot;apartment&quot; src=&quot;https://anubhavp.dev/assets/img/fall23/room-2.jpeg&quot; class=&quot;h-100 w-100&quot; loading=&quot;lazy&quot;&gt;
&lt;figcaption&gt;
Apartment
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;p&gt;Khusi and I visited the Mall of Emirates. We roamed around the place, realizing that we were too poor to be looking at any of the retail outlets. We explored various shops, eateries and fancy dessert shops. I bought her a cap and a pillow. We got groceries for the week.&lt;/p&gt;
&lt;p&gt;She also introduced me to the places nearby. I decided to get a haircut done and made friends with the barber who belonged from Kerala. He told me about his life in Dubai and how he was planning to go back to Kerala. I told him about my life in Bangalore. We chatted about regional languages. He was a movie buff and asked if I had watched &lt;em&gt;Leo&lt;/em&gt; yet. Leo stars &lt;em&gt;Vijay&lt;/em&gt;, his favourite actor, after which I promised I would watch it. I haven’t watched it yet.&lt;/p&gt;
&lt;p&gt;The following day, our adventure led us to the Dubai Mall, along with a visit to the Burj Khalifa. I was asked to get an Apple watch by a junior colleague. I visited the Apple Store and urged Khusi to get me something but she refused. After a ton of shopping, we left and roamed around in the streets, exploring Dubai until late at night. I realized that Dubai is a city that never sleeps, and somehow most of the cab drivers here are either from India or Pakistan. The streets were bustling with people, and the city was alive with activity. We had dinner at a restaurant and then went back to our apartment.&lt;/p&gt;
&lt;figure class=&quot;dubai&quot;&gt;
&lt;img alt=&quot;burjkhalifa&quot; src=&quot;https://anubhavp.dev/assets/img/fall23/burj-khalifa.jpeg&quot; class=&quot;h-75 w-75&quot; loading=&quot;lazy&quot;&gt;
&lt;figcaption&gt;
&lt;a href=&quot;https://www.instagram.com/p/CytDfh0PFAw/?utm_source=ig_web_copy_link&amp;amp;igshid=MzRlODBiNWFlZA==&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Burj Khalifa&lt;/a&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Over the next few days, we explored Bur Dubai with our friends, often also known as the “Little India” in Dubai, known for its extensive collection of electronic shops. We also visited a gold market, because gold is cheaper in Dubai than in India. We immediately brought out our inner Indian, put on a bright face, and prepared to bargain the hell out for the things that we wished to buy to death. I got &lt;em&gt;Marshall Kilburn II&lt;/em&gt;: an amazing speaker. The five of us went ahead and had dinner beside a lake, where we spoke about our college days and then explored a chocolate shop to get souvenirs for our friends in India.&lt;/p&gt;
&lt;p&gt;After six days of extensive exploration, we decided to have a breather on a Saturday morning and went swimming in the apartment’s swimming pool with our friends. That evening, we set out to visit the Palm Jumeirah, an opulent and magnificent hotel in Dubai known for its attractive theme parks and immersive experiences. We had dinner there and witnessed a live band perform. We then went ahead to explore an Indian Pub, &lt;em&gt;Havelli&lt;/em&gt;. It was loud and typical. Havelli reminded me of home, where we had our dinner. Khusi danced and made friends with strangers. Our card bills soared high, and we decided to head back to our apartment.&lt;/p&gt;
&lt;p&gt;My scheduled departure back to India was set for Sunday, the 22nd. On that morning, we made our way to Kite Beach. I was in awe at how clean the beaches were. Having lived my life in Bhubaneswar, close to Puri, an iconic beach in India, I couldn’t believe how amazing this place was as compared to Puri, where tourists have made it a trash can of all sorts. We had breakfast at a cafe and then went ahead and explored the beach. The beach was filled with people from all over the world.&lt;/p&gt;
&lt;figure class=&quot;dubai&quot;&gt;
&lt;img alt=&quot;beach&quot; src=&quot;https://anubhavp.dev/assets/img/fall23/beach-2.jpeg&quot; class=&quot;h-75 w-100&quot; loading=&quot;lazy&quot;&gt;
&lt;figcaption&gt;
&lt;a href=&quot;https://www.instagram.com/p/CytDNnKvQfr/?utm_source=ig_web_copy_link&amp;amp;igshid=MzRlODBiNWFlZA==&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;
Kite Beach
&lt;/a&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Before bidding adieu to this captivating city, we indulged in ice cream and mocktails and chatted a lot about how things were going on in our lives. We roamed on the beach, scouting for hats and sunglasses and bought &lt;em&gt;Oud&lt;/em&gt; perfumes. While our feet sank into the soft sand, we delved into discussions about life in different countries and argued about which was better. We knew in our hearts that all we wanted was to reside in the same place. With fond memories in our hearts, perhaps some flaky promises and a heavy heart, we made our way to the airport embarking on my return journey to India.&lt;/p&gt;

            &lt;hr&gt;
            &lt;div class=&quot;footer&quot;&gt;
              &lt;i&gt;Feedback, Suggestions, Comments - &lt;/i&gt;
              &lt;div class=&quot;giscus-div&quot; id=&quot;comments&quot;&gt;
                &lt;script src=&quot;https://giscus.app/client.js&quot; data-repo=&quot;anubhavpgit/anubhavpgit.github.io&quot; data-repo-id=&quot;MDEwOlJlcG9zaXRvcnk0MDQ1ODEzMjc=&quot; data-category-id=&quot;DIC_kwDOGB1rz84Cer0j&quot; data-mapping=&quot;title&quot; data-strict=&quot;0&quot; data-reactions-enabled=&quot;1&quot; data-emit-metadata=&quot;0&quot; data-input-position=&quot;bottom&quot; data-theme=&quot;noborder_light&quot; data-lang=&quot;en&quot; data-loading=&quot;lazy&quot; crossorigin=&quot;anonymous&quot; async=&quot;&quot;&gt;&lt;/script&gt;
              &lt;/div&gt;
              Feel free to
              &lt;a id=&quot;mailtoLink&quot; href=&quot;mailto:anubhavp@duck.com?subject=Here&apos;s%20a%20suggestion/feedback!&quot;&gt;send
                me an email&lt;/a&gt;.
            &lt;/div&gt;
          &lt;/div&gt;
        </content:encoded>
            <subtitle>Two most glorious weeks of my life, unbothered by the world, one in the mountains, chasing the clouds, looking for Nirvana, and the other in the desert, chasing the sun, looking at greater heights.</subtitle>
        </item>
        <item>
            <title><![CDATA[Ferry - A C compiler for RISC-V]]></title>
            <description><![CDATA[The one who compiles C lang to machine code.]]></description>
            <link>https://anubhavp.dev/blog/ferryman.html</link>
            <guid isPermaLink="true">https://anubhavp.dev/blog/ferryman.html</guid>
            <dc:creator><![CDATA[Anubhab Patnaik]]></dc:creator>
            <pubDate>Tue, 25 Mar 2025 00:00:00 GMT</pubDate>
            <content:encoded>
          &lt;div class=&quot;content custom&quot;&gt;
            &lt;div class=&quot;search-container&quot;&gt;&lt;/div&gt;
            &lt;script type=&quot;module&quot; src=&quot;/assets/js/yatch/main.js&quot;&gt;&lt;/script&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;/assets/css/yatch/style.css&quot;&gt;
&lt;p&gt;&lt;em&gt;The ferryman is a figure in various mythologies responsible for carrying souls across the river that divides the world of the living from the world of the dead.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;JK. This post is the second in a series of posts that explore the world of compilers, interpreters, CPUs and low-level systems. The &lt;a href=&quot;/blog/hacktoberfest.html&quot;&gt;previous post&lt;/a&gt; describes how the CPU works; and how CPUs process and execute instructions. This post explains how the code you write in a high-level language is transformed into machine code that the CPU can understand and execute.&lt;/p&gt;
&lt;h3 id=&quot;table-of-contents&quot; tabindex=&quot;-1&quot;&gt;Table of Contents&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#compiling-high-level-languages&quot;&gt;Recap&lt;/a&gt;: A brief overview of how high-level languages are compiled into machine code.
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#machine-code&quot;&gt;Machine Code&lt;/a&gt;: Compiled code that the CPU can execute.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#computer-architecture&quot;&gt;Computer Architecture&lt;/a&gt;: Understanding the components of a computer system. Why are compilers CPU-specific, while interpreters are not?&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#ferry&quot;&gt;Ferry&lt;/a&gt;: A simple C compiler that compiles to RISC-V assembly.
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#walkthrough&quot;&gt;Walkthrough&lt;/a&gt;: Compiling Ferry
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#the-subset-of-c-supported&quot;&gt;The Subset of C supported&lt;/a&gt;: The features of C that Ferry supports.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#core&quot;&gt;Core&lt;/a&gt;: Compiling a simple C program.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#lexical-analysis&quot;&gt;Lexical Analysis&lt;/a&gt;: Converting the input code into tokens.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#syntax-analysis&quot;&gt;Syntax Analysis&lt;/a&gt;: Checking the syntax of the input code.
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#ast&quot;&gt;AST&lt;/a&gt;: The abstract syntax tree representation of the input code.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#semantic-analysis&quot;&gt;Semantic Analysis&lt;/a&gt;: Checking the semantic correctness of the input code.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#intermediate-code-generation&quot;&gt;Intermediate Code Generation&lt;/a&gt;: Generating an intermediate representation of the input code.
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#optimization&quot;&gt;Optimization&lt;/a&gt;: Optimizing the intermediate code for performance.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#code-generation&quot;&gt;Code Generation&lt;/a&gt;: Intermediate code to assembly code.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#assembly-and-linking&quot;&gt;Assembly and Linking&lt;/a&gt;: Using an external assembler to convert assembly code into machine code.
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#instruction-decoder&quot;&gt;Instruction decoder&lt;/a&gt;: A tool to decode RISC-V instructions and convert them to assembly code.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#yatch&quot;&gt;Yatch&lt;/a&gt;: A simple machine code interpreter for RISC-V.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#future-work&quot;&gt;Future Work&lt;/a&gt;: Next?&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;This next section is a quick recap taken from the &lt;a href=&quot;/blog/hacktoberfest.html&quot;&gt;previous post-Docking Compilers&lt;/a&gt;. If you are already familiar with how the CPU works, feel free to skip &lt;a href=&quot;#ferry&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h1 id=&quot;compiling-high-level-languages&quot; tabindex=&quot;-1&quot;&gt;Compiling High-Level Languages&lt;/h1&gt;
&lt;p&gt;Compilers and interpreters are tools that convert high-level programming languages into machine code instructions that the CPU can execute. Compilers translate the entire program into machine code before execution, while interpreters translate and execute the program line by line.&lt;/p&gt;
&lt;p&gt;For ex.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;x = &lt;span class=&quot;hljs-number&quot;&gt;5&lt;/span&gt;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Can be compiled into assembly code like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-assembly&quot;&gt;li x1, 5 // load immediate 5 into register x1
sw x1, 0(x0) // store word 0 at address x0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This assembly code is then translated into machine code, which is a binary representation of the instructions that the CPU can execute. The CPU executes these instructions in a sequence, and the program runs.&lt;/p&gt;
&lt;p&gt;While interpreters translate and execute the program line by line. The interpreter:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;reads the source code line by line,&lt;/li&gt;
&lt;li&gt;translates it into machine code (or bytecode in HLLs),&lt;/li&gt;
&lt;li&gt;translates bytecode into machine code and runs it in a virtual machine.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This allows dynamic typing, interactive debugging, and easier integration with other languages. However, interpreters are generally slower than compilers because they don’t optimize the entire program before execution.&lt;/p&gt;
&lt;h2 id=&quot;machine-code&quot; tabindex=&quot;-1&quot;&gt;Machine Code&lt;/h2&gt;
&lt;p&gt;Binary code is run as instructions on the CPU. The CPU executes these instructions in a sequence, and the program runs. Each CPU has its own set of instructions it can execute, known as the instruction set architecture (ISA). The ISA defines the instructions the CPU can execute, the registers it uses, and the memory model it follows. For example, an instruction might look like &lt;code&gt;00000000000000000000000010000011&lt;/code&gt;, which translates to &lt;code&gt;lb x1, 0(x0)&lt;/code&gt; in RISC-V assembly. This instruction, specific to the RISC-V ISA, loads a byte from memory into register &lt;code&gt;x1&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&quot;computer-architecture&quot; tabindex=&quot;-1&quot;&gt;Computer Architecture&lt;/h1&gt;
&lt;p&gt;Computer architecture is the design of computer systems, including the CPU, memory, and I/O devices. The CPU executes machine code instructions, which are specific to the CPU architecture. CPU architectures like x86, ARM, and RISC-V have different instruction sets and memory models. Each instruction set has its own assembly language and machine code format.&lt;/p&gt;
&lt;p&gt;Here’s why it is important to understand computer architecture:
Compilers generate machine code &lt;strong&gt;specific&lt;/strong&gt; to the target CPU architecture. The machine code for x86 is different from ARM or RISC-V. Interpreters, on the other hand, are CPU-independent. They translate high-level code into bytecode or an intermediate representation that can be executed on any platform.&lt;/p&gt;
&lt;hr&gt;
&lt;h1 id=&quot;ferry&quot; tabindex=&quot;-1&quot;&gt;Ferry&lt;/h1&gt;
&lt;p&gt;Ferry is a simple C compiler written in Rust that compiles to RISC-V assembly. It is not a complete implementation of the C language, but a good starting point for understanding how compilers work.&lt;/p&gt;
&lt;p&gt;I would suggest getting a basic understanding of how Rust works, and how to set up a Rust project before diving further. Just the basics. Find the &lt;a href=&quot;https://doc.rust-lang.org/book/&quot;&gt;Rust Book&lt;/a&gt; here.&lt;/p&gt;
&lt;h2 id=&quot;walkthrough&quot; tabindex=&quot;-1&quot;&gt;Walkthrough&lt;/h2&gt;
&lt;p&gt;Compiling Ferry is a pretty straightforward:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cargo build --release
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and use&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;./target/release/ferry &amp;lt;input_file.c&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;to run the compiler.&lt;/p&gt;
&lt;p&gt;An assembly file with &apos;&lt;code&gt;&amp;lt;input_file&amp;gt;.s&lt;/code&gt; will be generated in the same directory as the input file.&lt;/p&gt;
&lt;p&gt;The assembly code can be assembled into machine code using an external assembler like &lt;code&gt;riscv64-unknown-elf-gcc&lt;/code&gt;. Or, feel free to use an online assembler like &lt;a href=&quot;https://riscvasm.lucasteske.dev/&quot;&gt;RISC-V Online Assembler&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;or&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cargo run --release --bin runner -- &amp;lt;input_file.s&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;to run the code in Mac OS (Apple Silicon - arm64). This will assemble the code and run it using &lt;code&gt;qemu-riscv64&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;the-subset-of-c-supported&quot; tabindex=&quot;-1&quot;&gt;The Subset of C supported&lt;/h3&gt;
&lt;p&gt;Before moving forward, Ferry only supports a subset of C. The following features are supported:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Basic arithmetic operations (+, -, *, /, %)&lt;/li&gt;
&lt;li&gt;Variable declarations and assignment&lt;/li&gt;
&lt;li&gt;Basic types (int, char, float, double)&lt;/li&gt;
&lt;li&gt;Control flow statements (if/else, while loops)&lt;/li&gt;
&lt;li&gt;Function declarations and calls&lt;/li&gt;
&lt;li&gt;Arrays (fixed-size only initially)&lt;/li&gt;
&lt;li&gt;Basic I/O functions (simplified printf-like functionality)&lt;/li&gt;
&lt;li&gt;Comments (just for readability, your tokenizer already handles this)&lt;/li&gt;
&lt;li&gt;Pointers (basic pointer operations)&lt;/li&gt;
&lt;li&gt;Typecasting (implicit and explicit)&lt;/li&gt;
&lt;li&gt;Structs (without unions initially)&lt;/li&gt;
&lt;li&gt;String manipulation (basic operations)&lt;/li&gt;
&lt;li&gt;Basic preprocessor (#include for essential libraries)&lt;/li&gt;
&lt;li&gt;For loops&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;core&quot; tabindex=&quot;-1&quot;&gt;Core&lt;/h2&gt;
&lt;p&gt;Building a compiler is a complicated task. Ferry takes in a program written in C and generates assembly code for the RISC-V using the following steps:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Source Code --&amp;gt; Parser --&amp;gt; AST --&amp;gt; IR Generator --&amp;gt; IR Optimizer --&amp;gt;
Assembly Generator (&lt;strong&gt;.s&lt;/strong&gt;) --&amp;gt; Assembler (&lt;strong&gt;.o&lt;/strong&gt;) --&amp;gt; Linker (&lt;strong&gt;executable&lt;/strong&gt;)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Lexical Analysis&lt;/strong&gt;: The first step in the compilation process is to break the source code into tokens. This is done using a lexer, which reads the source code and generates a stream of tokens. Each token represents a meaningful unit of the source code, such as a keyword, identifier, or operator.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Syntax Analysis&lt;/strong&gt;: The second step is to parse the tokens generated by the lexer and build an abstract syntax tree (AST). The AST is a tree representation of the source code, where each node represents a construct in the source code, such as a variable declaration or function call.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Semantic Analysis&lt;/strong&gt;: The third step is to check the AST for semantic correctness. This includes checking for type errors, variable declarations, and function calls. The semantic analyzer verifies that the types of variables and expressions are correct and that functions are called with the correct number and types of arguments.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Intermediate Code Generation&lt;/strong&gt;: The fourth step is to generate intermediate code from the AST. The intermediate code is a low-level representation of the source code that is easier to optimize and translate into machine code. The intermediate code is usually platform-independent, meaning it can be executed on different architectures.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Code Generation&lt;/strong&gt;: The final step is to generate machine code from the intermediate code. The machine code is a binary representation of the instructions that the CPU can execute. The code generator translates the intermediate code into machine code specific to the target architecture.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Assume we have a simple C program:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;hljs-type&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;()&lt;/span&gt; {
  &lt;span class=&quot;hljs-built_in&quot;&gt;printf&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&quot;Hello, World!\n&quot;&lt;/span&gt;);
  &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following code is the &lt;a href=&quot;https://github.com/anubhavpgit/ferry/blob/main/src/main.rs#L64&quot;&gt;exact implementation&lt;/a&gt; of the compiler with abstracted implementations of the steps.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-rs&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;compile&lt;/span&gt;(file: &lt;span class=&quot;hljs-type&quot;&gt;String&lt;/span&gt;) &lt;span class=&quot;hljs-punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;Result&lt;/span&gt;&amp;lt;&lt;span class=&quot;hljs-type&quot;&gt;bool&lt;/span&gt;, &lt;span class=&quot;hljs-type&quot;&gt;String&lt;/span&gt;&amp;gt; {
 &lt;span class=&quot;hljs-comment&quot;&gt;// Parse the source code&lt;/span&gt;
    &lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;mut &lt;/span&gt;&lt;span class=&quot;hljs-variable&quot;&gt;ast&lt;/span&gt; = &lt;span class=&quot;hljs-title function_ invoke__&quot;&gt;parse_source&lt;/span&gt;(&amp;amp;file)?; &lt;span class=&quot;hljs-comment&quot;&gt;// Parse the source code into an AST&lt;/span&gt;
 &lt;span class=&quot;hljs-comment&quot;&gt;// Perform semantic analysis&lt;/span&gt;
    ast = semantic::&lt;span class=&quot;hljs-title function_ invoke__&quot;&gt;analyze_semantics&lt;/span&gt;(ast)?; &lt;span class=&quot;hljs-comment&quot;&gt;// Perform semantic analysis on the AST&lt;/span&gt;
 &lt;span class=&quot;hljs-comment&quot;&gt;// Generate code from the AST&lt;/span&gt;
    ir::&lt;span class=&quot;hljs-title function_ invoke__&quot;&gt;generate_ir&lt;/span&gt;(&amp;amp;ast)?;
 &lt;span class=&quot;hljs-comment&quot;&gt;// Assembly generation&lt;/span&gt;
    &lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;assembly&lt;/span&gt; = codegen::&lt;span class=&quot;hljs-title function_ invoke__&quot;&gt;generate_assembly&lt;/span&gt;(&amp;amp;ir)?;
    &lt;span class=&quot;hljs-title function_ invoke__&quot;&gt;Ok&lt;/span&gt;(&lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;) &lt;span class=&quot;hljs-comment&quot;&gt;// Return true to indicate successful compilation&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The assembly code is platform-dependent, meaning that the same high-level code can be compiled into different assembly codes for different architectures. The assembly code is then assembled into machine code, which is specific to the target CPU architecture. Jump to the &lt;a href=&quot;#assembly-and-linking&quot;&gt;Assembly and Linking&lt;/a&gt; section to see how the assembly code can be converted into machine code using an external assembler.&lt;/p&gt;
&lt;h2 id=&quot;lexical-analysis&quot; tabindex=&quot;-1&quot;&gt;Lexical Analysis&lt;/h2&gt;
&lt;p&gt;The compiler reads the source code and breaks it down into tokens. Tokens are the smallest units of meaning in the code, such as keywords, identifiers, literals, and operators.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-rs&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;parse_source&lt;/span&gt;(source: &amp;amp;&lt;span class=&quot;hljs-type&quot;&gt;str&lt;/span&gt;) &lt;span class=&quot;hljs-punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;Result&lt;/span&gt;&amp;lt;(), &lt;span class=&quot;hljs-type&quot;&gt;String&lt;/span&gt;&amp;gt; {
    &lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;tokens&lt;/span&gt; = &lt;span class=&quot;hljs-title function_ invoke__&quot;&gt;tokenize&lt;/span&gt;(source)?;
    &lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;mut &lt;/span&gt;&lt;span class=&quot;hljs-variable&quot;&gt;_ast&lt;/span&gt; = &lt;span class=&quot;hljs-title function_ invoke__&quot;&gt;build_ast&lt;/span&gt;(&amp;amp;tokens)?;
    &lt;span class=&quot;hljs-title function_ invoke__&quot;&gt;Ok&lt;/span&gt;(())
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For our example, the tokens generated from the source code would look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;Token Stream:
PreprocessorDirective(&lt;span class=&quot;hljs-string&quot;&gt;&quot;#include &amp;lt;stdio.h&amp;gt;&quot;&lt;/span&gt;) --&amp;gt; header file  
Type(Int) --&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;type&lt;/span&gt; of variable  
Identifier(&lt;span class=&quot;hljs-string&quot;&gt;&quot;main&quot;&lt;/span&gt;) --&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt; name  
LeftParen --&amp;gt; opening parenthesis  
RightParen --&amp;gt; closing parenthesis  
LeftBrace --&amp;gt; opening brace  
Identifier(&lt;span class=&quot;hljs-string&quot;&gt;&quot;printf&quot;&lt;/span&gt;) --&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt; name  
LeftParen --&amp;gt; opening parenthesis  
String(&lt;span class=&quot;hljs-string&quot;&gt;&quot;Hello, World!\n&quot;&lt;/span&gt;) --&amp;gt; string literal  
RightParen --&amp;gt; closing parenthesis  
Semicolon --&amp;gt; semicolon  
Keyword(Return) --&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;return&lt;/span&gt; statement  
Number(0.0) --&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;return&lt;/span&gt; value  
Semicolon --&amp;gt; semicolon  
RightBrace --&amp;gt; closing brace  
EOF --&amp;gt; end of file  
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;syntax-analysis&quot; tabindex=&quot;-1&quot;&gt;Syntax Analysis&lt;/h2&gt;
&lt;p&gt;After tokenization, where the source code is broken into tokens, the syntax analyzer (parser) processes these tokens according to the language grammar rules. As it recognizes valid syntactic structures, it constructs the AST. The AST is the output or result of the syntax analysis process.&lt;/p&gt;
&lt;p&gt;Each time the parser recognizes a valid language construct (like an expression, statement, or declaration), it creates the corresponding AST nodes.&lt;/p&gt;
&lt;p&gt;The parser uses a recursive descent parsing approach, where each function corresponds to a grammar rule. For example, the &lt;code&gt;parse_expression&lt;/code&gt; function handles expressions, while the &lt;code&gt;parse_statement&lt;/code&gt; function handles statements. The root level function, &lt;code&gt;parse_program&lt;/code&gt;, is responsible for parsing the entire program, which then calls the other parsing functions as needed.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;parse_program&lt;/code&gt; function might look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-rs&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; &amp;amp;&lt;span class=&quot;hljs-keyword&quot;&gt;self&lt;/span&gt;.&lt;span class=&quot;hljs-title function_ invoke__&quot;&gt;peek&lt;/span&gt;().token_type { &lt;span class=&quot;hljs-comment&quot;&gt;// Check the type of the next token&lt;/span&gt;
  TokenType::&lt;span class=&quot;hljs-title function_ invoke__&quot;&gt;Type&lt;/span&gt;(_) =&amp;gt; { &lt;span class=&quot;hljs-comment&quot;&gt;// If it&apos;s a type, parse a declaration&lt;/span&gt;
    &lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;declaration&lt;/span&gt; = &lt;span class=&quot;hljs-keyword&quot;&gt;self&lt;/span&gt;.&lt;span class=&quot;hljs-title function_ invoke__&quot;&gt;parse_declaration&lt;/span&gt;()?;
    program.&lt;span class=&quot;hljs-title function_ invoke__&quot;&gt;add_child&lt;/span&gt;(declaration); &lt;span class=&quot;hljs-comment&quot;&gt;// Add the declaration to the program&lt;/span&gt;
 } 
  TokenType::&lt;span class=&quot;hljs-title function_ invoke__&quot;&gt;PreprocessorDirective&lt;/span&gt;(_) =&amp;gt; { &lt;span class=&quot;hljs-comment&quot;&gt;// Else if it&apos;s a preprocessor directive, parse it&lt;/span&gt;
    &lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;directive&lt;/span&gt; = &lt;span class=&quot;hljs-keyword&quot;&gt;self&lt;/span&gt;.&lt;span class=&quot;hljs-title function_ invoke__&quot;&gt;parse_preprocessor&lt;/span&gt;()?;
    program.&lt;span class=&quot;hljs-title function_ invoke__&quot;&gt;add_child&lt;/span&gt;(directive); &lt;span class=&quot;hljs-comment&quot;&gt;// And the directive to the program&lt;/span&gt;
 }
  _ =&amp;gt; {
    &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;hljs-title function_ invoke__&quot;&gt;Err&lt;/span&gt;(&lt;span class=&quot;hljs-built_in&quot;&gt;format!&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&quot;Expected declaration, found {:?}.&quot;&lt;/span&gt;, &lt;span class=&quot;hljs-comment&quot;&gt;// Error if neither&lt;/span&gt;
    &lt;span class=&quot;hljs-keyword&quot;&gt;self&lt;/span&gt;.&lt;span class=&quot;hljs-title function_ invoke__&quot;&gt;peek&lt;/span&gt;().token_type));
 }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;declaration_parser&lt;/code&gt; function would then handle the parsing of variable declarations, function declarations, and other constructs. It would create the appropriate AST nodes for each construct and add them to the program node.&lt;/p&gt;
&lt;h3 id=&quot;ast&quot; tabindex=&quot;-1&quot;&gt;AST&lt;/h3&gt;
&lt;p&gt;The Abstract Syntax Tree (AST) is a tree representation of the source code. Each node in the tree represents a construct in the source code, such as a variable declaration, function call, or control flow statement. The AST is used to represent the structure of the program and is an intermediate representation that can be further processed by the compiler.&lt;/p&gt;
&lt;p&gt;A node in the AST might look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-rs&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;hljs-title class_&quot;&gt;ASTNode&lt;/span&gt; {
    &lt;span class=&quot;hljs-keyword&quot;&gt;pub&lt;/span&gt; node_type: ASTNodeType,
    &lt;span class=&quot;hljs-keyword&quot;&gt;pub&lt;/span&gt; children: &lt;span class=&quot;hljs-type&quot;&gt;Vec&lt;/span&gt;&amp;lt;ASTNode&amp;gt;,
    &lt;span class=&quot;hljs-keyword&quot;&gt;pub&lt;/span&gt; value: &lt;span class=&quot;hljs-type&quot;&gt;Option&lt;/span&gt;&amp;lt;&lt;span class=&quot;hljs-type&quot;&gt;String&lt;/span&gt;&amp;gt;,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The parser generates the AST by creating nodes for each construct in the source code. For example, a function call might be represented as a node with the type &lt;code&gt;FunctionCall&lt;/code&gt;, and its children would be the arguments passed to the function and the function name.&lt;/p&gt;
&lt;p&gt;In our example, the AST for the entire program would look something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;AST Structure:
└── Root --&amp;gt; root node
├── PreprocessorDirective: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;#include &amp;lt;stdio.h&amp;gt;&quot;&lt;/span&gt;) --&amp;gt; header file
└── FunctionDeclaration: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;main&quot;&lt;/span&gt;) --&amp;gt; main &lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt; declaration
    ├── Type: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;Int&quot;&lt;/span&gt;) --&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;type&lt;/span&gt; of &lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;
    └── BlockStatement: None --&amp;gt; block of code starts
        ├── ExpressionStatement: None --&amp;gt; this node doesn&lt;span class=&quot;hljs-string&quot;&gt;&apos;t carry any specific value itself - it&apos;&lt;/span&gt;s just a container that holds the expression
        │   └── CallExpression: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;printf&quot;&lt;/span&gt;) --&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt; call (from stdio.h)
        │       ├── Variable: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;printf&quot;&lt;/span&gt;)  --&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt; name. During the semantic analysis phase after parsing, the compiler would verify that this identifier actually refers to a callable &lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;.
        │       └── Literal: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;\&quot;Hello, World!\n\&quot;&quot;&lt;/span&gt;) --&amp;gt; string literal
        └── ReturnStatement: None --&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;return&lt;/span&gt; statement &lt;span class=&quot;hljs-keyword&quot;&gt;for&lt;/span&gt; the &lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;
            └── Literal: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;0&quot;&lt;/span&gt;) --&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;return&lt;/span&gt; value
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;semantic-analysis&quot; tabindex=&quot;-1&quot;&gt;Semantic Analysis&lt;/h3&gt;
&lt;p&gt;The semantic analyzer checks the AST for semantic correctness. It verifies that the types of variables and expressions are correct, that functions are called with the correct number and types of arguments, and that variables are declared before they are used. The semantic analyzer also performs type checking and resolves any ambiguities in the code.&lt;/p&gt;
&lt;p&gt;It checks for preprocessor directives, variable declarations, function declarations, and function calls, and removes any unnecessary nodes from the AST like the &lt;code&gt;#include&lt;/code&gt; directives.&lt;/p&gt;
&lt;p&gt;For example, assuming there is a &lt;code&gt;#include&amp;lt;matlab.h&amp;gt;&lt;/code&gt; directive in the code, and the code looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;matlab.h&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;hljs-type&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;()&lt;/span&gt; {
 Matrix m = createMatrix(&lt;span class=&quot;hljs-number&quot;&gt;3&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot;&gt;3&lt;/span&gt;); &lt;span class=&quot;hljs-comment&quot;&gt;// Function declared in matlab.h&lt;/span&gt;
    &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The semantic analyzer would check that the &lt;code&gt;createMatrix&lt;/code&gt; function is declared in the &lt;code&gt;matlab.h&lt;/code&gt; header file and that it is called with the correct number of arguments. It would also check that the &lt;code&gt;Matrix&lt;/code&gt; type is defined in the header file and that it is used correctly.&lt;/p&gt;
&lt;p&gt;After preprocessing, it might look like:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;hljs-class&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;struct&lt;/span&gt; {&lt;/span&gt;...} Matrix;
Matrix &lt;span class=&quot;hljs-title function_&quot;&gt;createMatrix&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;(&lt;span class=&quot;hljs-type&quot;&gt;int&lt;/span&gt; rows, &lt;span class=&quot;hljs-type&quot;&gt;int&lt;/span&gt; cols)&lt;/span&gt;;
&lt;span class=&quot;hljs-comment&quot;&gt;// ...many more declarations...&lt;/span&gt;
&lt;span class=&quot;hljs-type&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;()&lt;/span&gt; {
 Matrix m = createMatrix(&lt;span class=&quot;hljs-number&quot;&gt;3&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot;&gt;3&lt;/span&gt;);
    &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The linker would then resolve the references to the &lt;code&gt;createMatrix&lt;/code&gt; function and the &lt;code&gt;Matrix&lt;/code&gt; type, ensuring that they are defined in the correct header file.&lt;/p&gt;
&lt;p&gt;In our original example, the semantic analyzer would check that the &lt;code&gt;printf&lt;/code&gt; function is declared in the &lt;code&gt;stdio.h&lt;/code&gt; header file and that it is called with the correct number of arguments. If any semantic errors are found, the compiler reports them to the user.&lt;/p&gt;
&lt;p&gt;In the &lt;code&gt;printf(&quot;Hello, World!\n&quot;)&lt;/code&gt; statement, the semantic analyzer checks that the &lt;code&gt;printf&lt;/code&gt; function is called with a string argument. If the argument is not a string, it raises an error.&lt;/p&gt;
&lt;p&gt;Two specific functions handle this case:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-rs&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;check_types&lt;/span&gt;(node: &amp;amp;ASTNode, symbol_table: &amp;amp;SymbolTable) &lt;span class=&quot;hljs-punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;Result&lt;/span&gt;&amp;lt;Type, &lt;span class=&quot;hljs-type&quot;&gt;String&lt;/span&gt;&amp;gt; {
  ...
  &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; value.&lt;span class=&quot;hljs-title function_ invoke__&quot;&gt;starts_with&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&apos;&quot;&apos;&lt;/span&gt;) {
    &lt;span class=&quot;hljs-title function_ invoke__&quot;&gt;Ok&lt;/span&gt;(Type::&lt;span class=&quot;hljs-title function_ invoke__&quot;&gt;Pointer&lt;/span&gt;(&lt;span class=&quot;hljs-type&quot;&gt;Box&lt;/span&gt;::&lt;span class=&quot;hljs-title function_ invoke__&quot;&gt;new&lt;/span&gt;(Type::Char))) &lt;span class=&quot;hljs-comment&quot;&gt;// String literal&lt;/span&gt;
 } &lt;span class=&quot;hljs-keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; value == &lt;span class=&quot;hljs-string&quot;&gt;&quot;true&quot;&lt;/span&gt; || value == &lt;span class=&quot;hljs-string&quot;&gt;&quot;false&quot;&lt;/span&gt; {
    &lt;span class=&quot;hljs-title function_ invoke__&quot;&gt;Ok&lt;/span&gt;(Type::Bool)
 } &lt;span class=&quot;hljs-keyword&quot;&gt;else&lt;/span&gt; {
    ...
 }
  ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-rs&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;check_types&lt;/span&gt;(node: &amp;amp;ASTNode, symbol_table: &amp;amp;SymbolTable) &lt;span class=&quot;hljs-punctuation&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;Result&lt;/span&gt;&amp;lt;Type, &lt;span class=&quot;hljs-type&quot;&gt;String&lt;/span&gt;&amp;gt; {
  ...
  &lt;span class=&quot;hljs-keyword&quot;&gt;match&lt;/span&gt; (target_type, value_type) {
 &lt;span class=&quot;hljs-comment&quot;&gt;// Basic types&lt;/span&gt;
 (Type::Int, Type::Int) =&amp;gt; &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;,
 (Type::Float, Type::Int) =&amp;gt; &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;, &lt;span class=&quot;hljs-comment&quot;&gt;// Implicit conversion&lt;/span&gt;
    ...
 &lt;span class=&quot;hljs-comment&quot;&gt;// Pointers&lt;/span&gt;
        
 &lt;span class=&quot;hljs-comment&quot;&gt;// For box types, recursively check if the inner types are compatible&lt;/span&gt;
 (Type::&lt;span class=&quot;hljs-title function_ invoke__&quot;&gt;Pointer&lt;/span&gt;(target_inner), Type::&lt;span class=&quot;hljs-title function_ invoke__&quot;&gt;Pointer&lt;/span&gt;(value_inner)) =&amp;gt; {
      &lt;span class=&quot;hljs-title function_ invoke__&quot;&gt;is_type_compatible&lt;/span&gt;(target_inner, value_inner)
 }

 &lt;span class=&quot;hljs-comment&quot;&gt;// Functions are compatible if their return types and parameter lists match&lt;/span&gt;
    &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; !&lt;span class=&quot;hljs-title function_ invoke__&quot;&gt;is_type_compatible&lt;/span&gt;(target_return, value_return) {
      &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/span&gt;;
 }
 }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This step raises compile-time errors if the AST is not semantically correct.&lt;/p&gt;
&lt;h2 id=&quot;intermediate-code-generation&quot; tabindex=&quot;-1&quot;&gt;Intermediate Code Generation&lt;/h2&gt;
&lt;p&gt;The intermediate code generator converts the AST into an intermediate representation (IR). The IR is a low-level, usually platform-independent representation of the code that is easier to optimize and translate into machine code.&lt;/p&gt;
&lt;p&gt;AST represents the syntactic structure of the code (closely mirrors source code) while IR represents the semantic operations (closer to what the machine will do). IR is specifically designed for optimizations that are difficult at the AST level. Common optimizations like constant folding, dead code elimination, and loop transformations work better on IR.&lt;/p&gt;
&lt;p&gt;IR representations are usually standardized and can be used across different compilers. LLVM IR is a widely used intermediate representation that is used by the LLVM compiler infrastructure. It is a low-level, typed assembly-like language that is designed to be easy to optimize and generate machine code from. It is often represented as a three-address code, where each instruction has at most three operands. An LLVM IR representation of the code might look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-llvm&quot;&gt;&lt;span class=&quot;hljs-title&quot;&gt;@.str&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;unnamed_addr&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;constant&lt;/span&gt; [&lt;span class=&quot;hljs-number&quot;&gt;14&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;] &lt;span class=&quot;hljs-keyword&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;&quot;Hello, World!&lt;span class=&quot;hljs-char escape_&quot;&gt;\00&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;align&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;hljs-keyword&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;@main&lt;/span&gt;() {
&lt;span class=&quot;hljs-symbol&quot;&gt;entry:&lt;/span&gt;
 &lt;span class=&quot;hljs-variable&quot;&gt;%call&lt;/span&gt; &lt;span class=&quot;hljs-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;call&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; (&lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;*&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; ...) &lt;span class=&quot;hljs-title&quot;&gt;@printf&lt;/span&gt;(&lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;* &lt;span class=&quot;hljs-keyword&quot;&gt;getelementptr&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;inbounds&lt;/span&gt; ([&lt;span class=&quot;hljs-number&quot;&gt;14&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;]&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; [&lt;span class=&quot;hljs-number&quot;&gt;14&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i8&lt;/span&gt;]* &lt;span class=&quot;hljs-title&quot;&gt;@.str&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;))
 &lt;span class=&quot;hljs-keyword&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Compilers typically use multiple IR forms during compilation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;High-level IR&lt;/strong&gt;: A Tree representation of the source code, easier to analyze and optimize.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Low-level IR/ Linear/Three-address code IR&lt;/strong&gt;: Each instruction typically has one destination and up to two source operands. Closer to assembly language&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ferry uses a simple IR representation that is built for the purpose of this compiler. The IR is a tree representation of the code, where each node represents an operation or a value. I could have also used &lt;code&gt;LLVM IR&lt;/code&gt; as the intermediate representation, but the learning curve is steep, and I wanted to keep it simple. Doing so would actually have made the compiler more robust and powerful.&lt;/p&gt;
&lt;p&gt;The IR would look something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;IR Structure: 
└── Root --&amp;gt; the root node of the IR
└── Function: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;main&quot;&lt;/span&gt;) --&amp;gt; the main &lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;
    └── BasicBlock: None --&amp;gt; the entry block of the &lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt;
        ├── Call: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;printf&quot;&lt;/span&gt;) --&amp;gt; &lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt; call
        │   └── Constant: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;\&quot;Hello, World!\n\&quot;&quot;&lt;/span&gt;) --&amp;gt; string literal
        └── Return: None --&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;return&lt;/span&gt; statement
            └── Constant: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;0&quot;&lt;/span&gt;) --&amp;gt; &lt;span class=&quot;hljs-built_in&quot;&gt;return&lt;/span&gt; value
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Industry Practice:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Modern compilers like LLVM, GCC, and .NET all use sophisticated IR systems:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;LLVM IR is a portable, typed, assembly-like language&lt;/li&gt;
&lt;li&gt;GCC uses GIMPLE and RTL as intermediate representations&lt;/li&gt;
&lt;li&gt;JIT compilers typically use IR to enable fast compilation and optimization&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Rust Language also uses LLVM IR as its intermediate representation. The Rust compiler (rustc) generates LLVM IR from the Rust source code, optimizes it, and then generates machine code for the target architecture.&lt;/p&gt;
&lt;p&gt;GCC also uses a similar approach, generating an intermediate representation called GIMPLE, which is then optimized and translated into machine code.&lt;/p&gt;
&lt;p&gt;Interpreters like Python and JavaScript engines (like V8) also use intermediate representations. For example, the V8 engine uses an intermediate representation called Ignition bytecode, which is a low-level representation of the JavaScript code that can be executed by the V8 engine.&lt;/p&gt;
&lt;h3 id=&quot;optimization&quot; tabindex=&quot;-1&quot;&gt;Optimization&lt;/h3&gt;
&lt;p&gt;The generated IR is not always optimal. The optimization phase of the compiler improves the IR to make it more efficient. This can include removing dead code, inlining functions, and optimizing loops. The goal of optimization is to improve the performance of the generated code without changing its semantics.&lt;/p&gt;
&lt;p&gt;Ferry uses the following optimizations:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Constant Folding and Propagation&lt;/strong&gt;: Evaluates constant expressions at compile time and propagates constant values to reduce the number of calculations performed at runtime. For example, if a variable is assigned a constant value, that value can be propagated to other parts of the code.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dead Code Elimination&lt;/strong&gt;: Removes code that is never executed or has no effect on the program’s output. For example, if a variable is declared but never used, it can be removed from the IR.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Common Subexpression Elimination&lt;/strong&gt;: Identifies and eliminates redundant calculations. For example, if the same expression is calculated multiple times, it can be stored in a temporary variable and reused.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Loop Optimizations&lt;/strong&gt;: Improves the performance of loops by unrolling them, reducing the number of iterations, or optimizing the loop structure.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Ferry employs two types of optimizations:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Basic optimizations: Simple optimizations that doesn’t change the semantics of the code, like constant folding and dead code elimination.&lt;/li&gt;
&lt;li&gt;Advanced optimizations: More complex optimizations that require a deeper understanding of the code structure like loop unrolling and function inlining.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Say our &lt;code&gt;code&lt;/code&gt; looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;hljs-type&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;()&lt;/span&gt;{
  &lt;span class=&quot;hljs-type&quot;&gt;int&lt;/span&gt; i = &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt; + &lt;span class=&quot;hljs-number&quot;&gt;2&lt;/span&gt;;
  &lt;span class=&quot;hljs-keyword&quot;&gt;for&lt;/span&gt; (i = &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;; i &amp;lt; &lt;span class=&quot;hljs-number&quot;&gt;10&lt;/span&gt;; i++)
  {
    &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (i == &lt;span class=&quot;hljs-number&quot;&gt;5&lt;/span&gt;)
      &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The optimizer should:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Evaluate the expression &lt;code&gt;0 + 2&lt;/code&gt; at compile time and replace it with &lt;code&gt;2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Stop the loop when &lt;code&gt;i == 5&lt;/code&gt; to avoid unnecessary iterations.&lt;/li&gt;
&lt;li&gt;Remove the unnecessary assignment of &lt;code&gt;i&lt;/code&gt; to &lt;code&gt;0&lt;/code&gt; in the loop header.&lt;/li&gt;
&lt;li&gt;Add a jump instruction to the loop header to avoid unnecessary iterations.&lt;/li&gt;
&lt;li&gt;Optimize the loop to exit early when &lt;code&gt;i == 5&lt;/code&gt; by adding a return statement.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The IR could look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;IR Structure (Original):
└── Root
└── Function: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;main&quot;&lt;/span&gt;)
    └── BasicBlock: None
        ├── BasicBlock: None
        │   ├── Alloca: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;i&quot;&lt;/span&gt;)                           // Allocate space &lt;span class=&quot;hljs-keyword&quot;&gt;for&lt;/span&gt; variable &lt;span class=&quot;hljs-string&quot;&gt;&apos;i&apos;&lt;/span&gt;
        │   └── Store: None                                 // Store initial value to &lt;span class=&quot;hljs-string&quot;&gt;&apos;i&apos;&lt;/span&gt;
        │       ├── BinaryOp: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;+&quot;&lt;/span&gt;)                     // Calculate 0+2
        │       │   ├── Constant: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;0&quot;&lt;/span&gt;)                 // First operand
        │       │   └── Constant: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;2&quot;&lt;/span&gt;)                 // Second operand
        │       └── Variable: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;i&quot;&lt;/span&gt;)                     // Target variable
        └── BasicBlock: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;for&quot;&lt;/span&gt;)
            ├── Store: None                                 // Loop initialization: i = 0
            │   ├── Constant: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;0&quot;&lt;/span&gt;)                     // Value to store
            │   └── Variable: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;i&quot;&lt;/span&gt;)                     // Target variable
            ├── BasicBlock: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;for.header&quot;&lt;/span&gt;)              // Loop condition check
            │   └── BinaryOp: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;&amp;lt;&quot;&lt;/span&gt;)                     // Compare i &amp;lt; 10
            │       ├── Load: None                          // Load value of &lt;span class=&quot;hljs-string&quot;&gt;&apos;i&apos;&lt;/span&gt;
            │       │   └── Variable: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;i&quot;&lt;/span&gt;)             // Variable to load
            │       └── Constant: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;10&quot;&lt;/span&gt;)                // Upper bound
            └── Branch: None                                // Conditional branch
                ├── BinaryOp: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;&amp;lt;&quot;&lt;/span&gt;)                     // Same comparison duplicated
                │   ├── Load: None                          // Load value of &lt;span class=&quot;hljs-string&quot;&gt;&apos;i&apos;&lt;/span&gt; again
                │   │   └── Variable: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;i&quot;&lt;/span&gt;)
                │   └── Constant: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;10&quot;&lt;/span&gt;)
                └── BasicBlock: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;for.body&quot;&lt;/span&gt;)            // Loop body
                    ├── BasicBlock: None                    // If statement block
                    │   └── Branch: None                    // Conditional branch
                    │       ├── BinaryOp: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;==&quot;&lt;/span&gt;)        // Compare i == 5
                    │       │   ├── Load: None              // Load value of &lt;span class=&quot;hljs-string&quot;&gt;&apos;i&apos;&lt;/span&gt;
                    │       │   │   └── Variable: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;i&quot;&lt;/span&gt;)
                    │       │   └── Constant: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;5&quot;&lt;/span&gt;)     // Value to compare against
                    │       └── Return: None                // Early &lt;span class=&quot;hljs-built_in&quot;&gt;return&lt;/span&gt;
                    │           └── Constant: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;0&quot;&lt;/span&gt;)     // Return value
                    ├── BasicBlock: None                    // Loop increment block
                    │   ├── Load: None                      // Load value of &lt;span class=&quot;hljs-string&quot;&gt;&apos;i&apos;&lt;/span&gt;
                    │   │   └── Variable: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;i&quot;&lt;/span&gt;)
                    │   └── Store: None                     // Store i+1 back to i
                    │       ├── BinaryOp: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;+&quot;&lt;/span&gt;)         // Calculate i+1
                    │       │   ├── Load: None              // Load value of &lt;span class=&quot;hljs-string&quot;&gt;&apos;i&apos;&lt;/span&gt; again
                    │       │   │   └── Variable: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;i&quot;&lt;/span&gt;)
                    │       │   └── Constant: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;1&quot;&lt;/span&gt;)     // Increment by 1
                    │       └── Variable: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;i&quot;&lt;/span&gt;)         // Target variable
                    └── Jump: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;for.header&quot;&lt;/span&gt;)  // Unconditional jump to loop header
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The basic optimizer would then optimize the IR using the following optimizations:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;---------Starting Optimization---------
Optimization iteration 1
Folded binary op to constant: 2
Replaced load of i with constant None
Replaced load of i with constant None
Replaced load of i with constant None
Replaced load of i with constant None
Replaced load of i with constant None
CSE: Found duplicate expression: LOAD(VAR(i))
CSE: Found duplicate expression: LOAD(VAR(i))
Optimization iteration 2
Replaced load of i with constant None
Replaced load of i with constant None
Replaced load of i with constant None
CSE: Found duplicate expression: LOAD(VAR(i))
CSE: Found duplicate expression: LOAD(VAR(i))
Optimization iteration 3
Replaced load of i with constant None
Replaced load of i with constant None
Replaced load of i with constant None
CSE: Found duplicate expression: LOAD(VAR(i))
CSE: Found duplicate expression: LOAD(VAR(i))
Optimization iteration 4
Replaced load of i with constant None
Replaced load of i with constant None
Replaced load of i with constant None
CSE: Found duplicate expression: LOAD(VAR(i))
CSE: Found duplicate expression: LOAD(VAR(i))
Optimization iteration 5
Replaced load of i with constant None
Replaced load of i with constant None
Replaced load of i with constant None
CSE: Found duplicate expression: LOAD(VAR(i))
CSE: Found duplicate expression: LOAD(VAR(i))
Optimization complete after 5 iterations
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and this is what the optimization would look like:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;IR Structure:
└── Root
└── Function: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;main&quot;&lt;/span&gt;)
    └── BasicBlock: None
        ├── BasicBlock: None
        │   ├── Alloca: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;i&quot;&lt;/span&gt;)                          // Allocate space &lt;span class=&quot;hljs-keyword&quot;&gt;for&lt;/span&gt; variable &lt;span class=&quot;hljs-string&quot;&gt;&apos;i&apos;&lt;/span&gt;
        │   └── Store: None                                // Store initial value to &lt;span class=&quot;hljs-string&quot;&gt;&apos;i&apos;&lt;/span&gt;
        │       ├── Constant: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;2&quot;&lt;/span&gt;)                    // OPTIMIZATION: Constant folding of 0+2 to 2
        │       └── Variable: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;i&quot;&lt;/span&gt;)                    // Target variable
        └── BasicBlock: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;for&quot;&lt;/span&gt;)
            ├── Store: None                                // Loop initialization: i = 0
            │   ├── Constant: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;0&quot;&lt;/span&gt;)                    // Value to store
            │   └── Variable: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;i&quot;&lt;/span&gt;)                    // Target variable
            ├── BasicBlock: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;for.header&quot;&lt;/span&gt;)             // Loop condition check
            └── Branch: None                               // Conditional branch
                ├── BinaryOp: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;&amp;lt;&quot;&lt;/span&gt;)                    // OPTIMIZATION: CSE - eliminated duplicate comparison
                │   ├── Load: None                         // OPTIMIZATION: Single load of &lt;span class=&quot;hljs-string&quot;&gt;&apos;i&apos;&lt;/span&gt; (CSE applied)
                │   │   └── Variable: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;i&quot;&lt;/span&gt;)  
                │   └── Constant: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;10&quot;&lt;/span&gt;)
                └── BasicBlock: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;for.body&quot;&lt;/span&gt;)
                    ├── BasicBlock: None
                    │   └── Branch: None
                    │       ├── BinaryOp: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;==&quot;&lt;/span&gt;)       // Compare i == 5
                    │       │   ├── Load: None             // OPTIMIZATION: Single load of &lt;span class=&quot;hljs-string&quot;&gt;&apos;i&apos;&lt;/span&gt; (CSE applied)
                    │       │   │   └── Variable: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;i&quot;&lt;/span&gt;)
                    │       │   └── Constant: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;5&quot;&lt;/span&gt;)
                    │       └── Return: None               // Early &lt;span class=&quot;hljs-built_in&quot;&gt;return&lt;/span&gt;
                    │           └── Constant: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;0&quot;&lt;/span&gt;)
                    ├── BasicBlock: None
                    │   └── Store: None                    // OPTIMIZATION: Simplified increment
                    │       ├── BinaryOp: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;+&quot;&lt;/span&gt;)
                    │       │   ├── Load: None             // OPTIMIZATION: Single load of &lt;span class=&quot;hljs-string&quot;&gt;&apos;i&apos;&lt;/span&gt; (CSE applied)
                    │       │   │   └── Variable: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;i&quot;&lt;/span&gt;)
                    │       │   └── Constant: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;1&quot;&lt;/span&gt;)
                    │       └── Variable: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;i&quot;&lt;/span&gt;)
                    └── Jump: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;for.header&quot;&lt;/span&gt;)           // Loop back
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While it correctly preserved the program’s structure and performed some basic optimizations like constant folding &lt;code&gt;(0 + 2 → 2)&lt;/code&gt;, it hasn’t performed the more advanced control flow analysis that would recognize this optimization opportunity. The advanced optimizer would then optimize the IR using the following optimizations:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;---------Starting Advanced Optimization---------
Optimization iteration 1
Optimization iteration 2
Optimization complete after 2 iterations

----- Optimization Summary -----
Constants folded: 0
Dead code blocks removed: 2
Common expressions eliminated: 0
Loops optimized: 0
Functions optimized: 0
-------------------------------
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and this is what the optimization would look like:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;IR Structure (During Advanced Optimization):
└── Root
└── Function: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;main&quot;&lt;/span&gt;)
    └── BasicBlock: None
        ├── Alloca: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;i&quot;&lt;/span&gt;)                     // Allocate space &lt;span class=&quot;hljs-keyword&quot;&gt;for&lt;/span&gt; variable &lt;span class=&quot;hljs-string&quot;&gt;&apos;i&apos;&lt;/span&gt;
        ├── Store: None                           // OPTIMIZATION: Eliminated dead store (i=2 never used)
        │   ├── Constant: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;0&quot;&lt;/span&gt;)               // Store initial loop value directly
        │   └── Variable: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;i&quot;&lt;/span&gt;)               // Target variable
        ├── BasicBlock: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;loop_check&quot;&lt;/span&gt;)        // OPTIMIZATION: Simplified loop structure
        │   └── Branch: None                      // Conditional branch &lt;span class=&quot;hljs-keyword&quot;&gt;for&lt;/span&gt; both loop and early &lt;span class=&quot;hljs-built_in&quot;&gt;exit&lt;/span&gt;
        │       ├── BinaryOp: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;==&quot;&lt;/span&gt;)          // OPTIMIZATION: Combined conditions - check i==5 directly
        │       │   ├── Load: None                // Load value of &lt;span class=&quot;hljs-string&quot;&gt;&apos;i&apos;&lt;/span&gt;
        │       │   │   └── Variable: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;i&quot;&lt;/span&gt;)
        │       │   └── Constant: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;5&quot;&lt;/span&gt;)       // OPTIMIZATION: Early &lt;span class=&quot;hljs-built_in&quot;&gt;exit&lt;/span&gt; condition
        │       └── Return: None                  // Early &lt;span class=&quot;hljs-built_in&quot;&gt;return&lt;/span&gt; when i==5
        │           └── Constant: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;0&quot;&lt;/span&gt;)       // Return value
        ├── Store: None                           // Increment i
        │   ├── BinaryOp: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;+&quot;&lt;/span&gt;)               // Calculate i+1
        │   │   ├── Load: None                    // Load value of &lt;span class=&quot;hljs-string&quot;&gt;&apos;i&apos;&lt;/span&gt;
        │   │   │   └── Variable: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;i&quot;&lt;/span&gt;)
        │   │   └── Constant: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;1&quot;&lt;/span&gt;)           // Increment by 1
        │   └── Variable: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;i&quot;&lt;/span&gt;)               // Target variable
        └── Jump: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;loop_check&quot;&lt;/span&gt;)              // OPTIMIZATION: Direct jump to loop check
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and finally, the IR structure would look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;IR Structure:
└── Root
└── Function: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;main&quot;&lt;/span&gt;)
    └── BasicBlock: None
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and our original code in the final optimised version would look like this:&lt;/p&gt;
&lt;p&gt;This optimizer has aggressively removed the dead code blocks and optimized the loops and correctly identified that the code always returns &lt;code&gt;0&lt;/code&gt; and thus removed the entire loop! While our original code example in &lt;code&gt;IR&lt;/code&gt; would look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;IR Structure:
└── Root
└── Function: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;main&quot;&lt;/span&gt;)
    └── BasicBlock: None
        ├── Call: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;printf&quot;&lt;/span&gt;)
        │   └── Constant: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;\&quot;Hello, World!\n\&quot;&quot;&lt;/span&gt;)
        └── Return: None
            └── Constant: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;0&quot;&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Sidenote:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;And this, kids, is precisely why a similar code in &lt;code&gt;C&lt;/code&gt;, &lt;code&gt;C++&lt;/code&gt;, or &lt;code&gt;Rust&lt;/code&gt; would be always be faster to run than in &lt;code&gt;Python&lt;/code&gt;, &lt;code&gt;Java&lt;/code&gt;, or &lt;code&gt;JavaScript&lt;/code&gt;. The optimizations are done at the IR level, which is much closer to the machine code than the source code. All optimizations happen before the program runs, so there’s no runtime overhead for these analyses. Type information is available at compile time, enabling more powerful optimizations and eliminating runtime type checking.&lt;/p&gt;
&lt;p&gt;In contrast, Interpreters typically analyze code line-by-line or function-by-function, missing many global optimization opportunities. Runtime type checking adds overhead and limits certain optimizations.&lt;/p&gt;
&lt;p&gt;Although, there are JITs (Just-In-Time) compilers that compile the code at runtime, which can be faster than traditional interpreters. JITs use a combination of interpretation and compilation to optimize the code at runtime. But, even JIT compilers that optimize during execution have to balance optimization time against execution time. Features like dynamic dispatch, reflection, and metaprogramming make certain optimizations impossible. Modern JIT compilers (like in JavaScript engines) have narrowed the gap through techniques like type specialization and trace-based compilation, but they’re still constrained by the dynamic nature of these languages and the need to optimize during execution.&lt;/p&gt;
&lt;h2 id=&quot;code-generation&quot; tabindex=&quot;-1&quot;&gt;Code Generation&lt;/h2&gt;
&lt;p&gt;The final step would be generating Assembly code from the IR. The assembly code is a low-level representation of the program that can be assembled into machine code and is CPU-specific. The code generator traverses the IR and generates assembly code for each instruction. Here’s a RISC-V reference for the &lt;a href=&quot;https://michaeljclark.github.io/asm&quot;&gt;assembly code&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A short summary of the RISC-V ISA to understand the assembly code:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../assets/img/hacktoberfest/riscv.png&quot; alt=&quot;RISCV- RV32I&quot; loading=&quot;lazy&quot;&gt;&lt;/p&gt;
&lt;p&gt;The codegenerator iterates over the generated IR and generates assembly code for each instruction. It traverses the IR tree and maps each &lt;code&gt;node type&lt;/code&gt; to specific RISC-V instructions, and this isn’t a simple one-to-one mapping - it involves careful register allocation, stack management, and preserving calling conventions. Here’s how the process works:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;IR Node → Register Allocation → Assembly Instructions → Function Prologue/Epilogue → Final Assembly
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Call Node&lt;/strong&gt;: For function calls, the code generator does the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Pushes temporary registers that might be modified by the call&lt;/li&gt;
&lt;li&gt;Evaluates all argument expressions&lt;/li&gt;
&lt;li&gt;Moves arguments to parameter registers (a0-a7)&lt;/li&gt;
&lt;li&gt;Issues the “call” instruction&lt;/li&gt;
&lt;li&gt;After the call, it restores temporary registers&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Register Allocation&lt;/strong&gt;: Incorporates a simple counter system (&lt;code&gt;get_new_temp()&lt;/code&gt;) to allocate registers for temporary variables. It uses a stack-like approach to manage the registers, where the most recently allocated register is used first. For our “Hello, World!” program, the code generator would do the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The string constant gets placed in the .rodata section with a unique label&lt;/li&gt;
&lt;li&gt;A temporary register (say t0) is loaded with the address of this string&lt;/li&gt;
&lt;li&gt;This register is moved to a0 before the printf call&lt;/li&gt;
&lt;li&gt;The return value 0 is loaded into a different register (like t1)&lt;/li&gt;
&lt;li&gt;This register is moved to a0 before the return&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Stack Management&lt;/strong&gt;: Stack management is crucial for function calls. The code generator handles this by:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Function prologue that saves return address (ra) and frame pointer (s0)&lt;/li&gt;
&lt;li&gt;Stack space allocation for local variables&lt;/li&gt;
&lt;li&gt;Parameter passing using both registers and stack&lt;/li&gt;
&lt;li&gt;Restoring saved registers in the epilogue&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;and the final compiled steps might look like this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The string “Hello, World!\n” is placed in the .rodata section with a label like .LC0&lt;/li&gt;
&lt;li&gt;The main function starts with a prologue to set up the stack frame&lt;/li&gt;
&lt;li&gt;The address of .LC0 is loaded into a temporary register&lt;/li&gt;
&lt;li&gt;This register is moved to a0 (first argument register)&lt;/li&gt;
&lt;li&gt;The printf function is called&lt;/li&gt;
&lt;li&gt;A constant 0 is loaded into a temporary register&lt;/li&gt;
&lt;li&gt;This register is moved to a0 (return value register)&lt;/li&gt;
&lt;li&gt;The epilogue restores saved registers and returns&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;IR Node: Call: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;printf&quot;&lt;/span&gt;)
     ↓
Assembly: la t0, .LC0    &lt;span class=&quot;hljs-comment&quot;&gt;# Load string address&lt;/span&gt;
          &lt;span class=&quot;hljs-built_in&quot;&gt;mv&lt;/span&gt; a0, t0      &lt;span class=&quot;hljs-comment&quot;&gt;# Set first argument&lt;/span&gt;
          call &lt;span class=&quot;hljs-built_in&quot;&gt;printf&lt;/span&gt;    &lt;span class=&quot;hljs-comment&quot;&gt;# Call the function&lt;/span&gt;

IR Node: Return: None → Constant: Some(&lt;span class=&quot;hljs-string&quot;&gt;&quot;0&quot;&lt;/span&gt;)
     ↓
Assembly: li t1, 0       &lt;span class=&quot;hljs-comment&quot;&gt;# Load immediate value 0&lt;/span&gt;
          &lt;span class=&quot;hljs-built_in&quot;&gt;mv&lt;/span&gt; a0, t1      &lt;span class=&quot;hljs-comment&quot;&gt;# Move to return register&lt;/span&gt;
          &lt;span class=&quot;hljs-comment&quot;&gt;# Epilogue follows&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and the final assembly code would look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-asm&quot;&gt;.section .data
.section .text
.global main

.extern printf
.global main

main:
    # Prologue
    addi sp, sp, -8
    sw ra, 4(sp)
    sw s0, 0(sp)
    addi s0, sp, 8

.section .rodata
.LC0:
    .string &quot;Hello, World!\n&quot;
.section .text
    la t0, .LC0
    mv a0, t0
    call printf
    li t1, 0
    mv a0, t1
    mv sp, s0
    addi sp, sp, -8
    lw ra, 4(sp)
    lw s0, 0(sp)
    addi sp, sp, 8
    ret

    # Epilogue
    lw ra, 4(sp)
    lw s0, 0(sp)
    addi sp, sp, 8
    ret
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;assembly-and-linking&quot; tabindex=&quot;-1&quot;&gt;Assembly and Linking&lt;/h2&gt;
&lt;p&gt;The assembly code generated by Ferry is specific to the RISC-V architecture. It can be assembled into machine code using an external assembler like &lt;code&gt;riscv64-unknown-elf-gcc&lt;/code&gt; and has to be linked with libc (C standard library) to create an executable binary. The assembly code is a low-level representation of the program that can be executed on a RISC-V CPU.&lt;/p&gt;
&lt;p&gt;The process flows like this:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;.s (Assembly code)&lt;/code&gt; --&amp;gt; &lt;strong&gt;Assembler&lt;/strong&gt; --&amp;gt; &lt;code&gt;.o (Object file)&lt;/code&gt; --&amp;gt; &lt;strong&gt;Linker&lt;/strong&gt; --&amp;gt; &lt;code&gt;Executable/ Machine code/ Binary&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Ferry has a separate module that helps with the assembly and linking process. This is a separate binary that uses the
&lt;code&gt;riscv64-unknown-elf-as&lt;/code&gt; to assemble and &lt;code&gt;riscv64-unknown-elf-gcc&lt;/code&gt; tools to assemble and link the code. It then uses &lt;code&gt;spike&lt;/code&gt; to run the code. The module is called &lt;code&gt;mac_os_runner&lt;/code&gt; and the binary is called &lt;code&gt;runner&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cargo run --release --bin runner -- &amp;lt;input_file.s&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The complete process of compiling and running a C program using Ferry in an ARM64 environment is as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cargo run --release --bin ferry -- &amp;lt;input_file.c&amp;gt;
cargo run --release --bin runner -- &amp;lt;input_file.s&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here’s a simple instruction decoder for RISC-V machine code&lt;/p&gt;
&lt;h3 id=&quot;instruction-decoder&quot; tabindex=&quot;-1&quot;&gt;Instruction decoder&lt;/h3&gt;
&lt;p&gt;This tool helps you decode RISCV32I instructions and convert them to their corresponding assembly code. (for example, &lt;code&gt;00000000000000000000000010000011&lt;/code&gt; to &lt;code&gt;lb x1, 0(x0)&lt;/code&gt;)&lt;/p&gt;
&lt;div class=&quot;container&quot; id=&quot;input-container&quot;&gt;
  &lt;input type=&quot;text&quot; class=&quot;input-box&quot; id=&quot;input-box&quot; placeholder=&quot;Instruction&quot;&gt;
  &lt;i class=&quot;icon fa-gear&quot; id=&quot;gear&quot;&gt;&lt;/i&gt;
&lt;/div&gt;
&lt;div id=&quot;result&quot; class=&quot;result&quot;&gt;&lt;/div&gt;
&lt;p&gt;Here is the standalone version of the tool: &lt;a href=&quot;https://anubhavp.dev/barney&quot;&gt;Barney- A RISC-V Instruction Decoder&lt;/a&gt;. This is going to be a handy tool to understand the instructions and their working. The tool will also include decoding assembly code to machine code in the future. (an assembler for RISC-V instructions)&lt;/p&gt;
&lt;h1 id=&quot;yatch&quot; tabindex=&quot;-1&quot;&gt;Yatch&lt;/h1&gt;
&lt;p&gt;Yatch is a simple machine code interpreter for RISC-V. It can execute RISC-V assembly code directly, allowing you to run machine code directly on a simulated RISC-V CPU. Yatch was meant to show how CPUs read and execute instructions. Read everything about Yatch &lt;a href=&quot;/blog/hacktoberfest.html#yatch&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Once you have the compiled assembly code, you can use a simulator like Yatch to simulate the execution of the code.&lt;/p&gt;
&lt;h1 id=&quot;future-work&quot; tabindex=&quot;-1&quot;&gt;Future Work&lt;/h1&gt;
&lt;p&gt;Well, the current scope of Ferry was to understand and demonstrate the working of compilers. While I would love to finish this, there are far better, superior compilers out there. This article was a simple entry into how systems work. My next steps would be delving more into the world of compilers, optimising CPU operations, and GPU computing, and understanding the mechanics behind the scenes.&lt;/p&gt;
&lt;p&gt;Also, a big big shoutout to my boy, &lt;code&gt;Claude 3.7 sonnet&lt;/code&gt; for improving the compiler and helping ship it 10x faster. Such a complex task would have taken me weeks, or even months, to complete. Claude wrote lines of redundant code - the extra parsing methods, a couple of functionality implementations in advanced optimisations and type checker functions that would have taken me a lot of time to finish manually. Especially the advanced optimiser. That part was a pain to write and Claude handled it like a pro. You still need a decent Rust knowledge to be able to fix whatever an AI model returns, but it did an excellent job.&lt;/p&gt;
&lt;p&gt;This article might seem overwhelming, but it’s pretty interesting to realize how all of modern computing works and see how far we’ve come.&lt;/p&gt;

            &lt;hr&gt;
            &lt;div class=&quot;footer&quot;&gt;
              &lt;i&gt;Feedback, Suggestions, Comments - &lt;/i&gt;
              &lt;div class=&quot;giscus-div&quot; id=&quot;comments&quot;&gt;
                &lt;script src=&quot;https://giscus.app/client.js&quot; data-repo=&quot;anubhavpgit/anubhavpgit.github.io&quot; data-repo-id=&quot;MDEwOlJlcG9zaXRvcnk0MDQ1ODEzMjc=&quot; data-category-id=&quot;DIC_kwDOGB1rz84Cer0j&quot; data-mapping=&quot;title&quot; data-strict=&quot;0&quot; data-reactions-enabled=&quot;1&quot; data-emit-metadata=&quot;0&quot; data-input-position=&quot;bottom&quot; data-theme=&quot;noborder_light&quot; data-lang=&quot;en&quot; data-loading=&quot;lazy&quot; crossorigin=&quot;anonymous&quot; async=&quot;&quot;&gt;&lt;/script&gt;
              &lt;/div&gt;
              Feel free to
              &lt;a id=&quot;mailtoLink&quot; href=&quot;mailto:anubhavp@duck.com?subject=Here&apos;s%20a%20suggestion/feedback!&quot;&gt;send
                me an email&lt;/a&gt;.
            &lt;/div&gt;
          &lt;/div&gt;
        </content:encoded>
            <subtitle>The one who compiles C lang to machine code.</subtitle>
        </item>
        <item>
            <title><![CDATA[Fourier Analysis]]></title>
            <description><![CDATA[Decomposing periodic functions into their constituent frequencies, and analyzing the amplitude and phase of each frequency.]]></description>
            <link>https://anubhavp.dev/blog/fourier.html</link>
            <guid isPermaLink="true">https://anubhavp.dev/blog/fourier.html</guid>
            <dc:creator><![CDATA[Anubhab Patnaik]]></dc:creator>
            <pubDate>Tue, 18 Nov 2025 00:00:00 GMT</pubDate>
            <content:encoded>
          &lt;div class=&quot;content custom&quot;&gt;
            &lt;div class=&quot;search-container&quot;&gt;&lt;/div&gt;
            &lt;script type=&quot;module&quot; src=&quot;/assets/js/fourier/main.js&quot;&gt;&lt;/script&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;/assets/css/fourier/style.css&quot;&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css&quot;&gt;
&lt;p&gt;Ever wondered how computers process and analyze images and shapes? You might have seen images stored as &lt;code&gt;.png&lt;/code&gt;, &lt;code&gt;.jpg&lt;/code&gt;, &lt;code&gt;.bmp&lt;/code&gt;, or &lt;code&gt;.svg&lt;/code&gt; while working with graphics or image processing. Broadly, image files can be represented using &lt;strong&gt;two&lt;/strong&gt; fundamental formats: &lt;strong&gt;raster&lt;/strong&gt; graphics and &lt;strong&gt;vector&lt;/strong&gt; graphics.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Raster graphics store images as a grid of pixels, where each pixel contains color or intensity information.&lt;/li&gt;
&lt;li&gt;Vector graphics represent shapes using mathematical equations — lines, curves, and polygons — allowing them to scale infinitely without losing quality.&lt;/li&gt;
&lt;/ul&gt;
&lt;figure class=&quot;raster-vector-compare&quot;&gt;
  &lt;div&gt;
    &lt;img alt=&quot;Batman&quot; src=&quot;../assets/img/fourier/batman.jpg&quot; loading=&quot;lazy&quot;&gt;
    &lt;figcaption&gt;Raster (JPG)&lt;/figcaption&gt;
  &lt;/div&gt;
  &lt;div&gt;
    &lt;img alt=&quot;Batman&quot; src=&quot;../assets/img/fourier/batman.svg&quot; loading=&quot;lazy&quot;&gt;
    &lt;figcaption&gt;Vector (SVG)&lt;/figcaption&gt;
  &lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;In mathematical terms, an image in a two-dimensional space can be represented in two ways: spatial domain and frequency domain. In the spatial domain, the image is represented as a grid of pixels, where each pixel has a specific intensity value. In the frequency domain, the image is represented as a combination of different frequencies, which can be analyzed using Fourier analysis.&lt;/p&gt;
&lt;p&gt;Fourier analysis is a mathematical technique used to decompose periodic functions into their constituent frequencies and analyze the amplitude and phase of each frequency component. Some of the key applications of Fourier analysis include audio processing, audio filtering, noise reduction, signal reconstruction, image compression, feature extraction, and recognition, object detection, and speech recognition among others. This means AirPods in your ears use some form of Fourier analysis to filter out the background noise when you activate noise cancellation in a subway or on a plane.&lt;/p&gt;
&lt;p&gt;At its core, Fourier analysis is about &lt;strong&gt;decomposing&lt;/strong&gt; a time-domain signal into its constituent frequencies, and inferring the &lt;strong&gt;amplitude&lt;/strong&gt; and &lt;strong&gt;phase&lt;/strong&gt; of each frequency component.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Draw a shape on the left canvas and watch Fourier epicycles trace it on the right!&lt;/em&gt; &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&quot;interactive-tracer-container&quot; id=&quot;image-tracer&quot;&gt;
   &lt;canvas style=&quot;border: 1px solid black; margin-right: 10px;&quot; id=&quot;canvas-original&quot; width=&quot;250&quot; height=&quot;250&quot;&gt;&lt;/canvas&gt;
   &lt;canvas style=&quot;border: 1px solid black;&quot; id=&quot;canvas-transformed&quot; width=&quot;250&quot; height=&quot;250&quot;&gt;&lt;/canvas&gt;
&lt;/div&gt;
&lt;p style=&quot;text-align: center; margin-top: 10px; font-family: monospace; font-size: 0.85rem; color: #666;&quot;&gt;
   &lt;strong&gt;Left:&lt;/strong&gt; Draw your shape | &lt;strong&gt;Right:&lt;/strong&gt; Fourier epicycles tracing it
&lt;/p&gt;
&lt;h2 id=&quot;table-of-contents&quot; tabindex=&quot;-1&quot;&gt;Table of Contents&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#recap&quot;&gt;Recap&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sinusoidal-waves&quot;&gt;Sinusoidal Waves&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#a-harmonic-wave&quot;&gt;A Harmonic Wave&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#functions-of-waves-and-signals&quot;&gt;Functions of Waves and Signals&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#fourier-series&quot;&gt;Fourier Series&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#periodic-signals&quot;&gt;Periodic Signals&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#approximating-complex-waves-with-fourier-series&quot;&gt;Approximating Complex Waves with Fourier Series&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#drawing-with-fourier-series-epicycles&quot;&gt;Drawing with Fourier Series: Epicycles&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sketches-as-functions&quot;&gt;Sketches as Functions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#fourier-approximation-of-the-bat-silhouette&quot;&gt;Fourier Approximation of the Bat Silhouette&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#epicycles-rotating-vectors&quot;&gt;Epicycles: Rotating Vectors&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#complex-exponential-notation&quot;&gt;Complex Exponential Notation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#computing-epicycles-with-the-dft&quot;&gt;Computing Epicycles with the DFT&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#retracing-our-drawing-with-epicycles&quot;&gt;Retracing our drawing with Epicycles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#the-mathematics-behind-epicycles&quot;&gt;The Mathematics Behind Epicycles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#why-this-works&quot;&gt;Why This Works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#generalizing-from-periodic-to-non-periodic-signals&quot;&gt;Generalizing: From Periodic to Non-Periodic Signals&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#fast-fourier-transform-fft&quot;&gt;Fast Fourier Transform (FFT)&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#the-performance-problem&quot;&gt;The Performance Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#enter-the-fft&quot;&gt;Enter the FFT&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#how-fft-works-intuition&quot;&gt;How FFT Works (Intuition)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#why-this-matters-1&quot;&gt;Why This Matters&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#libraries-and-implementation&quot;&gt;Libraries and Implementation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id=&quot;fourier-analysis&quot; tabindex=&quot;-1&quot;&gt;Fourier Analysis&lt;/h1&gt;
&lt;p&gt;Instead of jumping straight into the math, I’ll try to build an intuitive understanding of how waves and signals work which would make it easier to grasp the need for Fourier analysis.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Here’s a quick overview recap on how waves and signals work, followed by an introduction to Fourier series, Fourier transform, and discrete Fourier transform.&lt;/p&gt;
&lt;h2 id=&quot;recap&quot; tabindex=&quot;-1&quot;&gt;Recap&lt;/h2&gt;
&lt;p&gt;A wave is a disturbance that travels through a medium, and a signal is a wave that carries information.&lt;/p&gt;
&lt;h3 id=&quot;sinusoidal-waves&quot; tabindex=&quot;-1&quot;&gt;Sinusoidal Waves&lt;/h3&gt;
&lt;p&gt;The most fundamental wave pattern in nature is the &lt;strong&gt;sinusoidal wave&lt;/strong&gt; (or sine wave). A sine wave is a smooth, continuous oscillation that repeats periodically. It’s described mathematically by the sine function, which produces a characteristic S-shaped curve when plotted.&lt;/p&gt;
&lt;p&gt;The basic sine wave equation is:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;sin&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;y = \sin(x)
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base displaystyle textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;where &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;y&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.43056em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.625em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; oscillates smoothly between -1 and +1 as &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;x&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.43056em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.43056em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; increases.&lt;/p&gt;
&lt;div class=&quot;wave-container&quot;&gt;
  &lt;canvas id=&quot;basic-sine-canvas&quot;&gt;&lt;/canvas&gt;
&lt;/div&gt;
&lt;p&gt;This simple mathematical function appears everywhere in nature—from the oscillation of a pendulum to the vibration of guitar strings, from alternating current in electrical circuits to the propagation of light and sound waves.&lt;/p&gt;
&lt;p&gt;Sinusoidal waves are special because they are the &lt;strong&gt;building blocks&lt;/strong&gt; of all other periodic waves. No matter how complex a wave pattern looks, it can be broken down into a sum of simple sine (and cosine) waves—this is the fundamental insight of Fourier analysis.&lt;/p&gt;
&lt;h3 id=&quot;a-harmonic-wave&quot; tabindex=&quot;-1&quot;&gt;A Harmonic Wave:&lt;/h3&gt;
&lt;div class=&quot;wave-container&quot;&gt;
  &lt;canvas id=&quot;harmonic-wave-canvas&quot;&gt;&lt;/canvas&gt;
  &lt;div class=&quot;wave-controls&quot;&gt;
    &lt;div class=&quot;wave-control-row&quot;&gt;
      &lt;label&gt;Amplitude (A):&lt;/label&gt;
      &lt;input type=&quot;range&quot; id=&quot;amplitude-slider&quot; min=&quot;20&quot; max=&quot;120&quot; value=&quot;40&quot; step=&quot;5&quot;&gt;
      &lt;span id=&quot;amplitude-value&quot;&gt;40&lt;/span&gt;
    &lt;/div&gt;
    &lt;div class=&quot;wave-control-row&quot;&gt;
      &lt;label&gt;Frequency (f):&lt;/label&gt;
      &lt;input type=&quot;range&quot; id=&quot;frequency-slider&quot; min=&quot;0.5&quot; max=&quot;5&quot; value=&quot;2&quot; step=&quot;0.5&quot;&gt;
      &lt;span id=&quot;frequency-value&quot;&gt;2 Hz&lt;/span&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The equation &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;A&lt;/mi&gt;&lt;mi&gt;sin&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;ω&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;f(t) = A \sin(\omega t)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;ω&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; represents a &lt;strong&gt;simple harmonic wave&lt;/strong&gt; or oscillation with the following parameters:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Amplitude (A)&lt;/strong&gt;: The maximum displacement from the equilibrium position. It determines how “tall” the wave peaks are. In our example, &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;A&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;4&lt;/mn&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;A = 40&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.68333em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.68333em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; units.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Angular Frequency (ω)&lt;/strong&gt;: The rate of oscillation in radians per second. It is related to the frequency &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;f&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.69444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.8888799999999999em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; (in Hz) by the formula &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;ω&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mi&gt;π&lt;/mi&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\omega = 2\pi f&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.69444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.8888799999999999em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;ω&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;π&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;. In our example, if &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;f = 2&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.69444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.8888799999999999em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; Hz, then &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;ω&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;4&lt;/mn&gt;&lt;mi&gt;π&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\omega = 4\pi&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.64444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.64444em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;ω&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;π&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; radians per second.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Time (t)&lt;/strong&gt;: The independent variable, usually representing time in seconds.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Suppose we have a wave with frequency &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;f = 2&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.69444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.8888799999999999em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; Hz; the wave oscillates 2 times per second,&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;T&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mfrac&gt;&lt;mrow&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;/mrow&gt;&lt;/mfrac&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mfrac&gt;&lt;mrow&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/mrow&gt;&lt;/mfrac&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;.&lt;/mi&gt;&lt;mn&gt;5&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;T = \frac{1}{f} = \frac{1}{2} = 0.5&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.845108em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1.326216em;vertical-align:-0.481108em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.13889em;&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord reset-textstyle textstyle uncramped&quot;&gt;&lt;span class=&quot;sizing reset-size5 size5 reset-textstyle textstyle uncramped nulldelimiter&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mfrac&quot;&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.345em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.22999999999999998em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle textstyle uncramped frac-line&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.394em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size5 size5 reset-textstyle textstyle uncramped nulldelimiter&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord reset-textstyle textstyle uncramped&quot;&gt;&lt;span class=&quot;sizing reset-size5 size5 reset-textstyle textstyle uncramped nulldelimiter&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mfrac&quot;&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.345em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.22999999999999998em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle textstyle uncramped frac-line&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.394em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size5 size5 reset-textstyle textstyle uncramped nulldelimiter&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; seconds. (One cycle is completed in 0.5 seconds)&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;ω&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mi&gt;π&lt;/mi&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mi&gt;π&lt;/mi&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;4&lt;/mn&gt;&lt;mi&gt;π&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\omega = 2\pi f = 2\pi \times 2 = 4\pi&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.69444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.8888799999999999em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;ω&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;π&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;π&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;×&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;π&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; radians per second. (2 cycles are completed in 1 second)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The example equation &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;4&lt;/mn&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mi&gt;sin&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;4&lt;/mn&gt;&lt;mi&gt;π&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;f(t) = 40 \sin(4\pi t)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;π&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; describes a wave with an amplitude of 40 units and a frequency of 2 Hz. This means the wave oscillates between -40 and +40 units, completing 2 full cycles every second.&lt;/p&gt;
&lt;p&gt;This equation describes many &lt;strong&gt;periodic&lt;/strong&gt; phenomena, such as  a vibrating string, sound waves, light waves (for small angles in the wave equation), etc.&lt;/p&gt;
&lt;h3 id=&quot;functions-of-waves-and-signals&quot; tabindex=&quot;-1&quot;&gt;Functions of Waves and Signals&lt;/h3&gt;
&lt;p&gt;In mathematics, when we add two functions &lt;em&gt;(say, &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;f(x)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;g&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;g(x)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;) together)&lt;/em&gt;, we simply add their output values at each input point. This is expressed as:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;g&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;g&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;(f + g)(x) = f(x) + g(x)
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base displaystyle textstyle uncramped&quot;&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This simple property of functions has profound implications in physics. When two waves occupy the same space simultaneously, they don’t collide or bounce off each other like physical objects. Instead, they &lt;strong&gt;superpose&lt;/strong&gt;—their effects combine according to the &lt;strong&gt;principle of superposition&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The total displacement at any point is simply the sum of the individual wave displacements:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mrow&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mi&gt;o&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;mi&gt;l&lt;/mi&gt;&lt;/mrow&gt;&lt;/msub&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/msub&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/msub&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mn&gt;3&lt;/mn&gt;&lt;/msub&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;.&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;.&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;.&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;y_{total}(t) = y_1(t) + y_2(t) + y_3(t) + ...
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base displaystyle textstyle uncramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:-0.03588em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;o&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.01968em;&quot;&gt;l&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:-0.03588em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:-0.03588em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:-0.03588em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4 id=&quot;wave-interference&quot; tabindex=&quot;-1&quot;&gt;Wave Interference&lt;/h4&gt;
&lt;p&gt;And this leads us to the fascinating phenomenon of &lt;strong&gt;wave interference&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Constructive Interference&lt;/strong&gt; occurs when two waves are in phase (peaks align with peaks). Their amplitudes add together, creating a stronger wave:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;sin&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;ω&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;sin&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;ω&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mi&gt;sin&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;ω&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\sin(\omega t) + \sin(\omega t) = 2\sin(\omega t)
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base displaystyle textstyle uncramped&quot;&gt;&lt;span class=&quot;mop&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;ω&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;ω&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;ω&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;For example, when two sound waves constructively interfere, they produce louder noise. In light waves, constructive interference creates bright spots on reflective surfaces.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Destructive Interference&lt;/strong&gt; occurs when waves are out of phase (peaks align with troughs). They cancel each other out:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;sin&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;ω&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;sin&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;ω&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;π&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\sin(\omega t) + \sin(\omega t + \pi) = 0
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base displaystyle textstyle uncramped&quot;&gt;&lt;span class=&quot;mop&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;ω&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;ω&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;π&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This is the principle behind noise-cancelling headphones—they detect incoming sound waves and generate an exact opposite wave to cancel them out. When light waves destructively interfere, they appear as dim patches.&lt;/p&gt;
&lt;p&gt;These wave behaviors demonstrate that mathematical function addition directly corresponds to physical wave superposition, bridging abstract mathematics with observable phenomena in our universe.&lt;/p&gt;
&lt;div class=&quot;wave-container&quot;&gt;
  &lt;canvas id=&quot;superposition-canvas&quot;&gt;&lt;/canvas&gt;
  &lt;div class=&quot;wave-controls&quot;&gt;
    &lt;div class=&quot;wave-control-row&quot;&gt;
      &lt;label&gt;Wave 1 Amplitude:&lt;/label&gt;
      &lt;input type=&quot;range&quot; id=&quot;wave1-amp-slider&quot; min=&quot;10&quot; max=&quot;60&quot; value=&quot;30&quot; step=&quot;5&quot;&gt;
      &lt;span id=&quot;wave1-amp-value&quot;&gt;30&lt;/span&gt;
    &lt;/div&gt;
    &lt;div class=&quot;wave-control-row&quot;&gt;
      &lt;label&gt;Wave 1 Frequency:&lt;/label&gt;
      &lt;input type=&quot;range&quot; id=&quot;wave1-freq-slider&quot; min=&quot;0.5&quot; max=&quot;4&quot; value=&quot;1.5&quot; step=&quot;0.5&quot;&gt;
      &lt;span id=&quot;wave1-freq-value&quot;&gt;1.5 Hz&lt;/span&gt;
    &lt;/div&gt;
    &lt;div class=&quot;wave-control-row&quot;&gt;
      &lt;label&gt;Wave 2 Amplitude:&lt;/label&gt;
      &lt;input type=&quot;range&quot; id=&quot;wave2-amp-slider&quot; min=&quot;10&quot; max=&quot;60&quot; value=&quot;25&quot; step=&quot;5&quot;&gt;
      &lt;span id=&quot;wave2-amp-value&quot;&gt;25&lt;/span&gt;
    &lt;/div&gt;
    &lt;div class=&quot;wave-control-row&quot;&gt;
      &lt;label&gt;Wave 2 Frequency:&lt;/label&gt;
      &lt;input type=&quot;range&quot; id=&quot;wave2-freq-slider&quot; min=&quot;0.5&quot; max=&quot;4&quot; value=&quot;2.5&quot; step=&quot;0.5&quot;&gt;
      &lt;span id=&quot;wave2-freq-value&quot;&gt;2.5 Hz&lt;/span&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;hr&gt;
&lt;p&gt;Now that we have a basic understanding of waves and signals, imagine being given a complex wave pattern, like a sound wave or an image signal, and being asked to figure out what simple sine and cosine waves make up that complex pattern. This is exactly where &lt;strong&gt;Fourier analysis&lt;/strong&gt; comes in. Fourier analysis provides the mathematical tools to decompose complex signals into their constituent sine and cosine waves, allowing us to analyze the frequency content of the signal.&lt;/p&gt;
&lt;div class=&quot;decomposition-container&quot;&gt;
  &lt;div class=&quot;decomposition-item&quot;&gt;
    &lt;canvas id=&quot;composite-wave-canvas&quot;&gt;&lt;/canvas&gt;
    &lt;p class=&quot;decomposition-label&quot;&gt;Complex Wave&lt;/p&gt;
  &lt;/div&gt;
  &lt;div class=&quot;decomposition-arrow&quot;&gt;→&lt;/div&gt;
  &lt;div class=&quot;decomposition-components&quot;&gt;
    &lt;div class=&quot;decomposition-item&quot;&gt;
      &lt;canvas id=&quot;component-wave1-canvas&quot;&gt;&lt;/canvas&gt;
      &lt;p class=&quot;decomposition-label&quot;&gt;Component 1&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class=&quot;decomposition-item&quot;&gt;
      &lt;canvas id=&quot;component-wave2-canvas&quot;&gt;&lt;/canvas&gt;
      &lt;p class=&quot;decomposition-label&quot;&gt;Component 2&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This means when you record a sound using your phone, Fourier analysis can identify which low amplitude high-frequency signals are present in the complex sound wave, apply a 180-degree phase shift to them, and add them back to the original sound wave to cancel out the noise.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;fourier-series&quot; tabindex=&quot;-1&quot;&gt;Fourier Series&lt;/h2&gt;
&lt;p&gt;The Fourier series is a powerful tool that represents any reasonable&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn2&quot; id=&quot;fnref2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt; periodic function as a sum of sine and cosine waves with different frequencies, amplitudes, and phases.&lt;/p&gt;
&lt;h4 id=&quot;periodic-signals&quot; tabindex=&quot;-1&quot;&gt;Periodic Signals&lt;/h4&gt;
&lt;p&gt;For periodic signals (functions that repeat over time, with period T), a signal 𝑓(𝑡) can be written as a sum of sine and cosine terms:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;msubsup&gt;&lt;mo&gt;∑&lt;/mo&gt;&lt;mrow&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∞&lt;/mi&gt;&lt;/mrow&gt;&lt;/msubsup&gt;&lt;msub&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;mi&gt;cos&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mi&gt;π&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;msub&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;mi&gt;sin&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mi&gt;π&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;msub&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;f(t) = a_0 + \sum_{n=1}^{\infty} a_n \cos(2\pi n f_0 t) + b_n \sin(2\pi n f_0 t)
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1.6513970000000002em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:2.9185100000000004em;vertical-align:-1.267113em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base displaystyle textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mop op-limits&quot;&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:1.1671129999999998em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.000005000000000143778em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class=&quot;op-symbol large-op mop&quot;&gt;∑&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-1.2500050000000003em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;∞&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;π&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:-0.10764em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;π&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:-0.10764em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;where &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;f_0&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.69444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.8888799999999999em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:-0.10764em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; is the fundamental frequency (the lowest frequency component), and &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;a_0&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.43056em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.58056em;vertical-align:-0.15em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;a_n&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.43056em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.58056em;vertical-align:-0.15em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;, and &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;b_n&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.69444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.84444em;vertical-align:-0.15em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; are the Fourier coefficients that determine the amplitude of each frequency component:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;a_n&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.43056em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.58056em;vertical-align:-0.15em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; represents the amplitude of the cosine wave at frequency &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;msub&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;n f_0&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.69444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.8888799999999999em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:-0.10764em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;b_n&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.69444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.84444em;vertical-align:-0.15em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; represents the amplitude of the sine wave at frequency &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;msub&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;n f_0&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.69444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.8888799999999999em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:-0.10764em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Alternatively, this can be written in amplitude-phase form:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;msubsup&gt;&lt;mo&gt;∑&lt;/mo&gt;&lt;mrow&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∞&lt;/mi&gt;&lt;/mrow&gt;&lt;/msubsup&gt;&lt;msub&gt;&lt;mi&gt;A&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;mi&gt;cos&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mi&gt;π&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;msub&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/msub&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;ϕ&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;f(t) = a_0 + \sum_{n=1}^{\infty} A_n \cos(2\pi n f_0 t + \phi_n)
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1.6513970000000002em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:2.9185100000000004em;vertical-align:-1.267113em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base displaystyle textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mop op-limits&quot;&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:1.1671129999999998em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.000005000000000143778em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class=&quot;op-symbol large-op mop&quot;&gt;∑&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-1.2500050000000003em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;∞&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;π&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:-0.10764em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;ϕ&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;where &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;A&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;msqrt&gt;&lt;mrow&gt;&lt;msubsup&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/msubsup&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;msubsup&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/msubsup&gt;&lt;/mrow&gt;&lt;/msqrt&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;A_n = \sqrt{a_n^2 + b_n^2}&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.931559em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1.24001em;vertical-align:-0.308451em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sqrt mord&quot;&gt;&lt;span class=&quot;sqrt-sign&quot; style=&quot;top:-0.04155900000000001em;&quot;&gt;&lt;span class=&quot;style-wrap reset-textstyle textstyle uncramped&quot;&gt;&lt;span class=&quot;delimsizing size1&quot;&gt;√&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:1em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord textstyle cramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.247em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.28900000000000003em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.247em;margin-left:0em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.28900000000000003em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.851559em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:1em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle textstyle uncramped sqrt-line&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:1em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; is the amplitude and &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;ϕ&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;arctan&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;b&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;/&lt;/mi&gt;&lt;msub&gt;&lt;mi&gt;a&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\phi_n = \arctan(-b_n/a_n)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;ϕ&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;arctan&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; is the phase of the &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;n&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.43056em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.43056em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;-th harmonic component.&lt;/p&gt;
&lt;p&gt;Sound waves are periodic signals, and the Fourier series can be used to decompose them into their constituent frequencies.&lt;/p&gt;
&lt;h4 id=&quot;approximating-complex-waves-with-fourier-series&quot; tabindex=&quot;-1&quot;&gt;Approximating Complex Waves with Fourier Series&lt;/h4&gt;
&lt;p&gt;Fourier series can approximate &lt;strong&gt;any&lt;/strong&gt; periodic function by summing up sine and cosine waves. The more terms we include in the series, the better our approximation becomes. With an infinite number of terms, we can perfectly reconstruct the original function. (&lt;em&gt;In practice, we use a finite number of terms to get a good approximation.&lt;/em&gt;)&lt;/p&gt;
&lt;p&gt;Let’s see this in action with a &lt;strong&gt;square wave&lt;/strong&gt; - a function that abruptly alternates between +1 and -1:&lt;/p&gt;
&lt;div class=&quot;wave-container&quot;&gt;
  &lt;canvas id=&quot;fourier-approximation-canvas&quot;&gt;&lt;/canvas&gt;
  &lt;div class=&quot;wave-controls&quot;&gt;
    &lt;div class=&quot;wave-control-row&quot;&gt;
      &lt;label&gt;Number of Terms (n):&lt;/label&gt;
      &lt;input type=&quot;range&quot; id=&quot;terms-slider&quot; min=&quot;1&quot; max=&quot;50&quot; value=&quot;5&quot; step=&quot;1&quot;&gt;
      &lt;span id=&quot;terms-value&quot;&gt;5&lt;/span&gt;
    &lt;/div&gt;
    &lt;div class=&quot;approximation-info&quot;&gt;
      &lt;p&gt;&lt;span style=&quot;color: #888; font-weight: bold;&quot;&gt;━━&lt;/span&gt; Target Wave (Square Wave)&lt;/p&gt;
      &lt;p&gt;&lt;span style=&quot;color: #e74c3c; font-weight: bold;&quot;&gt;━━&lt;/span&gt; Fourier Approximation&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;As you increase the number of terms, notice how the red Fourier approximation gets closer to the gray target square wave. With just a few terms, we can already capture the general shape. With more terms, the approximation becomes remarkably accurate, though you’ll always see some overshoot at the discontinuities (known as the &lt;a href=&quot;https://en.wikipedia.org/wiki/Gibbs_phenomenon&quot;&gt;Gibbs phenomenon&lt;/a&gt;)—this happens because finite sums of smooth waves can’t perfectly match a jump discontinuity. Even functions with sharp corners and discontinuities can be represented as sums of smooth, continuous sine waves!&lt;/p&gt;
&lt;h2 id=&quot;drawing-with-fourier-series-epicycles&quot; tabindex=&quot;-1&quot;&gt;Drawing with Fourier Series: Epicycles&lt;/h2&gt;
&lt;p&gt;Coming back to recreating images using mechanical arms above, we can use Fourier series to break down complex 2D paths and use the &lt;strong&gt;same principles of wave decomposition&lt;/strong&gt; to reconstruct them.&lt;/p&gt;
&lt;h4 id=&quot;sketches-as-functions&quot; tabindex=&quot;-1&quot;&gt;Sketches as Functions&lt;/h4&gt;
&lt;p&gt;When you draw a picture, your pen traces a path through 2D space. You go in two directions simultaneously: horizontally (x-axis) and vertically (y-axis). At any moment in time &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;t&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.61508em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.61508em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;, your pen has:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;An x-coordinate: &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;x(t)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;A y-coordinate: &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;y(t)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This means &lt;strong&gt;any drawing can be represented as two separate functions of time&lt;/strong&gt; - one tracking horizontal movement, the other tracking vertical movement.&lt;/p&gt;
&lt;div class=&quot;sketch-container&quot;&gt;
  &lt;canvas id=&quot;cat-sketch-canvas&quot;&gt;&lt;/canvas&gt;
  &lt;p class=&quot;canvas-label&quot;&gt;Batman silhouette drawn as a continuous path&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Just like we decomposed sound waves, we can analyze the path by separating it into two time-domain signals.&lt;/p&gt;
&lt;div class=&quot;coordinate-decomposition-container&quot;&gt;
  &lt;canvas id=&quot;coordinate-decomposition-canvas&quot;&gt;&lt;/canvas&gt;
  &lt;p class=&quot;canvas-label&quot;&gt;The path decomposed into x(t) and y(t) signals&lt;/p&gt;
&lt;/div&gt;
&lt;h4 id=&quot;fourier-approximation-of-the-bat-silhouette&quot; tabindex=&quot;-1&quot;&gt;Fourier Approximation of the Bat Silhouette&lt;/h4&gt;
&lt;p&gt;We have two functions now: &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;x(t)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;y(t)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;. Using Fourier series, we can approximate both functions as sums of sine and cosine waves. Which means, two sets of Fourier coefficients - one for &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;x(t)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and one for &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;y(t)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; can be used to retrace the path of the drawing.&lt;/p&gt;
&lt;div class=&quot;cat-approximation-container&quot;&gt;
  &lt;canvas id=&quot;cat-approximation-canvas&quot;&gt;&lt;/canvas&gt;
  &lt;div class=&quot;wave-controls&quot;&gt;
    &lt;div class=&quot;wave-control-row&quot;&gt;
      &lt;label&gt;Number of Terms:&lt;/label&gt;
      &lt;input type=&quot;range&quot; id=&quot;cat-approx-slider&quot; min=&quot;3&quot; max=&quot;80&quot; value=&quot;10&quot; step=&quot;1&quot;&gt;
      &lt;span id=&quot;cat-approx-value&quot;&gt;10&lt;/span&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;With just a few terms, we get a rough outline. As we increase the number of terms, the Fourier reconstruction gets closer and closer to the original bat silhouette.&lt;/p&gt;
&lt;h4 id=&quot;epicycles-rotating-vectors&quot; tabindex=&quot;-1&quot;&gt;Epicycles: Rotating Vectors&lt;/h4&gt;
&lt;p&gt;There are primarily two ways to represent coordinates in 2D space: Cartesian coordinates &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;(x, y)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and Polar coordinates &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;r&lt;/mi&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mi&gt;θ&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;(r, \theta)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.02778em;&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.02778em;&quot;&gt;θ&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;. In Cartesian coordinates, a point is defined by its horizontal (x) and vertical (y) distances from the origin; &lt;em&gt;P(x, y)&lt;/em&gt;. In Polar coordinates, a point is defined by its distance from the origin (radius &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;r&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;r&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.43056em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.43056em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.02778em;&quot;&gt;r&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;) and the angle (&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;θ&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\theta&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.69444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.69444em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.02778em;&quot;&gt;θ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;) it makes with the positive x-axis; &lt;em&gt;P(r, θ)&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Polar coordinates use trigonometric functions to relate to Cartesian coordinates: &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;r&lt;/mi&gt;&lt;mi&gt;cos&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;θ&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;x = r \cos(\theta)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.02778em;&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.02778em;&quot;&gt;θ&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;r&lt;/mi&gt;&lt;mi&gt;sin&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;θ&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;y = r \sin(\theta)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.02778em;&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.02778em;&quot;&gt;θ&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;. In the polar coordinates system, a point can be represented as a vector originating from the origin, with length &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;r&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;r&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.43056em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.43056em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.02778em;&quot;&gt;r&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and angle &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;θ&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\theta&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.69444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.69444em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.02778em;&quot;&gt;θ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Look at this example of &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;sin&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\sin(t)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mop&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; represented as a rotating vector in the complex plane:&lt;/p&gt;
&lt;div class=&quot;rotating-vector-container&quot;&gt;
  &lt;canvas id=&quot;rotating-vector-canvas&quot;&gt;&lt;/canvas&gt;
  &lt;p class=&quot;canvas-label&quot;&gt;Sine wave represented as a rotating vector&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Notice how the tip of the rotating vector traces out the sine wave over time. Similarly, a periodic function can be represented as a sum of rotating vectors (epicycles) in the complex plane. Attach an epicycle on the tip of another epicycle, and so on.&lt;/p&gt;
&lt;div class=&quot;rotating-vectors-container&quot;&gt;
  &lt;canvas id=&quot;rotating-vectors-canvas&quot;&gt;&lt;/canvas&gt;
  &lt;p class=&quot;canvas-label&quot;&gt;y(t) = 50·sin(ωt) + 30·sin(3ωt)&lt;/p&gt;
&lt;/div&gt;
&lt;h4 id=&quot;complex-exponential-notation&quot; tabindex=&quot;-1&quot;&gt;Complex Exponential Notation&lt;/h4&gt;
&lt;p&gt;Earlier, we wrote the Fourier Transform and DFT using separate sine and cosine terms. There’s a more elegant way to write this using &lt;strong&gt;Euler’s formula&lt;/strong&gt;, which establishes a beautiful connection between exponentials and trigonometry:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msup&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mrow&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;θ&lt;/mi&gt;&lt;/mrow&gt;&lt;/msup&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;cos&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;θ&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;sin&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;θ&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;e^{i\theta} = \cos(\theta) + i\sin(\theta)
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8991079999999999em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1.149108em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base displaystyle textstyle uncramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:-0.413em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.02778em;&quot;&gt;θ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.02778em;&quot;&gt;θ&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.02778em;&quot;&gt;θ&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This remarkable equation means a complex exponential represents a &lt;strong&gt;rotating vector&lt;/strong&gt; in the complex plane. From this, we can derive:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;cos&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;θ&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mfrac&gt;&lt;mrow&gt;&lt;msup&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mrow&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;θ&lt;/mi&gt;&lt;/mrow&gt;&lt;/msup&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;msup&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;θ&lt;/mi&gt;&lt;/mrow&gt;&lt;/msup&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/mrow&gt;&lt;/mfrac&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\cos(\theta) = \frac{e^{i\theta} + e^{-i\theta}}{2}
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1.526108em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:2.212108em;vertical-align:-0.686em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base displaystyle textstyle uncramped&quot;&gt;&lt;span class=&quot;mop&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.02778em;&quot;&gt;θ&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord reset-textstyle displaystyle textstyle uncramped&quot;&gt;&lt;span class=&quot;sizing reset-size5 size5 reset-textstyle textstyle uncramped nulldelimiter&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mfrac&quot;&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.686em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle textstyle cramped&quot;&gt;&lt;span class=&quot;mord textstyle cramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.22999999999999998em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle textstyle uncramped frac-line&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.677em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle textstyle uncramped&quot;&gt;&lt;span class=&quot;mord textstyle uncramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:-0.363em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.02778em;&quot;&gt;θ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:-0.363em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.02778em;&quot;&gt;θ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size5 size5 reset-textstyle textstyle uncramped nulldelimiter&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;sin&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;θ&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mfrac&gt;&lt;mrow&gt;&lt;msup&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mrow&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;θ&lt;/mi&gt;&lt;/mrow&gt;&lt;/msup&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;msup&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;θ&lt;/mi&gt;&lt;/mrow&gt;&lt;/msup&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;/mrow&gt;&lt;/mfrac&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\sin(\theta) = \frac{e^{i\theta} - e^{-i\theta}}{2i}
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1.526108em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:2.212108em;vertical-align:-0.686em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base displaystyle textstyle uncramped&quot;&gt;&lt;span class=&quot;mop&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.02778em;&quot;&gt;θ&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord reset-textstyle displaystyle textstyle uncramped&quot;&gt;&lt;span class=&quot;sizing reset-size5 size5 reset-textstyle textstyle uncramped nulldelimiter&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mfrac&quot;&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.686em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle textstyle cramped&quot;&gt;&lt;span class=&quot;mord textstyle cramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;i&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.22999999999999998em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle textstyle uncramped frac-line&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.677em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle textstyle uncramped&quot;&gt;&lt;span class=&quot;mord textstyle uncramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:-0.363em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.02778em;&quot;&gt;θ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:-0.363em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.02778em;&quot;&gt;θ&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size5 size5 reset-textstyle textstyle uncramped nulldelimiter&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why this matters:&lt;/strong&gt; Instead of writing separate &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;A&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;ω&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mi&gt;cos&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;ω&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;B&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;ω&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mi&gt;sin&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;ω&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;A(\omega)\cos(\omega t) + B(\omega)\sin(\omega t)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;ω&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;ω&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.05017em;&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;ω&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;ω&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; terms, we can combine them into a single complex exponential:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;F&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;ω&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;msubsup&gt;&lt;mo&gt;∫&lt;/mo&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∞&lt;/mi&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∞&lt;/mi&gt;&lt;/mrow&gt;&lt;/msubsup&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;msup&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;ω&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/mrow&gt;&lt;/msup&gt;&lt;mi&gt;d&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;F(\omega) = \int_{-\infty}^{\infty} f(t) e^{-i\omega t} dt
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1.36em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:2.330581em;vertical-align:-0.970581em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base displaystyle textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.13889em;&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;ω&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;&lt;span class=&quot;op-symbol large-op mop&quot; style=&quot;margin-right:0.44445em;top:-0.0011249999999999316em;&quot;&gt;∫&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.91225em;margin-left:-0.44445em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;∞&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.974em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;∞&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:-0.41300000000000003em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;ω&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This is the &lt;strong&gt;compact form&lt;/strong&gt; of the Fourier Transform you’ll see in textbooks. It’s the same math as before, just written more concisely.&lt;/p&gt;
&lt;p&gt;Similarly, the DFT can be written as:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;X&lt;/mi&gt;&lt;mo&gt;[&lt;/mo&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;mo&gt;]&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;msubsup&gt;&lt;mo&gt;∑&lt;/mo&gt;&lt;mrow&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/msubsup&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;[&lt;/mo&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo&gt;]&lt;/mo&gt;&lt;msup&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mi&gt;π&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;/&lt;/mi&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;/mrow&gt;&lt;/msup&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;X[k] = \sum_{n=0}^{N-1} x[n] e^{-i2\pi nk/N}
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1.8283360000000004em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:3.0954490000000003em;vertical-align:-1.267113em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base displaystyle textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.07847em;&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mop op-limits&quot;&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:1.1671129999999998em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.000005000000000143778em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class=&quot;op-symbol large-op mop&quot;&gt;∑&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-1.2500050000000003em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:-0.413em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;π&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Now, coming back to the Fourier series representation of our drawing, we combine x and y into one complex signal:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;z&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;z(t) = x(t) + i y(t)
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base displaystyle textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.04398em;&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Fourier coefficients can be expressed as:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;z&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;msubsup&gt;&lt;mo&gt;∑&lt;/mo&gt;&lt;mrow&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∞&lt;/mi&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∞&lt;/mi&gt;&lt;/mrow&gt;&lt;/msubsup&gt;&lt;msub&gt;&lt;mi&gt;c&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;msup&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mrow&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mi&gt;ω&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/mrow&gt;&lt;/msup&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;z(t) = \sum_{n=-\infty}^{\infty} c_n e^{i n \omega t}
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1.6513970000000002em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:2.959733em;vertical-align:-1.308336em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base displaystyle textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.04398em;&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mop op-limits&quot;&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:1.150005em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;∞&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.000005000000000143778em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class=&quot;op-symbol large-op mop&quot;&gt;∑&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-1.2500050000000003em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;∞&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:-0.413em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;ω&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Each term &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msup&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mrow&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mi&gt;ω&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/mrow&gt;&lt;/msup&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;e^{i n \omega t}&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.824664em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.824664em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:-0.363em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;ω&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; represents a rotating vector (an epicycle) at frequency &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;n&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.43056em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.43056em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;. The magnitude &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∣&lt;/mi&gt;&lt;msub&gt;&lt;mi&gt;c&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∣&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;|c_n|&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;∣&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;∣&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; gives the radius, and &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;arg&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;c&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\arg(c_n)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mop&quot;&gt;ar&lt;span style=&quot;margin-right:0.01389em;&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; gives the starting phase.&lt;/p&gt;
&lt;p&gt;Each term in the Fourier series can be visualized as a circle rotating at a specific frequency. When you connect these circles end-to-end (placing the center of each circle at the tip of the previous one), their combined motion traces out your original drawing.&lt;/p&gt;
&lt;div class=&quot;epicycle-demo-container&quot;&gt;
  &lt;canvas id=&quot;epicycle-demo-canvas&quot;&gt;&lt;/canvas&gt;
  &lt;p class=&quot;canvas-label&quot;&gt;Rotating circles (epicycles) tracing a path&lt;/p&gt;
&lt;/div&gt;
&lt;h4 id=&quot;computing-epicycles-with-the-dft&quot; tabindex=&quot;-1&quot;&gt;Computing Epicycles with the DFT&lt;/h4&gt;
&lt;p&gt;Your drawing is sampled at discrete pixel points—not a continuous mathematical curve. For such &lt;strong&gt;sampled periodic signals&lt;/strong&gt;, we use the &lt;strong&gt;Discrete Fourier Transform (DFT)&lt;/strong&gt; to extract the frequency components.&lt;/p&gt;
&lt;p&gt;The DFT takes &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;N&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.68333em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.68333em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; sampled points and computes &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;N&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.68333em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.68333em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; frequency components, each with amplitude and phase:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;X&lt;/mi&gt;&lt;mo&gt;[&lt;/mo&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;mo&gt;]&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;msubsup&gt;&lt;mo&gt;∑&lt;/mo&gt;&lt;mrow&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/msubsup&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;[&lt;/mo&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo&gt;]&lt;/mo&gt;&lt;mspace width=&quot;0.16667em&quot;&gt;&lt;/mspace&gt;&lt;msup&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mi&gt;π&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;/&lt;/mi&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;/mrow&gt;&lt;/msup&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;X[k] = \sum_{n=0}^{N-1} x[n] \, e^{-i2\pi nk/N}
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1.8283360000000004em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:3.0954490000000003em;vertical-align:-1.267113em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base displaystyle textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.07847em;&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mop op-limits&quot;&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:1.1671129999999998em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.000005000000000143778em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class=&quot;op-symbol large-op mop&quot;&gt;∑&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-1.2500050000000003em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;mord mspace thinspace&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:-0.413em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;π&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Each complex number &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;X&lt;/mi&gt;&lt;mo&gt;[&lt;/mo&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;mo&gt;]&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;X[k]&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.07847em;&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; tells us:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Magnitude&lt;/strong&gt; &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∣&lt;/mi&gt;&lt;mi&gt;X&lt;/mi&gt;&lt;mo&gt;[&lt;/mo&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;mo&gt;]&lt;/mo&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∣&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;|X[k]|&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;∣&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.07847em;&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;∣&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;: radius of epicycle &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;k&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.69444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.69444em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Phase&lt;/strong&gt; &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;arg&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;X&lt;/mi&gt;&lt;mo&gt;[&lt;/mo&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;mo&gt;]&lt;/mo&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\arg(X[k])&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mop&quot;&gt;ar&lt;span style=&quot;margin-right:0.01389em;&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.07847em;&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;: starting angle of epicycle &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;k&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.69444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.69444em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since our drawing is 2D, we combine &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;x&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.43056em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.43056em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;x&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;y&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.43056em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.625em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; coordinates into one complex signal: &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;z&lt;/mi&gt;&lt;mo&gt;[&lt;/mo&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo&gt;]&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;[&lt;/mo&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo&gt;]&lt;/mo&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;[&lt;/mo&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo&gt;]&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;z[n] = x[n] + iy[n]&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.04398em;&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;. The DFT treats this closed path as &lt;strong&gt;one period of a repeating pattern&lt;/strong&gt;—that’s why the epicycles loop perfectly!&lt;/p&gt;
&lt;h4 id=&quot;retracing-our-drawing-with-epicycles&quot; tabindex=&quot;-1&quot;&gt;Retracing our drawing with Epicycles&lt;/h4&gt;
&lt;p&gt;Summing up, we have:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A sketch&lt;/li&gt;
&lt;li&gt;Decomposed into two time-domain signals: &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;x(t)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;y(t)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;, representing horizontal and vertical movement over time&lt;/li&gt;
&lt;li&gt;Each horizontal and vertical signal approximated using Fourier series&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since your drawing is sampled at discrete points (not a continuous function), we use the &lt;strong&gt;Discrete Fourier Transform (DFT)&lt;/strong&gt;—the sampled version of the Fourier transform.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 1: Analyzing the Drawing (DFT)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We compute complex coefficients &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;c&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;c_n&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.43056em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.58056em;vertical-align:-0.15em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; by projecting the sampled path &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;/msub&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;msub&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;/msub&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;(x_k + i y_k)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:-0.03588em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; onto each rotating basis &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msup&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mi&gt;π&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;/&lt;/mi&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;/mrow&gt;&lt;/msup&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;e^{-i2\pi nk/N}&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8879999999999999em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.8879999999999999em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:-0.363em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;π&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;for&lt;/span&gt; (&lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; n = -numFrequencies; n &amp;lt;= numFrequencies; n++) {
    &lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; realSum = &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;, imagSum = &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;;

    &lt;span class=&quot;hljs-keyword&quot;&gt;for&lt;/span&gt; (&lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; k = &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;; k &amp;lt; N; k++) {
        &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; angle = (-&lt;span class=&quot;hljs-number&quot;&gt;2&lt;/span&gt; * &lt;span class=&quot;hljs-title class_&quot;&gt;Math&lt;/span&gt;.&lt;span class=&quot;hljs-property&quot;&gt;PI&lt;/span&gt; * n * k) / N;
        realSum += x[k] * &lt;span class=&quot;hljs-title class_&quot;&gt;Math&lt;/span&gt;.&lt;span class=&quot;hljs-title function_&quot;&gt;cos&lt;/span&gt;(angle) - y[k] * &lt;span class=&quot;hljs-title class_&quot;&gt;Math&lt;/span&gt;.&lt;span class=&quot;hljs-title function_&quot;&gt;sin&lt;/span&gt;(angle);
        imagSum += x[k] * &lt;span class=&quot;hljs-title class_&quot;&gt;Math&lt;/span&gt;.&lt;span class=&quot;hljs-title function_&quot;&gt;sin&lt;/span&gt;(angle) + y[k] * &lt;span class=&quot;hljs-title class_&quot;&gt;Math&lt;/span&gt;.&lt;span class=&quot;hljs-title function_&quot;&gt;cos&lt;/span&gt;(angle);
    }

    &lt;span class=&quot;hljs-comment&quot;&gt;// Convert to polar form: amplitude and phase&lt;/span&gt;
    amplitude = &lt;span class=&quot;hljs-title function_&quot;&gt;sqrt&lt;/span&gt;(realSum² + imagSum²) / N;
    phase = &lt;span class=&quot;hljs-title function_&quot;&gt;atan2&lt;/span&gt;(imagSum, realSum);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This gives us:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Amplitude&lt;/strong&gt;: Radius of each rotating circle&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Phase&lt;/strong&gt;: Starting angle of each circle&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Frequency&lt;/strong&gt;: How fast each circle rotates&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Step 2: Reconstructing the Path (Inverse DFT)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;To redraw at time &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;t&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.61508em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.61508em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; (from 0 to 1):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;hljs-title function_&quot;&gt;x&lt;/span&gt;(t) = Σ amplitude[n] * &lt;span class=&quot;hljs-title function_&quot;&gt;cos&lt;/span&gt;(&lt;span class=&quot;hljs-number&quot;&gt;2&lt;/span&gt;π * freq[n] * t + phase[n])
&lt;span class=&quot;hljs-title function_&quot;&gt;y&lt;/span&gt;(t) = Σ amplitude[n] * &lt;span class=&quot;hljs-title function_&quot;&gt;sin&lt;/span&gt;(&lt;span class=&quot;hljs-number&quot;&gt;2&lt;/span&gt;π * freq[n] * t + phase[n])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each term is one rotating epicycle. Sum them all up to get the final pen position.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 3: Animation&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;for&lt;/span&gt; (t = &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;; t &amp;lt; &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;; t += &lt;span class=&quot;hljs-number&quot;&gt;0.01&lt;/span&gt;) {
    position = &lt;span class=&quot;hljs-title function_&quot;&gt;evaluateEpicycles&lt;/span&gt;(coefficients, t);
    &lt;span class=&quot;hljs-title function_&quot;&gt;drawPoint&lt;/span&gt;(position.&lt;span class=&quot;hljs-property&quot;&gt;x&lt;/span&gt;, position.&lt;span class=&quot;hljs-property&quot;&gt;y&lt;/span&gt;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;t&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.61508em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.61508em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; goes from 0 → 1, we complete one full cycle and trace the entire drawing!&lt;/p&gt;
&lt;p&gt;Now, for each Fourier coefficient, we create an epicycle (rotating circle) in the complex plane. By connecting these epicycles tip-to-tail, the final tip traces out the original drawing.&lt;/p&gt;
&lt;div class=&quot;cat-epicycle-container&quot;&gt;
  &lt;canvas id=&quot;cat-epicycle-canvas&quot;&gt;&lt;/canvas&gt;
  &lt;div class=&quot;epicycle-controls&quot;&gt;
    &lt;div class=&quot;wave-control-row&quot;&gt;
      &lt;label&gt;Number of Epicycles:&lt;/label&gt;
      &lt;input type=&quot;range&quot; id=&quot;epicycle-count-slider&quot; min=&quot;5&quot; max=&quot;80&quot; value=&quot;40&quot; step=&quot;5&quot;&gt;
      &lt;span id=&quot;epicycle-count-value&quot;&gt;40&lt;/span&gt;
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;p class=&quot;canvas-label&quot;&gt;More epicycles = better approximation&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;If you’ve followed this far, you’d have a fair understanding of how we used Fourier series to decompose a 2D drawing into two time-domain signals, approximated those signals using sine and cosine waves, and represented those waves as rotating vectors (epicycles) in the complex plane.&lt;/p&gt;
&lt;h4 id=&quot;the-mathematics-behind-epicycles&quot; tabindex=&quot;-1&quot;&gt;The Mathematics Behind Epicycles&lt;/h4&gt;
&lt;p&gt;For a closed curve sampled at &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;N&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.68333em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.68333em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; points &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;/msub&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;/msub&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;(x_k, y_k)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:-0.03588em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;, we calculate the Fourier coefficients:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;c&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mfrac&gt;&lt;mrow&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;/mrow&gt;&lt;/mfrac&gt;&lt;msubsup&gt;&lt;mo&gt;∑&lt;/mo&gt;&lt;mrow&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/msubsup&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;/msub&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;msub&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;/msub&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;msup&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mi&gt;π&lt;/mi&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;/&lt;/mi&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;/mrow&gt;&lt;/msup&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;c_n = \frac{1}{N} \sum_{k=0}^{N-1} (x_k + iy_k) e^{-2\pi i nk/N}
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1.8283360000000002em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:3.1304490000000005em;vertical-align:-1.302113em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base displaystyle textstyle uncramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord reset-textstyle displaystyle textstyle uncramped&quot;&gt;&lt;span class=&quot;sizing reset-size5 size5 reset-textstyle textstyle uncramped nulldelimiter&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mfrac&quot;&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.686em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle textstyle cramped&quot;&gt;&lt;span class=&quot;mord textstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.22999999999999998em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle textstyle uncramped frac-line&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.677em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle textstyle uncramped&quot;&gt;&lt;span class=&quot;mord textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size5 size5 reset-textstyle textstyle uncramped nulldelimiter&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mop op-limits&quot;&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:1.202113em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.000005000000000032756em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class=&quot;op-symbol large-op mop&quot;&gt;∑&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-1.250005em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:-0.03588em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:-0.413em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;π&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Each coefficient &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;msub&gt;&lt;mi&gt;c&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;c_n&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.43056em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.58056em;vertical-align:-0.15em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; can be converted to polar form:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Radius&lt;/strong&gt;: &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∣&lt;/mi&gt;&lt;msub&gt;&lt;mi&gt;c&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∣&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;|c_n|&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;∣&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;∣&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; (the size of the rotating circle)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Frequency&lt;/strong&gt;: &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;n&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.43056em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.43056em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; (how fast it rotates)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Phase&lt;/strong&gt;: &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;arg&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;c&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\arg(c_n)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mop&quot;&gt;ar&lt;span style=&quot;margin-right:0.01389em;&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; (where it starts)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At any time &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;t&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.61508em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.61508em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;, the position is:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;z&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;msubsup&gt;&lt;mo&gt;∑&lt;/mo&gt;&lt;mrow&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mi&gt;M&lt;/mi&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mi&gt;M&lt;/mi&gt;&lt;/mrow&gt;&lt;/msubsup&gt;&lt;msub&gt;&lt;mi&gt;c&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;/msub&gt;&lt;msup&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mrow&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mi&gt;π&lt;/mi&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/mrow&gt;&lt;/msup&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;z(t) = \sum_{n=-M}^{M} c_n e^{2\pi int}
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1.8283360000000002em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:3.1810030000000005em;vertical-align:-1.352667em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base displaystyle textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.04398em;&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mop op-limits&quot;&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:1.194336em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;M&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.000005000000000032756em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class=&quot;op-symbol large-op mop&quot;&gt;∑&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-1.250005em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;M&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.15em;margin-right:0.05em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:-0.413em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;π&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;where &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;M&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;M&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.68333em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.68333em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;M&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; is the number of terms used in the approximation, and &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;z&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;y&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;z(t) = x(t) + iy(t)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.04398em;&quot;&gt;z&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; represents the pen’s position in the complex plane.&lt;/p&gt;
&lt;h4 id=&quot;why-this-works&quot; tabindex=&quot;-1&quot;&gt;Why This Works&lt;/h4&gt;
&lt;p&gt;This technique works because:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Any periodic path&lt;/strong&gt; can be approximated by summing sinusoids&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rotating vectors&lt;/strong&gt; in the complex plane naturally create sinusoidal motion&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Adding vectors tip-to-tail&lt;/strong&gt; creates the epicycle visualization&lt;/li&gt;
&lt;li&gt;The more terms we include, the closer we get to the original drawing&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;generalizing-from-periodic-to-non-periodic-signals&quot; tabindex=&quot;-1&quot;&gt;Generalizing: From Periodic to Non-Periodic Signals&lt;/h3&gt;
&lt;p&gt;So far, we’ve treated your drawing as a &lt;strong&gt;periodic signal&lt;/strong&gt;—one complete cycle that the DFT assumes repeats infinitely. This is why closed curves work perfectly with epicycles.&lt;/p&gt;
&lt;p&gt;But what about signals that truly don’t repeat? A recording of your voice, a single burst of noise, or any one-time event?&lt;/p&gt;
&lt;h4 id=&quot;fourier-transform-for-non-periodic-signals&quot; tabindex=&quot;-1&quot;&gt;Fourier Transform for Non-Periodic Signals&lt;/h4&gt;
&lt;p&gt;The &lt;strong&gt;Fourier Transform&lt;/strong&gt; generalizes the Fourier series to non-periodic signals. Instead of discrete harmonics (1×, 2×, 3× the fundamental frequency), we now have a &lt;strong&gt;continuous spectrum&lt;/strong&gt; of all possible frequencies.&lt;/p&gt;
&lt;p&gt;Using complex exponential notation, the Fourier Transform is:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Forward Transform&lt;/strong&gt; (Signal → Frequency):&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;F&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;ω&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;msubsup&gt;&lt;mo&gt;∫&lt;/mo&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∞&lt;/mi&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∞&lt;/mi&gt;&lt;/mrow&gt;&lt;/msubsup&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;msup&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;ω&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/mrow&gt;&lt;/msup&gt;&lt;mspace width=&quot;0.16667em&quot;&gt;&lt;/mspace&gt;&lt;mi&gt;d&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;F(\omega) = \int_{-\infty}^{\infty} f(t) e^{-i\omega t} \, dt
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1.36em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:2.330581em;vertical-align:-0.970581em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base displaystyle textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.13889em;&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;ω&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;&lt;span class=&quot;op-symbol large-op mop&quot; style=&quot;margin-right:0.44445em;top:-0.0011249999999999316em;&quot;&gt;∫&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.91225em;margin-left:-0.44445em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;∞&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.974em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;∞&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:-0.41300000000000003em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;ω&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord mspace thinspace&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Inverse Transform&lt;/strong&gt; (Frequency → Signal):&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mfrac&gt;&lt;mrow&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mi&gt;π&lt;/mi&gt;&lt;/mrow&gt;&lt;/mfrac&gt;&lt;msubsup&gt;&lt;mo&gt;∫&lt;/mo&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∞&lt;/mi&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∞&lt;/mi&gt;&lt;/mrow&gt;&lt;/msubsup&gt;&lt;mi&gt;F&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;ω&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;msup&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mrow&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mi&gt;ω&lt;/mi&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;/mrow&gt;&lt;/msup&gt;&lt;mspace width=&quot;0.16667em&quot;&gt;&lt;/mspace&gt;&lt;mi&gt;d&lt;/mi&gt;&lt;mi&gt;ω&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;f(t) = \frac{1}{2\pi} \int_{-\infty}^{\infty} F(\omega) e^{i\omega t} \, d\omega
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1.36em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:2.330581em;vertical-align:-0.970581em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base displaystyle textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord reset-textstyle displaystyle textstyle uncramped&quot;&gt;&lt;span class=&quot;sizing reset-size5 size5 reset-textstyle textstyle uncramped nulldelimiter&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mfrac&quot;&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.686em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle textstyle cramped&quot;&gt;&lt;span class=&quot;mord textstyle cramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;π&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.22999999999999998em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle textstyle uncramped frac-line&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.677em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle textstyle uncramped&quot;&gt;&lt;span class=&quot;mord textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size5 size5 reset-textstyle textstyle uncramped nulldelimiter&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;&lt;span class=&quot;op-symbol large-op mop&quot; style=&quot;margin-right:0.44445em;top:-0.0011249999999999316em;&quot;&gt;∫&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.91225em;margin-left:-0.44445em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;∞&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.974em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;∞&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.13889em;&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;ω&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:-0.413em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;ω&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord mspace thinspace&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;ω&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;where:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;t&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;f(t)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; is the time-domain signal&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;F&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;ω&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;F(\omega)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.13889em;&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;ω&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; is the frequency-domain representation (a complex number with amplitude and phase)&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;ω&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\omega&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.43056em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.43056em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;ω&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; is the angular frequency&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The Fourier Transform is essential for analyzing non-repeating signals in audio processing, image filtering, and countless other applications.&lt;/p&gt;
&lt;h4 id=&quot;the-dft-sampled-and-periodic&quot; tabindex=&quot;-1&quot;&gt;The DFT: Sampled and Periodic&lt;/h4&gt;
&lt;p&gt;The &lt;strong&gt;Discrete Fourier Transform (DFT)&lt;/strong&gt; we used for drawings combines two properties:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Discrete&lt;/strong&gt;: Works with sampled points (not continuous functions)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Periodic&lt;/strong&gt;: Assumes the sample sequence repeats infinitely&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For a sequence of &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;N&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.68333em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.68333em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; samples &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;[&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mo&gt;]&lt;/mo&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;[&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;]&lt;/mo&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mo&gt;…&lt;/mo&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;[&lt;/mo&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mo&gt;]&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;x[0], x[1], \ldots, x[N-1]&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;minner&quot;&gt;…&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;X&lt;/mi&gt;&lt;mo&gt;[&lt;/mo&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;mo&gt;]&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;msubsup&gt;&lt;mo&gt;∑&lt;/mo&gt;&lt;mrow&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/msubsup&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;[&lt;/mo&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo&gt;]&lt;/mo&gt;&lt;mspace width=&quot;0.16667em&quot;&gt;&lt;/mspace&gt;&lt;msup&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mrow&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mi&gt;π&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;/&lt;/mi&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;/mrow&gt;&lt;/msup&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;X[k] = \sum_{n=0}^{N-1} x[n] \, e^{-i2\pi nk/N}
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1.8283360000000004em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:3.0954490000000003em;vertical-align:-1.267113em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base displaystyle textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.07847em;&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mop op-limits&quot;&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:1.1671129999999998em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.000005000000000143778em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class=&quot;op-symbol large-op mop&quot;&gt;∑&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-1.2500050000000003em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;mord mspace thinspace&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:-0.413em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;π&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Inverse DFT&lt;/strong&gt; (reconstructing the signal):&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;katex-display&quot;&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;x&lt;/mi&gt;&lt;mo&gt;[&lt;/mo&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mo&gt;]&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mfrac&gt;&lt;mrow&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;/mrow&gt;&lt;/mfrac&gt;&lt;msubsup&gt;&lt;mo&gt;∑&lt;/mo&gt;&lt;mrow&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/mrow&gt;&lt;mrow&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;/msubsup&gt;&lt;mi&gt;X&lt;/mi&gt;&lt;mo&gt;[&lt;/mo&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;mo&gt;]&lt;/mo&gt;&lt;mspace width=&quot;0.16667em&quot;&gt;&lt;/mspace&gt;&lt;msup&gt;&lt;mi&gt;e&lt;/mi&gt;&lt;mrow&gt;&lt;mi&gt;i&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mi&gt;π&lt;/mi&gt;&lt;mi&gt;n&lt;/mi&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;/&lt;/mi&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;/mrow&gt;&lt;/msup&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;x[n] = \frac{1}{N} \sum_{k=0}^{N-1} X[k] \, e^{i2\pi nk/N}
&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:1.8283360000000002em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:3.1304490000000005em;vertical-align:-1.302113em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base displaystyle textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord reset-textstyle displaystyle textstyle uncramped&quot;&gt;&lt;span class=&quot;sizing reset-size5 size5 reset-textstyle textstyle uncramped nulldelimiter&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mfrac&quot;&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.686em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle textstyle cramped&quot;&gt;&lt;span class=&quot;mord textstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.22999999999999998em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle textstyle uncramped frac-line&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.677em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle textstyle uncramped&quot;&gt;&lt;span class=&quot;mord textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;sizing reset-size5 size5 reset-textstyle textstyle uncramped nulldelimiter&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mop op-limits&quot;&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:1.202113em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.000005000000000032756em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class=&quot;op-symbol large-op mop&quot;&gt;∑&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-1.250005em;margin-left:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.07847em;&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;mord mspace thinspace&quot;&gt;&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:-0.413em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03588em;&quot;&gt;π&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Each &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;X&lt;/mi&gt;&lt;mo&gt;[&lt;/mo&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;mo&gt;]&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;X[k]&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.07847em;&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; decomposes into:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Amplitude&lt;/strong&gt;: &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∣&lt;/mi&gt;&lt;mi&gt;X&lt;/mi&gt;&lt;mo&gt;[&lt;/mo&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;mo&gt;]&lt;/mo&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;∣&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;msqrt&gt;&lt;mrow&gt;&lt;mi&gt;A&lt;/mi&gt;&lt;mo&gt;[&lt;/mo&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;msup&gt;&lt;mo&gt;]&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/msup&gt;&lt;mo&gt;+&lt;/mo&gt;&lt;mi&gt;B&lt;/mi&gt;&lt;mo&gt;[&lt;/mo&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;msup&gt;&lt;mo&gt;]&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/msup&gt;&lt;/mrow&gt;&lt;/msqrt&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;|X[k]| = \sqrt{A[k]^2 + B[k]^2}&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.9350050000000001em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1.24001em;vertical-align:-0.3050049999999999em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;∣&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.07847em;&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;∣&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sqrt mord&quot;&gt;&lt;span class=&quot;sqrt-sign&quot; style=&quot;top:-0.04500500000000007em;&quot;&gt;&lt;span class=&quot;style-wrap reset-textstyle textstyle uncramped&quot;&gt;&lt;span class=&quot;delimsizing size1&quot;&gt;√&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:1em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord textstyle cramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:-0.289em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.05017em;&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:-0.289em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;top:-0.855005em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:1em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle textstyle uncramped sqrt-line&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:1em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Phase&lt;/strong&gt;: &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;arg&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;X&lt;/mi&gt;&lt;mo&gt;[&lt;/mo&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;mo&gt;]&lt;/mo&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mi&gt;arctan&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mo&gt;−&lt;/mo&gt;&lt;mi&gt;B&lt;/mi&gt;&lt;mo&gt;[&lt;/mo&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;mo&gt;]&lt;/mo&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;/&lt;/mi&gt;&lt;mi&gt;A&lt;/mi&gt;&lt;mo&gt;[&lt;/mo&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;mo&gt;]&lt;/mo&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;\arg(X[k]) = \arctan(-B[k]/A[k])&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mop&quot;&gt;ar&lt;span style=&quot;margin-right:0.01389em;&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.07847em;&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;arctan&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;−&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.05017em;&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mord mathit&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;where &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;A&lt;/mi&gt;&lt;mo&gt;[&lt;/mo&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;mo&gt;]&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;A[k]&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;B&lt;/mi&gt;&lt;mo&gt;[&lt;/mo&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;mo&gt;]&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;B[k]&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.05017em;&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; are the cosine and sine components.&lt;/p&gt;
&lt;p&gt;The DFT is the foundation of all digital signal processing—analyzing digital audio, compressing images (JPEG), processing video, and more.&lt;/p&gt;
&lt;h2 id=&quot;fast-fourier-transform-fft&quot; tabindex=&quot;-1&quot;&gt;Fast Fourier Transform (FFT)&lt;/h2&gt;
&lt;p&gt;While our visualizations use the standard DFT algorithm shown above, &lt;strong&gt;real-world applications&lt;/strong&gt; use a much faster algorithm called the &lt;strong&gt;Fast Fourier Transform (FFT)&lt;/strong&gt;.&lt;/p&gt;
&lt;h4 id=&quot;the-performance-problem&quot; tabindex=&quot;-1&quot;&gt;The Performance Problem&lt;/h4&gt;
&lt;p&gt;The DFT we implemented has a critical limitation: &lt;strong&gt;computational complexity&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;For a signal with &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;N&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.68333em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.68333em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; points:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;DFT complexity&lt;/strong&gt;: &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;O&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;msup&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/msup&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;O(N^2)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8141079999999999em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1.064108em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.02778em;&quot;&gt;O&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:-0.363em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; operations
&lt;ul&gt;
&lt;li&gt;We loop through &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;N&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.68333em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.68333em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; frequencies&lt;/li&gt;
&lt;li&gt;For each frequency, we sum over &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;N&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.68333em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.68333em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; points&lt;/li&gt;
&lt;li&gt;Total: &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;msup&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/msup&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;N \times N = N^2&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8141079999999999em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.897438em;vertical-align:-0.08333em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;×&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:-0.363em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; operations&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; For a 1-second audio clip at 44,100 Hz (CD quality):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;4&lt;/mn&gt;&lt;mn&gt;4&lt;/mn&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;N = 44,100&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.68333em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.8777699999999999em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; samples&lt;/li&gt;
&lt;li&gt;DFT requires: &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;4&lt;/mn&gt;&lt;mn&gt;4&lt;/mn&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;msup&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/msup&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mi mathvariant=&quot;normal&quot;&gt;.&lt;/mi&gt;&lt;mn&gt;9&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;(44,100)^2 = 1.9&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.8141079999999999em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1.064108em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:-0.363em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;9&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; billion operations&lt;/li&gt;
&lt;li&gt;On a modern CPU: &lt;strong&gt;several seconds&lt;/strong&gt; to compute&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is &lt;strong&gt;too slow&lt;/strong&gt; for real-time applications like audio processing, video streaming, or live music visualizers.&lt;/p&gt;
&lt;h4 id=&quot;enter-the-fft&quot; tabindex=&quot;-1&quot;&gt;Enter the FFT&lt;/h4&gt;
&lt;p&gt;In 1965, Cooley and Tukey rediscovered an algorithm (originally found by Gauss in 1805) that computes the &lt;strong&gt;exact same result&lt;/strong&gt; as DFT, but much faster:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FFT complexity&lt;/strong&gt;: &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;O&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;mi&gt;log&lt;/mi&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;O(N \log N)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.02778em;&quot;&gt;O&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;lo&lt;span style=&quot;margin-right:0.01389em;&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; operations&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Same example (44,100 samples):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;FFT requires: &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mn&gt;4&lt;/mn&gt;&lt;mn&gt;4&lt;/mn&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mo&gt;×&lt;/mo&gt;&lt;msub&gt;&lt;mi&gt;log&lt;/mi&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;/msub&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mn&gt;4&lt;/mn&gt;&lt;mn&gt;4&lt;/mn&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;mo&gt;≈&lt;/mo&gt;&lt;mn&gt;7&lt;/mn&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;44,100 \times \log_2(44,100) \approx 700,000&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;mbin&quot;&gt;×&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;&lt;span class=&quot;mop&quot;&gt;lo&lt;span style=&quot;margin-right:0.01389em;&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:0.24444em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle cramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;≈&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; operations&lt;/li&gt;
&lt;li&gt;Speedup: &lt;strong&gt;2,700× faster&lt;/strong&gt; than DFT!&lt;/li&gt;
&lt;li&gt;On a modern CPU: &lt;strong&gt;milliseconds&lt;/strong&gt; instead of seconds&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;how-fft-works-intuition&quot; tabindex=&quot;-1&quot;&gt;How FFT Works (Intuition)&lt;/h4&gt;
&lt;p&gt;The FFT uses a &lt;strong&gt;divide-and-conquer&lt;/strong&gt; strategy:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Divide&lt;/strong&gt;: Split the signal into even and odd indexed samples&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Conquer&lt;/strong&gt;: Recursively compute FFT on each half&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Combine&lt;/strong&gt;: Merge the results using clever math&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The key insight: many of the calculations in DFT are &lt;strong&gt;redundant&lt;/strong&gt;. The FFT eliminates this redundancy by reusing intermediate results.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;// DFT: Computes everything from scratch&lt;/span&gt;
&lt;span class=&quot;hljs-keyword&quot;&gt;for&lt;/span&gt; (n &lt;span class=&quot;hljs-keyword&quot;&gt;in&lt;/span&gt; frequencies) {
    &lt;span class=&quot;hljs-keyword&quot;&gt;for&lt;/span&gt; (k &lt;span class=&quot;hljs-keyword&quot;&gt;in&lt;/span&gt; points) {
        &lt;span class=&quot;hljs-comment&quot;&gt;// N² operations total&lt;/span&gt;
    }
}

&lt;span class=&quot;hljs-comment&quot;&gt;// FFT: Divides work recursively&lt;/span&gt;
&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;FFT&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;points&lt;/span&gt;) {
    &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (points.&lt;span class=&quot;hljs-property&quot;&gt;length&lt;/span&gt; === &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;) &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; points;

    even = &lt;span class=&quot;hljs-title function_&quot;&gt;FFT&lt;/span&gt;(points[&lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot;&gt;2&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt;, ...]);  &lt;span class=&quot;hljs-comment&quot;&gt;// Recursion&lt;/span&gt;
    odd  = &lt;span class=&quot;hljs-title function_&quot;&gt;FFT&lt;/span&gt;(points[&lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot;&gt;3&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot;&gt;5&lt;/span&gt;, ...]);  &lt;span class=&quot;hljs-comment&quot;&gt;// Recursion&lt;/span&gt;

    &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;combine&lt;/span&gt;(even, odd);  &lt;span class=&quot;hljs-comment&quot;&gt;// N log N operations total&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Performance deep dive:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;For production systems, three details matter:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Power-of-two sizes&lt;/strong&gt;: FFT is fastest when &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;mo&gt;=&lt;/mo&gt;&lt;msup&gt;&lt;mn&gt;2&lt;/mn&gt;&lt;mi&gt;k&lt;/mi&gt;&lt;/msup&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;N = 2^k&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.849108em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.849108em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mord&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:-0.363em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.03148em;&quot;&gt;k&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; (e.g., 512, 1024, 2048). This is because the divide-and-conquer splits evenly at each level. Non-power-of-two sizes work but require different algorithms (Bluestein’s, mixed-radix) that are slower.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Iterative vs recursive&lt;/strong&gt;: The code above shows recursive FFT for clarity, but production libraries use &lt;strong&gt;iterative FFT&lt;/strong&gt; (bit-reversal + in-place butterfly operations). Why? Recursive FFT has function call overhead and poor cache locality. Iterative FFT processes data in cache-friendly sequential passes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Cache friendliness&lt;/strong&gt;: Modern FFT implementations (like FFTW) use clever memory layouts and loop tiling to keep data in L1/L2 cache. A well-tuned FFT is often &lt;strong&gt;an order of magnitude faster in practice&lt;/strong&gt; than a naive implementation, even with the same &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;O&lt;/mi&gt;&lt;mo&gt;(&lt;/mo&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;mi&gt;log&lt;/mi&gt;&lt;mi&gt;N&lt;/mi&gt;&lt;mo&gt;)&lt;/mo&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;O(N \log N)&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.02778em;&quot;&gt;O&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;mop&quot;&gt;lo&lt;span style=&quot;margin-right:0.01389em;&quot;&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10903em;&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; complexity.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is why audio buffer sizes are always powers of two (256, 512, 1024)—it’s not arbitrary, it’s for FFT performance!&lt;/p&gt;
&lt;h4 id=&quot;why-this-matters&quot; tabindex=&quot;-1&quot;&gt;Why This Matters&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;DFT is great for:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Learning and understanding Fourier analysis&lt;/li&gt;
&lt;li&gt;Small signals (&amp;lt; 1,000 points)&lt;/li&gt;
&lt;li&gt;Our interactive visualizations&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;FFT is essential for:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Audio processing&lt;/strong&gt;: Real-time effects, compression (MP3, AAC)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Image processing&lt;/strong&gt;: JPEG compression, filters, Instagram effects&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Video streaming&lt;/strong&gt;: Netflix, YouTube use FFT for compression&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Telecommunications&lt;/strong&gt;: 4G/5G networks, WiFi&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Medical imaging&lt;/strong&gt;: MRI and CT scans&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scientific computing&lt;/strong&gt;: Weather prediction, astronomy&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;libraries-and-implementation&quot; tabindex=&quot;-1&quot;&gt;Libraries and Implementation&lt;/h4&gt;
&lt;p&gt;Most programming languages provide optimized FFT libraries:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;// JavaScript (using Web Audio API)&lt;/span&gt;
&lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; fft = &lt;span class=&quot;hljs-keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;FFT&lt;/span&gt;(bufferSize);
fft.&lt;span class=&quot;hljs-title function_&quot;&gt;forward&lt;/span&gt;(audioData);  &lt;span class=&quot;hljs-comment&quot;&gt;// O(N log N) instead of O(N²)&lt;/span&gt;

&lt;span class=&quot;hljs-comment&quot;&gt;// Python (NumPy)&lt;/span&gt;
&lt;span class=&quot;hljs-keyword&quot;&gt;import&lt;/span&gt; numpy &lt;span class=&quot;hljs-keyword&quot;&gt;as&lt;/span&gt; np
frequencies = np.&lt;span class=&quot;hljs-property&quot;&gt;fft&lt;/span&gt;.&lt;span class=&quot;hljs-title function_&quot;&gt;fft&lt;/span&gt;(signal)  &lt;span class=&quot;hljs-comment&quot;&gt;// Uses FFTW library&lt;/span&gt;

&lt;span class=&quot;hljs-comment&quot;&gt;// MATLAB&lt;/span&gt;
X = &lt;span class=&quot;hljs-title function_&quot;&gt;fft&lt;/span&gt;(x);  &lt;span class=&quot;hljs-comment&quot;&gt;// Built-in FFT&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These libraries use highly optimized implementations like &lt;strong&gt;FFTW&lt;/strong&gt; (Fastest Fourier Transform in the West), which can be 100× faster than a naive FFT implementation.&lt;/p&gt;
&lt;p&gt;Equipped with this you can now go on to explore the vast west of signal processing. This new weaponry can help you build something cool, like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Implement noise reduction in sounds.&lt;/li&gt;
&lt;li&gt;Sharpen images with denoising.&lt;/li&gt;
&lt;li&gt;Create music visualizers that respond to audio frequencies.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr class=&quot;footnotes-sep&quot;&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;This article including the image retracing is inspired from &lt;a href=&quot;https://injuly.in/blog/fourier-series/&quot;&gt;injuly’s fourier series blog&lt;/a&gt;. &lt;a href=&quot;#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;“Reasonable” functions are those that are piecewise continuous and have a finite number of discontinuities within a period. Not every periodic function is representable in a strong sense. There are periodic functions that are so pathological that: 1.the Fourier series fails to converge at some points, or even 2. diverges almost everywhere. These exist (classic results by du Bois-Reymond, later strengthened by others). You won’t meet them in engineering, but mathematically they kill the fully-general “any periodic function” claim. &lt;a href=&quot;#fnref2&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;

            &lt;hr&gt;
            &lt;div class=&quot;footer&quot;&gt;
              &lt;i&gt;Feedback, Suggestions, Comments - &lt;/i&gt;
              &lt;div class=&quot;giscus-div&quot; id=&quot;comments&quot;&gt;
                &lt;script src=&quot;https://giscus.app/client.js&quot; data-repo=&quot;anubhavpgit/anubhavpgit.github.io&quot; data-repo-id=&quot;MDEwOlJlcG9zaXRvcnk0MDQ1ODEzMjc=&quot; data-category-id=&quot;DIC_kwDOGB1rz84Cer0j&quot; data-mapping=&quot;title&quot; data-strict=&quot;0&quot; data-reactions-enabled=&quot;1&quot; data-emit-metadata=&quot;0&quot; data-input-position=&quot;bottom&quot; data-theme=&quot;noborder_light&quot; data-lang=&quot;en&quot; data-loading=&quot;lazy&quot; crossorigin=&quot;anonymous&quot; async=&quot;&quot;&gt;&lt;/script&gt;
              &lt;/div&gt;
              Feel free to
              &lt;a id=&quot;mailtoLink&quot; href=&quot;mailto:anubhavp@duck.com?subject=Here&apos;s%20a%20suggestion/feedback!&quot;&gt;send
                me an email&lt;/a&gt;.
            &lt;/div&gt;
          &lt;/div&gt;
        </content:encoded>
            <subtitle>Decomposing periodic functions into their constituent frequencies, and analyzing the amplitude and phase of each frequency.</subtitle>
        </item>
        <item>
            <title><![CDATA[Conway's Game of Life]]></title>
            <description><![CDATA[Understanding computational models and implementing Conway's Game of Life using simple rules that mimic real-life population dynamics.]]></description>
            <link>https://anubhavp.dev/blog/gameoflife.html</link>
            <guid isPermaLink="true">https://anubhavp.dev/blog/gameoflife.html</guid>
            <dc:creator><![CDATA[Anubhab Patnaik]]></dc:creator>
            <pubDate>Tue, 12 Nov 2024 00:00:00 GMT</pubDate>
            <content:encoded>
          &lt;div class=&quot;content custom&quot;&gt;
            &lt;div class=&quot;search-container&quot;&gt;&lt;/div&gt;
            &lt;script type=&quot;module&quot; src=&quot;/assets/js/gameoflife/main.js&quot;&gt;&lt;/script&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.5.1/katex.min.css&quot;&gt;
&lt;h1 id=&quot;abstract-machines-and-the-computational-universe&quot; tabindex=&quot;-1&quot;&gt;Abstract machines and the computational universe&lt;/h1&gt;
&lt;p&gt;Automata theory is a branch of theoretical computer science that deals with abstract machines and the computational problems that can be solved using these machines. Automata are mathematical models of a machine that can perform certain computations. Essentialy, these are &lt;strong&gt;fundamental units of computation&lt;/strong&gt; that can process input and produce output based on a set of rules. They are used to model and analyze computational systems, study the limits of computation, and explore the properties of formal languages(sets of strings of symbols that can be recognized by automata).&lt;/p&gt;
&lt;p&gt;For example, this automaton can be thought of as a machine that processes input strings of 0s and 1s and produces an output based on a set of rules, such as:&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;mo&gt;:&lt;/mo&gt;&lt;mo&gt;{&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;msup&gt;&lt;mo&gt;}&lt;/mo&gt;&lt;mo&gt;∗&lt;/mo&gt;&lt;/msup&gt;&lt;mo&gt;→&lt;/mo&gt;&lt;mo&gt;{&lt;/mo&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;mo separator=&quot;true&quot;&gt;,&lt;/mo&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;msup&gt;&lt;mo&gt;}&lt;/mo&gt;&lt;mo&gt;∗&lt;/mo&gt;&lt;/msup&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;f: \{0, 1\}^* \rightarrow \{0, 1\}^*&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.75em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:1em;vertical-align:-0.25em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;&lt;span class=&quot;mclose&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:-0.363em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;∗&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;mrel&quot;&gt;→&lt;/span&gt;&lt;span class=&quot;mopen&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;mpunct&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mord mathrm&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;mclose&quot;&gt;&lt;span class=&quot;mclose&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;vlist&quot;&gt;&lt;span style=&quot;top:-0.363em;margin-right:0.05em;&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;reset-textstyle scriptstyle uncramped&quot;&gt;&lt;span class=&quot;mord&quot;&gt;∗&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;baseline-fix&quot;&gt;&lt;span class=&quot;fontsize-ensurer reset-size5 size5&quot;&gt;&lt;span style=&quot;font-size:0em;&quot;&gt;​&lt;/span&gt;&lt;/span&gt;​&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;where &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mi&gt;f&lt;/mi&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;f&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.69444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.8888799999999999em;vertical-align:-0.19444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathit&quot; style=&quot;margin-right:0.10764em;&quot;&gt;f&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; is a function that takes an input string of &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;0&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.64444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.64444em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;s and &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;1&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.64444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.64444em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;s and produces an output string of &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mn&gt;0&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;0&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.64444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.64444em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;s and &lt;span class=&quot;katex&quot;&gt;&lt;span class=&quot;katex-mathml&quot;&gt;&lt;math&gt;&lt;semantics&gt;&lt;mrow&gt;&lt;mn&gt;1&lt;/mn&gt;&lt;/mrow&gt;&lt;annotation encoding=&quot;application/x-tex&quot;&gt;1&lt;/annotation&gt;&lt;/semantics&gt;&lt;/math&gt;&lt;/span&gt;&lt;span class=&quot;katex-html&quot; aria-hidden=&quot;true&quot;&gt;&lt;span class=&quot;strut&quot; style=&quot;height:0.64444em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;strut bottom&quot; style=&quot;height:0.64444em;vertical-align:0em;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;base textstyle uncramped&quot;&gt;&lt;span class=&quot;mord mathrm&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;s, based on the following rules:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If the input string contains an odd number of 1s, the output string should be 1.&lt;/li&gt;
&lt;li&gt;If the input string contains an even number of 1s, the output string should be 0.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This automaton can be represented as a state machine, with states representing the number of 1s seen so far and transitions based on the input symbols. The machine starts in an initial state and transitions between states based on the input symbols, eventually reaching a final state that determines the output.&lt;/p&gt;
&lt;p&gt;In simpler terms, think of it this way: an automaton is the smallest part of a machine that can operate independently and perform a specific task. Breaking this unit further would lead us nowhere, as it is the smallest indivisible part of a machine that can perform a computation. Like, a gearbox in a car is an automaton that performs the task of changing gears, and it can’t be broken down further into smaller parts that perform any meaningful task.&lt;/p&gt;
&lt;h1 id=&quot;conways-game-of-life&quot; tabindex=&quot;-1&quot;&gt;Conway’s Game of Life&lt;/h1&gt;
&lt;p&gt;Building on automata theory, cellular automata are computational systems used to model complex systems and nonlinear dynamics. They are made up of simple, identical units called cells that evolve in parallel at discrete time steps. The state of each cell is determined by the states of its neighbouring cells, and the cells update their states based on a set of rules. Cellular automata have been used to study a wide range of phenomena, including biological systems, physical processes, and social dynamics.&lt;/p&gt;
&lt;p&gt;A fascinating aspect of cellular automata is their ability to exhibit complex and unpredictable behaviour from simple rules that mimic real-life population dynamics. Conway’s Game of Life is a simple cellular automaton devised by the British mathematician John Horton Conway in 1970. It is a zero-player game, meaning that its evolution is determined by its initial state, requiring no further input. One interacts with the Game of Life by creating an initial configuration and observing how it evolves. Specifically, the game explores how simple rules governing individual cells can lead to emergent complexity and patterns over time, including stable structures, oscillating patterns, and even patterns that exhibit motion.&lt;/p&gt;
&lt;p&gt;A few rules govern the evolution of the game are as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Any live cell with fewer than two live neighbours dies, as if by underpopulation.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;container&quot; style=&quot;display: flex; align-items: center; justify-content: center; text-align: center;&quot;&gt;
    &lt;canvas id=&quot;lessthantwo&quot; style=&quot;border: 1px solid black;&quot;&gt;
    &lt;/canvas&gt;
    &lt;span style=&quot;padding: 10px; color: black !important;&quot;&gt;
 --&amp;gt;
    &lt;/span&gt;
    &lt;canvas id=&quot;lessthantwodead&quot; style=&quot;border: 1px solid black;&quot;&gt;
    &lt;/canvas&gt;
&lt;/div&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Any live cell with two or three live neighbours lives on to the next generation.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;container&quot; style=&quot;display: flex; align-items: center; justify-content: center; text-align: center;&quot;&gt;
    &lt;canvas id=&quot;twoorthree&quot; style=&quot;border: 1px solid black;&quot;&gt;
    &lt;/canvas&gt;
    &lt;span style=&quot;padding: 10px; color: black !important;&quot;&gt;
 --&amp;gt;
    &lt;/span&gt;
    &lt;canvas id=&quot;twoorthreelive&quot; style=&quot;border: 1px solid black;&quot;&gt;
    &lt;/canvas&gt;
&lt;/div&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;Any live cell with more than three live neighbours dies, as if by overpopulation.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;container&quot; style=&quot;display: flex; align-items: center; justify-content: center; text-align: center;&quot;&gt;
    &lt;canvas id=&quot;morethanthree&quot; style=&quot;border: 1px solid black;&quot;&gt;
    &lt;/canvas&gt;
    &lt;span style=&quot;padding: 10px; color: black !important;&quot;&gt;
 --&amp;gt;
    &lt;/span&gt;
    &lt;canvas id=&quot;morethanthreedead&quot; style=&quot;border: 1px solid black;&quot;&gt;
    &lt;/canvas&gt;
&lt;/div&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;container&quot; style=&quot;display: flex; align-items: center; justify-content: center; text-align: center;&quot;&gt;
    &lt;canvas id=&quot;three&quot; style=&quot;border: 1px solid black;&quot;&gt;
    &lt;/canvas&gt;
    &lt;span style=&quot;padding: 10px; color: black !important;&quot;&gt;
 --&amp;gt;
    &lt;/span&gt;
    &lt;canvas id=&quot;threelive&quot; style=&quot;border: 1px solid black;&quot;&gt;
    &lt;/canvas&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;p&gt;The game is played on a two-dimensional grid of cells, each of which can be in one of two states: alive or dead. The game proceeds in discrete steps, with each step representing a generation of cells. At each step, the game applies the rules to each cell in the grid simultaneously, updating the grid to reflect the new state of each cell based on its current state and the states of its neighbours.&lt;/p&gt;
&lt;h1 id=&quot;the-game-of-life-in-action&quot; tabindex=&quot;-1&quot;&gt;The Game of Life in Action&lt;/h1&gt;
&lt;div style=&quot;text-align: start; width: 100%;&quot;&gt;
    &lt;button id=&quot;reset&quot;&gt;Reset&lt;/button&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;div class=&quot;container&quot; style=&quot;display: flex; align-items: center; justify-content: center; text-align: center;&quot;&gt;
&lt;canvas id=&quot;game-of-life&quot; style=&quot;border: 1px solid black;&quot;&gt;
&lt;/canvas&gt;
&lt;/div&gt;
&lt;div class=&quot;container&quot; style=&quot;display: flex; flex-direction: column; align-items: center; justify-content: center; margin-top: 20px;&quot;&gt;
    &lt;input type=&quot;range&quot; id=&quot;grid-slider&quot; name=&quot;speed&quot; min=&quot;5&quot; max=&quot;15&quot; value=&quot;10&quot;&gt;
    &lt;label for=&quot;speed&quot; style=&quot;margin-top: 10px;&quot;&gt;Grid&lt;/label&gt;
    &lt;span id=&quot;time&quot; style=&quot;margin-top: 10px;&quot;&gt;&lt;/span&gt;
    &lt;span id=&quot;population&quot; style=&quot;margin-top: 10px;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;div class=&quot;container&quot; style=&quot;display: flex; align-items: center; justify-content: start; margin-top: 20px;&quot;&gt;
    &lt;label for=&quot;speed&quot; style=&quot;margin-right: 10px;&quot;&gt;Speed &lt;/label&gt;
    &lt;input type=&quot;range&quot; id=&quot;speed-slider&quot; name=&quot;speed&quot; min=&quot;1&quot; max=&quot;10&quot; value=&quot;1&quot;&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;div&gt;
    &lt;button id=&quot;start-stop&quot; style=&quot;margin-right: 10px;&quot;&gt;Start&lt;/button&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;p&gt;&lt;strong&gt;Generations&lt;/strong&gt;: &lt;span id=&quot;generation&quot;&gt;0&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;To start, design your initial configuration by clicking on the cells to toggle their state. Once you’re ready, click the “Start/Stop” button to watch the game evolve. You can pause the game at any time by clicking the “Stop” button, and clear the grid by clicking the “Clear” button.&lt;/p&gt;
&lt;p&gt;The speed of the game can be adjusted by changing the &lt;code&gt;speed&lt;/code&gt; slider. The game will evolve at a faster pace as the slider is moved to the right. The &lt;code&gt;grid&lt;/code&gt; slider can be used to adjust the size of the grid, allowing for larger or smaller configurations.&lt;/p&gt;
&lt;h1 id=&quot;a-turing-complete-machine&quot; tabindex=&quot;-1&quot;&gt;A Turing Complete Machine&lt;/h1&gt;
&lt;p&gt;This might seem cool; just a game, right? It’s more interesting than that. To explain why, I would have to make your brain hurt a little bit more.&lt;/p&gt;
&lt;p&gt;Automata like these can be classified into two main categories: finite automata( finite states, finite memory) and infinite automata(infinite states, infinite memory). For example, a finite automaton can be used to recognize whether a given input string is a valid email address or a phone number(A &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions&quot;&gt;regular expression&lt;/a&gt;). Infinite automata are more complex and powerful. For example, an infinite automaton can be used to recognize whether a given input string is a valid programming language statement or a mathematical expression. (Compilers and interpreters). Game of Life is a prime example of an infinite automaton, as it can simulate complex systems and exhibit infinite states from a fixed configuration.&lt;/p&gt;
&lt;p&gt;Finite automata can be further classified into:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Deterministic Finite Automata (DFA): A determined outcome for a given input.&lt;/li&gt;
&lt;li&gt;Non-Deterministic Finite Automata (NFA): Various outcomes for a given input.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;However, both DFA and NFA:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Operate on a finite amount of memory (the states).&lt;/li&gt;
&lt;li&gt;Can only make decisions based on the current state and the immediate input.&lt;/li&gt;
&lt;li&gt;Cannot handle languages that require unbounded memory, like those involving nested structures or long-term dependencies.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To solve these issues, a Pushdown Automaton (PDA) was introduced. A PDA is an automaton with a &lt;strong&gt;stack&lt;/strong&gt; that can store an unbounded amount of memory. It can push and pop symbols onto the stack, allowing it to handle &lt;strong&gt;context-free languages&lt;/strong&gt;( languages that can be described by context-free grammar; languages powerful enough to describe many programming language constructs, such as nested structures (e.g., balanced parentheses, if-else blocks)) that require more complex memory access. Simply put, a PDA can recognize languages that a DFA or NFA cannot, making it a more powerful model of computation.&lt;/p&gt;
&lt;p&gt;Bear with me, this useless information will make sense in a bit; I promise. The concepts of FSMs lay the groundwork for understanding why this cellular automaton is such a fascinating piece of work by this brilliant British mathematician.&lt;/p&gt;
&lt;p&gt;However, a PDA still has limitations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The stack provides memory, but it’s limited in structure (LIFO- Last in First Out).&lt;/li&gt;
&lt;li&gt;It can’t handle languages requiring more general or unbounded memory access.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This led to the development of the Turing Machine, a theoretical model of computation that can simulate any algorithm or computation that can be performed by a digital computer. A Turing machine consists of an infinite tape divided into cells, a read/write head that can move left or right along the tape and a finite set of states. The machine can read the symbol on the current cell, write a new symbol, move the tape left or right, and change its state based on a set of rules.&lt;/p&gt;
&lt;p&gt;Turing Machine is the pinnacle of computation, as it laid the foundation for modern computers and computational theory. It can, in theory, solve any computational problem that can be solved by a digital computer, making it a universal model of computation. Whatever we see today, from the smallest microcontroller to the most powerful supercomputers, satelite systems, and AI, all are based on the principles of the Turing Machine.&lt;/p&gt;
&lt;p&gt;The Game of Life has been shown to be Turing complete, meaning it can simulate any computation that a Turing machine can perform, given the right initial conditions. Certain configurations in the Game of Life can be used to simulate logic gates, memory, and other components of a computer, demonstrating its computational universality and performing universal computation, making it a fascinating area of study for computer scientists and mathematicians alike. It has been studied extensively by computer scientists, mathematicians, and physicists, and has been used to explore a wide range of topics, including complexity theory, artificial life, and emergent behaviour.&lt;/p&gt;
&lt;h2 id=&quot;building-a-cpu-in-the-game-of-life&quot; tabindex=&quot;-1&quot;&gt;Building A CPU in the Game of Life&lt;/h2&gt;
&lt;p&gt;Having come this far, let’s attempt to build a CPU in the Game of Life. A CPU essentially is built up of three main components:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ALU (Arithmetic Logic Unit): Performs arithmetic and logical operations on data.&lt;/li&gt;
&lt;li&gt;Memory: Stores data and instructions that are currently being executed by the CPU.&lt;/li&gt;
&lt;li&gt;Control Unit: Manages the CPU’s operations by directing data between the ALU, memory, and I/O devices.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;arithmetic-logic-unit&quot; tabindex=&quot;-1&quot;&gt;Arithmetic Logic Unit&lt;/h3&gt;
&lt;p&gt;The &lt;strong&gt;ALU&lt;/strong&gt; is responsible for performing arithmetic and logical operations on data. It consists of a number of logic gates, adders, and other components that work together to perform operations such as addition, subtraction, AND, OR, and NOT.&lt;/p&gt;
&lt;div class=&quot;container&quot; style=&quot;display: flex; align-items: center; justify-content: center; text-align: center;&quot;&gt;
    &lt;div style=&quot;margin: 10px;&quot;&gt;
        &lt;canvas id=&quot;alu-addition&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/canvas&gt;
        &lt;div&gt;Adder Circuit&lt;/div&gt;
    &lt;/div&gt;
    &lt;div style=&quot;margin: 10px;&quot;&gt;
        &lt;canvas id=&quot;alu-andgate&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/canvas&gt;
        &lt;div&gt;AND Gate&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In addition, you can set up a glider collision that represents the addition of two binary values. Each glider can be thought of as representing a binary input (either 0 or 1). The gliders in this pattern are designed to approach each other from opposite directions. When two gliders collide, they interact to produce an output, which can be interpreted as the sum of the two inputs. This collision represents the addition of two binary values, with the output glider moving in a different direction depending on the inputs.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If only one glider is present (input 1 + 0 or 0 + 1), it moves through without a collision, representing a result of 1.&lt;/li&gt;
&lt;li&gt;If two gliders collide (input 1 + 1), they create a predictable pattern that can represent the sum of these inputs, often leaving behind a specific “output” glider that can represent the result.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Similarly, An AND gate can be created by positioning still-life patterns (static configurations that do not change) to manipulate gliders. If both inputs are “1” (represented by gliders arriving simultenously), they will interact to produce an output.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If both gliders arrive at the interaction point simultaneously, they will interact in a way that produces a specific pattern, representing the output 1 for an AND operation.&lt;/li&gt;
&lt;li&gt;If only one glider arrives, it will pass through or interact with other cells without producing the 1 pattern, representing an output of 0.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;memory-unit&quot; tabindex=&quot;-1&quot;&gt;Memory Unit&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Memory Unit&lt;/strong&gt; stores data and instructions that are currently being executed by the CPU. It consists of registers, cache, and main memory. It is responsible for storing and retrieving data from memory locations.&lt;/p&gt;
&lt;h4 id=&quot;blinker&quot; tabindex=&quot;-1&quot;&gt;Blinker&lt;/h4&gt;
&lt;div class=&quot;container&quot; style=&quot;display: flex; align-items: center; justify-content: center; text-align: center;&quot;&gt;
    &lt;div style=&quot;margin: 10px;&quot;&gt;
        &lt;canvas id=&quot;memory&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/canvas&gt;
        &lt;div&gt;Memory Cell(1 block)&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This configuration is a 3x3 blinker, which oscillates between two shapes in two generations. Its oscillation does not spread or decay, so it remains contained and stable in its oscillating state.&lt;/p&gt;
&lt;p&gt;Memory can be represented by stable patterns that remain constant unless disturbed by an external glider or oscillator. Stable patterns like blocks act as “bits” that can be toggled on or off by gliders, representing data storage. These two states can represent binary values (0 and 1) in a very simplistic way, with each state encoding one bit of information depending on its phase. This stability in position and periodic change makes it suitable for acting as a memory cell, as it reliably returns to a known state every two generations.&lt;/p&gt;
&lt;p&gt;Similarly, an external pattern could be designed to change or “write” to the memory cell, altering its oscillation phase to represent a different binary state.&lt;/p&gt;
&lt;h3 id=&quot;control-unit&quot; tabindex=&quot;-1&quot;&gt;Control Unit&lt;/h3&gt;
&lt;p&gt;The control unit manages the CPU’s operations by directing data between the ALU, memory, and I/O devices. It fetches and decodes instructions, then signals the ALU and memory to execute.&lt;/p&gt;
&lt;div class=&quot;container&quot; style=&quot;display: flex; align-items: center; justify-content: center; text-align: center;&quot;&gt;
    &lt;div style=&quot;margin: 10px;&quot;&gt;
        &lt;canvas id=&quot;control&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/canvas&gt;
        &lt;div&gt;Control Unit&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This pattern is designed to function as a control unit by leveraging the behavior of known oscillators and spaceships in the Game of Life to produce predictable and repeatable outcomes. The pattern includes configurations that will evolve into gliders, which are small patterns that move across the grid over successive generations. Gliders can be used to transmit information or interact with other patterns in the grid.&lt;/p&gt;
&lt;h4 id=&quot;glider-gun&quot; tabindex=&quot;-1&quot;&gt;Glider gun&lt;/h4&gt;
&lt;p&gt;A glider gun is a configuration of cells that emits gliders at regular intervals. It can be used to create a clock signal that controls the timing of operations in the CPU.&lt;/p&gt;
&lt;div class=&quot;container&quot; style=&quot;display: flex; align-items: center; justify-content: center; text-align: center;&quot;&gt;
    &lt;div style=&quot;margin: 10px;&quot;&gt;
        &lt;canvas id=&quot;glider&quot; style=&quot;border: 0.2px solid black;&quot;&gt;&lt;/canvas&gt;
        &lt;div&gt;Glider Gun&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;A single block here can represent ‘1’ and an empty cell can represent ‘0’. The glider gun emits gliders at regular intervals, which can be used to synchronize the operations of the CPU. These inputs can work with adders, logic gates, and memory cells to perform ALU operations, store data, and control the flow of information within the CPU.&lt;/p&gt;
&lt;h2 id=&quot;a-fully-functional-computer&quot; tabindex=&quot;-1&quot;&gt;A Fully Functional Computer&lt;/h2&gt;
&lt;p&gt;To build a fully functional computer, you would need to design and implement a wide range of components, including registers, multiplexers, and arithmetic logic units, and connect them to form a complete system. Some of the components you would need to build include:&lt;/p&gt;
&lt;p&gt;ALU components:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Adders (Half and Full- they can be used to add binary numbers) &lt;a href=&quot;#arithmetic-logic-unit&quot;&gt;⏎&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Logic Gates (AND, OR, NOT, XOR, etc.- they perform logical operations on binary inputs) &lt;a href=&quot;#arithmetic-logic-unit&quot;&gt;⏎&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Multiplexers( MUX- they select one of many inputs and route it to the output, used to handle multiple data inputs and control signals)&lt;/li&gt;
&lt;li&gt;Registers( they store data temporarily during processing and can be used to store intermediate results)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Memory components:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Flip-Flops (they store a single bit of data using feedback) &lt;a href=&quot;#memory-unit&quot;&gt;⏎&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;RAM (Random Access Memory- they store data that can be read and written to used for storing data and instructions specific to the program)&lt;/li&gt;
&lt;li&gt;ROM (Read-Only Memory- they store data that can only be read from- used for storing fixed data and instructions that do not change)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Control Unit components:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Finite State Machines (FSM- they have a finite number of states and transition between states based on inputs) &lt;a href=&quot;#control-unit&quot;&gt;⏎&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Clock Signals (they provide a timing mechanism for the CPU, controlling the rate at which operations are performed- using glider guns) &lt;a href=&quot;#control-unit&quot;&gt;⏎&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Instruction Decoders (they interpret instructions and direct the flow of data within the CPU)&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;next&quot; tabindex=&quot;-1&quot;&gt;Next&lt;/h1&gt;
&lt;p&gt;While it is theoretically possible to build a computer within the Game of Life, it is painstakingly complex and fun! It requires a deeper understanding of logic gates, instruction sets, implementing memory, and control units.&lt;/p&gt;
&lt;p&gt;Building the CPU would take you to combine these components to carry out fully functional operations. It would be a fun and challenging project to undertake, requiring a deep understanding of digital logic and computer architecture. The Game of Life serves as a fascinating model of how complexity can arise from simplicity, providing insight into topics such as self-organization, emergence, and cellular automata theory.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://nicholas.carlini.com/writing/2021/unlimited-register-machine-game-of-life.html&quot;&gt;Here’s an actual CPU built in the Game of Life by Nicholas Carlini&lt;/a&gt;. In this series of posts, he tries to explain how he built digital logic gates, multiplexers, and registers in the Game of Life. I would love to do this someday when NYU is not down my throat threatening to kick me out for not doing my assignments.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;If you choose carefully enough, you can make an entire computer inside the game, powered entirely by little things running around based only on those same simple rules of what lives and what dies in the next generation. An entire computer that could, in theory, perform any calculation that your computer could. It’s an interesting mathematical diversion depicting Turing’s completeness, the chaos that arises from simple rules, and it just looks pretty.&lt;/em&gt;&quot;&lt;/p&gt;
&lt;p&gt;- Reddit&lt;/p&gt;
&lt;p&gt;Also, someone built a &lt;a href=&quot;https://www.youtube.com/watch?v=xP5-iIeKXE8&quot;&gt;Game of Life inside a computer built on top of THE GAME OF LIFE!!&lt;/a&gt;&lt;/p&gt;

            &lt;hr&gt;
            &lt;div class=&quot;footer&quot;&gt;
              &lt;i&gt;Feedback, Suggestions, Comments - &lt;/i&gt;
              &lt;div class=&quot;giscus-div&quot; id=&quot;comments&quot;&gt;
                &lt;script src=&quot;https://giscus.app/client.js&quot; data-repo=&quot;anubhavpgit/anubhavpgit.github.io&quot; data-repo-id=&quot;MDEwOlJlcG9zaXRvcnk0MDQ1ODEzMjc=&quot; data-category-id=&quot;DIC_kwDOGB1rz84Cer0j&quot; data-mapping=&quot;title&quot; data-strict=&quot;0&quot; data-reactions-enabled=&quot;1&quot; data-emit-metadata=&quot;0&quot; data-input-position=&quot;bottom&quot; data-theme=&quot;noborder_light&quot; data-lang=&quot;en&quot; data-loading=&quot;lazy&quot; crossorigin=&quot;anonymous&quot; async=&quot;&quot;&gt;&lt;/script&gt;
              &lt;/div&gt;
              Feel free to
              &lt;a id=&quot;mailtoLink&quot; href=&quot;mailto:anubhavp@duck.com?subject=Here&apos;s%20a%20suggestion/feedback!&quot;&gt;send
                me an email&lt;/a&gt;.
            &lt;/div&gt;
          &lt;/div&gt;
        </content:encoded>
            <subtitle>Understanding computational models and implementing Conway&apos;s Game of Life using simple rules that mimic real-life population dynamics.</subtitle>
        </item>
        <item>
            <title><![CDATA[Docking Compilers]]></title>
            <description><![CDATA[Understanding compilers and building binary interpreters for machine code in RISC-V in Hacktoberfest.]]></description>
            <link>https://anubhavp.dev/blog/hacktoberfest.html</link>
            <guid isPermaLink="true">https://anubhavp.dev/blog/hacktoberfest.html</guid>
            <dc:creator><![CDATA[Anubhab Patnaik]]></dc:creator>
            <pubDate>Thu, 12 Dec 2024 00:00:00 GMT</pubDate>
            <content:encoded>
          &lt;div class=&quot;content custom&quot;&gt;
            &lt;div class=&quot;search-container&quot;&gt;&lt;/div&gt;
            &lt;script type=&quot;module&quot; src=&quot;/assets/js/yatch/main.js&quot;&gt;&lt;/script&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;/assets/css/yatch/style.css&quot;&gt;
&lt;p&gt;This post is the first post in a series of posts on compilers and interpreters. The second post, &lt;a href=&quot;../blog/ferryman.html&quot;&gt;The Ferryman&lt;/a&gt;, introduces compiling high-level languages into machine code instructions, and we attempt at building a working C compiler for RISC-V. This post will delve deeper into the next part; understanding how CPUs execute machine code instructions.&lt;/p&gt;
&lt;p&gt;Hacktoberfest is a fantastic opportunity to dive into the world of open source, make meaningful contributions, and sharpen your dev skills. This year, I’m most excited about &lt;a href=&quot;#current-yatch&quot;&gt;Yatch&lt;/a&gt;: a machine code interpreter for RISC-V written in C++.&lt;/p&gt;
&lt;h3 id=&quot;table-of-contents&quot; tabindex=&quot;-1&quot;&gt;Table of Contents&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#compiling-high-level-languages&quot;&gt;Recap&lt;/a&gt;: A brief overview of how high-level languages are compiled into machine code.
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#machine-code&quot;&gt;Machine Code&lt;/a&gt;: Compiled code that the CPU can execute.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#computer-architecture&quot;&gt;Computer Architecture&lt;/a&gt;: Understanding the components of a computer system. Why are compilers CPU-specific, while interpreters are not?
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#risc-v-isa&quot;&gt;RISC-V ISA&lt;/a&gt;: A brief overview of the RISC-V ISA.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#instruction-decoder&quot;&gt;Instruction decoder&lt;/a&gt;: A tool to decode RISC-V instructions.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#yatch&quot;&gt;Yatch&lt;/a&gt;: A machine code interpreter for RISC-V written in C++.
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#walkthrough&quot;&gt;Walkthrough&lt;/a&gt;: Compiling Yatch and executing instructions.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#1-single-stage-pipeline&quot;&gt;Single Stage Pipeline&lt;/a&gt;: A simple interpretation of how CPUs execute instructions.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-five-stage-pipeline&quot;&gt;Five-Stage Pipeline&lt;/a&gt;: A real simulation of how CPUs execute instructions.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;compiling-high-level-languages&quot; tabindex=&quot;-1&quot;&gt;Compiling High-Level Languages&lt;/h1&gt;
&lt;p&gt;Compilers and interpreters are tools that convert high-level programming languages into machine code instructions that the CPU can execute. Compilers translate the entire program into machine code before execution, while interpreters translate and execute the program line by line.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;hljs-type&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;()&lt;/span&gt;{
  &lt;span class=&quot;hljs-built_in&quot;&gt;printf&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&quot;Hello, World!&quot;&lt;/span&gt;);
  &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here’s a brief overview of GCC would compile this program:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Preprocessing&lt;/strong&gt;: The compiler processes the &lt;code&gt;#include&lt;/code&gt; directive and includes the contents of the &lt;code&gt;stdio.h&lt;/code&gt; header file into the program. It also handles macros and other preprocessor directives.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Preprocessed Code:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;hljs-type&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;()&lt;/span&gt;{
  &lt;span class=&quot;hljs-built_in&quot;&gt;printf&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&quot;Hello, World!&quot;&lt;/span&gt;);
  &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;&lt;strong&gt;Lexical Analysis&lt;/strong&gt;: The compiler breaks the preprocessed code into tokens. It reads the program character by character and groups them into tokens like keywords, identifiers, literals, operators, and punctuation.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;Tokens: &lt;code&gt;int&lt;/code&gt;, &lt;code&gt;main&lt;/code&gt;, &lt;code&gt;(&lt;/code&gt;, &lt;code&gt;)&lt;/code&gt;, &lt;code&gt;{&lt;/code&gt;, &lt;code&gt;printf&lt;/code&gt;, &lt;code&gt;(&lt;/code&gt;, &lt;code&gt;&quot;Hello, World!&quot;&lt;/code&gt;, &lt;code&gt;)&lt;/code&gt;, &lt;code&gt;;&lt;/code&gt;, &lt;code&gt;return&lt;/code&gt;, &lt;code&gt;0&lt;/code&gt;, &lt;code&gt;;&lt;/code&gt;, &lt;code&gt;}&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;&lt;strong&gt;Syntax Analysis&lt;/strong&gt;: The compiler checks if the sequence of tokens follows the grammatical rules of C. It builds a parse tree (or abstract syntax tree) representing the program’s structure.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;FunctionDefinition
├── ReturnType: int
├── FunctionName: main
├── Parameters: ( )
└── Body:
    ├── ExpressionStatement: printf(&quot;Hello, World!&quot;);
    └── ReturnStatement: return 0;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;&lt;strong&gt;Semantic Analysis&lt;/strong&gt;: The compiler checks the program for semantic correctness. This includes type checking, verifying that functions and variables are declared before use, and ensuring that operations are valid for the given data types.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;printf&lt;/span&gt; is declared in stdio.h and is correctly used.
The &lt;span class=&quot;hljs-built_in&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;Hello, World!&quot;&lt;/span&gt; is a valid argument.
The main function correctly returns an integer.
&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;5&quot;&gt;
&lt;li&gt;&lt;strong&gt;Intermediate Code Generation&lt;/strong&gt;: TThe compiler generates an intermediate representation (IR) of the program. GCC uses internal representations like GIMPLE and RTL.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;// This is a simplified illustration&lt;/span&gt;
function &lt;span class=&quot;hljs-title function_&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;()&lt;/span&gt;
{
  tmp0 = &lt;span class=&quot;hljs-string&quot;&gt;&quot;Hello, World!&quot;&lt;/span&gt;;
  call &lt;span class=&quot;hljs-title function_&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;(tmp0)&lt;/span&gt;;
  &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;6&quot;&gt;
&lt;li&gt;&lt;strong&gt;Optimization&lt;/strong&gt;: The compiler optimizes the intermediate code to improve performance. It may remove redundant code, simplify expressions, and reorder instructions.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;function &lt;span class=&quot;hljs-title function_&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;()&lt;/span&gt;
{
  call &lt;span class=&quot;hljs-title function_&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&quot;Hello, World!&quot;&lt;/span&gt;)&lt;/span&gt;;
  &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;7&quot;&gt;
&lt;li&gt;&lt;strong&gt;Code Generation&lt;/strong&gt;: The compiler generates assembly code from the optimized intermediate code. This code is specific to the target CPU architecture.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Assembly Code (Simplified x86-64 Example):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-assembly&quot;&gt;    .section .rodata
.LC0:
    .string &quot;Hello, World!&quot;

    .text
    .globl main
main:
    push    %rbp
    mov     %rsp, %rbp
    lea     .LC0(%rip), %rdi
    call    puts
    mov     $0, %eax
    pop     %rbp
    ret
&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;8&quot;&gt;
&lt;li&gt;&lt;strong&gt;Assembly and Linking&lt;/strong&gt;:&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Assembly&lt;/strong&gt;: The assembler converts the assembly code into object code (machine code in binary form).&lt;br&gt;
&lt;strong&gt;Linking&lt;/strong&gt;: The linker combines object code with libraries to produce the final executable.&lt;/p&gt;
&lt;p&gt;For example, for the x86-64 architecture, the conversion in hexadecimal would look like:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# Data Section (.rodata):&lt;/span&gt;
01001000 01100101 01101100 01101100 01101111 00101100 00100000 01010111 01101111 01110010 01101100 01100100 00100001 00000000

&lt;span class=&quot;hljs-comment&quot;&gt;# Text Section (.text):&lt;/span&gt;
01010101 01010101 01010101 01010101 : push %rbp
01001000 10001001 11100101 : mov %rsp, %rbp
01001000 10001101 00111101 **** **** **** **** : lea .LC0(%rip), %rdi
11101000 **** **** **** **** : call puts
10111000 00000000 00000000 00000000 00000000  : mov &lt;span class=&quot;hljs-variable&quot;&gt;$0&lt;/span&gt;, %eax
01011101 : pop %rbp
11000011 : ret
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;GCC uses intermediate representations during compilation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GIMPLE: A simplified, language-independent representation that makes it easier to perform optimizations.&lt;/li&gt;
&lt;li&gt;RTL (Register Transfer Language): A lower-level representation closer to assembly, used for target-specific optimizations and code generation.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;While, interpreters translate and execute the program line by line. The interpreter:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;reads the source code line by line,&lt;/li&gt;
&lt;li&gt;translates it into machine code (or bytecode in HLLs),&lt;/li&gt;
&lt;li&gt;translates bytecode into machine code and runs it in a virtual machine.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This allows for dynamic typing, interactive debugging, and easier integration with other languages. However, interpreters are generally slower than compilers because they don’t optimize the entire program before execution.&lt;/p&gt;
&lt;p&gt;I will finish up a &lt;a href=&quot;https://anubhavp.dev/posts/ferryman&quot;&gt;detailed post on a C compiler&lt;/a&gt; soon. This post is an intriduction to the next part of the series, a machine code interpreter for RISC-V.&lt;/p&gt;
&lt;h2 id=&quot;machine-code&quot; tabindex=&quot;-1&quot;&gt;Machine Code&lt;/h2&gt;
&lt;p&gt;The above generated binary code is run as instructions on the CPU. The CPU executes these instructions in a sequence, and the program runs. The CPU has a set of instructions it can execute, known as the instruction set architecture (ISA). The ISA defines the instructions the CPU can execute, the registers it uses, and the memory model it follows. For example, an instruction might look like &lt;code&gt;00000000000000000000000010000011&lt;/code&gt;, which translates to &lt;code&gt;lb x1, 0(x0)&lt;/code&gt; in RISC-V assembly. This instruction, specific to the RISC-V ISA, loads a byte from memory into register &lt;code&gt;x1&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&quot;computer-architecture&quot; tabindex=&quot;-1&quot;&gt;Computer Architecture&lt;/h1&gt;
&lt;p&gt;Computer architecture is the design of computer systems, including the CPU, memory, and I/O devices. The CPU executes machine code instructions, which are specific to the CPU architecture. CPU architectures like x86, ARM, and RISC-V have different instruction sets and memory models. Each instruction set has its own assembly language and machine code format.&lt;/p&gt;
&lt;p&gt;Here’s why it is important to understand computer architecture:
Compilers generate machine code &lt;strong&gt;specific&lt;/strong&gt; to the target CPU architecture. The machine code for x86 is different from ARM or RISC-V. Interpreters, on the other hand, are CPU-independent. They translate high-level code into bytecode or an intermediate representation that can be executed on any platform.&lt;/p&gt;
&lt;p&gt;The following post explores machine code instructions and the RISC-V ISA, a popular open-source instruction set architecture. We try to see how a RISC-V CPU would execute machine code instructions using Yatch, a machine code interpreter written in C++.&lt;/p&gt;
&lt;h2 id=&quot;risc-v-isa&quot; tabindex=&quot;-1&quot;&gt;RISC-V ISA&lt;/h2&gt;
&lt;p&gt;RISC-V is an open-source instruction set architecture (ISA) based on established reduced instruction set computing (RISC) principles. Here is the complete ISA: &lt;a href=&quot;https://five-embeddev.com/riscv-user-isa-manual/Priv-v1.12/instr-table.html&quot;&gt;RISC-V IS Table&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The base ISA consists of approximately 40 instructions, and this project aims to implement most of them. Other instructions sets are extensions to the base ISA, and we might explore them later.&lt;/p&gt;
&lt;p&gt;Here is a summary of the base ISA instructions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Load/Store&lt;/strong&gt;: Load and store instructions to move data between memory and registers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Arithmetic/Logical&lt;/strong&gt;: Arithmetic and logical operations on registers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Control Transfer&lt;/strong&gt;: Branch and jump instructions to control program flow.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Immediate&lt;/strong&gt;: Instructions that use an immediate value.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;System&lt;/strong&gt;: Instructions for system calls and other privileged operations.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The instructions are divided into six categories based on their operation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;R&lt;/strong&gt;: Register-Register Operations (ADD, SUB, AND, OR, XOR, etc.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;I&lt;/strong&gt;: Immediate Operations (ADDI, SLTI, SLTIU, XORI, ORI, ANDI, etc.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;S&lt;/strong&gt;: Store Operations (SW, SH, SB)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;B&lt;/strong&gt;: Branch Operations (BEQ, BNE, BLT, BGE, BLTU, BGEU)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;U&lt;/strong&gt;: Upper Immediate Operations (LUI, AUIPC)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;J&lt;/strong&gt;: Jump Operations (JAL, JALR)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A short summary of the RISC-V Card:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../assets/img/hacktoberfest/riscv.png&quot; alt=&quot;RISCV- RV32I&quot; loading=&quot;lazy&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;instruction-decoder&quot; tabindex=&quot;-1&quot;&gt;Instruction decoder&lt;/h3&gt;
&lt;p&gt;Before moving on to the implementation, here’s a small tool that would aid in your understanding of instructions and their working. This tool helps you decode RISCV32I instructions and convert them to their corresponding assembly code. (for example, &lt;code&gt;00000000000000000000000010000011&lt;/code&gt; to &lt;code&gt;lb x1, 0(x0)&lt;/code&gt;)&lt;/p&gt;
&lt;div class=&quot;container&quot; id=&quot;input-container&quot;&gt;
  &lt;input type=&quot;text&quot; class=&quot;input-box&quot; id=&quot;input-box&quot; placeholder=&quot;Instruction&quot;&gt;
  &lt;i class=&quot;icon fa-gear&quot; id=&quot;gear&quot;&gt;&lt;/i&gt;
&lt;/div&gt;
&lt;div id=&quot;result&quot; class=&quot;result&quot;&gt;&lt;/div&gt;
&lt;p&gt;Here is the standalone version of the tool: &lt;a href=&quot;https://anubhavp.dev/barney&quot;&gt;Barney- A RISC-V Instruction Decoder&lt;/a&gt;. This is going to be a handy tool to understand the instructions and their working. The tool will also include decoding assembly code to machine code in the future.( an assembler for RISC-V instructions )&lt;/p&gt;
&lt;h2 id=&quot;yatch&quot; tabindex=&quot;-1&quot;&gt;Yatch&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/anubhavpgit/yatch&quot;&gt;Yatch&lt;/a&gt; is a machine code interpreter for RISC-V written in C++. The project aims to provide a basic understanding of how CPUs execute instructions and the principles of pipelining.&lt;/p&gt;
&lt;p&gt;To get started with Yatch, you need a C++ compiler. You can use &lt;code&gt;g++&lt;/code&gt; or &lt;code&gt;clang++&lt;/code&gt; to compile the code.&lt;/p&gt;
&lt;p&gt;Compile and run the code using the following commands:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ g++ -std=c++20 -o yatch src/main.cpp
$ ./yatch src/io
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;walkthrough&quot; tabindex=&quot;-1&quot;&gt;Walkthrough&lt;/h3&gt;
&lt;p&gt;The process of executing instructions is divided into five stages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;IF: Instruction Fetch&lt;/li&gt;
&lt;li&gt;ID: Instruction Decode&lt;/li&gt;
&lt;li&gt;EX: Execution&lt;/li&gt;
&lt;li&gt;MEM: Memory Access&lt;/li&gt;
&lt;li&gt;WB: Write Back&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The main code runs in a loop, it keeps processing instructions until either it encounters a &lt;code&gt;HALT&lt;/code&gt; instruction or reaches the end of the program. The interpreter has two main “pipelines” for executing instructions:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;The single stage pipeline is used for a simple interpretation of how CPUs execute instructions, and is not &lt;strong&gt;actively&lt;/strong&gt; used in the current implementation. It helps understand the basic principles and builds a foundation for the more complex pipeline.&lt;/em&gt;&lt;/p&gt;
&lt;h4 id=&quot;1-single-stage-pipeline&quot; tabindex=&quot;-1&quot;&gt;1. Single Stage Pipeline:&lt;/h4&gt;
&lt;!-- insert diagram --&gt;
&lt;p&gt;One instruction is executed at a time. The interpreter fetches the instruction, decodes it, executes it, accesses memory, and writes back the result in a single cycle, repeats the process for the next instruction.&lt;/p&gt;
&lt;p&gt;Example:
(instruction in memory)&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;00000000 00000000 00000000 10000011
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(data in memory)&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;01010101 01010101 01010101 01010101
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This instruction translates to &lt;code&gt;lb x1, 0(x0)&lt;/code&gt; in RISC-V assembly. It loads a byte from memory into register &lt;code&gt;x1&lt;/code&gt;. The instruction is executed in the following stages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Instruction Fetch (IF)&lt;/strong&gt;: The interpreter fetches the instruction from memory. A program counter (PC) keeps track of the current instruction. An instruction in RISC-V is 32 bits long. Yatch stores the instructions in memory as an array of 8-bit integers.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;while&lt;/span&gt; (&lt;span class=&quot;hljs-built_in&quot;&gt;getline&lt;/span&gt;(imem, line)){
 IMem[i] = &lt;span class=&quot;hljs-built_in&quot;&gt;bitset&lt;/span&gt;&amp;lt;&lt;span class=&quot;hljs-number&quot;&gt;8&lt;/span&gt;&amp;gt;(line);
 i++;
}
....
bitset&amp;lt;32&amp;gt; instruction;
&lt;span class=&quot;hljs-keyword&quot;&gt;for&lt;/span&gt; (&lt;span class=&quot;hljs-type&quot;&gt;int&lt;/span&gt; i = &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;; i &amp;lt; &lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt;; ++i){
instruction &amp;lt;&amp;lt;= &lt;span class=&quot;hljs-number&quot;&gt;8&lt;/span&gt;; &lt;span class=&quot;hljs-comment&quot;&gt;// Shift left by 8 bits to make room for the next byte&lt;/span&gt;
instruction |= &lt;span class=&quot;hljs-built_in&quot;&gt;bitset&lt;/span&gt;&amp;lt;&lt;span class=&quot;hljs-number&quot;&gt;32&lt;/span&gt;&amp;gt;(IMem[address + i].&lt;span class=&quot;hljs-built_in&quot;&gt;to_ulong&lt;/span&gt;()); &lt;span class=&quot;hljs-comment&quot;&gt;// Combine the next byte&lt;/span&gt;
&lt;span class=&quot;hljs-comment&quot;&gt;// 00000000 00000000 00000000 10000011&lt;/span&gt;
}

&lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; instruction;
....
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The reason why Yatch stores instructions in memory as an array of 8-bit integers and not 32-bit integers is that the instructions are read from a file, and each line in the file is 8-bits long. However, future implementations might change this.&lt;/p&gt;
&lt;p&gt;The program counter (PC) increases by 4 bytes (32 bits) after each instruction.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Instruction Decode (ID)&lt;/strong&gt;: The instruction is decoded and the opcode and operands are extracted. Now, based on the opcode, the interpreter knows which instruction to execute.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Opcode (bits 0-6): 0000011 - This is a Load instruction.&lt;/li&gt;
&lt;li&gt;Funct3 (bits 12-14): 000 - Specifies the type of load, which is LB (Load Byte).&lt;/li&gt;
&lt;li&gt;Destination Register (rd) (bits 7-11): 00001 - Register x1.&lt;/li&gt;
&lt;li&gt;Source Register (rs1) (bits 15-19): 00000 - Register x0.&lt;/li&gt;
&lt;li&gt;Immediate (bits 20-31): 000000000000 - Immediate value 0.&lt;br&gt;
&lt;br&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Execution (EX)&lt;/strong&gt;: The instruction is executed according to the specific case. For the &lt;code&gt;lb&lt;/code&gt;, the interpreter reads the byte from memory and stores it in the destination register.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;switch&lt;/span&gt; (opcode){
    &lt;span class=&quot;hljs-keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0x33&lt;/span&gt;:{ &lt;span class=&quot;hljs-comment&quot;&gt;// R-type instructions&lt;/span&gt;
    &lt;span class=&quot;hljs-keyword&quot;&gt;switch&lt;/span&gt; (funct3){
        &lt;span class=&quot;hljs-keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0x0&lt;/span&gt;:
        &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (funct7 == &lt;span class=&quot;hljs-number&quot;&gt;0x00&lt;/span&gt;){
 result = &lt;span class=&quot;hljs-built_in&quot;&gt;bitset&lt;/span&gt;&amp;lt;&lt;span class=&quot;hljs-number&quot;&gt;32&lt;/span&gt;&amp;gt;(myRF.&lt;span class=&quot;hljs-built_in&quot;&gt;readRF&lt;/span&gt;(rs1).&lt;span class=&quot;hljs-built_in&quot;&gt;to_ulong&lt;/span&gt;() + myRF.&lt;span class=&quot;hljs-built_in&quot;&gt;readRF&lt;/span&gt;(rs2).&lt;span class=&quot;hljs-built_in&quot;&gt;to_ulong&lt;/span&gt;()); &lt;span class=&quot;hljs-comment&quot;&gt;// ADD&lt;/span&gt;
            } &lt;span class=&quot;hljs-keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (funct7 == &lt;span class=&quot;hljs-number&quot;&gt;0x20&lt;/span&gt;){
 &lt;span class=&quot;hljs-comment&quot;&gt;// SUB&lt;/span&gt;
.....

    &lt;span class=&quot;hljs-keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0x03&lt;/span&gt;:{ &lt;span class=&quot;hljs-comment&quot;&gt;// I-type instructions&lt;/span&gt;
    &lt;span class=&quot;hljs-keyword&quot;&gt;switch&lt;/span&gt; (funct3){
        &lt;span class=&quot;hljs-keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0x0&lt;/span&gt;:
 &lt;span class=&quot;hljs-comment&quot;&gt;// LB&lt;/span&gt;
 result = &lt;span class=&quot;hljs-built_in&quot;&gt;bitset&lt;/span&gt;&amp;lt;&lt;span class=&quot;hljs-number&quot;&gt;32&lt;/span&gt;&amp;gt;(myRF.&lt;span class=&quot;hljs-built_in&quot;&gt;readRF&lt;/span&gt;(rs1).&lt;span class=&quot;hljs-built_in&quot;&gt;to_ulong&lt;/span&gt;() + imm.&lt;span class=&quot;hljs-built_in&quot;&gt;to_ulong&lt;/span&gt;());
        &lt;span class=&quot;hljs-keyword&quot;&gt;break&lt;/span&gt;;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Memory Access (MEM)&lt;/strong&gt;: Yatch reads the memory from a file and uses an 8-bit array to store the memory. It further uses specific functions to read specific memory locations.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;while&lt;/span&gt; (&lt;span class=&quot;hljs-built_in&quot;&gt;getline&lt;/span&gt;(dmem, line)){
 DMem[i] = &lt;span class=&quot;hljs-built_in&quot;&gt;bitset&lt;/span&gt;&amp;lt;&lt;span class=&quot;hljs-number&quot;&gt;8&lt;/span&gt;&amp;gt;(line);
 i++;
}
....
&lt;span class=&quot;hljs-function&quot;&gt;bitset&amp;lt;8&amp;gt; &lt;span class=&quot;hljs-title&quot;&gt;readByte&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;(&lt;span class=&quot;hljs-type&quot;&gt;uint32_t&lt;/span&gt; address)&lt;/span&gt;&lt;/span&gt;{
    &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (address &amp;lt; DMem.&lt;span class=&quot;hljs-built_in&quot;&gt;size&lt;/span&gt;())
    &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; DMem[address];
    &lt;span class=&quot;hljs-keyword&quot;&gt;else&lt;/span&gt; {
        &lt;span class=&quot;hljs-keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;runtime_error&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&quot;Read Byte Error: Address out of bounds.&quot;&lt;/span&gt;); &lt;span class=&quot;hljs-comment&quot;&gt;// Handle out-of-bounds access&lt;/span&gt;
        &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;bitset&lt;/span&gt;&amp;lt;&lt;span class=&quot;hljs-number&quot;&gt;8&lt;/span&gt;&amp;gt;(&lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The opcode in the example is &lt;strong&gt;0000011&lt;/strong&gt;, I type the instruction, corresponding to the &lt;code&gt;load&lt;/code&gt; instruction. Funct3 is &lt;strong&gt;000&lt;/strong&gt;, corresponding to the &lt;code&gt;lb&lt;/code&gt; instruction. The &lt;code&gt;lb&lt;/code&gt; instruction &lt;strong&gt;loads a byte&lt;/strong&gt; from memory into a register. Similarly, a different funct3, for ex. &lt;em&gt;010&lt;/em&gt; would correspond to the &lt;code&gt;lw&lt;/code&gt; instruction, which loads a word from memory into a register. The primary step is to switch on the opcode and execute the corresponding instruction.&lt;/p&gt;
&lt;p&gt;Memory is handled using registers. Yatch uses a 32-bit vector to store 32 registers. The instruction loads a byte from memory at the address calculated by adding the immediate offset 0 to the value in register x0 (0). The data in the 0th memory location(01010101) is read and stored in the destination register.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Write Back (WB)&lt;/strong&gt;: The result of the operation is written back to the register file.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;Registers. &lt;span class=&quot;hljs-built_in&quot;&gt;resize&lt;/span&gt;(&lt;span class=&quot;hljs-number&quot;&gt;32&lt;/span&gt;); &lt;span class=&quot;hljs-comment&quot;&gt;// 32 registers in total, each 32 bits wide&lt;/span&gt;
Registers[&lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;] = &lt;span class=&quot;hljs-built_in&quot;&gt;bitset&lt;/span&gt;&amp;lt;&lt;span class=&quot;hljs-number&quot;&gt;32&lt;/span&gt;&amp;gt;(&lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;); &lt;span class=&quot;hljs-comment&quot;&gt;// Register x0 is always 0 in RISC-V&lt;/span&gt;

&lt;span class=&quot;hljs-function&quot;&gt;bitset&amp;lt;32&amp;gt; &lt;span class=&quot;hljs-title&quot;&gt;readRF&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;(bitset&amp;lt;&lt;span class=&quot;hljs-number&quot;&gt;5&lt;/span&gt;&amp;gt; Reg_addr)&lt;/span&gt;&lt;/span&gt;{
    &lt;span class=&quot;hljs-type&quot;&gt;uint32_t&lt;/span&gt; reg_index = Reg_addr.&lt;span class=&quot;hljs-built_in&quot;&gt;to_ulong&lt;/span&gt;(); &lt;span class=&quot;hljs-comment&quot;&gt;// Converts Reg_addr to integer for indexing&lt;/span&gt;
    &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; Registers[reg_index]; &lt;span class=&quot;hljs-comment&quot;&gt;// Returns the register value at the given index&lt;/span&gt;
}   

&lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-type&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;writeRF&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;(bitset&amp;lt;&lt;span class=&quot;hljs-number&quot;&gt;5&lt;/span&gt;&amp;gt; Reg_addr, bitset&amp;lt;&lt;span class=&quot;hljs-number&quot;&gt;32&lt;/span&gt;&amp;gt; Wrt_reg_data)&lt;/span&gt;&lt;/span&gt;{
    &lt;span class=&quot;hljs-type&quot;&gt;uint32_t&lt;/span&gt; reg_index = Reg_addr.&lt;span class=&quot;hljs-built_in&quot;&gt;to_ulong&lt;/span&gt;(); &lt;span class=&quot;hljs-comment&quot;&gt;// Converts Reg_addr to integer for indexing&lt;/span&gt;
    &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (reg_index != &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;) Registers[reg_index] = Wrt_reg_data; &lt;span class=&quot;hljs-comment&quot;&gt;// Write the data to the register&lt;/span&gt;

    &lt;span class=&quot;hljs-keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;hljs-built_in&quot;&gt;runtime_error&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&quot;Cannot write to register x0.&quot;&lt;/span&gt;);   
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once all the instructions are executed, the memory is written back to a file.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This entire journey is completed in a single cycle. This serves as a good simulator for understanding how CPUs execute instructions, but the real-world compute requires a more complex pipeline, parallel processing; and multiple instructions executed simultaneously.&lt;/p&gt;
&lt;h4 id=&quot;2-five-stage-pipeline&quot; tabindex=&quot;-1&quot;&gt;2. Five-Stage Pipeline:&lt;/h4&gt;
&lt;!-- insert diagram --&gt;
&lt;p&gt;A single program has millions of instructions, and executing them one by one would take a lot of time. This pipeline allows the CPU to execute multiple instructions simultaneously, improving the overall performance.&lt;/p&gt;
&lt;p&gt;The pipeline is divided into five stages: IF, ID, EX, MEM, and WB. Each stage is responsible for a specific action. The main loop calls these functions in reverse order, starting with the WB stage and ending with the IF stage.&lt;/p&gt;
&lt;p&gt;The reverse order achieves to handle hazards. There are three types of hazards: data hazards, structural hazards, and control hazards.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Data hazards occur when instructions that exhibit data dependence modify data in different stages of a pipeline. Ignoring potential data hazards can result in race conditions. Following are the types of data hazards:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;read after write (RAW), a true dependency: A read after write (RAW) data hazard refers to a situation where an instruction refers to a result that has not yet been calculated or retrieved. This can occur because even though an instruction is executed after a prior instruction, the prior instruction has been processed only partly through the pipeline. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-md&quot;&gt;  i1. &lt;span class=&quot;hljs-strong&quot;&gt;**R2**&lt;/span&gt; &amp;lt;- R5 + R8
  i2. R4 &amp;lt;- &lt;span class=&quot;hljs-strong&quot;&gt;**R2**&lt;/span&gt; + R8
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;write after read (WAR), an anti-dependency: A write after read (WAR) data hazard refers to a situation where an instruction writes to a register that another instruction reads from. This can occur because the instruction that writes to the register is executed before the instruction that reads from the register. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-md&quot;&gt;  i1. R4 &amp;lt;- &lt;span class=&quot;hljs-strong&quot;&gt;**R2**&lt;/span&gt; + R8
  i2. &lt;span class=&quot;hljs-strong&quot;&gt;**R2**&lt;/span&gt; &amp;lt;- R5 + R8
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;write after write (WAW), an output dependency: A write after write (WAW) data hazard may occur in a concurrent execution environment. It refers to a situation where two instructions are written to the same register. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-md&quot;&gt;  i1. &lt;span class=&quot;hljs-strong&quot;&gt;**R5**&lt;/span&gt; &amp;lt;- R4 + R7
  i2. &lt;span class=&quot;hljs-strong&quot;&gt;**R5**&lt;/span&gt; &amp;lt;- R1 + R3
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Structural hazards: A structural hazard occurs when two instructions need the same hardware resource at the same time. For example, two instructions need to access the memory at the same time.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Control hazards: A control hazard occurs when the pipeline makes the wrong decision on a branch instruction. The pipeline must be flushed, and the correct instructions must be fetched.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This pipeline is designed to handle control hazards and data hazards. The pipeline initializes the PC, and all the stages except the IF stage are set to NOP (no operation). The IF stage fetches the first instruction from memory and sets the PC to the next instruction.&lt;/p&gt;
&lt;p&gt;Example:
(instruction in memory)&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;00000000 00000000 00000000 10000011
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(data in memory)&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;01010101 01010101 01010101 01010101
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The main loop calls these functions in reverse order, in the following sequence:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;// Initialize pipeline stages to nop&lt;/span&gt;
  state.IF.nop = &lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/span&gt;;
  state.ID.nop = &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;;
  state.EX.nop = &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;;
  state.MEM.nop = &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;;
  state.WB.nop = &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;;

  &lt;span class=&quot;hljs-comment&quot;&gt;// Initialize PC to 0&lt;/span&gt;
  state.IF.PC = &lt;span class=&quot;hljs-built_in&quot;&gt;bitset&lt;/span&gt;&amp;lt;&lt;span class=&quot;hljs-number&quot;&gt;32&lt;/span&gt;&amp;gt;(&lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;);
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;WB&lt;/strong&gt;: Write Back: Checks if the instruction has a destination register and writes the result back to the register file.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;/* --------------------- WB stage --------------------- */&lt;/span&gt;
&lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (!state.WB.nop){ &lt;span class=&quot;hljs-comment&quot;&gt;// Check if the instruction is not a NOP&lt;/span&gt;
  &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (state.WB.wrt_enable){ &lt;span class=&quot;hljs-comment&quot;&gt;// Write back to register file&lt;/span&gt;
    &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (state.WB.Wrt_reg_addr.&lt;span class=&quot;hljs-built_in&quot;&gt;to_ulong&lt;/span&gt;() != &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;) &lt;span class=&quot;hljs-comment&quot;&gt;// x0 is always zero. Cannot override&lt;/span&gt;
 myRF.&lt;span class=&quot;hljs-built_in&quot;&gt;writeRF&lt;/span&gt;(state.WB.Wrt_reg_addr.&lt;span class=&quot;hljs-built_in&quot;&gt;to_ulong&lt;/span&gt;(), state.WB.Wrt_data); &lt;span class=&quot;hljs-comment&quot;&gt;// Write the data to the register&lt;/span&gt;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the first step, this stage is set as a NOP. In the subsequent steps, the IF stage fetches the instruction from memory and sets the PC to the next instruction. Once the instruction is fetched, the ID stage decodes the instruction and extracts the opcode and operands. The EX stage executes the instruction, and the MEM stage reads or writes data to memory. Finally, the WB stage writes the result back to the register file. The loop continues until the end of the program. (All the stages are NOP)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;MEM&lt;/strong&gt;: Memory Access: Reads or writes data to memory.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;  &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (state.MEM.rd_mem)
  {
&lt;span class=&quot;hljs-comment&quot;&gt;// Load from memory based on MemOp&lt;/span&gt;
    &lt;span class=&quot;hljs-type&quot;&gt;uint32_t&lt;/span&gt; address = state.MEM.ALUresult.&lt;span class=&quot;hljs-built_in&quot;&gt;to_ulong&lt;/span&gt;(); &lt;span class=&quot;hljs-comment&quot;&gt;// Address to read from &lt;/span&gt;
bitset&amp;lt;32&amp;gt; memData; &lt;span class=&quot;hljs-comment&quot;&gt;// Data read from memory&lt;/span&gt;

    &lt;span class=&quot;hljs-keyword&quot;&gt;switch&lt;/span&gt; (state.MEM.mem_op) &lt;span class=&quot;hljs-comment&quot;&gt;// Check the memory operation&lt;/span&gt;
    {
    &lt;span class=&quot;hljs-keyword&quot;&gt;case&lt;/span&gt; MemLB: &lt;span class=&quot;hljs-comment&quot;&gt;// Load Byte&lt;/span&gt;
    {
bitset&amp;lt;8&amp;gt; data = ext_dmem.&lt;span class=&quot;hljs-built_in&quot;&gt;readByte&lt;/span&gt;(address); &lt;span class=&quot;hljs-comment&quot;&gt;// Read a byte from memory&lt;/span&gt;
      &lt;span class=&quot;hljs-type&quot;&gt;int8_t&lt;/span&gt; signed_data = (&lt;span class=&quot;hljs-type&quot;&gt;int8_t&lt;/span&gt;)data.&lt;span class=&quot;hljs-built_in&quot;&gt;to_ulong&lt;/span&gt;(); &lt;span class=&quot;hljs-comment&quot;&gt;// Convert to signed data&lt;/span&gt;
memData = &lt;span class=&quot;hljs-built_in&quot;&gt;bitset&lt;/span&gt;&amp;lt;&lt;span class=&quot;hljs-number&quot;&gt;32&lt;/span&gt;&amp;gt;(signed_data); &lt;span class=&quot;hljs-comment&quot;&gt;// Store the data in a 32-bit bitset&lt;/span&gt;
 ......
  &lt;span class=&quot;hljs-keyword&quot;&gt;else&lt;/span&gt; nextState.WB.Wrt_data = state.MEM.ALUresult; &lt;span class=&quot;hljs-comment&quot;&gt;// No memory operation, pass the ALU result to the WB stage.&lt;/span&gt;
}
&lt;span class=&quot;hljs-keyword&quot;&gt;else&lt;/span&gt;
nextState.WB.nop = &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;; &lt;span class=&quot;hljs-comment&quot;&gt;// If MEM stage is nop, so WB stage is also nop&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the example, the instruction is a &lt;strong&gt;load&lt;/strong&gt; instruction, so the MEM stage reads data from memory. The data is then passed to the WB stage. The MEM stage also checks if the instruction is a load or store instruction and reads or writes data to memory accordingly. Here,&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;bitset&amp;lt;32&amp;gt; memData = ext_dmem.&lt;span class=&quot;hljs-built_in&quot;&gt;readByte&lt;/span&gt;(address); &lt;span class=&quot;hljs-comment&quot;&gt;// Read a byte from memory&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The ALU result is the address of the memory location to read from. The data is then passed on from the ID stage.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;EX&lt;/strong&gt;: Execution: Executes the instruction. The instruction, decoded in the ID stage, is executed here.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (!state.EX.nop)
{
&lt;span class=&quot;hljs-comment&quot;&gt;// Perform ALU operations&lt;/span&gt;
bitset&amp;lt;32&amp;gt; operand1 = state.EX.Read_data1; &lt;span class=&quot;hljs-comment&quot;&gt;// First operand&lt;/span&gt;
bitset&amp;lt;32&amp;gt; operand2 = state.EX.is_I_type ? state.EX.Imm: state.EX.Read_data2; &lt;span class=&quot;hljs-comment&quot;&gt;// Second operand&lt;/span&gt;

&lt;span class=&quot;hljs-comment&quot;&gt;// Forwarding from MEM stage&lt;/span&gt;
  &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (state.MEM.wrt_enable &amp;amp;&amp;amp; state.MEM.Wrt_reg_addr.&lt;span class=&quot;hljs-built_in&quot;&gt;to_ulong&lt;/span&gt;() != &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;){ &lt;span class=&quot;hljs-comment&quot;&gt;// Handles data hazards&lt;/span&gt;
    &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (state.MEM.Wrt_reg_addr == state.EX.Rs)
operand1 = state.MEM.ALUresult; &lt;span class=&quot;hljs-comment&quot;&gt;// Forward data from MEM stage to operand1&lt;/span&gt;
    
 .......
  &lt;span class=&quot;hljs-keyword&quot;&gt;switch&lt;/span&gt; (state.EX.alu_op) &lt;span class=&quot;hljs-comment&quot;&gt;// perform ALU operation based on the ALU control signal&lt;/span&gt;
  {
  &lt;span class=&quot;hljs-keyword&quot;&gt;case&lt;/span&gt; ADDU:
ALUresult = &lt;span class=&quot;hljs-built_in&quot;&gt;bitset&lt;/span&gt;&amp;lt;&lt;span class=&quot;hljs-number&quot;&gt;32&lt;/span&gt;&amp;gt;(operand&lt;span class=&quot;hljs-number&quot;&gt;1.&lt;/span&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;to_ulong&lt;/span&gt;() + operand&lt;span class=&quot;hljs-number&quot;&gt;2.&lt;/span&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;to_ulong&lt;/span&gt;());
    &lt;span class=&quot;hljs-keyword&quot;&gt;break&lt;/span&gt;;
  &lt;span class=&quot;hljs-keyword&quot;&gt;case&lt;/span&gt; SUBU:
ALUresult = &lt;span class=&quot;hljs-built_in&quot;&gt;bitset&lt;/span&gt;&amp;lt;&lt;span class=&quot;hljs-number&quot;&gt;32&lt;/span&gt;&amp;gt;(operand&lt;span class=&quot;hljs-number&quot;&gt;1.&lt;/span&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;to_ulong&lt;/span&gt;() - operand&lt;span class=&quot;hljs-number&quot;&gt;2.&lt;/span&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;to_ulong&lt;/span&gt;());
    &lt;span class=&quot;hljs-keyword&quot;&gt;break&lt;/span&gt;;
  &lt;span class=&quot;hljs-keyword&quot;&gt;case&lt;/span&gt; AND:
ALUresult = &lt;span class=&quot;hljs-built_in&quot;&gt;bitset&lt;/span&gt;&amp;lt;&lt;span class=&quot;hljs-number&quot;&gt;32&lt;/span&gt;&amp;gt;(operand&lt;span class=&quot;hljs-number&quot;&gt;1.&lt;/span&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;to_ulong&lt;/span&gt;() &amp;amp; operand&lt;span class=&quot;hljs-number&quot;&gt;2.&lt;/span&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;to_ulong&lt;/span&gt;());
    &lt;span class=&quot;hljs-keyword&quot;&gt;break&lt;/span&gt;;
 .....
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The ALU result is calculated based on the opcode and funct3 fields. The result is then passed on to the MEM stage. Our example instruction is a load instruction, so the ALU result is the address of the memory location to read from. The data is then passed on from the ID stage.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;ALUresult = &lt;span class=&quot;hljs-built_in&quot;&gt;bitset&lt;/span&gt;&amp;lt;&lt;span class=&quot;hljs-number&quot;&gt;32&lt;/span&gt;&amp;gt;(operand&lt;span class=&quot;hljs-number&quot;&gt;1.&lt;/span&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;to_ulong&lt;/span&gt;() + operand&lt;span class=&quot;hljs-number&quot;&gt;2.&lt;/span&gt;&lt;span class=&quot;hljs-built_in&quot;&gt;to_ulong&lt;/span&gt;()); &lt;span class=&quot;hljs-comment&quot;&gt;// calculates the address to read from&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ID&lt;/strong&gt;: Instruction Decode: Decodes the instruction and extracts the opcode and operands.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (!state.ID.nop){
bitset&amp;lt;32&amp;gt; instruction = state.ID.Instr;
&lt;span class=&quot;hljs-comment&quot;&gt;// Decode instruction&lt;/span&gt;
  &lt;span class=&quot;hljs-type&quot;&gt;uint32_t&lt;/span&gt; instr = instruction.&lt;span class=&quot;hljs-built_in&quot;&gt;to_ulong&lt;/span&gt;();
  &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (instr == &lt;span class=&quot;hljs-number&quot;&gt;0xFFFFFFFF&lt;/span&gt;)
	  {
		  &lt;span class=&quot;hljs-comment&quot;&gt;// HALT instruction encountered&lt;/span&gt;
		  state.IF.nop = &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;;		 &lt;span class=&quot;hljs-comment&quot;&gt;// Stop fetching new instructions&lt;/span&gt;
		  nextState.IF.nop = &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;; &lt;span class=&quot;hljs-comment&quot;&gt;// Stop fetching new instructions&lt;/span&gt;
	  }
	  &lt;span class=&quot;hljs-keyword&quot;&gt;else&lt;/span&gt;{
    &lt;span class=&quot;hljs-type&quot;&gt;uint32_t&lt;/span&gt; opcode = instr &amp;amp; &lt;span class=&quot;hljs-number&quot;&gt;0x7F&lt;/span&gt;;
    &lt;span class=&quot;hljs-type&quot;&gt;uint32_t&lt;/span&gt; rd = (instr &amp;gt;&amp;gt; &lt;span class=&quot;hljs-number&quot;&gt;7&lt;/span&gt;) &amp;amp; &lt;span class=&quot;hljs-number&quot;&gt;0x1F&lt;/span&gt;;
    &lt;span class=&quot;hljs-type&quot;&gt;uint32_t&lt;/span&gt; funct3 = (instr &amp;gt;&amp;gt; &lt;span class=&quot;hljs-number&quot;&gt;12&lt;/span&gt;) &amp;amp; &lt;span class=&quot;hljs-number&quot;&gt;0x7&lt;/span&gt;;
    &lt;span class=&quot;hljs-type&quot;&gt;uint32_t&lt;/span&gt; rs1 = (instr &amp;gt;&amp;gt; &lt;span class=&quot;hljs-number&quot;&gt;15&lt;/span&gt;) &amp;amp; &lt;span class=&quot;hljs-number&quot;&gt;0x1F&lt;/span&gt;;
    &lt;span class=&quot;hljs-type&quot;&gt;uint32_t&lt;/span&gt; rs2 = (instr &amp;gt;&amp;gt; &lt;span class=&quot;hljs-number&quot;&gt;20&lt;/span&gt;) &amp;amp; &lt;span class=&quot;hljs-number&quot;&gt;0x1F&lt;/span&gt;;  
    &lt;span class=&quot;hljs-type&quot;&gt;uint32_t&lt;/span&gt; funct7 = (instr &amp;gt;&amp;gt; &lt;span class=&quot;hljs-number&quot;&gt;25&lt;/span&gt;) &amp;amp; &lt;span class=&quot;hljs-number&quot;&gt;0x7F&lt;/span&gt;;
&lt;span class=&quot;hljs-comment&quot;&gt;// Hazard Detection&lt;/span&gt;
    &lt;span class=&quot;hljs-type&quot;&gt;bool&lt;/span&gt; stall = &lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/span&gt;; &lt;span class=&quot;hljs-comment&quot;&gt;// Flag to indicate a stall is required&lt;/span&gt;
&lt;span class=&quot;hljs-comment&quot;&gt;// Check for RAW hazards with EX stage&lt;/span&gt;
    &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (state.EX.rd_mem &amp;amp;&amp;amp; state.EX.Wrt_reg_addr.&lt;span class=&quot;hljs-built_in&quot;&gt;to_ulong&lt;/span&gt;() != &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;){ &lt;span class=&quot;hljs-comment&quot;&gt;// checks if the instruction in EX stage is a load instr and that the writeback register is not x0&lt;/span&gt;
      &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (state.EX.Wrt_reg_addr.&lt;span class=&quot;hljs-built_in&quot;&gt;to_ulong&lt;/span&gt;() == rs1 || state.EX.Wrt_reg_addr.&lt;span class=&quot;hljs-built_in&quot;&gt;to_ulong&lt;/span&gt;() == rs2) stall = &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;; &lt;span class=&quot;hljs-comment&quot;&gt;// Stall required&lt;/span&gt;
  &lt;span class=&quot;hljs-comment&quot;&gt;// handles hazards here&lt;/span&gt;
 ...
    &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (stall){
nextState.ID = state.ID; &lt;span class=&quot;hljs-comment&quot;&gt;// Keep the instruction in the ID stage&lt;/span&gt;
nextState.EX.nop = &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;; &lt;span class=&quot;hljs-comment&quot;&gt;// Insert nop in EX stage&lt;/span&gt;
nextState.IF = state.IF; &lt;span class=&quot;hljs-comment&quot;&gt;// IF stage also needs to stall&lt;/span&gt;
&lt;span class=&quot;hljs-comment&quot;&gt;// stall helps the EX stage to finish the operation before the ID stage reads the value&lt;/span&gt;
    }
    &lt;span class=&quot;hljs-keyword&quot;&gt;else&lt;/span&gt;{
&lt;span class=&quot;hljs-comment&quot;&gt;// Prepare data for EX stage&lt;/span&gt;
nextState.EX.nop = &lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/span&gt;;
nextState.EX.Read_data1 = Read_data1;
nextState.EX.Read_data2 = Read_data2;
nextState.EX.Rs = rs1;
nextState.EX.Rt = rs2;
nextState.EX.Wrt_reg_addr = rd;
nextState.EX.Imm = &lt;span class=&quot;hljs-built_in&quot;&gt;bitset&lt;/span&gt;&amp;lt;&lt;span class=&quot;hljs-number&quot;&gt;32&lt;/span&gt;&amp;gt;(&lt;span class=&quot;hljs-built_in&quot;&gt;signExtendImmediate&lt;/span&gt;(instr));

&lt;span class=&quot;hljs-comment&quot;&gt;// Set control signals based on opcode&lt;/span&gt;
      &lt;span class=&quot;hljs-built_in&quot;&gt;setControlSignals&lt;/span&gt;(opcode, funct3, funct7, nextState.EX); &lt;span class=&quot;hljs-comment&quot;&gt;// sets the controls for the EX stage to execute the instruction based on the control signals&lt;/span&gt;

&lt;span class=&quot;hljs-comment&quot;&gt;// Branch Handling&lt;/span&gt;
      &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (opcode == &lt;span class=&quot;hljs-number&quot;&gt;0x63&lt;/span&gt;) &lt;span class=&quot;hljs-comment&quot;&gt;// Branch instructions&lt;/span&gt;
      {
 .....
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the example, the instruction is a load instruction, so the ID stage decodes the instruction and extracts the opcode and operands. The ID stage also checks for hazards with the EX stage. If a hazard is detected, the ID stage stalls and waits for the EX stage to finish the operation before reading the value. The ID stage then prepares the data for the EX stage and sets the control signals based on the opcode.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;0xFFFFFFFF&lt;/code&gt; instruction is a placeholder for the HALT instruction. The HALT instruction stops fetching new instructions and halts the program. ID is responsible for HALT detection and handling.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;IF&lt;/strong&gt;: Instruction Fetch: Fetches the instruction from memory.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (!state.IF.nop){
&lt;span class=&quot;hljs-comment&quot;&gt;// Fetch instruction from instruction memory&lt;/span&gt;
bitset&amp;lt;32&amp;gt; instruction = ext_imem.&lt;span class=&quot;hljs-built_in&quot;&gt;readInstr&lt;/span&gt;(state.IF.PC);
&lt;span class=&quot;hljs-comment&quot;&gt;// Prepare data for ID stage&lt;/span&gt;
nextState.ID.nop = &lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/span&gt;;
nextState.ID.Instr = instruction;
nextState.ID.PC = state.IF.PC;
&lt;span class=&quot;hljs-comment&quot;&gt;// Update PC&lt;/span&gt;
nextState.IF.PC = &lt;span class=&quot;hljs-built_in&quot;&gt;bitset&lt;/span&gt;&amp;lt;&lt;span class=&quot;hljs-number&quot;&gt;32&lt;/span&gt;&amp;gt;(state.IF.PC.&lt;span class=&quot;hljs-built_in&quot;&gt;to_ulong&lt;/span&gt;() + &lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt;); &lt;span class=&quot;hljs-comment&quot;&gt;// Fetches the next instruction&lt;/span&gt;
}
&lt;span class=&quot;hljs-keyword&quot;&gt;else&lt;/span&gt;
nextState.ID.nop = &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;; &lt;span class=&quot;hljs-comment&quot;&gt;// IF stage is nop, so ID stage is also nop&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The IF stage fetches the instruction from memory and sets the PC to the next instruction. The instruction is then passed on to the ID stage. The PC is updated to fetch the next instruction.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;While a five-stage pipeline is a correct and realistic representation for many simple RISC-V processors, more advanced implementations can have more stages and additional complexities. The five-stage model remains an effective starting point for understanding pipelining principles and serves as a foundation for more advanced pipeline structures in modern processors.&lt;/p&gt;

            &lt;hr&gt;
            &lt;div class=&quot;footer&quot;&gt;
              &lt;i&gt;Feedback, Suggestions, Comments - &lt;/i&gt;
              &lt;div class=&quot;giscus-div&quot; id=&quot;comments&quot;&gt;
                &lt;script src=&quot;https://giscus.app/client.js&quot; data-repo=&quot;anubhavpgit/anubhavpgit.github.io&quot; data-repo-id=&quot;MDEwOlJlcG9zaXRvcnk0MDQ1ODEzMjc=&quot; data-category-id=&quot;DIC_kwDOGB1rz84Cer0j&quot; data-mapping=&quot;title&quot; data-strict=&quot;0&quot; data-reactions-enabled=&quot;1&quot; data-emit-metadata=&quot;0&quot; data-input-position=&quot;bottom&quot; data-theme=&quot;noborder_light&quot; data-lang=&quot;en&quot; data-loading=&quot;lazy&quot; crossorigin=&quot;anonymous&quot; async=&quot;&quot;&gt;&lt;/script&gt;
              &lt;/div&gt;
              Feel free to
              &lt;a id=&quot;mailtoLink&quot; href=&quot;mailto:anubhavp@duck.com?subject=Here&apos;s%20a%20suggestion/feedback!&quot;&gt;send
                me an email&lt;/a&gt;.
            &lt;/div&gt;
          &lt;/div&gt;
        </content:encoded>
            <subtitle>Understanding compilers and building binary interpreters for machine code in RISC-V in Hacktoberfest.</subtitle>
        </item>
        <item>
            <title><![CDATA[Jajabara (I)]]></title>
            <description><![CDATA[A journey through whims of fate and lucid memories. Growing up and looking for the purpose of life.]]></description>
            <link>https://anubhavp.dev/blog/jajabara.html</link>
            <guid isPermaLink="true">https://anubhavp.dev/blog/jajabara.html</guid>
            <dc:creator><![CDATA[Anubhab Patnaik]]></dc:creator>
            <pubDate>Sat, 10 May 2025 00:00:00 GMT</pubDate>
            <content:encoded>
          &lt;div class=&quot;content custom&quot;&gt;
            &lt;div class=&quot;search-container&quot;&gt;&lt;/div&gt;
            &lt;p&gt;Greek mythology is fascinating and full of stories that explore the human condition. My fascination stems from the fact that even gods are flawed - subject to the same emotions and desires as mortals. Zeus is known for his numerous affairs and impulsive decisions, while Hera is often portrayed as jealous and vengeful. Aphhrodite embodies the complexities of love and desire, often leading to chaos and conflict. All divine, yet deeply imperfect.&lt;/p&gt;
&lt;p&gt;Sisyphus, the king of Ephyra, was punished by Zeus for cheating death twice. He was condemned to roll a boulder up a hill, only to watch it roll back down, doomed to repeat this task for eternity, never able to complete it. I see the myth of Sisyphus as a metaphor for the futility of life and the eternal journey to find purpose in a world that is indifferent to our existence; a never-ending quest, a journey fraught with constant change and uncertainty. My journey throughout these years feels quite similar. Not because I am being punished by Zeus for cheating death (not that I’d get caught), but because I find myself constantly building a new life in a new corner of the world, pushing a new boulder up a new hill.&lt;/p&gt;
&lt;p&gt;Each journey represents a new beginning, a fresh start in a different city, where I build a new life and make new friends. The ascent is filled with hope and possibility. I try to find my place in this newfound world and craft memories before the boulder rolls back down. Signalling the inevitable need to move, leaving behind what I’ve built and starting afresh. Empty houses—ones filled with laughter and joy, shops that let me pay later since I was a regular, now closed, replaced with malls and supermarkets, friends and their stories now only in distant memories, neighbours who became family, and friends who became strangers.&lt;/p&gt;
&lt;h3 id=&quot;bhubaneswar-the-early-years&quot; tabindex=&quot;-1&quot;&gt;Bhubaneswar: The Early Years&lt;/h3&gt;
&lt;p&gt;My earliest memories are rooted in Bhubaneswar when I was around two or three years old- dating back to how my room looked, the faint essence of my bed, the tube lights and going to school. My mother’s image isn’t vivid - just fragments of her hair, a white dress, and the stories she told when getting me to sleep. We had an oval mirror in our room, and my faintest memories are looking at her getting ready. She took me everywhere with her, mostly to meet her friends and to her home. I do not remember the fragrance of her perfume, but I remember that I used to love her applying powder on my face.&lt;/p&gt;
&lt;p&gt;My father had a Suzuki Max 100. We used to go out on rides, to the beach with his friends, and to places to eat. My parents are foodies, and I was a child who refused to eat anything. I always had this inexplicable urge to sit on the fuel tank. The “shotgun” equivalent of a motorcycle. It makes you feel like a rider, the man in control. My father used to let me sit there, and I remember the wind hitting my face and the thrill of the ride. I loved it. I still do. But now, as an adult, I see how that feeling of control is an illusion. At twenty-five, I see how I wouldn’t want to be the man in control, given a choice. Adulting is hard.&lt;/p&gt;
&lt;p&gt;The lucid memories of faint incense sticks, the snug bed I slept in, and the blue tricycle I rode all feel like a different lifetime now, pieces of a world I left behind every time we moved.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Blue&lt;/em&gt;, because I remember it was blue, and my cousin-sister had a red one, but she somehow managed to break hers. Our mothers asked us to share the one I had. Sly, that one. Always knew right from wrong, sporting devilish smirks, with a knack for breaking things—chewed, scratched, or demolished in forms beyond recognition. We were colour-coded. All my things, from my tiffin and a huge water bottle to my pencils, were blue. Hers were red.&lt;/p&gt;
&lt;p&gt;We are six months apart. Every day, our mothers would pick us up from school, and once we were home, they’d make us sit on the floor for lunch. For reasons I still don’t fully understand, I always took an absurdly long time to finish my meal—it could stretch anywhere from one to three hours. The afternoon naps were floaty and euphoric. We had this incredible Sony music system, and both followed a routine. The same music CD played every afternoon, and we were asleep by the end of the second song. That’s why I could only remember the first couple of songs on the CD, and one of them was &lt;em&gt;Jajabara&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Similar to Sisyphus, &lt;a href=&quot;https://music.apple.com/us/album/jajabara-original-motion-picture-soundtrack-ep/1380220136&quot;&gt;Jajabara&lt;/a&gt; is a poem about a nomadic lifestyle, with the poet describing his journey through the world, and the world being a stage. The poet refers to their mind as a nomad who constantly roams or seeks something beyond immediate reality. It speaks about the poet’s limitless hopes and indicates a deep longing or an unquenchable thirst for something greater, a cyclical nature of life where values or rules are constantly created and discarded like sandcastles, highlighting the transient, Sisyphean nature of human beliefs. The twenty-five-year-old me relates to it now, the nomadic lifestyle, the constant search for meaning, and the Sisyphean journey of life.&lt;/p&gt;
&lt;p&gt;My cousin, who once a child breaking her red tricycle, got married last month. We started as children with colour-coded possessions, and now she is building her own family while I build a career across the ocean in the opposite part of the globe. Strange how nostalgia grips you.&lt;/p&gt;
&lt;p&gt;My Sisyphean journey began when my father was transferred from Bhubaneswar to Kolkata in 2005. Each time we packed up and left, I saw the boulder rolling back down. We started building a new life in a different city. The cycle of moving and rebuilding continued, each time leaving behind a piece of myself. Exploring new places and thinking more about the purpose of life.&lt;/p&gt;
&lt;h3 id=&quot;tram-rides-and-power-rangers&quot; tabindex=&quot;-1&quot;&gt;Tram Rides and Power Rangers&lt;/h3&gt;
&lt;p&gt;Leaving behind my grandparents and family was the most difficult. Each of my grandparents had lived for over half a century, carrying a treasury of experiences, perspectives, and philosophies that I loved to listen to. My maternal grandfather worked in the Secretariat, Odisha, while my paternal grandfather had been working in the education department in Odisha. Both of my grandmothers were teachers, though my father’s mother left her profession after marriage, while my mother’s mother continued teaching. Their stories weren’t just simple fables but windows into worlds shaped by time and wisdom. Years later, now that I think of it, the stories make me understand human psychology better. Each scrutinising from their own lens of how the world worked, right or wrong, they were mere perspectives which I seemed to absorb and live through. A time when crossing rivers to attend school and fishing for lunch was the norm. As a child, I was oblivious to the weight of their words, but now, as an adult, I see how their shoes fit me. Leaving my family was the hardest part of moving.&lt;/p&gt;
&lt;p&gt;We moved to Kolkata in 2005 when my father’s job took us there. We lived in the company’s quarters in Tollygunge, a small, close-knit space with a single bedroom with an attached balcony that quickly became our new home. Our apartment was on the fourth floor, and the balcony overlooked the entire Kolkata. The colony had just two modest buildings, side by side, separated by a narrow passage that led to a small backyard. At the end of this passage, tucked against the wall, was a bench where you could sit and feel the world slow down. One side was flanked by the buildings, the other by a tall barrier that seemed to enclose our little world.&lt;/p&gt;
&lt;p&gt;We couldn’t roam around on our bikes as freely as we used to; the streets of Kolkata felt too busy, the city too vast for us. Luckily, the main road I lived on had a tram stop near the mosque. Trams were slow enough to be safe, yet fascinating enough for me to hang my head out of the window. I remember how the ticket looked, the old paper with a red border, and the sounds of the bells; the bus conductor used to pull a rope tied to the roof, which was connected to a bell. Slowly settling into the busy, loud Kolkata life, the tram rides were a welcome respite, a chance to slow down and watch the world pass by.&lt;/p&gt;
&lt;p&gt;A mosque was situated in the middle of the road. I used to figure out play time by listening to the &lt;em&gt;azaan&lt;/em&gt;. Four-thirty in the afternoon marked the time for me to rush out and play. The other side of the road was a sweet shop. This one was responsible for sharing all our love with our relatives who came to visit, or the friends and family whom we visited. This shop embodied the essence of Kolkata’s culture.&lt;/p&gt;
&lt;p&gt;Kolkata was kind and homely to us. The streets buzzed with busy life, clattering trams, honking yellow taxis, and the vibrant hum of people filling every corner. The smells of street food, especially sweet shops mixed with the scent of incense from nearby temples, and the narrow lanes wound through neighbourhoods like veins through the heart of the city, each turn leading to a different world. It was a world much bigger than what we were used to. The transition was already difficult for us Odias, as we did not understand Bengali, and Kolkata was adamant about making us learn it.&lt;/p&gt;
&lt;p&gt;We explored the city mostly by metro, and a trip to a station sparked an odd obsession in me—the escalators. I couldn’t resist them. I’d race up and down in the same one-way belt, completely captivated, much to my father’s chagrin. In those days, corporal punishment was a common disciplinary response to disobedience, and each time I ran wild on the escalator and fell down, every time, I knew what awaited me next. Still, I couldn’t resist the pull of the moving stairs. I had to try and see if I could walk upstairs faster than the escalator moving down. I never could. It’s only now, decades later, that I see how that simple childhood struggle foretold a pattern in my life.&lt;/p&gt;
&lt;p&gt;Initially, due to a shift in the middle of an academic year, I was enrolled in a girls’ school, which was a nightmare. Including me, there were four boys in the entire class, and I was the only one who didn’t know Bengali. The next year, we shifted to St. Joseph’s and Mary’s School, and I loved it. I don’t remember anything about it, except that the older boys had their assembly around at 12-1 pm, after we finished our classes, and this one time my principal awarded me a prize for being selected in the IMO. School life had always been good for me, and Kolkata was the beginning of my academic journey.&lt;/p&gt;
&lt;p&gt;My sister was born in 2005, and we spent the next year in Kolkata. I’m unsure how I felt about her arrival. I was five and a half. With time, I remember the feeling of having to share my parents with her, which was new and strange, and I was unwilling. A new human being started taking away all my things, which led me to feel annoyed at first. Siblings are territorial, and we were no different. We have some wild stories to tell. I pushed her so hard once that she had to get a stitch on her head. She doesn’t hold that against me anymore, now that I manage to pay her pocket money from time to time.&lt;/p&gt;
&lt;p&gt;During this time, our maid used to take care of me. She and her daughter used to babysit me and my sister. She was kind and loving, often shielding me from my mother’s scolding when I refused to study in the evenings, writing down multiplication tables. She even stood up for me when the colony kids bullied me.&lt;/p&gt;
&lt;p&gt;That nineteen-year-old evil with a stitched head is now a design student in India, using up all my clothes and my room. She crafts stories and creates art and watches weird shows while eating all the food I used to love. The adulting part of me is now constantly worried about her career, and part of me slightly understands why my parents were constantly fixated on my education and future. It doesn’t justify them, but I see them now.  Now that I don’t live with her, I miss her a lot, though I would never admit it to her. I cannot, at any cost, give her the satisfaction of knowing that I miss her.&lt;/p&gt;
&lt;p&gt;With my mother having less mobility, I roamed around with my father. Kolkata was a city of yellow taxis, constant honking, and street food. I did not have the same freedom riding my bike as I did in Bhubaneswar, but my father took me everywhere in the metro. Our family and friends visited us regularly, and we often went to the zoo, the Science City, and the Victoria Memorial.&lt;/p&gt;
&lt;p&gt;I remember one time I got lost in the Victoria Memorial. My aunt was visiting us, and we went to the Victoria Memorial. I held my father’s hand while gazing at the stars and walking straight. They seemed to follow me as if looking straight at me. I was fascinated by the stars, and I still am. They feel like a nomadic tribe, wandering the sky, telling stories of the past, much like Jajabara. At some point, my father let go of my hand to take out his wallet. Oblivious, I kept walking straight, and when I turned back, I couldn’t see him. I was lost, and an extremely kind family offered me help and asked for my father’s number. They even offered me ice cream, but I was too shaken to eat anything.&lt;/p&gt;
&lt;p&gt;Mother never let me go to the Victoria Memorial again. I feel like she had always been my mother in all other worlds—loving, pushing me to get a 100/100 in exams for only God knows what reason, and constantly opposed to whatever I wanted to do because it might be too dangerous, too expensive, or unholy in some way as if God were constantly waiting for me to eat chicken on a Tuesday and punish me for it.&lt;/p&gt;
&lt;p&gt;The most memorable part of living in Kolkata would be the train journeys to and from Kolkata to Bhubaneswar. We often visited our home in Bhubaneswar, and I loved the train journeys. The rhythmic sound of the train on the tracks is soothing, and the gentle rocking motion still comforts me while I listen to stories of fellow passengers, living their lives and judging the morality of the world. A time to disconnect from the world and connect with myself, a time to dream, to imagine, and to create.&lt;/p&gt;
&lt;p&gt;The train used to halt before entering West Bengal, and my dad would bring food from Kharagpur Station. I feel that the journeys in my life have always been exciting. They helped me live multiple lives, one in Kolkata, and others in the places I visited. During the journey, we halted at various cities, each with different relatives, friends, and stories of their own. Oddly enough, the Indian Railways has a way of making me feel at home.&lt;/p&gt;
&lt;p&gt;The transition from Indian Railways to the New York Subway is vivid in my mind, poetic in a way. The boulder, in a different form now, with different stops, 33rd Street, 42nd Street, and 59th Street, as opposed to Balasore, Kharagpur, and Howrah. The train journeys remain the same - a time for introspection.&lt;/p&gt;
&lt;p&gt;New York is now my home. Now, I feel like I have always lived here, and the memories of my childhood feel like a distant dream. Turning twenty-five reminds me of the hues of blue I grew up with, the pastel blues of the Indian Railways and the warm blue skies of Bhubaneswar. The blues in New York feel slightly different, colder.&lt;/p&gt;
&lt;p&gt;The blue skies remind me of my time in Kolkata, getting lost in the Victoria Memorial, memories of watching Power Rangers, playing too much nintendo, and the tram rides. It reminds me of the food in Kolkata, and the five-year-old me not being able to finish any food. Somewhere in mid-2007, I found myself packed with bags, my mother and cousin’s uncles helping us move with a new boulder this time. This eternal movement in my fate, my Sisyphean journey, was because my father’s job required us to constantly uproot and rebuild in different cities, every two years, as the government mandated it. The following years were spent in Asansol, a small town in West Bengal.&lt;/p&gt;
&lt;figure class=&quot;image-pair&quot;&gt;
	&lt;img alt=&quot;In a blue tub&quot; src=&quot;../assets/img/jajabara/blue_tub.webp&quot; loading=&quot;lazy&quot;&gt;
	&lt;img alt=&quot;Burritoed in a blue towel&quot; src=&quot;../assets/img/jajabara/blue_towel.webp&quot; loading=&quot;lazy&quot;&gt;
&lt;/figure&gt;
&lt;figcaption&gt;2002-2004. Bhubaneswar, India&lt;/figcaption&gt;
&lt;figure style=&quot;justify-content: center; align-items: center; display: flex;flex-direction: column;&quot;&gt;
&lt;img alt=&quot;Blue sky over Manhattan&quot; src=&quot;../assets/img/jajabara/blue_sky.webp&quot; class=&quot;h-75 w-75&quot; loading=&quot;lazy&quot;&gt;
&lt;/figure&gt;
&lt;figcaption style=&quot;text-align: center; font-size: 0.8em;&quot;&gt;May, 2025. Manhattan, NY, US&lt;/figcaption&gt;
&lt;hr&gt;
&lt;h6 id=&quot;next-entries&quot; tabindex=&quot;-1&quot;&gt;Next entries:&lt;/h6&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;&lt;a href=&quot;/blog/sisyphus.html&quot;&gt;The myth of Sisyphus (II)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/102.html&quot;&gt;The 102nd hike (III)&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

            &lt;hr&gt;
            &lt;div class=&quot;footer&quot;&gt;
              &lt;i&gt;Feedback, Suggestions, Comments - &lt;/i&gt;
              &lt;div class=&quot;giscus-div&quot; id=&quot;comments&quot;&gt;
                &lt;script src=&quot;https://giscus.app/client.js&quot; data-repo=&quot;anubhavpgit/anubhavpgit.github.io&quot; data-repo-id=&quot;MDEwOlJlcG9zaXRvcnk0MDQ1ODEzMjc=&quot; data-category-id=&quot;DIC_kwDOGB1rz84Cer0j&quot; data-mapping=&quot;title&quot; data-strict=&quot;0&quot; data-reactions-enabled=&quot;1&quot; data-emit-metadata=&quot;0&quot; data-input-position=&quot;bottom&quot; data-theme=&quot;noborder_light&quot; data-lang=&quot;en&quot; data-loading=&quot;lazy&quot; crossorigin=&quot;anonymous&quot; async=&quot;&quot;&gt;&lt;/script&gt;
              &lt;/div&gt;
              Feel free to
              &lt;a id=&quot;mailtoLink&quot; href=&quot;mailto:anubhavp@duck.com?subject=Here&apos;s%20a%20suggestion/feedback!&quot;&gt;send
                me an email&lt;/a&gt;.
            &lt;/div&gt;
          &lt;/div&gt;
        </content:encoded>
            <subtitle>A journey through whims of fate and lucid memories. Growing up and looking for the purpose of life.</subtitle>
        </item>
        <item>
            <title><![CDATA[Life, the Universe, and Everything else]]></title>
            <description><![CDATA[A few thoughts that warrant a write-up. An attempt to put into words the emotional state of the past few months; a life update.]]></description>
            <link>https://anubhavp.dev/blog/lifeandtheuniverse.html</link>
            <guid isPermaLink="true">https://anubhavp.dev/blog/lifeandtheuniverse.html</guid>
            <dc:creator><![CDATA[Anubhab Patnaik]]></dc:creator>
            <pubDate>Sun, 18 Feb 2024 00:00:00 GMT</pubDate>
            <content:encoded>
          &lt;div class=&quot;content custom&quot;&gt;
            &lt;div class=&quot;search-container&quot;&gt;&lt;/div&gt;
            &lt;p&gt;This is a recent life update. Amidst the whirlwind of emotions, finding the right words seems like catching lightning in a bottle. I’ve always been the one to share the highs, the adventures, the trips, and the zeal to power through. But now, as I peer into the shadows that have crept into my days, I find myself at a loss. I don’t know where to begin or how to put things into perspective. I might be bad at this, and all I ask of you is to bear with me.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;So here’s the deal: &lt;strong&gt;This post will be dauntingly long&lt;/strong&gt;. I’m not promising any grand revelations or profound insights. This isn’t going to be a masterpiece of prose. It’s just me, reaching out to anyone who might need to hear that they’re not alone in their struggles. Because sometimes, just knowing that someone else is stumbling through the darkness alongside you can make all the difference.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;December brought forth the wrath of everything life had to offer: the chilly unemployment, the windy solitude, the crushing weight of imposter syndrome, and the cold, relentless struggle with body image and an eating disorder. Lately, I’ve had this epiphany that I’ve been lonely and empty for quite some time now. The reasons remain elusive; I haven’t figured it out yet.&lt;/p&gt;
&lt;p&gt;These issues have always been simmering beneath the surface, but starting afresh in adulthood has brought them all to a head—like life suddenly vomited its troubles onto my metaphorical plate all at once. I was fat earlier, but college and friends made it easy. We spent time together, going on road trips and walks, sharing laughs as we strolled through the streets, kicking pebbles, and picking up the nuances of our everyday lives. I never struggled with weight back then.&lt;/p&gt;
&lt;p&gt;I weigh roughly the same now, yet adulthood has changed my perspective profoundly. Each step feels heavy as the body weight pulls me down. I’ve stopped buying clothes, knowing ‘L’-sized ones might not fit me anymore. I’ve stopped going out. I find myself avoiding mirrors, dreading the sight of my own reflection and the excess flesh that seems to haunt me. My friends and my oblivious college life made it easy. It never mattered then. It’s a struggle I face daily now, grappling with the physical and emotional toll of my weight.&lt;/p&gt;
&lt;p&gt;We pondered how we would pursue our passion and earn a shitload of money, how we would fight, build our future, save for trips, and see the world together. But now, the landscape has shifted. I find myself having nowhere to go and no one to visit. Everyone is consumed by the relentless pace of life. I still talk to those three friends with whom I’ve shared everything for the past two or three years. Nothing changed in friendship. We just grew up. We still hang out with each other. However, the lens through which I view the world has shifted, colored by the stark realities of adulthood. We can’t stay at each other’s homes. We have families to look after, money to save, debts and loans to pay back, deadlines to attend to, and work hard enough to keep our jobs.&lt;/p&gt;
&lt;p&gt;On those particularly tough days, I contemplate the meaning of it all—just going through the motions without any real sense of purpose, getting up every morning, trying to get through the day, somehow holding back all that is pulling me down, and going back to sleep, hoping that tomorrow gets magically better.&lt;/p&gt;
&lt;p&gt;The cherry on top would be these two most incredible, life-altering things that happened in December: having to find a new job and breaking up.&lt;/p&gt;
&lt;p&gt;December enveloped me in its icy grip; its harsh, frigid nights felt especially brutal as I had to leave my job and hunt for a new one. The hunt began several weeks before, but it wasn’t until December that I fully faced the burden of potential unemployment. The situation was perplexing: a tangled web of concerns involving work-life balance, higher expectations from teammates, and wrestling with self-doubt about my future and growth loomed over me. I had to move on.&lt;/p&gt;
&lt;p&gt;Each passing day brought a surge of stress and anxiety, accompanied by relentless questions echoing in my mind. Could I make it? Did I truly possess the skills to deserve another opportunity? Or was my past success merely a stroke of luck? The relentless grip of imposter syndrome left me reeling, my eyes weary, and my head pounding with loud thoughts. The fear gnawed at me—what if this were my only chance?&lt;/p&gt;
&lt;p&gt;We are the same, you and I, in the same swamps. Trust me, you’ll get there. If I could make it, you would too. I know things are hard right now, and honestly, though I may not have all the answers, I know this much: the path ahead may be daunting, but you’ll make it through. The swamps are dark, but you’re not alone.&lt;/p&gt;
&lt;p&gt;The universe dealt its masterstroke when, amidst the uncertain darkness, the one person I could always confide in decided to leave. I shut down. All I wanted was to sleep, avoid confronting the harsh reality, and not get up. But I had to. I was serving my notice period. I had to get up. How else would I pay my EMIs if I didn’t find a job?&lt;/p&gt;
&lt;p&gt;My mind raced with a million thoughts. What about the things I planned to do with her? The two-bedroom apartment we were supposed to rent in Bangalore, the road trip to Ladakh we were supposed to go on, and the new car we wanted to save money for—moving abroad together and finding jobs, all dashed in an instant. It felt like a brutal accident. How do I pick myself up and drive to the hospital? How do I go on from here, with no job and no one to talk to?&lt;/p&gt;
&lt;p&gt;Life changed after December 15th. I got a job, a better one with better pay, and got the rest of the month off. I tried to put in more work in my relationship, trying to salvage what was left of it. Things started improving. I went back home, spent time with my family, and slept all day. I went back to those familiar streets with that friend, ate all I wanted, unbothered, hung out with my friends, drove past those old streets, rolled down the windows, and let the December ember winds hit me.&lt;/p&gt;
&lt;p&gt;I went past those old college roads, looking at tiny ducklings stepping out into the real world. Observing the vibrant energy of youth, oblivious to life’s complexities, untethered, eating and laughing, brought a sense of solace. Brooding over all that I had gone through recently, I remembered that scene from &lt;em&gt;The Dark Knight&lt;/em&gt; and realized that the night is darkest just before dawn, and I &lt;strong&gt;promise you&lt;/strong&gt; that dawn is coming.&lt;/p&gt;
&lt;p&gt;The universe is oddly funny. January unfolded in vivid, contrasting shades. While work life went smoothly and was promising, my love life plummeted to unforeseen depths. We met, and she bid adieu. It was the end. She was rigid and determined. Her resolve was unyielding as she uttered, “I’ve fallen out of love.”&lt;/p&gt;
&lt;p&gt;How does one simply fall out of love? It’s a question that continues to baffle me. Long-distance relationships are inherently challenging, requiring immense love, effort, and dedication to sustain. Any relationship, for that matter, is equally challenging. January left me shattered. I fought hard to get out of this. I tried going on walks and talking to people. Nothing helped.&lt;/p&gt;
&lt;p&gt;As a man grappling with both the aftermath of a breakup and the desire for self-improvement, I found myself lost in a sea of uncertainty. A fat guy who got dumped, trying to make it, become thinner, and get payback by building himself up. It didn’t work for me; I couldn’t push myself enough. Life became blank. Those million questions came rushing back. How do you stop talking to somebody you planned your entire life with? This seems like a new life altogether.&lt;/p&gt;
&lt;p&gt;She said she needed to explore herself, figure out more about her, and find out who she really was, rather than staying my girlfriend. She said she never got a chance to discover more about herself.&lt;/p&gt;
&lt;p&gt;A part of me wanted what was best for her, even if it meant separating. A part of me understood her motivations and truly wished for her happiness, while another part longed for reconciliation, clinging to hope like a fragile icicle. I had no choice but to agree with her, secretly wishing that she would do all this while staying together. A part of me saw through the facade. I knew she had mentally checked out long before. A part of me remembers the last few conversations we had, where she always seemed disengaged, where the conclusion was always the same — she wanted to break up and organise her life. The timeline was just being drawn out. The plans were being charted out.&lt;/p&gt;
&lt;p&gt;Had she always been out of love? Or maybe she knew she was going to move on eventually, her exploration of self was always the plan. Maybe a part of her journey was to experience life with different people before finally settling down. Maybe this was all premeditated; letting me down gently over time. A part of me truly wishes the best for her.&lt;/p&gt;
&lt;p&gt;The dread begins when you’re still connected on social media and find out that she has moved on. The realization that she had been mentally disconnected long before physically severing ties only added to the anguish. The thought that she moved on a while ago, while you were stuck there, dreaming of a life that was never there, now intensifies this mental agony. The dread is when you ponder all the inconsistencies, like how she claimed she wanted to live life without being involved with men for a year or so before finally moving on, yet it didn’t take her more than a week to let go.&lt;/p&gt;
&lt;p&gt;Hope is the most destructive tool. It’s the hope that kills you. Hope builds up when she calls back, wants to talk to you, and tells you she misses you. Hope builds faith. Faith makes you a fanatic. Hope is that same icicle that now wrecks your heart when she says she wants you to move on as she did. What does kill hope?&lt;/p&gt;
&lt;p&gt;To you, reading this, if you’re facing similar struggles, know that I’m right there with you, navigating these stormy waters as best I can.&lt;/p&gt;
&lt;p&gt;It’s February 18th today. I sit alone in my room, writing this in a familiar place—my chest feeling heavy, lost in the depths of despair, grappling with loneliness, wondering what went wrong and what I could have done differently. Each passing moment feels like a battle, as I wrestle with the question: Where do I go from here?&lt;/p&gt;
&lt;p&gt;The idea of stepping into the gym beckons, but doubts claw at the edges of my mind. The thought of lacing up my sneakers and embarking on the daily pilgrimage to the gym fills me with apprehension, each step a painful reminder of my lack of discipline. How do I make friends? Bangalore is a bustling city. My friends do not have time. They are either busy with work, stay far away, or have more important things to deal with. Nobody has time.&lt;/p&gt;
&lt;p&gt;I tried dating apps for a month, but they didn’t work. The internet made it pretty clear that the crowd wasn’t interested. Will I be forever alone? In a city teeming with life, I find myself adrift, yearning for connection but unable to find a foothold.&lt;/p&gt;
&lt;p&gt;As I said, I don’t have a solution. What has worked for me so far includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Hobbies and keeping busy&lt;/strong&gt;: Life goes on. As you tend to work more, follow up on your hobbies, take up singing classes, pick up those boxing lessons that you’ve always marked as not-done on your list, walk and shop for the shopping list you had, you slowly realize that it isn’t so bad after all. Looking at people from all walks of life, talking to them and living their stories lifts you up.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Reading, watching, gaming&lt;/strong&gt;: Those half-read books, the shows left behind, and the paused podcasts are yet to be finished. Delving into stories, living lives as mythical new characters, fighting demons in hell, and yearning for the love of your wife like &lt;em&gt;Kratos&lt;/em&gt; pushes up your heart. You feel happy, wanting to eat pizza, chug boba tea, and sleep peacefully.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Trips, day outs, and living more&lt;/strong&gt;: Take out time to live. Do not think; book that solo trip. Order that tandoori chicken and bump up the volume on that stand-up special. Convince friends to build that project together. Take synchronized leaves with friends, and carry out that Goa plan. At the end of the day, you’ll find it easy to fall asleep when you’re tired from the trip, looking at the moon from the beach, and thinking about all that went wrong. You may find a couple of answers written up there, or somewhere beyond the horizon where the water, the sun, and the sky meet.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Talk to people&lt;/strong&gt;: I know and understand that sharing is hard. But try talking to people—your close friends, family, or even the guy who sells you milk and newspapers. People relate and share stories, and in these conversations, you tend to find answers. Confiding in people helps.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you’re still reading this, I thank you from the deepest, rockiest bottom of my heart for staying with me and reading through all my misery. If you’re going through something like this, you are not alone. I am still figuring out how to save money, build discipline to go to the gym, lose weight, and find someone—life is too beautiful to spend alone. I’m looking for a group of friends willing to take me in.&lt;/p&gt;
&lt;p&gt;I am still inside these swamps, trying just to get a breath and not drown and swirl to the depths. I’ve caught a few breaths, barely staying alive. I can assure you, it gets easier as we move forward. The despair doesn’t recede. We become busy and slowly start moving on. We tend to grow around this space. This is what real growth looks like: waking up someday, not feeling like crying, and actually wanting to look forward to what the day has to offer. Willing enough to go to sleep, peaceful. Starting to live, and not merely exist. We aren’t there yet. We will get there, together.&lt;/p&gt;

            &lt;hr&gt;
            &lt;div class=&quot;footer&quot;&gt;
              &lt;i&gt;Feedback, Suggestions, Comments - &lt;/i&gt;
              &lt;div class=&quot;giscus-div&quot; id=&quot;comments&quot;&gt;
                &lt;script src=&quot;https://giscus.app/client.js&quot; data-repo=&quot;anubhavpgit/anubhavpgit.github.io&quot; data-repo-id=&quot;MDEwOlJlcG9zaXRvcnk0MDQ1ODEzMjc=&quot; data-category-id=&quot;DIC_kwDOGB1rz84Cer0j&quot; data-mapping=&quot;title&quot; data-strict=&quot;0&quot; data-reactions-enabled=&quot;1&quot; data-emit-metadata=&quot;0&quot; data-input-position=&quot;bottom&quot; data-theme=&quot;noborder_light&quot; data-lang=&quot;en&quot; data-loading=&quot;lazy&quot; crossorigin=&quot;anonymous&quot; async=&quot;&quot;&gt;&lt;/script&gt;
              &lt;/div&gt;
              Feel free to
              &lt;a id=&quot;mailtoLink&quot; href=&quot;mailto:anubhavp@duck.com?subject=Here&apos;s%20a%20suggestion/feedback!&quot;&gt;send
                me an email&lt;/a&gt;.
            &lt;/div&gt;
          &lt;/div&gt;
        </content:encoded>
            <subtitle>A few thoughts that warrant a write-up. An attempt to put into words the emotional state of the past few months; a life update.</subtitle>
        </item>
        <item>
            <title><![CDATA[Decentralization in MetaMUI Wallet]]></title>
            <description><![CDATA[A case study on how MetaMUI wallet claims to be decentralized and how it actully works.]]></description>
            <link>https://anubhavp.dev/blog/metamuiwallet.html</link>
            <guid isPermaLink="true">https://anubhavp.dev/blog/metamuiwallet.html</guid>
            <dc:creator><![CDATA[Anubhab Patnaik]]></dc:creator>
            <pubDate>Wed, 31 Aug 2022 00:00:00 GMT</pubDate>
            <content:encoded>
          &lt;div class=&quot;content custom&quot;&gt;
            &lt;div class=&quot;search-container&quot;&gt;&lt;/div&gt;
            &lt;p&gt;I am working with &lt;a href=&quot;https://squbix.com/&quot;&gt;Squbix Digital&lt;/a&gt; to build a decentralized, secure and scalable solution using blockchain technology for &lt;a href=&quot;https://swnglobal.com/&quot;&gt;Sovereign Wallet&lt;/a&gt;. The solution is to build a platform to exchange digital assets such as cryptocurrencies and digital currencies across a country/ organization and a cross-border payments system. Here is the &lt;a href=&quot;https://sovereignwallet-network.github.io/whitepaper/MetaMUI-Blockchain-White-Paper.pdf&quot;&gt;metamui whitepaper&lt;/a&gt; and here are some of the things that I couldn’t digest well.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#metablockchain-core&quot;&gt;Metablockchain-core&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#robust-decentralized-and-secure&quot;&gt;Robust, decentralized, and secure?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#issues-with-the-current-infrastructure&quot;&gt;Issues with the current infrastructure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#ideological-challenges&quot;&gt;Ideological challenges&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#a-better-direction&quot;&gt;A better direction&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#improving-the-current-infrastructure&quot;&gt;Improving the current infrastructure&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;metablockchain-core&quot; tabindex=&quot;-1&quot;&gt;Metablockchain-core&lt;/h2&gt;
&lt;p&gt;Metablockchain: The blockchain that lets you regulate digital currencies and cryptocurrencies across the nation. The platform is built on Polkadot protocol that has significantly better runtime efficiency, is cost-effective, and supports parallel faster transactions when compared to other traditional blockchains. The Polkadot protocol is designed to allow unrelated blockchains to securely talk to each other, so that value or data can flow between, say, the Ethereum and Bitcoin blockchains without any intermediary. It’s also designed to be speedy and scalable, via the use of many parallel blockchains (or “parachains”) that take much of the processing demand off of the main blockchain. The Polkadot network can process more than 1,000 transactions per second, compared to about 7 for Bitcoin and 30 for Ethereum. As the network grows and more parachains are added, Polkadot should get even faster, with speeds that could hit a million transactions per second.&lt;/p&gt;
&lt;h3 id=&quot;robust-decentralized-and-secure&quot; tabindex=&quot;-1&quot;&gt;Robust, decentralized, and secure?&lt;/h3&gt;
&lt;p&gt;The product is built in such a way that a country/ government/central banking authority can adopt this platform and make it run parallel with the currently existing infrastructure. Users can send and receive money across the country and it takes significantly less time to handle international transactions. It seems great, an easier way to handle transactions, without having to pay taxes to the government for making international exchanges! But the reality may not be as exciting.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;MetaMUI is claimed to solve the blockchain trilemma by having a hybrid architecture. For micropayment, we
used centralized architecture to achieve high performance and high security. For higher volume payment, we
used decentralized architecture to achieve high security and decentralization.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The current infrastructure is easy to use but is not as secure as claimed. The primary goal of the infrastructure is to make it easier for users to send and receive (traditional banking) money across the country and, it is not secure because it is &lt;strong&gt;not decentralized&lt;/strong&gt;, and &lt;strong&gt;well-developed&lt;/strong&gt; . Introducing a blockchain as a means of a runtime to carry out transactions as opposed to a traditional banking system is to make sure that all the transactions are handled in a decentralized manner and anyone when wanted, can query and view the source, and all the states of the transactions but it is not the case here.&lt;/p&gt;
&lt;h3 id=&quot;issues-with-the-current-infrastructure&quot; tabindex=&quot;-1&quot;&gt;Issues with the current infrastructure&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;The usage of a private blockchain&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The banks are responsible for running validator nodes that run on the private blockchain and are responsible for validating the transactions and the states of the system. The claims as said were to improve security and transparency but this approach opposes the purpose of the claims. A private blockchain to carry out transactions makes it a kind of database and a runtime that is not public and not accessible to anyone. The banks are servers and the blockchains act as databases. The clients are the users. Seem familiar? This is a client-server architecture with a blockchain running as a database.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Bank Node is a publisher of anonymous tokenized cash. Users can choose Bank Node service providers and
have a token contract to issue digital cash. Based on the contract, it can be a debit card or credit card type.
When the user pays the merchant with digital cash, the merchant can claim the digital currency to the issuing
Bank Node. “The performance of this payment process should be equal to or better than normal credit card
payments.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;For high-volume money transfer, MetaMUI utilizes a normal blockchain consensus protocol. All Bank Nodes are
involved in the consensus of multiple digital currencies. Since this a transfer between identities, it is a kind of
digital cheque payment. Also since we are using blockchain consensus to do so instead of a centralized server
for cheque clearance, this is a decentralized cheque system. This payment process is slower than the
conventional credit card payment but it is much faster and costs less than an account-based international bank
transfer.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Building a platform for carrying out transactions is perfectly okay but introducing blockchains as a means of a just database doesn’t make sense. It feels like a gimmick, a buzzword to secure seed &amp;amp; money from investors. Also, there is nothing wrong with a client-server architecture but the speed of current infrastructure relies on implementing a blockchain as a runtime for transactions, which, as always, is &lt;strong&gt;slow&lt;/strong&gt;. Blockchains are supposed to be secure and transparent but they are not efficient and fast. The transaction data when accessible publicly make the network secure, which it is not, here. Whereas a more traditional client-server architecture is equally secure and more efficient. Look at the current banking and payment gateway scenario in India. UPI payments, net banking, and debit card payments, are all carried out in a secure environment and are blazing fast.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A blockchain-style data store is secure but it is not efficient in terms of computation, communication, and data point of view.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;The Consensus mechanism&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;Consesnus Protocol
MetaMUI’s consensus protocol is a combination of PBFT(Practical Byzantine Fault Tolerance) and PoS(Proof of
Stake). Only Bank Nodes participate in the consensus of built-in blockchains. Bank Node can be a block
proposer and endorser of both built-in blockchains and all digital currency blockchains. The mobile node can
participate in the consensus of newly created digital currencies as an endorser. In the case of digital currency
consensus, &lt;strong&gt;only a Bank Node can be a leader or the block proposer&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Bank nodes have the authority to govern, validate transactions and decide the fate of the entire system, which makes the bank a central authority here. This gives authority to the bank nodes to validate any transactions. The bank may decide to invalidate valid transactions or validate invalid transactions and no one would know cause it would be there “on the blockchain”. (Not saying that this would be done, because a banking sector obviously wouldn’t carry out fraudulent transactions.) This does raise a question about the prorposed solution that claims to have solved the blockchain trilemma.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The leader node also acts as a serializer to serialize transactions. The leader node receives block rewards and
transaction fees. Endorser also receives the endorsing rewards when the node’s endorsement is included in the
majority vote.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The endorser and leader nodes receive rewards based on the node’s endorsement. The endorser node receives the
endorsement rewards when the node’s endorsement is included in the majority vote. The leader node receives the
block rewards when the node’s block is included in the majority vote. How does a network with an nPOS consensus protocol pay or reward nodes if there are no gas fees involved?&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;ACB (Algorithmic central bank)&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The current platform runs a single and private blockchain without any overhead of the AI mechanism that will fuel the infrastructure.
Implementing the Algorithmic Central Bank can be a key player in the industry. The current platform is inefficient when run using a single private blockchain and no centralized banking establishment to control inflation and deflation. The product can be improved when the existing mechanism as proposed in the whitepaper come to play. The current platform might not be a very good solution for the industry unless the stated propositions come to play.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;MetaMUI is just the starting point. We suggested fundamental solutions for Algorithmic Central Bank and a
decentralized, but expandable ecosystem based on mobile nodes. But we believe the current development of
artificial intelligence technologies such as deep learning and reinforcement learning will be the key game changers of the blockchain platform. MetaMUI was designed to take care of these technologies. In near future,
we can see the powerful coordination of more flexibilities based on artificial intelligence and robustness/
stability for transactions based on the blockchain platform.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;The digitalization of currency opens up new opportunities for digitalized monetary decision-making. Bank node
is an early form of Algorithmic Central Bank that makes monetary decisions based on financial big data. It is
possible to apply a federated learning algorithm at the central bank node and collect and learn a decentralized
model on many mobile nodes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;ideological-challenges&quot; tabindex=&quot;-1&quot;&gt;Ideological challenges&lt;/h3&gt;
&lt;p&gt;MetaMUI wallet also lets you regulate digital currencies and crypto-currencies across the world and carry out transactions without having to pay conversion fees. This current implementation of the ideology may become an issue because of the following reasons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Governments of countries do not generally allow cryptocurrencies to be legal tender.&lt;/strong&gt; There are two countries as of now that currently allow cryptocurrencies to be traded and accepted as legal tender and both of them are not the most developed or developing nations in the world. Targeting these countries to sell the platform might not be wise.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Governments usually have a means of regulating easier banking methods and exchange methods. Let us take the example of India. India doesn’t allow cryptocurrencies to be legal tender. Digital payments are very popular and online payments being carried out in India follow traditional banking and government norms and are very fast. I don’t think anyone in the current generation nowadays goes to the bank to deposit or withdraw money. Let us take another example of the UID system followed in India, &lt;strong&gt;Adhaar&lt;/strong&gt; system. The system is encrypted using military-grade encryption. The system is very secure and the government is very responsible for the security of the system. The current implementation of encryption used at MetaMUI Wallet is SHA-256 which although a very secure algorithm would seem like legacy software for the Indian government to integrate and work with. The task is tedious and unnecessary.&lt;/p&gt;
&lt;p&gt;There seems no solid revolutionary reason for a bank/government to introduce a new platform to run which regulates and carries out transactions and exchanges for free. Excellent existing platforms are already available and our infrastructure is not a new platform. &lt;em&gt;(Paytm, Gpay, Paypal, CoinDCX etc.)&lt;/em&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Conversion fees are a means of generating tax for a government.&lt;/strong&gt; International exchanges or cryptocurrency exchanges are a means of generating tax for a government. When you convert INR to USD or vice versa, you are generating tax for the government. Current conversion from ETH, BTC to INR is a very low fee but there does exist a fee.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;MetaMUI Network is an Internet-based cross-border payment network. In MetaMUI Network, each user’s DID is
a universal accounting address that user can send or receive digital currencies. Utilizing collateral asset feature
and meta-blockchain feature of MetaMUI Blockchain, it is possible to dynamically create meta-coin on the fly to
facilitate cross-border payment between the currencies those are not on the MetaMUI Network. Similar to the
stable coin issuance, central bank or commercial bank of each country can create stable meta-coin on the
MetaMUI Network and perform international fund transfer&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The platform introduced doesn’t have gas fees. Gas fees are the fees in a blockchain that you need to pay to make a transaction or carry out a smart contract. A miner validates your transaction by spending its computation power and in return is awarded the gas money. Gas fees are a means of generating revenue for a miner, but having no gas fees in a private blockchain implies that the bank and the infrastructure have to spend money on electricity and computing resources to validate transactions. It doesn’t make sense to have a platform that makes you spend money on electricity and computing resources just to validate transactions.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When users are trading digital stocks or assets in a peer-to-peer way, MetaMUI provides an atomic swap of
digital stock and digital currency. Since digital stock is bind to the user’s identity, ownership transfer notification
and tax payment can happen at the same time as the stock trade. This eliminates the need for separate
shareholder registration, issuance of shareholder certificates, tax reports to the government, and tax payments.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let us again take the example of India. Cryptocurrencies when made legal in India would have a 30% conversion fee, you’d have to pay a 30% tax to the government for converting the cryptocurrency. It wouldn’t make sense for India to allow the platform to run without a conversion fee. Also, there are a lot of other, well-established platforms playing in the same field and pitching and hitting hard in these areas. &lt;em&gt;(CoinDCX, Coinbase, etc)&lt;/em&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Present operating scenario in foreign exchange platforms.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;Cheaper, faster, and efficient cross-border payments are the need of the hour in today’s digital world. The
MetaMUI Network is designed to host multiple blockchains concurrently. Each of these blockchains can run
independently of each other and communicate (transact) with each other. The currency exchange is made
possible through atomic swaps and multi-currency transfer is possible with an exchange service provider
(Master Node) making it excellent for direct sovereign currency to sovereign currency cross-border payments&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The existing exchange platforms are extremely secure, well-established, and highly efficient. The working and operation of these platforms are governed by international laws. The current implementation of MetaMUI Wallet doesn’t include any gas fees for transactions. It’d either have to tie up with an exchange platform or would have to come up with some other way to convince a country to let it handle all of its transactions. Either way, it would be both cost ineffective solutions. With private blockchains and 0 gas fees, MetaMUI Wallet will be having a hard time trying to carry out free transactions across the globe. The organization, at first, would have to pay for the mining and electricity and on top of that would have to pay the cross-border payment fees too.&lt;/p&gt;
&lt;h2 id=&quot;a-better-direction&quot; tabindex=&quot;-1&quot;&gt;A better direction&lt;/h2&gt;
&lt;p&gt;There might exist better, more efficient solutions to the above problems but two of them may have these similar approaches:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Introduce a public blockchain&lt;/strong&gt; This solves the problem of spending money on validating transactions. Miners can validate transactions and the government/ bank can verify the transactions. This would be a huge bump in security, transparency, and cost efficiency.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It still doesn’t solve the problem of introducing a new platform just to do this. The tax play still becomes an issue here. How does the platform plan on managing taxes? Why would a bank allow a platform to run which would not benefit it in any manner? The government levies taxes to exchange international currencies. Why would it stop doing that? Even if it is allowed, how would it compete with other platforms working towards a similar strategy?&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Following traditional client-server architecture using a distributed database&lt;/strong&gt; This would solve the problem of efficiency. Traditional architectures have been here for a very long time and a lot of research has been done on optimizing the existing infrastructure. Horizontal slicing, vertical slicing, and many other optimization techniques may be used to improve the efficiency of the platform. The platform would be faster, equally secure, and more efficient.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The issue with this approach is that what problem is it really trying to solve. Don’t there exist platforms that are already doing everything this infrastructure is trying to solve? How would it be able to compete with the existing giants? Isn’t the solution building a redundant, regular, exchange banking platform that the world has no less of?  How would the platform differentiate itself? What is MVP, the USP of the platform? If it decides to work together with the government, what ensures that other existing strong infrastructures do not also decide to do this and do it better?&lt;/p&gt;
&lt;h3 id=&quot;improving-the-current-infrastructure&quot; tabindex=&quot;-1&quot;&gt;Improving the current infrastructure&lt;/h3&gt;
&lt;p&gt;The approaches may be justified once some of the important issues are addressed. Other than the mentioned problems, a lot of other factors need to make sense in order to improve and make the platform more a feasible good product to be sold. The product being built is excellent, no doubt. The deep learning models in the ACB mechanism, the tech being used, the next generation Polkadot blockchains which are much, much faster (1000 transactions per second as compared to 7-10 transactions in traditional blockchain networks) and allow a huge no. of queries in a much faster time, the faster and more efficient transaction mechanisms, interoperability, the economic scalability, user-driven governance, the forkless upgrades, and the claimed security and transparency, are a step in the right direction, but there are grave issues those still need to be addressed before the product is introduced and launched.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Ref: &lt;a href=&quot;https://sovereignwallet-network.github.io/whitepaper/MetaMUI-Blockchain-White-Paper.pdf&quot;&gt;Whitepaper&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

            &lt;hr&gt;
            &lt;div class=&quot;footer&quot;&gt;
              &lt;i&gt;Feedback, Suggestions, Comments - &lt;/i&gt;
              &lt;div class=&quot;giscus-div&quot; id=&quot;comments&quot;&gt;
                &lt;script src=&quot;https://giscus.app/client.js&quot; data-repo=&quot;anubhavpgit/anubhavpgit.github.io&quot; data-repo-id=&quot;MDEwOlJlcG9zaXRvcnk0MDQ1ODEzMjc=&quot; data-category-id=&quot;DIC_kwDOGB1rz84Cer0j&quot; data-mapping=&quot;title&quot; data-strict=&quot;0&quot; data-reactions-enabled=&quot;1&quot; data-emit-metadata=&quot;0&quot; data-input-position=&quot;bottom&quot; data-theme=&quot;noborder_light&quot; data-lang=&quot;en&quot; data-loading=&quot;lazy&quot; crossorigin=&quot;anonymous&quot; async=&quot;&quot;&gt;&lt;/script&gt;
              &lt;/div&gt;
              Feel free to
              &lt;a id=&quot;mailtoLink&quot; href=&quot;mailto:anubhavp@duck.com?subject=Here&apos;s%20a%20suggestion/feedback!&quot;&gt;send
                me an email&lt;/a&gt;.
            &lt;/div&gt;
          &lt;/div&gt;
        </content:encoded>
            <subtitle>A case study on how MetaMUI wallet claims to be decentralized and how it actully works.</subtitle>
        </item>
        <item>
            <title><![CDATA[Neak: Natural Language --> SQL]]></title>
            <description><![CDATA[Neak is a natural language to SQL engine that uses the RAG pipeline to generate SQL queries from natural language questions.]]></description>
            <link>https://anubhavp.dev/blog/neak.html</link>
            <guid isPermaLink="true">https://anubhavp.dev/blog/neak.html</guid>
            <dc:creator><![CDATA[Anubhab Patnaik]]></dc:creator>
            <pubDate>Sun, 10 Dec 2023 00:00:00 GMT</pubDate>
            <content:encoded>
          &lt;div class=&quot;content custom&quot;&gt;
            &lt;div class=&quot;search-container&quot;&gt;&lt;/div&gt;
            &lt;p&gt;In the realm of AI, it is evident that for those without technical expertise, the desire to steer away from coding or constructing intricate queries has intensified. The advent of large language models has conditioned us to prioritize results. We do not want to do the manual labor of writing code or queries. Instead, we now tend to present a cluster of questions, offer contextual details, and allow GPT and similar tools to handle the rest. From writing a letter to building scalable applications, LLMs like Chat-GPT, Bard, Llama etc. have become the go-to tools for all our needs. The most complex of tasks, such as writing code or constructing queries have become a breeze.&lt;/p&gt;
&lt;p&gt;However, a challenge arises when we seek to safeguard our data from direct interaction with the LLM layer. Neak expands upon the RAG framework by specializing in generating SQL queries from natural language inquiries without letting LLM touch the actual data.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Caveat: This is a work in progress. The code is not yet available for public use. Below is a brief overview of the project.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;prompt-engineering&quot; tabindex=&quot;-1&quot;&gt;Prompt Engineering&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;“Prompt engineering is the process of structuring text that can be interpreted and understood by a generative AI model. A prompt is natural language text describing the task that an AI should perform”.&lt;/em&gt; (Source: &lt;a href=&quot;https://en.wikipedia.org/wiki/Prompt_engineering&quot;&gt;Wikipedia&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;In the realm of AI, SQL query generation utilizes prompt engineering: a prompt, essentially a natural language query, is inputted into the AI model, which in turn generates the SQL query. For accurate query generation, the model necessitates training on an extensive dataset containing questions paired with their respective SQL queries.&lt;/p&gt;
&lt;p&gt;Some of the popular models for SQL query generation are:&lt;/p&gt;
&lt;h3 id=&quot;lang-chain-sql-generator&quot; tabindex=&quot;-1&quot;&gt;Lang Chain SQL Generator&lt;/h3&gt;
&lt;p&gt;Lang Chain has a dedicated module for SQL query generation. The module is called &lt;code&gt;langchain.chat_models.ChatOpenAI&lt;/code&gt;. To generate a SQL query from a DB, a short Python code may look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;model = ChatOpenAI()

sql_response = (
    RunnablePassthrough.assign(schema=get_schema)
    | prompt
    | model.bind(stop=[&lt;span class=&quot;hljs-string&quot;&gt;&quot;\nSQLResult:&quot;&lt;/span&gt;])
    | StrOutputParser()
)

sql_response.invoke({&lt;span class=&quot;hljs-string&quot;&gt;&quot;question&quot;&lt;/span&gt;: &lt;span class=&quot;hljs-string&quot;&gt;&quot;How many employees are there?&quot;&lt;/span&gt;})

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The function uses the schema of the db to generate an SQL query and then runs the query to get the result. This is part of a code section to generate SQL from plain text. The full code can be found here: &lt;a href=&quot;https://python.langchain.com/docs/expression_language/cookbook/sql_db&quot;&gt;&lt;em&gt;Reference&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;sql-coder&quot; tabindex=&quot;-1&quot;&gt;SQL Coder&lt;/h3&gt;
&lt;p&gt;Defog’s SQLCoder is a state-of-the-art LLM for converting natural language questions to SQL queries. SQLCoder is a 15B parameter model that slightly outperforms GPT-3.5-turbo for natural language to SQL generation tasks on the ‘sql-eval’ framework and significantly outperforms all popular open-source models. It also significantly outperforms text-davinci-003, a model that’s more than 10 times its size.&lt;/p&gt;
&lt;p&gt;SQLCoder is fine-tuned on a base StarCoder model. Defog was trained on more than 20,000 human-curated questions. These questions were based on 10 different schemas. None of the schemas in the training data were included in the evaluation framework. &lt;a href=&quot;https://github.com/defog-ai/sqlcoder&quot;&gt;Reference&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Picture this: you need SQL queries for your database’s data. Usually, an AI or LLM needs the dataset or context to generate these queries. But here’s the catch – &lt;strong&gt;sharing sensitive data with the AI&lt;/strong&gt; layer might not be safe. The data might be leaked, and the privacy of the users might be compromised. You would not want to share your data with the AI layer.&lt;/p&gt;
&lt;h2 id=&quot;rag-pipelines&quot; tabindex=&quot;-1&quot;&gt;RAG pipelines&lt;/h2&gt;
&lt;p&gt;A recent addition to the NLP landscape is the RAG (Retrieval Augmented Generation) pipeline. This involves retrieving &lt;strong&gt;relevant documents&lt;/strong&gt; from a large corpus and then using a generator to generate the answer. Retrieval-Augmented Generation (RAG) is the concept to provide LLMs with additional information from an external knowledge source. This allows them to generate more accurate and contextual answers while reducing hallucinations.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Advantages of RAG pipelines:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The retriever &lt;strong&gt;only provides the relevant data&lt;/strong&gt; to the generator. This&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;reduces the amount of data that the generator has to process,&lt;/li&gt;
&lt;li&gt;improves the accuracy of the generator as it hallucinates less, and&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;protects the privacy of the data&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some of the recent RAG pipelines are:&lt;/p&gt;
&lt;h3 id=&quot;lang-chain&quot; tabindex=&quot;-1&quot;&gt;Lang Chain&lt;/h3&gt;
&lt;p&gt;Lang chain also implements dedicated workflows using RAG pipelines. The data is stored in a vectorstore and the retriever is a FAISS index. The generator is a LLM. A code snippet to generate SQL from plain text using RAG pipelines looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;vector store = FAISS.from_texts(
    [&lt;span class=&quot;hljs-string&quot;&gt;&quot;Harrison worked at Kensho&quot;&lt;/span&gt;], embedding=OpenAIEmbeddings()
)
retriever = vectorstore.as_retriever()

template = &lt;span class=&quot;hljs-string&quot;&gt;&quot; Answer the question based only on the following context:
{context}

Question: {question}
&quot;&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;&quot;&quot;&lt;/span&gt;
prompt = ChatPromptTemplate.from_template(template)

model = ChatOpenAI()

chain = (
    {&lt;span class=&quot;hljs-string&quot;&gt;&quot;context&quot;&lt;/span&gt;: retriever, &lt;span class=&quot;hljs-string&quot;&gt;&quot;question&quot;&lt;/span&gt;: RunnablePassthrough()}
    | prompt
    | model
    | StrOutputParser()
)

chain.invoke(&lt;span class=&quot;hljs-string&quot;&gt;&quot;where did harrison work?&quot;&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The code attempts to create a vector of data and then uses the vector to retrieve the answer. The generator breaks down the question into words and then generates a vector for each word. The dataset is then searched for the nearest vectors and &lt;strong&gt;only&lt;/strong&gt; the relevant data is sent to the AI model/ LLM to generate the SQL query.&lt;/p&gt;
&lt;p&gt;The full code can be found here: &lt;a href=&quot;https://python.langchain.com/docs/expression_language/cookbook/retrieval&quot;&gt;&lt;em&gt;Reference&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;llama-index&quot; tabindex=&quot;-1&quot;&gt;Llama Index&lt;/h3&gt;
&lt;p&gt;Llama Index follows a similar RAG pipeline. In Llama Index, a query engine is a generic interface that allows you to ask questions about your data.&lt;/p&gt;
&lt;p&gt;A query engine takes in a natural language query and returns a rich response. It is most often (but not always) built on one or many indexes via retrievers. You can compose multiple query engines to achieve more advanced capability.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# paul_graham_essay.txt&lt;/span&gt;
documents = SimpleDirectoryReader(&lt;span class=&quot;hljs-string&quot;&gt;&quot;data&quot;&lt;/span&gt;).load_data()
index = VectorStoreIndex.from_documents(documents)

query_engine = index.as_query_engine()
response = query_engine.query(&lt;span class=&quot;hljs-string&quot;&gt;&quot;Who is Paul Graham.&quot;&lt;/span&gt;)

To stream response:

query_engine = index.as_query_engine(streaming=&lt;span class=&quot;hljs-literal&quot;&gt;True&lt;/span&gt;)
streaming_response = query_engine.query(&lt;span class=&quot;hljs-string&quot;&gt;&quot;Who is Paul Graham.&quot;&lt;/span&gt;)
streaming_response.print_response_stream()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, the essay is vectorized, and then the query engine is used to generate the answer. The full code can be found here: &lt;a href=&quot;https://docs.llamaindex.ai/en/stable/getting_started/starter_example.html&quot;&gt;&lt;em&gt;Reference&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;An RAG (Retriever-Generator) pipeline comprises two core components: a retriever and a generator. In this setup, the retriever functions as a vector store, while the generator is typically an AI model, often an LLM. Their collaboration involves the retriever’s task of extracting pertinent data from the vector store based on the question, followed by the generator’s role in crafting the answer.&lt;/p&gt;
&lt;p&gt;Thus, you would want to use an &lt;em&gt;RAG pipeline&lt;/em&gt; to generate the SQL queries instead of sharing sensitive data with the LLM layer. However, RAG pipelines tend to be &lt;strong&gt;slow&lt;/strong&gt; and are not as accurate as &lt;strong&gt;prompt engineering&lt;/strong&gt;. The &lt;strong&gt;process of storing the data&lt;/strong&gt; in a vector store and then retrieving the data from the vector store is time-consuming. After that, LLMs tend to &lt;strong&gt;hallucinate&lt;/strong&gt; a lot.&lt;/p&gt;
&lt;h2 id=&quot;neak&quot; tabindex=&quot;-1&quot;&gt;Neak&lt;/h2&gt;
&lt;p&gt;Neak builds up on the LlamaIndex query engine and tries to solve this performance issue. It tries to reduce the time taken to generate SQL queries using RAG pipelines and reduce the hallucinations.&lt;/p&gt;
&lt;p&gt;Neak achieves this by:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Improving the retriever
&lt;ul&gt;
&lt;li&gt;Chunking only the &lt;strong&gt;schema&lt;/strong&gt; of the database and not the actual data.&lt;/li&gt;
&lt;li&gt;Setting the chunk size efficiently. A &lt;strong&gt;single chunk&lt;/strong&gt; corresponds to a &lt;strong&gt;single table&lt;/strong&gt; in the database. The chunk size is small enough to not leak any sensitive information.&lt;/li&gt;
&lt;li&gt;Using an &lt;strong&gt;in-memory vector store&lt;/strong&gt; to store the schema.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Improving the generator
&lt;ul&gt;
&lt;li&gt;Using a &lt;strong&gt;sub-querying engine&lt;/strong&gt; to generate better prompts from the original query/ question.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;chunking&quot; tabindex=&quot;-1&quot;&gt;Chunking&lt;/h3&gt;
&lt;p&gt;Using Llama Index’s chunking engine, the schema of the database is chunked. The chunk size is set to a single table. This ensures that no sensitive data is leaked.&lt;/p&gt;
&lt;p&gt;The chunks of the Postgres database may look something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;public&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;hljs-attr&quot;&gt;&quot;departments&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-punctuation&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;hljs-comment&quot;&gt;// chunk 1 in raw text&lt;/span&gt;
            &lt;span class=&quot;hljs-punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;hljs-attr&quot;&gt;&quot;columnName&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;department_id&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;hljs-attr&quot;&gt;&quot;dataType&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;integer&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;hljs-attr&quot;&gt;&quot;isNullable&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;NO&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;hljs-attr&quot;&gt;&quot;default&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;nextval(&apos;departments_department_id_seq&apos;::regclass)&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;hljs-attr&quot;&gt;&quot;udtName&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;int4&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;hljs-attr&quot;&gt;&quot;udtSchema&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;pg_catalog&quot;&lt;/span&gt;
            &lt;span class=&quot;hljs-punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;hljs-comment&quot;&gt;// chunk 2 in raw text&lt;/span&gt;
            &lt;span class=&quot;hljs-punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;hljs-attr&quot;&gt;&quot;columnName&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;department_name&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;hljs-attr&quot;&gt;&quot;dataType&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;character varying&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;hljs-attr&quot;&gt;&quot;isNullable&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;NO&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;hljs-attr&quot;&gt;&quot;default&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;null&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;hljs-attr&quot;&gt;&quot;udtName&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;varchar&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;hljs-attr&quot;&gt;&quot;udtSchema&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;pg_catalog&quot;&lt;/span&gt;
            &lt;span class=&quot;hljs-punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;hljs-punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;hljs-attr&quot;&gt;&quot;employees&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-punctuation&quot;&gt;[&lt;/span&gt;
            &lt;span class=&quot;hljs-punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;hljs-attr&quot;&gt;&quot;columnName&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;employee_id&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;hljs-attr&quot;&gt;&quot;dataType&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;integer&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;hljs-attr&quot;&gt;&quot;isNullable&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;NO&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;hljs-attr&quot;&gt;&quot;default&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;nextval(&apos;employees_employee_id_seq&apos;::regclass)&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;hljs-attr&quot;&gt;&quot;udtName&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;int4&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;hljs-attr&quot;&gt;&quot;udtSchema&quot;&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;pg_catalog&quot;&lt;/span&gt;
            &lt;span class=&quot;hljs-punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;hljs-punctuation&quot;&gt;,&lt;/span&gt;
....
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The data is chunked only while initializing the engine. Once the chunking process is complete, the chunks are stored in an in-memory vector store. The vector store is then used to retrieve the data.&lt;/p&gt;
&lt;h3 id=&quot;prompt-engineering-1&quot; tabindex=&quot;-1&quot;&gt;Prompt Engineering&lt;/h3&gt;
&lt;p&gt;The generator converts the query into sub-queries, answers each query asynchronously and then combines the results to generate the final SQL query.&lt;/p&gt;
&lt;p&gt;A question like “How many active employees are there with age more than 45 and working in the education sector, and are eligible for a bonus?” is converted into sub-queries like:&lt;br&gt;
“how many active employees are there with age more than 45?”&lt;br&gt;
“how many active employees are there working in the education sector?”&lt;br&gt;
“how many active employees are there eligible for a bonus?”&lt;/p&gt;
&lt;p&gt;The sub queries are then answered asynchronously and the results are combined to generate the final SQL query.&lt;/p&gt;
&lt;h2 id=&quot;whats-next&quot; tabindex=&quot;-1&quot;&gt;What’s next?&lt;/h2&gt;
&lt;p&gt;RAG pipelines are not perfect. Neak is a fine model, but not ready for production yet. It is in a nascent stage and requires a lot of refinement. Some of the issues that I faced are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GPT-3.5 turbo and GPT-4  hallucinated a lot. The results were not accurate.&lt;/li&gt;
&lt;li&gt;The time taken to retrieve the chunks has reduced, but the query generation is still slow. Although the sub-queries are generated asynchronously, the time taken to generate the final query is still high. The overall difference in time taken to generate the query is not significant.&lt;/li&gt;
&lt;li&gt;there is no context stored. A chat-based approach may be better.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;While better alternatives like Defog’s SQLcoder, which operates locally using Huggingface’s transformers, resolve data leakage concerns, their complex setup poses usability. For an average person, setting up an AI model to run locally is not easy.&lt;/p&gt;
&lt;p&gt;Technically, the most apt way to generate SQL queries is using &lt;strong&gt;RAG pipelines&lt;/strong&gt; with &lt;strong&gt;fine-tuned models&lt;/strong&gt;. While this is a more challenging approach, it is also the most accurate and secure. Neak is merely a bleak attempt to solve this. It is a work in progress and requires a lot of refinement. in the future, I plan to follow an approach similar to Defog’s SQL coder: fine-tuning open-source LLMs and then using them to generate SQL queries using the Llama Index based Neak’s approeach: a sub-querying engine.&lt;/p&gt;

            &lt;hr&gt;
            &lt;div class=&quot;footer&quot;&gt;
              &lt;i&gt;Feedback, Suggestions, Comments - &lt;/i&gt;
              &lt;div class=&quot;giscus-div&quot; id=&quot;comments&quot;&gt;
                &lt;script src=&quot;https://giscus.app/client.js&quot; data-repo=&quot;anubhavpgit/anubhavpgit.github.io&quot; data-repo-id=&quot;MDEwOlJlcG9zaXRvcnk0MDQ1ODEzMjc=&quot; data-category-id=&quot;DIC_kwDOGB1rz84Cer0j&quot; data-mapping=&quot;title&quot; data-strict=&quot;0&quot; data-reactions-enabled=&quot;1&quot; data-emit-metadata=&quot;0&quot; data-input-position=&quot;bottom&quot; data-theme=&quot;noborder_light&quot; data-lang=&quot;en&quot; data-loading=&quot;lazy&quot; crossorigin=&quot;anonymous&quot; async=&quot;&quot;&gt;&lt;/script&gt;
              &lt;/div&gt;
              Feel free to
              &lt;a id=&quot;mailtoLink&quot; href=&quot;mailto:anubhavp@duck.com?subject=Here&apos;s%20a%20suggestion/feedback!&quot;&gt;send
                me an email&lt;/a&gt;.
            &lt;/div&gt;
          &lt;/div&gt;
        </content:encoded>
            <subtitle>Neak is a natural language to SQL engine that uses the RAG pipeline to generate SQL queries from natural language questions.</subtitle>
        </item>
        <item>
            <title><![CDATA[The Parakeet King]]></title>
            <description><![CDATA[A story about a king who lost his kingdom and found a friend.]]></description>
            <link>https://anubhavp.dev/blog/parakeetking.html</link>
            <guid isPermaLink="true">https://anubhavp.dev/blog/parakeetking.html</guid>
            <dc:creator><![CDATA[Anubhab Patnaik]]></dc:creator>
            <pubDate>Thu, 01 Aug 2024 00:00:00 GMT</pubDate>
            <content:encoded>
          &lt;div class=&quot;content custom&quot;&gt;
            &lt;div class=&quot;search-container&quot;&gt;&lt;/div&gt;
            &lt;p&gt;I recently wrote about &lt;a href=&quot;https://anubhavp.dev/blog/lifeandtheuniverse.html&quot;&gt;battling anxiety and depression&lt;/a&gt;. After six months, writing about something uncomfortable seems partly easier now. My last article helped me engage with an audience experiencing similar struggles. It’s remarkable how much we can uncover about each other’s inner worlds simply by communicating. Everyday conversations can be incredibly therapeutic—a reminder that we are not alone in our struggles, and my recent experiences have been a testament to this.&lt;/p&gt;
&lt;p&gt;The last article shed light on how my life transitioned from one horrid experience to another, how life kept pushing and pushing, each time scraping a larger piece of my knees. In a journey fraught with self-doubt, anxiety, and depression, I found myself grappling with all kinds of challenges life threw my way. Moving from one trouble to the next, I built up ounces of resilience as I walked through these challenges, slowly attempting to fight back and stand up again. While trying to regain my footing, I grasped a few outstretched hands reaching toward me, taking slow steps, hesitant with the looming possibility of failure. As I began to walk again, I realized I wasn’t alone. Others walked alongside—some ahead, some behind—each with their own stories and struggles.&lt;/p&gt;
&lt;p&gt;Now, looking around, I see familiar faces looking back at me. Some walk along the same path as me. While, some are ahead. They acknowledge their missteps, their gaze carrying the weight of a million untold stories—apologetic yet determined to make amends. We walk together, hoping to help each other move forward. Some just want to talk, wanting me to be there and listen and not judge. To be there for them. That’s all it takes. Others, too tired to take the next step, want to change lanes and ask for help.&lt;/p&gt;
&lt;p&gt;As we walk alongside each other, this eerie feeling of “this happened to me too” surrounds us. I realized that our lives were not very different from each other. All of us walking together are equally in debt, though with separate issues, but we are there together. Talking and sharing with each other helped me scratch the surface of the walls, looking behind them, uncovering the unsettling darkness. These are the walls we construct in our lives and not look behind. The walls that we build to protect ourselves from the world.&lt;/p&gt;
&lt;p&gt;In a world teeming with activity, it’s apparent that everyone, everywhere, is grappling with their own set of challenges. Life has universally become a struggle. Some speak about the dysfunctional job market, some about house prices soaring through the roofs of lighthouses, some about increasingly stressful finances, and others about how capitalism has reached its peak: the rich get richer.&lt;/p&gt;
&lt;p&gt;Amidst the bustling cityscape, forging genuine connections feels like an insurmountable feat. The ones you want to talk to are in a different city, timezone, or space altogether. They are not available anymore. Those promises we made while leaving school and college—promises to stay in touch, meet, and gossip—were all mere promises: sweet and generous lies we told ourselves. We moved on and learned to live without each other. The family has done its part. Exploring what you are passionate about while managing unwilling expenditures in a delusional “life” within the work-life balance is eating you up from the inside, and our mere existence feels morbid. We grapple with our internal demons, navigating the labyrinth of our minds where uncertainty rules. The inevitable challenge now becomes wrestling with the monsters that inhabit your gray space. Welcome to the daunting realm of adulthood!&lt;/p&gt;
&lt;p&gt;Amid this darkness, empathy proved to be a beacon of light. With a myriad of challenges weighing me down—financial issues, work-life balance struggles, having to find new work, living alone, grappling with weight gain, being unable to make friends, experiencing a breakup, and what else not-the empathy I received was my knight in shining armor.&lt;/p&gt;
&lt;p&gt;I turned twenty-four last month. Life has been gradually improving for quite some time now, ushering in a subtle calmness with each day. The days are still a blur of monotonous routines, the nights a cycle of napping with nothing to do, but I find myself more at peace with the world. Each morning, I awaken with a sense of purpose, eagerly planning my day and contemplating the possibilities lying ahead. I’ve settled into a new workplace, made new friends, and realized that the trials I faced were not mine alone. Through heartfelt conversations, I discovered that others were navigating similar storms.&lt;/p&gt;
&lt;p&gt;I asked my friends to read my article about the issues I had been experiencing. They loved it and shared feedback. They rooted for me as if I were the main character. They wanted to help. They shared their stories and showed me different perspectives. I realized the world works differently for each individual. Speaking to them helped me understand that it is okay and that these struggles are common. One colleague confided in me about experiencing impostor syndrome, a sentiment I wrestled with. She said she also thinks she somehow got this job by chance. Another friend shared that he went through a similar breakup process. It’s uplifting to see connections with friends and colleagues becoming meaningful experiences.&lt;/p&gt;
&lt;p&gt;One friend mentioned he had been looking to join a gym for a long time, while another wanted a badminton buddy, just like me. Some wanted to go on trips, and others wanted to hang out after work, have a beer and talk about everyday life. A friend from my previous company reached out for help, saying it had become too much for him, and he needed an escape. Grappling with job switching and confiding his issues in me helped him discover new insights. Some of my juniors reached out for help, and we started working together on projects to improve our collective knowledge. Talking to people, sharing my problems, listening to theirs, collectively trying to come up with solutions, and being involved in others’ lives brought a sense of fulfillment.&lt;/p&gt;
&lt;p&gt;There are still many things on my list. Now, I find it easier to tick them off one by one. I resumed playing the guitar. I planned and went on new trips with my family, tried out river rafting with my mom and sister, and visited deserts, mountains, and beaches. I resumed my coding community, made new friends, and got busy. I learned that I am not the only one unsatisfied with their cook. I am not the only one looking for a better apartment. We chat about our short stories, lives, and places we come from. Talking about these countless things started lifting me up. I didn’t plan on doing that. It just happened.&lt;/p&gt;
&lt;p&gt;I now find joy in simple pleasures: having a hearty breakfast, coaxing colleagues into joining me for fancy lunches, and persuading friends to hang out and spend an evening of fun before settling into bed, weary but fulfilled. An evening stroll, working from a café, catching the latest movies with friends and colleagues, attending stand-up comedy shows, and trying out new beer breweries, gin joints, and pubs before bed have become my daily norm. We spend most of our lunches outside. Time passes by, and we don’t even notice. Amidst it all, I find solace in the conversations and connections made along the way. Together, we navigate life’s ups and downs, finding support in each other’s company.&lt;/p&gt;
&lt;p&gt;These conversations transcend the mundane, offering glimpses into each other’s lives, dreams, and struggles. As we share our stories, I find solace in the fact that my experiences are not unique. We laugh, commiserate, and dream, finding comfort in our shared humanity. Visualizing lives from another perspective helps us remarkably. Empathy reigns, and we look forward to living another day more resilient, breaking bread, and gulping beer with each other as we engage in laughter and mutual connection.&lt;/p&gt;
&lt;p&gt;We are all stuck here. You might be on the further end of the scale than I am right now. But both of us are here. If I could walk downstairs, you can too. Talk to people, share, watch movies, read stories, get lost in a million other worlds, and address your issues. In the end, it all becomes an act of letting go. It took me some time to figure this out: you take the sourest lemon life has to offer and turn it into something resembling lemonade. Share it with others; live, try, and help others live. Build memories. After all, that’s all we are, really. Memories.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../assets/img/parakeetking/evildoer.png&quot; alt=&quot;parakeet king&quot; loading=&quot;lazy&quot;&gt;&lt;/p&gt;
&lt;p&gt;- &lt;em&gt;the evildoer&lt;/em&gt;&lt;br&gt;
&lt;em&gt;undersigned&lt;/em&gt;&lt;/p&gt;

            &lt;hr&gt;
            &lt;div class=&quot;footer&quot;&gt;
              &lt;i&gt;Feedback, Suggestions, Comments - &lt;/i&gt;
              &lt;div class=&quot;giscus-div&quot; id=&quot;comments&quot;&gt;
                &lt;script src=&quot;https://giscus.app/client.js&quot; data-repo=&quot;anubhavpgit/anubhavpgit.github.io&quot; data-repo-id=&quot;MDEwOlJlcG9zaXRvcnk0MDQ1ODEzMjc=&quot; data-category-id=&quot;DIC_kwDOGB1rz84Cer0j&quot; data-mapping=&quot;title&quot; data-strict=&quot;0&quot; data-reactions-enabled=&quot;1&quot; data-emit-metadata=&quot;0&quot; data-input-position=&quot;bottom&quot; data-theme=&quot;noborder_light&quot; data-lang=&quot;en&quot; data-loading=&quot;lazy&quot; crossorigin=&quot;anonymous&quot; async=&quot;&quot;&gt;&lt;/script&gt;
              &lt;/div&gt;
              Feel free to
              &lt;a id=&quot;mailtoLink&quot; href=&quot;mailto:anubhavp@duck.com?subject=Here&apos;s%20a%20suggestion/feedback!&quot;&gt;send
                me an email&lt;/a&gt;.
            &lt;/div&gt;
          &lt;/div&gt;
        </content:encoded>
            <subtitle>A story about a king who lost his kingdom and found a friend.</subtitle>
        </item>
        <item>
            <title><![CDATA[QTree - Images in Quadtrees ]]></title>
            <description><![CDATA[Inspired by KoalasToTheMax, QTree is a short live demonstration of image compression and decompression using Quadtrees that partition a two-dimensional image by recursively subdividing it into four quadrants.]]></description>
            <link>https://anubhavp.dev/blog/qtree.html</link>
            <guid isPermaLink="true">https://anubhavp.dev/blog/qtree.html</guid>
            <dc:creator><![CDATA[Anubhab Patnaik]]></dc:creator>
            <pubDate>Tue, 14 Feb 2023 00:00:00 GMT</pubDate>
            <content:encoded>
          &lt;div class=&quot;content custom&quot;&gt;
            &lt;div class=&quot;search-container&quot;&gt;&lt;/div&gt;
            &lt;script type=&quot;module&quot; src=&quot;/assets/js/qtree/index.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;module&quot; src=&quot;/assets/js/qtree/qdtree.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;I stumbled upon &lt;a href=&quot;https://koalastothemax.com/&quot;&gt;KoalasToTheMax&lt;/a&gt; while reading a blog post about the most exciting web pages built for fun, and I was blown away. &lt;a href=&quot;https://injuly.in/&quot;&gt;Srijan&lt;/a&gt; explained how it works, and we were inspired to create something similar.&lt;/p&gt;
&lt;p&gt;But first, let’s get into the basics of the data structures used in our project.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#quadtree&quot;&gt;Quadtree&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#member-functions&quot;&gt;Member Functions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#node&quot;&gt;Node&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#demonstration&quot;&gt;Demonstration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#setting-up-the-canvas&quot;&gt;Setting up the Canvas&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#image-data-compression&quot;&gt;Image Data Compression&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#bounding-box&quot;&gt;Bounding Box&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#image-data-to-quadtree&quot;&gt;Image Data to Quadtree&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;quadtree&quot; tabindex=&quot;-1&quot;&gt;Quadtree&lt;/h2&gt;
&lt;p&gt;A quadtree is a tree-based data structure where each node has exactly four child nodes. Our quadtree represents a partition of space in two dimensions by dividing the region into four equal quadrants. Each quadrant is then subdivided into four equal quadrants, and so on. Each node in the tree has exactly four children or no children at all, which makes it a leaf node. The height of a quadtree depends on the amount of data being&amp;nbsp;decomposed.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://upload.wikimedia.org/wikipedia/commons/a/a0/Quad_tree_bitmap.svg&quot; alt=&quot;quadtree&quot; loading=&quot;lazy&quot;&gt;&lt;/p&gt;
&lt;p&gt;The root node is the image. Each node is the average value of its children’s pixel values. The tree is recursively subdivided until each leaf node is a single pixel. The tree is then traversed to compress the image. To decompress the image, the tree is traversed&amp;nbsp;again.&lt;/p&gt;
&lt;h3 id=&quot;member-functions&quot; tabindex=&quot;-1&quot;&gt;Member Functions&lt;/h3&gt;
&lt;p&gt;Our quadtree has the following member functions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;compressImageData&lt;/strong&gt; : It takes the image data and the compression factor as the input and returns the quadtree.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;createQTreeOfHeight&lt;/strong&gt; : It takes the height of the tree and the bounding box as the input and returns the quadtree.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;populate&lt;/strong&gt; : It populates the quadtree with the pixel values.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;getRGBValuesFromCoordinates&lt;/strong&gt; : It takes the quadtree and the coordinates as the input and returns the pixel value at the given coordinates.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;node&quot; tabindex=&quot;-1&quot;&gt;Node&lt;/h3&gt;
&lt;p&gt;The QTNODE class represents a node in the quadtree. It has the following properties:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;x&lt;/strong&gt; : x-coordinate&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;y&lt;/strong&gt; : y-coordinate&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;w&lt;/strong&gt; : width of the bounding box.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;h&lt;/strong&gt; : height of the bounding box.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;children&lt;/strong&gt; : array of four children.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;rgb&lt;/strong&gt; : pixel value of the node.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Functions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;draw&lt;/strong&gt; : draws the node. Takes the canvas context as the input and returns nothing.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;insert&lt;/strong&gt;: inserts a node into the quadtree. Takes the quadtree and the node as the input and returns the quadtree.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;drawAtHeight&lt;/strong&gt;: draws the nodes at a given height. Takes the canvas context, the height of the tree, and the current height as the input and returns nothing.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;draw&lt;/strong&gt;: draws the nodes. Takes the canvas context and the height of the tree as the input and returns nothing.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;reveal&lt;/strong&gt;: reveals the nodes. Takes the canvas context and the height of the tree as the input and returns nothing.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;computeAverageColor&lt;/strong&gt;: computes the average color of the node. Takes the quadtree and the image data as the input and returns the pixel value.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;demonstration&quot; tabindex=&quot;-1&quot;&gt;Demonstration&lt;/h2&gt;
&lt;div class=&quot;container&quot; style=&quot;text-align: center;&quot;&gt;
	&lt;canvas id=&quot;canvas-2&quot; style=&quot;border: 1px solid black;&quot;&gt;
	&lt;/canvas&gt;
	&lt;br&gt;
&lt;p&gt;Hover over any part of the canvas to recursively divide it into four quadrants.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;container&quot; style=&quot;text-align: center;&quot;&gt;
	&lt;canvas id=&quot;canvas-1&quot; style=&quot;border: 1px solid black;&quot;&gt; &lt;/canvas&gt;
	&lt;br&gt;
	&lt;input type=&quot;range&quot; id=&quot;slider&quot; min=&quot;0&quot; max=&quot;100&quot; value=&quot;0&quot;&gt;
	&lt;br&gt;
&lt;p&gt;The slider controls the depth of the tree.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The slider is set to 0 by default, which means the entire image is compressed into a single pixel. The slider when set to 100 means the image is not compressed at all. The slider can be set to any value between 0 and 100.&lt;/p&gt;
&lt;h2 id=&quot;setting-up-the-canvas&quot; tabindex=&quot;-1&quot;&gt;Setting up the Canvas&lt;/h2&gt;
&lt;p&gt;To start with, we need two canvases - one for you to hover over and the other for you to control the depth of the tree using a slider and render the nodes evenly. Initially, we had multiple ways of taking an image as the input form, such as uploading an image, using query parameters, etc. But for this demonstration, we’ll keep it simple and use a static image.&lt;/p&gt;
&lt;p&gt;Here’s some JavaScript code that will load the image&amp;nbsp;into&amp;nbsp;a&amp;nbsp;canvas:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; image = &lt;span class=&quot;hljs-keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;hljs-title class_&quot;&gt;Image&lt;/span&gt;();
img.&lt;span class=&quot;hljs-property&quot;&gt;src&lt;/span&gt; = &lt;span class=&quot;hljs-string&quot;&gt;&quot;/blog/assets/images/qtree/cryptopunk.jpeg&quot;&lt;/span&gt;;
img.&lt;span class=&quot;hljs-property&quot;&gt;onload&lt;/span&gt; = &lt;span class=&quot;hljs-function&quot;&gt;() =&amp;gt;&lt;/span&gt; {
    &lt;span class=&quot;hljs-title function_&quot;&gt;initSliderCanvas&lt;/span&gt;(img);
    &lt;span class=&quot;hljs-title function_&quot;&gt;initMouseCanvas&lt;/span&gt;(img);
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I’ll go ahead and explain the working of the mouse hover canvas and you can explore the slider canvas. The code is available on &lt;a href=&quot;https://github.com/cbrtl/qd-compression&quot;&gt;GitHub&lt;/a&gt;, and you can play around with it later if you are interested.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;import&lt;/span&gt; { compressImageData } &lt;span class=&quot;hljs-keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;./qdtree.js&quot;&lt;/span&gt;;
&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;initMouseCanvas&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;img&lt;/span&gt;){
	&lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; canvas = &lt;span class=&quot;hljs-variable language_&quot;&gt;document&lt;/span&gt;.&lt;span class=&quot;hljs-title function_&quot;&gt;getElementById&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&quot;canvas-2&quot;&lt;/span&gt;);
    &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; ctx = canvas.&lt;span class=&quot;hljs-title function_&quot;&gt;getContext&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&quot;2d&quot;&lt;/span&gt;);

    &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; imageData = &lt;span class=&quot;hljs-title function_&quot;&gt;readImageDataUsingCanvas&lt;/span&gt;(canvas, ctx, image);
    &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; qTree = &lt;span class=&quot;hljs-title function_&quot;&gt;compressImageData&lt;/span&gt;(imageData, &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;);
    qTree.&lt;span class=&quot;hljs-title function_&quot;&gt;draw&lt;/span&gt;(ctx);
	...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;image-data-compression&quot; tabindex=&quot;-1&quot;&gt;Image Data Compression&lt;/h3&gt;
&lt;p&gt;Now, let’s get to the fun part - compressing images. We import the &lt;code&gt;compressImageData&lt;/code&gt; function from the qdtree.js file. This function takes the image data and the compression factor as the input and returns&amp;nbsp;the&amp;nbsp;quadtree. The &lt;strong&gt;height of the tree&lt;/strong&gt; is calculated by taking the log of the number of pixels in the image and dividing it by the log of 4 (number of children of a node). The log of 4 is 2, and the log of the number of pixels is the height of the tree. The height of the tree is then rounded down to the nearest integer. The tree is then created using the &lt;code&gt;createQTreeOfHeight&lt;/code&gt; function that takes the height of the tree and the &lt;strong&gt;bounding box&lt;/strong&gt; as the input and returns the quadtree.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;qdtree.js&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;compressImageData&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;imageData, factor&lt;/span&gt;) {
  &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; { width, height } = imageData;
  &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; newWidth = &lt;span class=&quot;hljs-title class_&quot;&gt;Math&lt;/span&gt;.&lt;span class=&quot;hljs-title function_&quot;&gt;ceil&lt;/span&gt;(width / factor);
  &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; newHeight = &lt;span class=&quot;hljs-title class_&quot;&gt;Math&lt;/span&gt;.&lt;span class=&quot;hljs-title function_&quot;&gt;ceil&lt;/span&gt;(height / factor);

  &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; qTreeHeight = &lt;span class=&quot;hljs-title class_&quot;&gt;Math&lt;/span&gt;.&lt;span class=&quot;hljs-title function_&quot;&gt;floor&lt;/span&gt;(&lt;span class=&quot;hljs-title class_&quot;&gt;Math&lt;/span&gt;.&lt;span class=&quot;hljs-title function_&quot;&gt;log&lt;/span&gt;(newWidth * newHeight) / &lt;span class=&quot;hljs-title class_&quot;&gt;Math&lt;/span&gt;.&lt;span class=&quot;hljs-title function_&quot;&gt;log&lt;/span&gt;(&lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt;));

  &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; qTree = &lt;span class=&quot;hljs-title function_&quot;&gt;createQTreeOfHeight&lt;/span&gt;(qTreeHeight, {
    &lt;span class=&quot;hljs-attr&quot;&gt;x&lt;/span&gt;: &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;,
    &lt;span class=&quot;hljs-attr&quot;&gt;y&lt;/span&gt;: &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;,
    &lt;span class=&quot;hljs-attr&quot;&gt;w&lt;/span&gt;: width,
    &lt;span class=&quot;hljs-attr&quot;&gt;h&lt;/span&gt;: height,
  });

  &lt;span class=&quot;hljs-title function_&quot;&gt;populate&lt;/span&gt;(qTree, imageData);
  &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; qTree;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;createQTreeOfHeight&lt;/code&gt; function takes in the height of the tree and the bounding box as the input and returns the quadtree.&lt;/p&gt;
&lt;h4 id=&quot;bounding-box&quot; tabindex=&quot;-1&quot;&gt;Bounding Box&lt;/h4&gt;
&lt;p&gt;The bounding box is the area that the node represents. The bounding box is initially the entire image. The bounding box is then divided into four equal quadrants, and the process is repeated until the height of the tree is 0. The &lt;code&gt;populate&lt;/code&gt; function takes the quadtree and the image data as the input and populates the tree with the average pixel values of the children’s pixel values.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;createQTreeOfHeight&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;height, aabb&lt;/span&gt;) {
  &lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;recursiveCreate&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;node, height&lt;/span&gt;) {
    &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (height === &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;) &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt;;

    &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; { x, y, w, h } = node.&lt;span class=&quot;hljs-property&quot;&gt;aabb&lt;/span&gt;;
    &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; halfW = w / &lt;span class=&quot;hljs-number&quot;&gt;2&lt;/span&gt;;
    &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; halfH = h / &lt;span class=&quot;hljs-number&quot;&gt;2&lt;/span&gt;;


	&lt;span class=&quot;hljs-comment&quot;&gt;//top left&lt;/span&gt;
    node.&lt;span class=&quot;hljs-property&quot;&gt;tl&lt;/span&gt; = &lt;span class=&quot;hljs-keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;hljs-title class_&quot;&gt;QTNode&lt;/span&gt;({
      x,
      y,
      &lt;span class=&quot;hljs-attr&quot;&gt;w&lt;/span&gt;: halfW,
      &lt;span class=&quot;hljs-attr&quot;&gt;h&lt;/span&gt;: halfH,
    });
		&lt;span class=&quot;hljs-comment&quot;&gt;//top right&lt;/span&gt;
    node.&lt;span class=&quot;hljs-property&quot;&gt;tr&lt;/span&gt; = &lt;span class=&quot;hljs-keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;hljs-title class_&quot;&gt;QTNode&lt;/span&gt;({
      &lt;span class=&quot;hljs-attr&quot;&gt;x&lt;/span&gt;: x + halfW,
      y,
      &lt;span class=&quot;hljs-attr&quot;&gt;w&lt;/span&gt;: halfW,
      &lt;span class=&quot;hljs-attr&quot;&gt;h&lt;/span&gt;: halfH,
    });
		&lt;span class=&quot;hljs-comment&quot;&gt;//bottom left&lt;/span&gt;
    node.&lt;span class=&quot;hljs-property&quot;&gt;bl&lt;/span&gt; = &lt;span class=&quot;hljs-keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;hljs-title class_&quot;&gt;QTNode&lt;/span&gt;({
      x,
      &lt;span class=&quot;hljs-attr&quot;&gt;y&lt;/span&gt;: y + halfH,
      &lt;span class=&quot;hljs-attr&quot;&gt;w&lt;/span&gt;: halfW,
      &lt;span class=&quot;hljs-attr&quot;&gt;h&lt;/span&gt;: halfH,
    });
		&lt;span class=&quot;hljs-comment&quot;&gt;//bottom right&lt;/span&gt;
    node.&lt;span class=&quot;hljs-property&quot;&gt;br&lt;/span&gt; = &lt;span class=&quot;hljs-keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;hljs-title class_&quot;&gt;QTNode&lt;/span&gt;({
      &lt;span class=&quot;hljs-attr&quot;&gt;x&lt;/span&gt;: x + halfW,
      &lt;span class=&quot;hljs-attr&quot;&gt;y&lt;/span&gt;: y + halfH,
      &lt;span class=&quot;hljs-attr&quot;&gt;w&lt;/span&gt;: halfW,
      &lt;span class=&quot;hljs-attr&quot;&gt;h&lt;/span&gt;: halfH,
    });

    &lt;span class=&quot;hljs-title function_&quot;&gt;recursiveCreate&lt;/span&gt;(node.&lt;span class=&quot;hljs-property&quot;&gt;tl&lt;/span&gt;, height - &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;);
    &lt;span class=&quot;hljs-title function_&quot;&gt;recursiveCreate&lt;/span&gt;(node.&lt;span class=&quot;hljs-property&quot;&gt;tr&lt;/span&gt;, height - &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;);
    &lt;span class=&quot;hljs-title function_&quot;&gt;recursiveCreate&lt;/span&gt;(node.&lt;span class=&quot;hljs-property&quot;&gt;bl&lt;/span&gt;, height - &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;);
    &lt;span class=&quot;hljs-title function_&quot;&gt;recursiveCreate&lt;/span&gt;(node.&lt;span class=&quot;hljs-property&quot;&gt;br&lt;/span&gt;, height - &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;);
  }
 }
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;image-data-to-quadtree&quot; tabindex=&quot;-1&quot;&gt;Image data to Quadtree&lt;/h3&gt;
&lt;p&gt;Alright, let’s talk about the &lt;code&gt;reveal&lt;/code&gt; function, which is like a magician revealing the hidden nodes under the mouse. And then there’s the &lt;code&gt;draw&lt;/code&gt; function, which is like an artist sketching the nodes on the canvas. The &lt;code&gt;update&lt;/code&gt; function is like your mom constantly cleaning up after you every 30 milliseconds. It clears the canvas and redraws the nodes on the canvas, all to make sure it looks neat and tidy.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;initMouseCanvas&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;img&lt;/span&gt;){
	...
 &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; mousePos = { &lt;span class=&quot;hljs-attr&quot;&gt;x&lt;/span&gt;: &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;hljs-attr&quot;&gt;y&lt;/span&gt;: &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt; };
    &lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; lastUpdateTime = -&lt;span class=&quot;hljs-title class_&quot;&gt;Infinity&lt;/span&gt;;
    &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; frameTime = &lt;span class=&quot;hljs-number&quot;&gt;30&lt;/span&gt;;

    &lt;span class=&quot;hljs-keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;update&lt;/span&gt;(&lt;span class=&quot;hljs-params&quot;&gt;&lt;/span&gt;) {
        &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; currentTime = &lt;span class=&quot;hljs-title class_&quot;&gt;Date&lt;/span&gt;.&lt;span class=&quot;hljs-title function_&quot;&gt;now&lt;/span&gt;();
        &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; diff = currentTime - lastUpdateTime;
        &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (diff &amp;lt; frameTime) &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt;;

        lastUpdateTime = currentTime;
        ctx.&lt;span class=&quot;hljs-title function_&quot;&gt;clearRect&lt;/span&gt;(&lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;, canvas.&lt;span class=&quot;hljs-property&quot;&gt;width&lt;/span&gt;, canvas.&lt;span class=&quot;hljs-property&quot;&gt;height&lt;/span&gt;);
        qTree.&lt;span class=&quot;hljs-title function_&quot;&gt;reveal&lt;/span&gt;(mousePos.&lt;span class=&quot;hljs-property&quot;&gt;x&lt;/span&gt;, mousePos.&lt;span class=&quot;hljs-property&quot;&gt;y&lt;/span&gt;);
        qTree.&lt;span class=&quot;hljs-title function_&quot;&gt;draw&lt;/span&gt;(ctx);
    }

    canvas.&lt;span class=&quot;hljs-title function_&quot;&gt;addEventListener&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&quot;mousemove&quot;&lt;/span&gt;, &lt;span class=&quot;hljs-function&quot;&gt;(&lt;span class=&quot;hljs-params&quot;&gt;e&lt;/span&gt;) =&amp;gt;&lt;/span&gt; {
        &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; rect = canvas.&lt;span class=&quot;hljs-title function_&quot;&gt;getBoundingClientRect&lt;/span&gt;();
        &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; x = e.&lt;span class=&quot;hljs-property&quot;&gt;clientX&lt;/span&gt; - rect.&lt;span class=&quot;hljs-property&quot;&gt;left&lt;/span&gt;;
        &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; y = e.&lt;span class=&quot;hljs-property&quot;&gt;clientY&lt;/span&gt; - rect.&lt;span class=&quot;hljs-property&quot;&gt;top&lt;/span&gt;;
        mousePos.&lt;span class=&quot;hljs-property&quot;&gt;x&lt;/span&gt; = x;
        mousePos.&lt;span class=&quot;hljs-property&quot;&gt;y&lt;/span&gt; = y;
        &lt;span class=&quot;hljs-title function_&quot;&gt;update&lt;/span&gt;();
    });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;So, what’s the point of all this? Well, we can use a quadtree to compress and decompress images when the mouse hovers over a specific area of the canvas. It’s like a secret code that unlocks a hidden image!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Ref: &lt;a href=&quot;https://en.wikipedia.org/wiki/Quadtree&quot;&gt;Wikipedia&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

            &lt;hr&gt;
            &lt;div class=&quot;footer&quot;&gt;
              &lt;i&gt;Feedback, Suggestions, Comments - &lt;/i&gt;
              &lt;div class=&quot;giscus-div&quot; id=&quot;comments&quot;&gt;
                &lt;script src=&quot;https://giscus.app/client.js&quot; data-repo=&quot;anubhavpgit/anubhavpgit.github.io&quot; data-repo-id=&quot;MDEwOlJlcG9zaXRvcnk0MDQ1ODEzMjc=&quot; data-category-id=&quot;DIC_kwDOGB1rz84Cer0j&quot; data-mapping=&quot;title&quot; data-strict=&quot;0&quot; data-reactions-enabled=&quot;1&quot; data-emit-metadata=&quot;0&quot; data-input-position=&quot;bottom&quot; data-theme=&quot;noborder_light&quot; data-lang=&quot;en&quot; data-loading=&quot;lazy&quot; crossorigin=&quot;anonymous&quot; async=&quot;&quot;&gt;&lt;/script&gt;
              &lt;/div&gt;
              Feel free to
              &lt;a id=&quot;mailtoLink&quot; href=&quot;mailto:anubhavp@duck.com?subject=Here&apos;s%20a%20suggestion/feedback!&quot;&gt;send
                me an email&lt;/a&gt;.
            &lt;/div&gt;
          &lt;/div&gt;
        </content:encoded>
            <subtitle>Inspired by KoalasToTheMax, QTree is a short live demonstration of image compression and decompression using Quadtrees that partition a two-dimensional image by recursively subdividing it into four quadrants.</subtitle>
        </item>
        <item>
            <title><![CDATA[Resoc, a gift to my alma mater]]></title>
            <description><![CDATA[RESOC; short for Resources + Community, is the ABD of notes - the coolest academic notes-sharing platform around, built by a bunch of tech-savvy students at Silicon Institute, and it's totally free!]]></description>
            <link>https://anubhavp.dev/blog/resoc.html</link>
            <guid isPermaLink="true">https://anubhavp.dev/blog/resoc.html</guid>
            <dc:creator><![CDATA[Anubhab Patnaik]]></dc:creator>
            <pubDate>Fri, 17 Mar 2023 00:00:00 GMT</pubDate>
            <content:encoded>
          &lt;div class=&quot;content custom&quot;&gt;
            &lt;div class=&quot;search-container&quot;&gt;&lt;/div&gt;
            &lt;style&gt;
 .resoc {
 justify-content: center;
 align-items: center;
 display: flex;
 flex-direction: column;
 }
 &lt;/style&gt;
&lt;p&gt;RESOC, a free and open-source platform that primarily lets you share notes, question papers, and other academic resources with your friends and classmates.&lt;/p&gt;
&lt;h2 id=&quot;how-it-all-started&quot; tabindex=&quot;-1&quot;&gt;How it all started&lt;/h2&gt;
&lt;p&gt;The idea came to me in the first year of my undergrad, when I found myself scouring the internet for notes, and calling up friends in the middle of the night. I have a terrible habit of studying just before the exam( and I am sure, you do too ), and at the end of the day, I always find myself having nothing to read from. This led me to build a Google Drive collection that became an instant hit among my peers. Everybody wanted the link! I didn’t bother to put much effort into it, and it was just a bunch of notes that I had collected over the years. Later, I built a static html page and hosted it on GitHub pages.&lt;/p&gt;
&lt;p&gt;Cut to the end of 2022, in my final year, I decided to join together bits and pieces from other projects to build RESOC. Resoc is a community-driven platform that lets you share notes, question papers, and other academic resources with friends and classmates. It also helps you stay organized with a personal task board, and a community chat page to interact with other users. The platform is built using React and Firebase and is hosted in Firebase Hosting. The notes are stored in Google Drive, and the user data is stored in Cloud Firestore. The platform is open-source and can be found &lt;a href=&quot;https://github.com/anubhavpgit/resoc&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;the-open-source-codebase&quot; tabindex=&quot;-1&quot;&gt;The open-source codebase&lt;/h3&gt;
&lt;p&gt;Going forward, I would want to make the platform more user-friendly and add more features. It has bugs and lacks a lot of implementations for the features we have added. Since it is primarily made for my alma mater, I would want a silicon student to pick this up, fix the issues, and maintain it. To get started, here’s a brief overview of the codebase:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Frontend&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;li&gt;React Router&lt;/li&gt;
&lt;li&gt;Bootstrap&lt;/li&gt;
&lt;li&gt;Undraw + Storyset for illustrations&lt;/li&gt;
&lt;li&gt;React - Firebase for Firebase integration&lt;/li&gt;
&lt;li&gt;Context API for state management&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Backend&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Firebase&lt;/li&gt;
&lt;li&gt;Google Drive for storing and fetching notes&lt;/li&gt;
&lt;li&gt;Firebase Authentication for user &lt;strong&gt;authentication&lt;/strong&gt;: Google OAuth and email/password are used for authentication using Firebase Authentication.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Database&lt;/strong&gt;:&lt;br&gt;
The notes are in Google Drive, and Cloud Firestore is used for authentication and storing user data, tasks, and chat messages. Firebase storage is used to store files uploaded by users and contributions.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Hosting&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Firebase &lt;strong&gt;Hosting&lt;/strong&gt; for hosting the platform.&lt;/li&gt;
&lt;li&gt;A GitHub action is used to &lt;strong&gt;deploy&lt;/strong&gt; the codebase to Firebase Hosting.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;features&quot; tabindex=&quot;-1&quot;&gt;Features&lt;/h3&gt;
&lt;p&gt;The primary features of RESOC are sharing Notes, Question Papers, and other academic resources. Other than this, users can have a personal &lt;em&gt;Kanan board&lt;/em&gt; to manage their tasks. The &lt;em&gt;community chat page&lt;/em&gt; is a place where users can interact with each other. Resoc also includes community contributions, where users can contribute to the platform. The platform also includes a team page, where the team members are listed, and there are specific community guidelines that need to be followed.&lt;/p&gt;
&lt;h3 id=&quot;deep-dive-into-the-codebase&quot; tabindex=&quot;-1&quot;&gt;Deep Dive into the codebase&lt;/h3&gt;
&lt;p&gt;The major components and routes are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;/team  - The team page&lt;/li&gt;
&lt;li&gt;/notes  - Collection of notes arranged by year and branch. The structure is terribly simple. The IDs are hardcoded and the notes are stored in a JSON file.&lt;/li&gt;
&lt;li&gt;/previewnotes - The page that renders the notes. The notes are stored in a JSON file and the links are hardcoded.&lt;/li&gt;
&lt;li&gt;/community-guidelines - The community guidelines page, lists a couple of rules on public contributions of notes, and the chat.&lt;/li&gt;
&lt;li&gt;/community - The community chat page is built using Firebase Firestore. The chat is real-time and uses WebSockets under the hood.&lt;/li&gt;
&lt;li&gt;/taskboard - The task board page has the bare minimum features.&lt;/li&gt;
&lt;li&gt;/login - The login page, uses Google OAuth for authentication; the user needs to login to access the chat and task board.&lt;/li&gt;
&lt;li&gt;/signup - Basic signup page&lt;/li&gt;
&lt;li&gt;/forgot-password - Basic forgot password page&lt;/li&gt;
&lt;li&gt;/contributions - The contributions page, where users can contribute to the platform. The contributions are stored in Firebase Storage.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;getting-started&quot; tabindex=&quot;-1&quot;&gt;Getting Started&lt;/h3&gt;
&lt;p&gt;The best way to get started would be to clone the repository and try running and exploring all sections of the web app to become familiar with the codebase. The codebase is open-source and can be found &lt;a href=&quot;https://github.com/anubhavpgit/resoc&quot;&gt;here&lt;/a&gt;. The codebase is a Nodejs project, so you would need to have Nodejs installed on your system. You can install the dependencies by running &lt;code&gt;npm install&lt;/code&gt; in the root directory. You can run the project by running &lt;code&gt;npm start&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The React codebase is in the &lt;code&gt;src&lt;/code&gt; folder. The &lt;code&gt;components&lt;/code&gt; folder contains all the components used in the project. The &lt;code&gt;context&lt;/code&gt; folder contains the context APIs used in the project. The root folder contains the Firebase configuration.&lt;/p&gt;
&lt;p&gt;The control starts with the &lt;code&gt;index.js&lt;/code&gt; file that renders the App component. It contains the routes and the context providers. The &lt;code&gt;App&lt;/code&gt; component is the home page. &lt;code&gt;contexts/authContext.js&lt;/code&gt; contains the context API for authentication. Components are lazy-loaded using React Lazy, and the routes are protected using the &lt;code&gt;PrivateRoute&lt;/code&gt; component.&lt;/p&gt;
&lt;p&gt;Each page is a separate file in the &lt;code&gt;components&lt;/code&gt; folder. The &lt;code&gt;utils&lt;/code&gt; folder contains the utility functions used in the project.&lt;/p&gt;
&lt;h4 id=&quot;notes&quot; tabindex=&quot;-1&quot;&gt;Notes&lt;/h4&gt;
&lt;p&gt;The notes are rendered from a metadata file: &lt;code&gt;data.JSON&lt;/code&gt;, that contains two types of elements in the list. One specifies the header: the &lt;strong&gt;year&lt;/strong&gt; or the &lt;strong&gt;branch&lt;/strong&gt;, and the other is the actual notes. The &lt;code&gt;notes&lt;/code&gt; component renders a list of links using this data. Each link is a button that opens the new &lt;code&gt;preview_notes&lt;/code&gt; component. The reason behind using a JSON file is to make it easier for the maintainers to add notes, and to enable a search feature using the tags. This isn’t a traditional search feature, but a filter feature that filters the notes based on the tags. It was a simple solution, so I didn’t bother to put much effort and used a simple filter function.&lt;/p&gt;
&lt;h4 id=&quot;community-chat&quot; tabindex=&quot;-1&quot;&gt;Community Chat&lt;/h4&gt;
&lt;p&gt;The community chat is built using Firebase Firestore. The chat is real-time and uses WebSockets under the hood. The chat is stored in the &lt;code&gt;chats&lt;/code&gt; collection in Firestore. It  includes a button to load more messages and sign out. The ChatRoom component, memoized for performance, fetches and displays messages from Firestore, and allows users to send new messages. The ChatMessage component, also memoized, formats and displays individual messages, including handling URLs within the message text.&lt;/p&gt;
&lt;h4 id=&quot;task-board&quot; tabindex=&quot;-1&quot;&gt;Task Board&lt;/h4&gt;
&lt;p&gt;The task management interface integrates with Firebase Firestore to store and manage tasks. The tasks are fetched from Firestore and displayed in a list, with options to mark tasks as done or delete them. It includes form elements for adding new tasks and buttons for marking tasks as done or deleting them.&lt;/p&gt;
&lt;h4 id=&quot;contributions&quot; tabindex=&quot;-1&quot;&gt;Contributions&lt;/h4&gt;
&lt;p&gt;Contributions, allows users to upload files to a Firebase storage and submit their contributions. It includes form elements for displaying the user’s name and email and input for file selection. It handles file uploads, displays upload progress and shows success or error messages based on the upload status. It also provides a download link for the uploaded file and instructions for further actions. It uses Firebase for authentication, Firestore for storing metadata, and Firebase Storage for file uploads.&lt;/p&gt;
&lt;h4 id=&quot;authentication-login-signup&quot; tabindex=&quot;-1&quot;&gt;Authentication( Login/ Signup )&lt;/h4&gt;
&lt;p&gt;Here’s why there was &lt;strong&gt;a need for authentication&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;There are various actions that would need to distinguish individual users. From uploading notes to maintaining personal task list and communicating with the community, authentication is a must. RESOC uses Google OAuth for authentication. The login/ signup page handles basic authentication using Firebase Authentication. The email verification is deliberately not implemented. We don’t users to feel violated by the platform. The signup page is a simple form that takes the user’s email and password and creates a new user account using Firebase Authentication. The login page is a simple form that takes the user’s email and password, and signs in the user using Firebase Authentication. The forgot password page is a simple form that takes the user’s email and sends a password reset email using Firebase Authentication.&lt;/p&gt;
&lt;p&gt;Other features include a team page, community guidelines, and a login page. The team page lists the team members and their roles and includes links to their profiles. The community guidelines page lists a couple of rules on public contributions of notes and the chat. The login page uses Google OAuth for authentication; user needs to login to access the chat and task board.&lt;/p&gt;
&lt;h2 id=&quot;next&quot; tabindex=&quot;-1&quot;&gt;Next?&lt;/h2&gt;
&lt;p&gt;There are a ton of features and fixes we are looking to implement in the platform. A couple of bugs that we are looking to fix are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The structure of the notes page is terrible. We want to refactor the notes page to make it more readable and uniform. It needs to handle dynamic updates to the notes like adding a subject in the middle of the list. Right now, the IDs are serialized and hardcoded.&lt;/li&gt;
&lt;li&gt;The community chat loading page is too slow; we want to store the chats in cache before lazy loading them to make the page load faster.&lt;/li&gt;
&lt;li&gt;The contributions page needs to have a github service trigger that would automatically create a pull request to the repository with the new contributions. It also needs to be able to handle new subject additions.&lt;/li&gt;
&lt;li&gt;The router fails when a page needs authentication and the user is not logged in. When the user logs in, he should be redirected to the page he was trying to access, not the default profile page.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;metrics&quot; tabindex=&quot;-1&quot;&gt;Metrics&lt;/h3&gt;
&lt;figure class=&quot;resoc&quot;&gt;
&lt;img alt=&quot;analytics&quot; src=&quot;https://anubhavp.dev/assets/img/resoc/resoc-traffic.jpeg&quot; class=&quot;h-100 w-100&quot; loading=&quot;lazy&quot;&gt;
&lt;figcaption&gt;
RESOC Traffic during exam time!
&lt;/figcaption&gt;
&lt;figure class=&quot;resoc&quot;&gt;
&lt;img alt=&quot;analytics&quot; src=&quot;../assets/img/resoc/24traffic.png&quot; class=&quot;h-100 w-100&quot; loading=&quot;lazy&quot;&gt;
&lt;figcaption&gt;
RESOC Traffic in 2024!
&lt;/figcaption&gt;
&lt;/figure&gt;
            &lt;hr&gt;
            &lt;div class=&quot;footer&quot;&gt;
              &lt;i&gt;Feedback, Suggestions, Comments - &lt;/i&gt;
              &lt;div class=&quot;giscus-div&quot; id=&quot;comments&quot;&gt;
                &lt;script src=&quot;https://giscus.app/client.js&quot; data-repo=&quot;anubhavpgit/anubhavpgit.github.io&quot; data-repo-id=&quot;MDEwOlJlcG9zaXRvcnk0MDQ1ODEzMjc=&quot; data-category-id=&quot;DIC_kwDOGB1rz84Cer0j&quot; data-mapping=&quot;title&quot; data-strict=&quot;0&quot; data-reactions-enabled=&quot;1&quot; data-emit-metadata=&quot;0&quot; data-input-position=&quot;bottom&quot; data-theme=&quot;noborder_light&quot; data-lang=&quot;en&quot; data-loading=&quot;lazy&quot; crossorigin=&quot;anonymous&quot; async=&quot;&quot;&gt;&lt;/script&gt;
              &lt;/div&gt;
              Feel free to
              &lt;a id=&quot;mailtoLink&quot; href=&quot;mailto:anubhavp@duck.com?subject=Here&apos;s%20a%20suggestion/feedback!&quot;&gt;send
                me an email&lt;/a&gt;.
            &lt;/div&gt;
          &lt;/figure&gt;&lt;/div&gt;
        </content:encoded>
            <subtitle>RESOC; short for Resources + Community, is the ABD of notes - the coolest academic notes-sharing platform around, built by a bunch of tech-savvy students at Silicon Institute, and it&apos;s totally free!</subtitle>
        </item>
        <item>
            <title><![CDATA[Rust: the future C++?]]></title>
            <description><![CDATA[Rust is a multi-paradigm systems programming language created to ensure high performance similar to that offered by C and C++ but with emphasis on code safety. Will it replace C++ anytime soon?]]></description>
            <link>https://anubhavp.dev/blog/rust.html</link>
            <guid isPermaLink="true">https://anubhavp.dev/blog/rust.html</guid>
            <dc:creator><![CDATA[Anubhab Patnaik]]></dc:creator>
            <pubDate>Fri, 14 Oct 2022 00:00:00 GMT</pubDate>
            <content:encoded>
          &lt;div class=&quot;content custom&quot;&gt;
            &lt;div class=&quot;search-container&quot;&gt;&lt;/div&gt;
            &lt;p&gt;While choosing the next language to learn, or to use for building a high-performing, memory-efficient application, you might have come across Rust. Here’s a breakdown of what I found about Rust and how it compares to the already existing compiled language king, C++.&lt;/p&gt;
&lt;p&gt;Rust is a multi-paradigm systems programming language created to ensure high performance similar to that offered by C and C++, but with emphasis on code safety, the lack of which is probably why C and C++ are painful to deal with. It accomplishes memory safety without using a dedicated garbage collector. Rust is also an ahead-of-time compiled language, which means that you can compile a rust program, give it to someone else, and they can run it even without having Rust installed. However, Rust has more than just memory safety on its side. High performance while processing large amounts of data, support for concurrent programming, and an effective compiler are other reasons why well-known software heavyweights such as Firefox, Dropbox, Cloudflare, and many web-3 startups and large corporations use Rust in production.&lt;/p&gt;
&lt;p&gt;Some questions that may come to your mind are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;If Rust is created to achieve performance similar to that offered by C++, then why not use C++ instead?&lt;/li&gt;
&lt;li&gt;I know Java, JavaScript, and Python to be more popular choices amongst peers. Why not use those languages instead?&lt;/li&gt;
&lt;li&gt;What about new languages like Go, Kotlin, Swift, etc.?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To answer these questions, let us first go through how a programming language works.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#programming-languages-and-their-working&quot;&gt;Programming Languages and their working&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#compilers-and-interpreters&quot;&gt;Compilers and interpreters&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#compiled-vs-interpreted-languages&quot;&gt;Compiled Vs Interpreted languages&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#c-the-king-of-programming-languages&quot;&gt;C++: The king of programming languages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#memory-management-in-programming-languages&quot;&gt;Memory management in programming languages&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#c&quot;&gt;c++&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#garbage-collection&quot;&gt;Garbage collection&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#rust&quot;&gt;Rust&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#rust-c&quot;&gt;Rust &amp;gt; C++&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;programming-languages-and-their-working&quot; tabindex=&quot;-1&quot;&gt;Programming Languages and their working&lt;/h2&gt;
&lt;p&gt;A programming language is a set of instructions that can be used to interact with and control a computer. These languages can be used for a multitude of purposes, such as creating a website, analyzing data, writing a program to solve a mathematical problem, creating a game, piloting a car, building a robot, making rockets take off, controlling spacecraft and the list goes on. A computer, even though can control a rover on Mars, detect an incoming ballistic missile, and detonate it before it reaches you, cannot understand English, or anything else except &lt;strong&gt;‘0’&lt;/strong&gt; &amp;amp; &lt;strong&gt;‘1’&lt;/strong&gt;. Computers can be thought of to be made up of tiny switches, and can be either ‘on’ (1) or ‘off’ (0) called &lt;strong&gt;‘bits’&lt;/strong&gt;. Whatever instruction you want to execute on a computer, has to be converted into a series of &apos;0’s and &apos;1’s before it can be executed. Even a simple “Hi” is parsed as &lt;strong&gt;01001000 01101001&lt;/strong&gt;. Yes, this is what Siri responds when you &lt;em&gt;Hey Siri&lt;/em&gt;. Since the English language is vast and complicated, it is not possible to convert it into a series of ‘0’ and ‘1’ directly. A subset of English or any other language is created, which is called a &lt;strong&gt;programming language&lt;/strong&gt;. High-Level Programming Languages have English-like syntax and are designed to be easy to read and write, whereas low-Level Programming Languages are designed to be easy for the computer to understand. To make things easier for us, there are tools that convert whatever we want the computer to do into a series of &apos;0’s and &apos;1’s. This series of &apos;0’s and &apos;1’s is then executed by the computer.&lt;/p&gt;
&lt;h3 id=&quot;compilers-and-interpreters&quot; tabindex=&quot;-1&quot;&gt;Compilers and interpreters&lt;/h3&gt;
&lt;p&gt;A &lt;strong&gt;compiler&lt;/strong&gt; or an &lt;strong&gt;interpreter&lt;/strong&gt; is a tool that converts a program written in a programming language &lt;em&gt;(source code)&lt;/em&gt; into a series of &apos;0’s and &apos;1’s that can be executed by a computer. Compilers and interpreters differ in the way they work. A compiler converts the entire program into a series of &apos;0’s and &apos;1’s &lt;em&gt;(machine code)&lt;/em&gt; and then executes it. An interpreter, on the other hand, executes the program line by line.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why did we need interpreters?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Compiled languages need a “build” step. You need to compile your program before you can run it. To run your program on a different computer, you will have to compile it on that computer as well. Interpreters run through a program line by line and execute each command. You can run a program without having to compile it first. This makes it easier to run programs on different computers.&lt;/p&gt;
&lt;p&gt;Another notable disadvantage of compilers is &lt;strong&gt;platform dependency&lt;/strong&gt; of the generated binary code. Compilers are designed to be CPU specific and run on a specific CPU architecture. This means that if you want to run a program on a different CPU architecture, you will have to compile it again.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why do we still make use of compilers ?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Compilers are designed to be CPU specific, and as a result, they tend to be a lot &lt;strong&gt;faster and more efficient&lt;/strong&gt; than interpreters. They also give the developer &lt;strong&gt;more control&lt;/strong&gt; over hardware aspects, like memory management and CPU usage.&lt;/p&gt;
&lt;p&gt;A compiler is faster and more efficient than an interpreter, but an interpreter is easier to write than a compiler.&lt;/p&gt;
&lt;h3 id=&quot;compiled-vs-interpreted-languages&quot; tabindex=&quot;-1&quot;&gt;Compiled Vs Interpreted languages&lt;/h3&gt;
&lt;p&gt;Interpreted languages were once significantly slower than compiled languages. But, with the development of &lt;a href=&quot;https://guide.freecodecamp.org/computer-science/just-in-time-compilation&quot;&gt;just-in-time compilation&lt;/a&gt;, that gap is shrinking. Modern scripting languages like Python and JavaScript are compiled to machine code at runtime using both compilers and interpreters, which makes them as fast as compiled languages. They are first compiled into an intermediate representation called &lt;strong&gt;bytecode&lt;/strong&gt;, and then interpreted by a virtual machine which converts it to machine code.&lt;/p&gt;
&lt;p&gt;If you’re wondering what language should you choose to build your next project with, ask yourself this: what kind of platform do I want the application to run in? If you want to run your application on a web browser, you should go with JavaScript or TypeScript. If you want to run your application on a server, you may want to use Python or Go. In a mobile device, Swift or Kotlin might be the way to go. C++ is used for building complex applications and systems software, such as operating systems, browsers, and video games which require a heavy performance overhead.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Rust&lt;/em&gt;, &lt;em&gt;Go&lt;/em&gt; and &lt;em&gt;C++&lt;/em&gt; are popular compiled languages that are used for building high-performance applications. &lt;em&gt;Python&lt;/em&gt; and &lt;em&gt;JavaScript&lt;/em&gt; are popular interpreted languages that are used for building web applications.&lt;/p&gt;
&lt;p&gt;The speed advantage of the compiled language such as Golang (Go) in comparison to an interpreted language such as Java is one of the reasons why organizations write their microservices in Go. In complex computing environments such as cloud computing environments, where users get charged for every clock cycle, it makes sense to use the most efficient deployment artifact.&lt;/p&gt;
&lt;h2 id=&quot;c-the-king-of-programming-languages&quot; tabindex=&quot;-1&quot;&gt;C++: The king of programming languages&lt;/h2&gt;
&lt;p&gt;C++ is a low-level, statically typed object-oriented language that allows you to have a good grasp of your computer’s resources and utilize them at your convenience. Since it is a compiled language, it surpasses the performance of most of the other interpreted languages. It is an extremely powerful language and is used in many applications such as operating systems, video games, the development of compilers and interpreters, etc. It has a huge community and is one of the most popular languages in the world.&lt;/p&gt;
&lt;p&gt;Reasons why C++&apos;s performance is unparalleled:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A compiled language. C++ is extremely fast because it is a compiled language.&lt;/li&gt;
&lt;li&gt;A low-level language. It allows you to cheaply use computing resources.&lt;/li&gt;
&lt;li&gt;Statically typed. It allows the compiler to optimize the code.&lt;/li&gt;
&lt;li&gt;Object-oriented programming. It allows you to create reusable code.&lt;/li&gt;
&lt;li&gt;A general purpose language. It can be used to create any kind of application.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The issue with C++ boils down to how it &lt;strong&gt;manages memory&lt;/strong&gt;. C++ is prone to memory leaks and dangling pointers, if not written properly.&lt;/p&gt;
&lt;h2 id=&quot;memory-management-in-programming-languages&quot; tabindex=&quot;-1&quot;&gt;Memory Management in programming languages&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Variables&lt;/strong&gt; are named memory locations that store data. A variable is a container that holds a value. The value can be of any type, such as &lt;em&gt;integer&lt;/em&gt;, &lt;em&gt;float&lt;/em&gt;, &lt;em&gt;character&lt;/em&gt;, etc. Example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int a = 10;
float b = 10.5;
char c = &apos;a&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Computer programs need to allocate memory to store variables, data values, and data structures and deallocate memory when done using them. Memory is also used to store the program itself and the run-time system needed to support it. Programming languages can be categorized as those which provide &lt;strong&gt;automatic memory management&lt;/strong&gt; and those which ask the programmer to allocate and &lt;strong&gt;free memory manually&lt;/strong&gt;. Requiring the programmer to manage memory manually leads to a simpler compiler and run-time but requires more work from the programmer and is more error-prone. While automatic memory management is more convenient for the programmer, it is also more complex and slower and it is achieved by the use of &lt;strong&gt;garbage collection&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id=&quot;c&quot; tabindex=&quot;-1&quot;&gt;C++&lt;/h3&gt;
&lt;p&gt;C++ is a low-level language with manual memory management. C++ programs manually allocate and free memory using &lt;strong&gt;pointers&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pointers&lt;/strong&gt;
Pointers are variables that store the &lt;strong&gt;address&lt;/strong&gt; of another variable and access the memory location of a variable. Pointers are used to pass large data structures to functions, to return multiple values from a function, to dynamically allocate memory, etc. Since there is no automatic memory management in C++, you need to be responsible for allocating and freeing memory. This process is achieved using the &lt;strong&gt;malloc&lt;/strong&gt;, &lt;strong&gt;calloc&lt;/strong&gt;, &lt;strong&gt;new&lt;/strong&gt;, and &lt;strong&gt;delete&lt;/strong&gt; keywords.&lt;/p&gt;
&lt;p&gt;With manual memory management, a few things can go wrong like memory leaks and dangling pointers. For instance, the dangling pointer problem arises when there is an attempt to use a pointer after it has been freed. Dangling pointer errors can arise whenever there is an error in the control flow logic of a program. The use of a pointer before allocation may be a fatal run-time error. Use after deallocation is not always fatal but neither of these is a good thing.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;
&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-type&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;hljs-title&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;()&lt;/span&gt;  
  &lt;/span&gt;{
    &lt;span class=&quot;hljs-type&quot;&gt;int&lt;/span&gt; *ptr=(&lt;span class=&quot;hljs-type&quot;&gt;int&lt;/span&gt; *)&lt;span class=&quot;hljs-built_in&quot;&gt;malloc&lt;/span&gt;(&lt;span class=&quot;hljs-built_in&quot;&gt;sizeof&lt;/span&gt;(&lt;span class=&quot;hljs-type&quot;&gt;int&lt;/span&gt;));  
    &lt;span class=&quot;hljs-type&quot;&gt;int&lt;/span&gt; a=&lt;span class=&quot;hljs-number&quot;&gt;560&lt;/span&gt;;  
    ptr=&amp;amp;a;  
    &lt;span class=&quot;hljs-built_in&quot;&gt;free&lt;/span&gt;(ptr);  
    &lt;span class=&quot;hljs-comment&quot;&gt;// dangling pointer&lt;/span&gt;
    &lt;span class=&quot;hljs-built_in&quot;&gt;printf&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&quot;%d&quot;&lt;/span&gt;,*ptr);
    &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;;  
}  

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above code will produce a segmentation fault since the pointer is pointing to a memory location that has been freed. To avoid this, we can set the pointer to NULL after freeing it.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;
    &lt;span class=&quot;hljs-built_in&quot;&gt;free&lt;/span&gt;(ptr);
    ptr=&lt;span class=&quot;hljs-literal&quot;&gt;NULL&lt;/span&gt;;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Memory leaks and dangling pointer bugs are some reasons why C++ is not preferred for applications that require a lot of memory management. To avoid such issues, languages that provide automatic memory management are preferred over C++. Scripting languages manage memory using a &lt;strong&gt;garbage collector&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id=&quot;garbage-collection&quot; tabindex=&quot;-1&quot;&gt;Garbage collection&lt;/h3&gt;
&lt;p&gt;Garbage is a memory that was once used by objects but will never be read or written by the program again. A garbage collector (GC) is a background process that provides automatic memory management for modern languages by taking care of the allocation and deallocation of a program’s computer memory resources. As a result, certain categories of bugs are eliminated or substantially reduced such as:-&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Dangling pointer bugs&lt;/strong&gt; - a piece of memory is freed, but the objects still have references – one of these references is used in the program.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Double-free bugs&lt;/strong&gt; – the program attempts to free a piece of memory that has already been freed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Memory leaks&lt;/strong&gt; – if a program does not free memory that is no longer referenced by any object, it can lead to memory exhaustion over time.&lt;/p&gt;
&lt;p&gt;Garbage collection seemed like a really good solution to the memory leak issues occurring in low-level languages such as C/C++ but, it had a few CPU issues. CPU usage increases when a significant amount of CPU time is spent in garbage collection. &lt;em&gt;Heap&lt;/em&gt; is the memory that is used to allocate memory dynamically as opposed to the &lt;em&gt;stack&lt;/em&gt; memory which is used to store the local variables. Local memory is quite automatic and local variables are allocated automatically. An increased allocation rate of objects on the managed heap causes garbage collection to occur more frequently.&lt;/p&gt;
&lt;p&gt;Here are a few types of Garbage collectors:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Mark &amp;amp; Sweep GC&lt;/strong&gt;(Tracing GC): A two-phase algorithm that first marks objects that are being referenced as “alive” and in the next phase frees the memory of objects that are not alive. JVM, C#, Ruby, JavaScript, and Golang employ this approach. JavaScript engines like V8 use a Mark &amp;amp; Sweep GC along with Reference counting GC to complement it. This kind of GC is also available for C &amp;amp; C++ as an external library.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Reference counting GC&lt;/strong&gt;: Every object gets a reference count which is incremented or decremented as references to it change. Garbage is collected when the count becomes zero. This is not preferred as it cannot handle cyclic references. PHP, Perl, and Python use this kind of GC with workarounds to overcome cyclic references. This type of GC can be enabled for C++ as well.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Automatic Reference Counting(ARC)&lt;/strong&gt;: Similar to Reference counting GC but instead of running a runtime process at a specific interval the retain and release instructions are inserted into the compiled code at compile-time and when an object’s reference becomes zero, it is cleared automatically as a part of the code execution. It also cannot handle cyclic references and relies on the developer. ARC is a feature of the Clang compiler and provides ARC for Objective C &amp;amp; Swift.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Resource Acquisition is Initialization (RAII)&lt;/strong&gt;: Objects and variables are &lt;em&gt;scoped&lt;/em&gt;, and an object’s memory allocation is tied to its lifetime, which is from construction until destruction. It was introduced in C++ and is also used by Ada and Rust.&lt;/p&gt;
&lt;h2 id=&quot;rust&quot; tabindex=&quot;-1&quot;&gt;Rust&lt;/h2&gt;
&lt;p&gt;Rust is a general-purpose systems programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety. It is a multi-paradigm language that supports imperative, functional, and object-oriented programming. Rust is not only used to create low-level systems software such as operating systems, device drivers, and embedded software, but also used to create high-level applications such as web servers, command-line tools, and graphical user interfaces.&lt;/p&gt;
&lt;p&gt;Rust builds on &lt;strong&gt;RAII&lt;/strong&gt;( Resource Acquisition is Initialization) to provide automatic memory management. RAII is a programming technique that uses the lifetime of an object to manage the lifetime of its resources. In Rust, the compiler ensures that the memory is freed as soon as the object goes out of scope. This is achieved by the use of &lt;strong&gt;smart pointers&lt;/strong&gt;. Rust implements borrow checking and ownership rules to ensure that memory is freed as soon as the object goes out of scope. Additionally, Rust also provides a &lt;strong&gt;garbage collector&lt;/strong&gt; that can be used to free memory when the object goes out of scope.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Ownership and Borrowing&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#[derive(Debug)]&lt;/span&gt;
&lt;span class=&quot;hljs-keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;hljs-title class_&quot;&gt;Employee&lt;/span&gt; {
    id : &lt;span class=&quot;hljs-type&quot;&gt;i32&lt;/span&gt;
}

&lt;span class=&quot;hljs-keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;main&lt;/span&gt;() {
    &lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;a&lt;/span&gt; = Employee{id: &lt;span class=&quot;hljs-number&quot;&gt;43&lt;/span&gt;} ;
    &lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;b&lt;/span&gt;  = a ;
    &lt;span class=&quot;hljs-comment&quot;&gt;// println!(&quot;{:?}&quot;, a) ; // error: borrow of moved value: `a`&lt;/span&gt;
    &lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;c&lt;/span&gt;= a ;
    &lt;span class=&quot;hljs-comment&quot;&gt;// println!(&quot;{:?}&quot;, a) ; // error: borrow of moved value: `a`&lt;/span&gt;
} 
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;RAII&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;    &lt;span class=&quot;hljs-keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;main&lt;/span&gt;() {
        &lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;foo&lt;/span&gt; = &lt;span class=&quot;hljs-string&quot;&gt;&quot;value&quot;&lt;/span&gt;; &lt;span class=&quot;hljs-comment&quot;&gt;// owner is foo and is valid within this method&lt;/span&gt;
        &lt;span class=&quot;hljs-comment&quot;&gt;// bar is not valid here &lt;/span&gt;

        {
            &lt;span class=&quot;hljs-keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;hljs-variable&quot;&gt;bar&lt;/span&gt; = &lt;span class=&quot;hljs-string&quot;&gt;&quot;bar value&quot;&lt;/span&gt;; &lt;span class=&quot;hljs-comment&quot;&gt;// owner is bar and is valid &lt;/span&gt;
            &lt;span class=&quot;hljs-comment&quot;&gt;//within this block scope&lt;/span&gt;
            &lt;span class=&quot;hljs-built_in&quot;&gt;println!&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&quot;value of bar is {}&quot;&lt;/span&gt;, bar); &lt;span class=&quot;hljs-comment&quot;&gt;// bar is valid &lt;/span&gt;
            &lt;span class=&quot;hljs-comment&quot;&gt;//here&lt;/span&gt;
            &lt;span class=&quot;hljs-built_in&quot;&gt;println!&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&quot;value of foo is {}&quot;&lt;/span&gt;, foo); &lt;span class=&quot;hljs-comment&quot;&gt;// foo is valid &lt;/span&gt;
            &lt;span class=&quot;hljs-comment&quot;&gt;//here&lt;/span&gt;
        }

        &lt;span class=&quot;hljs-built_in&quot;&gt;println!&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&quot;value of foo is {}&quot;&lt;/span&gt;, foo); &lt;span class=&quot;hljs-comment&quot;&gt;// foo is valid here&lt;/span&gt;
        &lt;span class=&quot;hljs-built_in&quot;&gt;println!&lt;/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&quot;value of bar is {}&quot;&lt;/span&gt;, bar); &lt;span class=&quot;hljs-comment&quot;&gt;// bar is not valid &lt;/span&gt;
        &lt;span class=&quot;hljs-comment&quot;&gt;//here as its out of scope&lt;/span&gt;
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;rust-c&quot; tabindex=&quot;-1&quot;&gt;Rust &amp;gt; C++ ?&lt;/h3&gt;
&lt;p&gt;C++ is a high-performance, general-purpose programming language that has been widely used for decades. It is known for its flexibility and ability to handle low-level tasks, making it a popular choice for systems programming and game development. C++ also has a large and active community, which means that there are many libraries and resources available for developers to use. Rust, on the other hand, is a relatively &lt;strong&gt;new programming language&lt;/strong&gt; that was first released in 2010. It is designed to be a safe and concurrent language, with a strong focus on preventing common programming errors such as null pointer dereferences and buffer overflows.&lt;/p&gt;
&lt;p&gt;Coming back to our questions that we were pondering upon earlier, now we get that compiled languages are preferred over interpreted languages as they are much faster and hence C++/ Go are preferred over Python/JavaScript. While C++ is extremely fast, it is also prone to memory leaks. Other languages such as Rust and Go offer better automatic memory management. Go implements a garbage collector which has a CPU usage overhead while Rust builds over RAII and implements borrow checking and ownership rules to ensure that memory is freed as soon as the object goes out of scope. Rust also provides a garbage collector that can be used to free memory when the object goes out of scope.&lt;/p&gt;
&lt;p&gt;Will rust replace C++ anytime soon? &lt;strong&gt;No&lt;/strong&gt;. Rust is a relatively new language and is still in its early stages of development. It is not yet widely used in production, and there are still many features that are missing. However, it is gaining popularity and is being used in many large projects, such as Firefox and Servo. C++ has been widely used for decades and has a vast amount of &lt;em&gt;legacy code&lt;/em&gt;, making it difficult for Rust to replace it. C++ has a much larger community and ecosystem, with a wealth of libraries, tools, and resources, making it easier for developers to find help and resources. Rust’s tooling is still evolving and may not be as mature or widely used as C++.&lt;/p&gt;

            &lt;hr&gt;
            &lt;div class=&quot;footer&quot;&gt;
              &lt;i&gt;Feedback, Suggestions, Comments - &lt;/i&gt;
              &lt;div class=&quot;giscus-div&quot; id=&quot;comments&quot;&gt;
                &lt;script src=&quot;https://giscus.app/client.js&quot; data-repo=&quot;anubhavpgit/anubhavpgit.github.io&quot; data-repo-id=&quot;MDEwOlJlcG9zaXRvcnk0MDQ1ODEzMjc=&quot; data-category-id=&quot;DIC_kwDOGB1rz84Cer0j&quot; data-mapping=&quot;title&quot; data-strict=&quot;0&quot; data-reactions-enabled=&quot;1&quot; data-emit-metadata=&quot;0&quot; data-input-position=&quot;bottom&quot; data-theme=&quot;noborder_light&quot; data-lang=&quot;en&quot; data-loading=&quot;lazy&quot; crossorigin=&quot;anonymous&quot; async=&quot;&quot;&gt;&lt;/script&gt;
              &lt;/div&gt;
              Feel free to
              &lt;a id=&quot;mailtoLink&quot; href=&quot;mailto:anubhavp@duck.com?subject=Here&apos;s%20a%20suggestion/feedback!&quot;&gt;send
                me an email&lt;/a&gt;.
            &lt;/div&gt;
          &lt;/div&gt;
        </content:encoded>
            <subtitle>Rust is a multi-paradigm systems programming language created to ensure high performance similar to that offered by C and C++ but with emphasis on code safety. Will it replace C++ anytime soon?</subtitle>
        </item>
        <item>
            <title><![CDATA[The myth of Sisyphus (II)]]></title>
            <description><![CDATA[A journey through whims of fate and lucid memories. Growing up and looking for the purpose of life.]]></description>
            <link>https://anubhavp.dev/blog/sisyphus.html</link>
            <guid isPermaLink="true">https://anubhavp.dev/blog/sisyphus.html</guid>
            <dc:creator><![CDATA[Anubhab Patnaik]]></dc:creator>
            <pubDate>Sat, 09 Aug 2025 00:00:00 GMT</pubDate>
            <content:encoded>
          &lt;div class=&quot;content custom&quot;&gt;
            &lt;div class=&quot;search-container&quot;&gt;&lt;/div&gt;
            &lt;p&gt;&lt;em&gt;Previous entries:&lt;/em&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;/blog/jajabara.html&quot;&gt;Jajabara (I)&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The myth of Sisyphus speaks about the futility of life, the absurdity of existence, and the struggle against the inevitable. Growing up, looking for the purpose of life, turning twenty-five, exploring existentialism and quarter-life crisis. Sisyphus, the king of Ephyra, was condemned to roll a boulder up a hill, only for it to roll back down each time he reached the top. This endless cycle of moving to reach a destination that always eludes him mirrors my human experience. Growing up, I found myself packing and moving every couple of years, always searching for a place to call home.&lt;/p&gt;
&lt;h3 id=&quot;growing-up&quot; tabindex=&quot;-1&quot;&gt;Growing Up&lt;/h3&gt;
&lt;p&gt;Life in Asansol was a lively experience. The company quarters we moved into were located in a sprawling colony, and my house number was B2/2. The colony was huge, a little universe of its own, with its own customs. It was a mix of people from different backgrounds and cultures, mostly from South and Central East—West Bengal, Jharkhand, Bihar, and Odisha. We traded homemade dishes, celebrated festivals together, and played until the sun disappeared—or until our parents dragged us back home, whichever came first.&lt;/p&gt;
&lt;p&gt;I was lucky enough to meet many kids around my age. Together, we formed a large, rambunctious group, though most of them were four or five years older than me. That age gap meant I often served as their errand boy, fetching items or doing other grunt work, but I was happy to be part of the group. Two rival groups prevailed: the men versus the ladies. Each group had four to five members, and we played hide-and-seek, football, badminton, and all sorts of games together. I was one of the younger members and was at the mercy of the older ones. The women bossed me around, always using me in their battles. Men were simpler, but equally provocative in wars. I was the weapon of choice for both sides.&lt;/p&gt;
&lt;p&gt;We still had harmony for most of the time. We went to tuitions together, watched TV, shared comics, went on long walks, exchanged game disks and comic books, played IGI, and had fun. Us boys were more focused on comics, sports, and video games. We played badminton, football, and cricket, and usually, the cricket ball would end up in someone’s house, and we would have to beg them to give it back. Every evening we would dash out of the house, knocking and ringing doorbells to bring everyone out to play—without fail, every single day.&lt;/p&gt;
&lt;p&gt;On weekends, the colony would come alive with house parties—usually arranged by the girls in our group. All they needed was a little food, some snacks, and a place to sit, and they would plan a host of games I never quite understood. Birthdays were also a big deal; everyone would show up to celebrate, regardless of how well they knew the birthday kid. We played badminton and hide-and-seek frequently. These games were gender-neutral and thus played by everyone.&lt;/p&gt;
&lt;p&gt;My family and relatives often visited us. In this new world, where the invisible boundary of the colony defined my universe, my family and relatives were always a joy to have. They brought with them stories, laughter, and love, filling our home with warmth and joy. Their arrival meant less studying, more roaming around, and some petty cash to spend when they left. Now, years later, their memories make me want to rush back home. The memories accompany me making my subway rides a bit more bearable, and my nights a bit more peaceful.&lt;/p&gt;
&lt;p&gt;Beyond the colony, there wasn’t much exploration of Asansol itself. Unlike Kolkata, we didn’t go out much; the colony truly was my whole world. At eight, I was starting to understand that there was a larger, more complex society beyond our boundary walls, but the extent of my daily life revolved around my friends and our home. Now, at twenty-four, I watch days pass by, and nights go white with the snow and the world outside—a place where I am yet to find my place.&lt;/p&gt;
&lt;p&gt;My school was far away. I remember the bus rides taking an hour to reach the school. My school was like stepping onto a different dimension. It was a Christian Missionary School, Assembly of the God Church, deeply invested in sharing biblical stories and holding long, reflective assemblies. The institution’s strictness was jarring to me at first. It was also huge, boasting two expansive playgrounds and a canteen that sold amazing spring rolls. Academically, I was doing well, scored a 100% in my math exams. I was always good at Math, Science, Grammar, and Literature and terrible at History, Civics, Hindi, and Arts.&lt;/p&gt;
&lt;p&gt;My parents put a lot of emphasis on scoring well. This somehow slowly started to shape my life in a way that I would not have actually wanted. I feel children should be left alone to be children, constantly failing and succeeding on their own merit—paving their own way in the world, and not be burdened with the weight of expectations. A lemon now I know what to do with.&lt;/p&gt;
&lt;p&gt;Vacations were mostly spent back home. Asansol—and indeed most of West Bengal—came alive in October and November with Durga Puja festivities. Durga Puja has always been the most joyous time for me throughout the years. In all the cities I have lived in, life has always been kinder to me during these few days. We would roam the streets at night, visiting brightly lit pandals and paying our respects to the idol of the goddess, returning just in time for community dinners at the colony tents. In November and December, the winters were chilly, and we couldn’t sleep without a heater. That was also the year we bought our first car—a cherry-coloured Hyundai Getz Prime. We often drove the 500 km to Bhubaneswar, weaving through scenic highways, pausing at roadside stalls, and listening to stories from my parents’ own childhoods, oblivious to what awaited me in adulthood.&lt;/p&gt;
&lt;p&gt;Looking back, I realize how simple everything was back then. The world felt small, and the days stretched endlessly. The transient inevitability of the non-linear passage of time was yet to dawn on me. I still don’t truly believe in the concept of linear time. I don’t feel Asansol was just two years of my life. It feels like much longer. Days were longer. Surrounded by family and relatives, life never felt lonely. My sister, who once fit snugly in my arms, is nineteen now. Back then, the world was a playground, and I was the undisputed king of my castle.&lt;/p&gt;
&lt;p&gt;Yet, like every chapter before, the boulder couldn’t stay perched on that hill forever. This journey from one hill to another—the ultimate Sisyphean truth—hurt this time. My friends in the colony were gradually being uprooted too—their parents worked in the same organization, which meant one by one, they all had to move on, and I realized the inevitability of this journey. Again, back to square one, we found ourselves with our bags packed. After five odd years of living in a different state, my father got a chance and thought it would be nice to go back to Odisha and live near home. Those years in a different state had raced by. It was time to start over, to push yet another boulder up another hill. But even though leaving Asansol stung, I found solace in the understanding that such is the nature of life: a Sisyphean cycle of endings and beginnings, each one layered with memories, friendships, and lessons I would carry forward.&lt;/p&gt;
&lt;h3 id=&quot;back-to-roots&quot; tabindex=&quot;-1&quot;&gt;Back to Roots&lt;/h3&gt;
&lt;p&gt;I was nine years old now, in 2009, and my parents seemed happy. Moving to Jajpur, a small town in Odisha, meant we were closer to Bhubaneswar, making frequent visits to our extended family much easier. My grandparents were overjoyed; they could see us more often, visiting every weekend and sometimes staying with us for extended periods. This was a welcome change for all of us.&lt;/p&gt;
&lt;p&gt;Our new move was peaceful, and we gradually started settling down. I was in fourth grade now and attended &lt;em&gt;Harrow Public School&lt;/em&gt;. The school was small, with a playground that was more of a dust bowl. The school itself was housed in a large, unfinished two-story building. The first floor was divided into two sections: a vast hall accommodating four different classes without any partitions, and a smaller room designated for the primary grades—first, second, and third, separated by walls and curtains.&lt;/p&gt;
&lt;p&gt;I was introduced to my native Odia language in a more raw form. The prayers, scripts, and literature were a bit difficult for me to grasp since other students had been learning the language for a long time. Despite this, the culture felt personal and heartfelt.&lt;/p&gt;
&lt;p&gt;The exciting part was witnessing sixth and seventh-grade students getting disciplined by the teachers. Beating students until they turned red was an essential discipline technique in a rural town. The teachers were strict, and the students were rowdy. The school was a mix of different backgrounds. Some were from the town, while others were from the nearby villages. I was excited since the school allowed students pens in the fourth grade, and that is what mattered to me the most; pen users were the elite, and being able to scribble with a pen instead of a pencil was a significant rite of passage.&lt;/p&gt;
&lt;p&gt;Jajpur life was slow, peaceful, and simple. The town was small, with narrow, muddy lanes and small shops, enveloped by paddy fields and empty grounds. The air was rich with the scent of fresh earth and filled with the sound of birds. The evenings were cool, filled with the chorus of crickets, children playing, and temple bells ringing. Nights were serene and quiet. The town was a world away from the hustle and bustle. We rented a house and settled in, making it our home. The weekends were a ride to Bhubaneswar, and the weekdays were spent in school and solitary confinement.&lt;/p&gt;
&lt;p&gt;Transitioning from a place where I had countless friends to a new home with hardly any children nearby was a strange and emotionally difficult adjustment. It’s not that I had zero friends, I did have a lot of friends in school, and a couple near my house. There was a disconnect, though, not palpable then, but slightly more evident now. It was my first real encounter with loneliness. The few children who lived near us attended a different school—a more polished institution. In the evenings, I spent most of my time alone, watching TV, playing on computers, or just wandering around the house. The loneliness was palpable, a constant companion that followed me everywhere. Afternoons and evenings passed by, blueish violet skies, and the sun setting in the distance. I would often wait for the sun to set completely and listen to the sounds of the temple prayers blasting on the speaker in a loop. Mostly lucid, I would sit on my bed, just reminiscing about the past, overthinking about the future, and wondering what or where would I be, in 15 years. New York, the US? Careful what you wish for.&lt;/p&gt;
&lt;p&gt;I spent most of my time reading and watching TV soap operas. I have read countless books. From comics to Dickens and Tolstoy, I was a voracious reader. I do not remember popular books or prominent series that I read- never read Narnia or Harry Potter, was more into the classics. Tolstoy was a nice read but too polished for my taste. Dickens had this amazing grounded writing style, exploring the human condition much like Sisyphus. I was fascinated by the way he portrayed the struggles of his characters, their resilience in the face of adversity, and their quest for meaning in a chaotic world. These stories resonated with me, lost in pages and in worlds far away.&lt;/p&gt;
&lt;p&gt;Other times I was invested in Soap operas, an addict. That was what primarily kept me entertained. And my computer. We got a new computer after moving to Jajpur. I still remember my dad weighing in the pros and cons of assembling a PC and buying a pre-built one. We went ahead with an assembled one. Actually, the loneliness didn’t affect me a lot, unlike how in adulthood it slammed right on my face, anxiety creeping up my spine. Childhood loneliness was a happy loneliness. My mind wandered off to places I had never been, and I was happy to be lost in my own world. Maybe I don’t completely understand this, and although not the most ideal situation- having to spend most of my time alone, I was happy, and at peace. The weekends were a relief, back in Bhubaneswar with all my extended family and cousins.&lt;/p&gt;
&lt;p&gt;My favourite memory has to be the journey back home. We would travel in our Hyundai Getz Prime, taking the four-hour drive to Bhubaneswar. The route was picturesque, winding through lush green fields, quaint villages, and increasingly wider roads as we crossed cities. The journey was a time to bond with my family, to talk about lives lived in the 70s, 80s, and 90s, to laugh, and to share stories—a time to reflect and plan for the future, a time to dream, to imagine, and to create. The soundtrack to these memories was the Odia songs from the CD my father bought, featuring the soulful music of Akshaya Mohanty. The same one who sang &lt;em&gt;Jajabara&lt;/em&gt;. I still remember the order of the songs and the lyrics, each one etching itself into my memory.&lt;/p&gt;
&lt;p&gt;There always felt something profoundly liberating about being on the road, in motion, part of a journey. Roads are a metaphor for life itself—a journey fraught with constant change and uncertainty.&lt;/p&gt;
&lt;p&gt;However, our time in Jajpur was brief- a year. Settling down proved difficult, and concerns about education and livelihood began to outweigh the town’s tranquil allure. My parents decided it was best to move to Cuttack, as enrolling in a school in Bhubaneswar mid-year seemed impossible. The following year was spent with me, my mother, and my sister in Cuttack, while my father stayed back in Jajpur to wrap up his term. A new beginning awaited us, a new boulder to be pushed up a new hill. The Sisyphean cycle continued, and I was ready to embrace it.&lt;/p&gt;
&lt;h3 id=&quot;leaving-behind-the-rural-life&quot; tabindex=&quot;-1&quot;&gt;Leaving Behind the Rural Life&lt;/h3&gt;
&lt;p&gt;Mother, sister, and I moved to Cuttack. Jajpur and Cuttack weren’t that far apart- a four-hour drive. The move to Cuttack restored a sense of belonging. The city was vibrant, with a rich history and culture. Cuttack is an old city with a diverse population. People from all over India lived there, a melting pot of cultures. The streets were lined with ancient lanes, bustling markets, and the scent of fresh flowers. While Odia was the main language, I also encountered Bengali, Marwari, and other influences daily. The school introduced me to a bunch of new friends and perspectives, and my tuition classes were fun-filled. I was in fifth grade now, and I attended DAV Public School, CDA Sector 9.&lt;/p&gt;
&lt;p&gt;Cuttack introduced me to people more my speed. I made some amazing friends, whom I am still in touch with. We spent our days playing cricket, attended tuition classes, and went on school picnics. There was a radical change in the sixth grade. Although we moved to Jamshedpur once my fifth grade was over, before the summer, I spent a month or two in Cuttack. Sixth grade was spent in Sector, was a new ballgame. Sections spanning up to I or J, each holding sixty to seventy students. The school was huge, with a sprawling campus, and multiple playgrounds. I didn’t have a lot of time to explore before we moved. It had these amazing food stalls outside the school, and I remember asking my mother to spare some change every day to get food from there. She obliged because she knew I wasn’t an avid eater, yet, and wouldn’t be able to stand and eat food from the stalls. I took an absurdly long time to finish my food.&lt;/p&gt;
&lt;p&gt;Our life in Cuttack was beautiful, always filled with family and relatives, and more than half the time was spent back at home in Bhubaneswar. I made many friends, and living in a city made perfect sense to me. We were there for just another year before my father’s office decided it was time for another ascent, a new life to be built. Bags packed, trucks loaded, sitting in a car watching the city pass by, we found ourselves in Jamshedpur. The year was 2011, and I was in the sixth grade.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Next entries:&lt;/em&gt;
3. &lt;a href=&quot;/blog/102.html&quot;&gt;The 102nd hike (III)&lt;/a&gt;&lt;/p&gt;

            &lt;hr&gt;
            &lt;div class=&quot;footer&quot;&gt;
              &lt;i&gt;Feedback, Suggestions, Comments - &lt;/i&gt;
              &lt;div class=&quot;giscus-div&quot; id=&quot;comments&quot;&gt;
                &lt;script src=&quot;https://giscus.app/client.js&quot; data-repo=&quot;anubhavpgit/anubhavpgit.github.io&quot; data-repo-id=&quot;MDEwOlJlcG9zaXRvcnk0MDQ1ODEzMjc=&quot; data-category-id=&quot;DIC_kwDOGB1rz84Cer0j&quot; data-mapping=&quot;title&quot; data-strict=&quot;0&quot; data-reactions-enabled=&quot;1&quot; data-emit-metadata=&quot;0&quot; data-input-position=&quot;bottom&quot; data-theme=&quot;noborder_light&quot; data-lang=&quot;en&quot; data-loading=&quot;lazy&quot; crossorigin=&quot;anonymous&quot; async=&quot;&quot;&gt;&lt;/script&gt;
              &lt;/div&gt;
              Feel free to
              &lt;a id=&quot;mailtoLink&quot; href=&quot;mailto:anubhavp@duck.com?subject=Here&apos;s%20a%20suggestion/feedback!&quot;&gt;send
                me an email&lt;/a&gt;.
            &lt;/div&gt;
          &lt;/div&gt;
        </content:encoded>
            <subtitle>A journey through whims of fate and lucid memories. Growing up and looking for the purpose of life.</subtitle>
        </item>
        <item>
            <title><![CDATA[Teasquared]]></title>
            <description><![CDATA[A goodbye to the best four years of my life: an ode to my alma mater.]]></description>
            <link>https://anubhavp.dev/blog/teasquared.html</link>
            <guid isPermaLink="true">https://anubhavp.dev/blog/teasquared.html</guid>
            <dc:creator><![CDATA[Anubhab Patnaik]]></dc:creator>
            <pubDate>Mon, 15 May 2023 00:00:00 GMT</pubDate>
            <content:encoded>
          &lt;div class=&quot;content custom&quot;&gt;
            &lt;div class=&quot;search-container&quot;&gt;&lt;/div&gt;
            &lt;style&gt;
 .skylab {
 justify-content: center;
 align-items: center;
 display: flex;
 flex-direction: column;
 }
 &lt;/style&gt;
&lt;p&gt;Standing here on the cusp of graduating, gazing upon the halls and pathways that have become my home for the past four years, a swirl of emotions engulfs me. My heart feels heavy with this melancholy as I roam around this campus for the final time. Every nook and corner of this campus holds a special place in my heart. Every memory, every laugh, and every tear have been etched into these walls. And now, as I take my final steps through these corridors, I can feel a sense of separation looming over me. It’s hard to let go of something that has been a part of your life for so long.&lt;/p&gt;
&lt;p&gt;The classrooms where we are always late are filled with nostalgia. The same classrooms where we listened to lectures with half attention, where we struggled to keep our eyes open during the post-lunch sessions, and where we made friends. As I stand at the back of the room and look at the empty seats, I can hear the echo of our conversations. The long hours spent with our lab partners, trying to make sense of the experiments, the fear of lab tests, the laughter and the frustration - all of it comes flooding back. Walking past these memories, I feel a sense of loss. I am leaving behind a part of myself.&lt;/p&gt;
&lt;figure class=&quot;skylab&quot;&gt;
&lt;img alt=&quot;skylab&quot; src=&quot;https://anubhavp.dev/assets/img/teasquared/sit-1.webp&quot; class=&quot;h-75 w-75&quot; loading=&quot;lazy&quot;&gt;
&lt;figcaption&gt;
Silicon Institute of Technology
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;It feels like only yesterday that I was a wide-eyed fresher, stepping onto campus for the first time. I was, in my mind, a tech hero, filled with adrenaline, prepared to win and rule. As I stepped into the world of the unknown and grown-ups, I realized I had much to learn. I was a small fish in a big lake and had to learn to swim. I was overwhelmed by the sheer number of people, the hustle and bustle of the campus, and the endless possibilities that lay ahead of me. We used to walk around with an ID card hanging and hang out in corners, bragging about how we were going to change the world upon graduating. I remember hopping on the evening bus to visit the market with my friends. We’d eat a ton while discussing the everyday nuances of our college lives. Participating in events, giving out interviews for clubs, helping organize events and hanging out late with seniors were all we did; we were young, naive, and full of dreams.&lt;/p&gt;
&lt;p&gt;I yearn to go back to the first year and walk through the gate again. I long to don those ID cards once again and stand with my friends at T-Square as we reminisce about our first-year experiences. I remember getting asked to demonstrate riding bikes, ask a senior’s name in the proper format, and pry on our classmates and get their numbers for the seniors. Pondering back, I wish I could attend classes again, get sent outside for disturbing, run in sweaty formals, enter the chilled CS labs, and sit there staring blankly at the screens. Looking back, I can’t help but smile at the memories.&lt;/p&gt;
&lt;figure class=&quot;skylab&quot;&gt;
&lt;img alt=&quot;skylab&quot; src=&quot;https://anubhavp.dev/assets/img/teasquared/sit-6.jpeg&quot; class=&quot;h-75 w-75&quot; loading=&quot;lazy&quot;&gt;
&lt;figcaption&gt;
Skylab
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Now that most of my friends have moved on, I miss going to ABD with them, not worrying about the future, and rambling about the terrible college we studied in and the magic we’d have done had we been running the college. I want to keep discussing what we should wear to Zygon and Rythmnova and whether we’ll need to wear our ID cards at night. Walking past the hostel gates, memories flood back of us staying together, sharing each other’s shirts, shampoos, and snacks, and using one hairdryer among two hundred people. The late nights spent in the hostel corridors talking about life, family, the future, movies, and music were magical. The evening’s borrowed speakers ensured that none of us slept. On exam nights, we used to knock on a random room and ask them for a few pointers and questions, and then they wouldn’t know either (well because they are my friends, what else do you expect ? :D) and then we would go down knocking on other rooms, which I will cherish forever.&lt;/p&gt;
&lt;p&gt;As we bid farewell to each other, we make promises to stay in touch, meet, and gossip. We know in our hearts that these are sweet, generous lies that we tell ourselves. Life happens. We move on and learn to live without each other.&lt;/p&gt;
&lt;p&gt;Filled with bittersweet nostalgia, I reflect on the journey that led me here, the friends I have made, and the experiences I have had. As I pen these words, I want to express my deepest gratitude to my alma mater and everyone who has been a part of my journey. I can’t help but wonder about my choices and the roads I’ve taken during this journey. It has been a time of growth, discovery, and unforgettable memories. I bid adieu to this cherished chapter of my life and reflect on the moments that have made it memorable. My silicontites, I will cherish you for a lifetime. While it is bittersweet to say goodbye to this phase of my life, I eagerly look forward to embarking on a new chapter. With my sights set on new horizons, I am excited to see where life takes me and what the future holds.&lt;/p&gt;
&lt;figure class=&quot;skylab&quot;&gt;
&lt;img alt=&quot;zygon&quot; src=&quot;https://anubhavp.dev/assets/img/teasquared/sit1.jpeg&quot; class=&quot;h-100 w-100&quot; loading=&quot;lazy&quot;&gt;
&lt;figcaption&gt;
Goodbye, SIT ❤️
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;code&gt;190310030 Signing Off&lt;/code&gt;&lt;/p&gt;

            &lt;hr&gt;
            &lt;div class=&quot;footer&quot;&gt;
              &lt;i&gt;Feedback, Suggestions, Comments - &lt;/i&gt;
              &lt;div class=&quot;giscus-div&quot; id=&quot;comments&quot;&gt;
                &lt;script src=&quot;https://giscus.app/client.js&quot; data-repo=&quot;anubhavpgit/anubhavpgit.github.io&quot; data-repo-id=&quot;MDEwOlJlcG9zaXRvcnk0MDQ1ODEzMjc=&quot; data-category-id=&quot;DIC_kwDOGB1rz84Cer0j&quot; data-mapping=&quot;title&quot; data-strict=&quot;0&quot; data-reactions-enabled=&quot;1&quot; data-emit-metadata=&quot;0&quot; data-input-position=&quot;bottom&quot; data-theme=&quot;noborder_light&quot; data-lang=&quot;en&quot; data-loading=&quot;lazy&quot; crossorigin=&quot;anonymous&quot; async=&quot;&quot;&gt;&lt;/script&gt;
              &lt;/div&gt;
              Feel free to
              &lt;a id=&quot;mailtoLink&quot; href=&quot;mailto:anubhavp@duck.com?subject=Here&apos;s%20a%20suggestion/feedback!&quot;&gt;send
                me an email&lt;/a&gt;.
            &lt;/div&gt;
          &lt;/div&gt;
        </content:encoded>
            <subtitle>A goodbye to the best four years of my life: an ode to my alma mater.</subtitle>
        </item>
        <item>
            <title><![CDATA[Zuzu]]></title>
            <description><![CDATA[Zuzu is a static site generator that converts all your markdown files into static html pages. It uses Github-flavoured Markdown CSS and highlight.js to beautify code snippets.]]></description>
            <link>https://anubhavp.dev/blog/zuzu.html</link>
            <guid isPermaLink="true">https://anubhavp.dev/blog/zuzu.html</guid>
            <dc:creator><![CDATA[Anubhab Patnaik]]></dc:creator>
            <pubDate>Sun, 29 May 2022 00:00:00 GMT</pubDate>
            <content:encoded>
          &lt;div class=&quot;content custom&quot;&gt;
            &lt;div class=&quot;search-container&quot;&gt;&lt;/div&gt;
            &lt;p&gt;Zuzu is a static site generator that takes in markdown files and renders HTML pages. This blog has been written using this generator. This enables noobs like me to write blogs without having to learn a lot of code :P .&lt;/p&gt;
&lt;p&gt;⚠️ The latest version of zuzu might not updated in the &lt;a href=&quot;https://github.com/anubhavpgit/zuzu&quot;&gt;original codebase&lt;/a&gt;, but instead all the features can be found here: &lt;a href=&quot;https://github.com/anubhavpgit/anubhavpgit.github.io&quot;&gt;anubhavpgit/anubhavpgit.github.io&lt;/a&gt;. A couple of features have been added to the original codebase, such as RSS feed, PDF generation, and CSS/JS injection. The better codebase is the one mentioned above❗&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#features&quot;&gt;Features&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#how-does-it-work&quot;&gt;How does it work?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#getting-started&quot;&gt;Getting Started&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#next&quot;&gt;Next?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;features&quot; tabindex=&quot;-1&quot;&gt;Features&lt;/h2&gt;
&lt;p&gt;Zuzu builds on a very basic problem statement: &lt;em&gt;I want to start my own blog without having to learn a lot of code&lt;/em&gt;. The current version supports a ton of features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Markdown&lt;/strong&gt;: Zuzu supports Github-flavoured markdown. Ramble on about your favourite topics, add code snippets, tables, and images, and Zuzu will render them for you.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Syntax Highlighting&lt;/strong&gt;: Zuzu uses highlight.js to beautify your code snippets. Just add your code in a code block and Zuzu will take care of the rest.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CSS/JS Injection&lt;/strong&gt;: Zuzu allows you to add your own CSS and JS files. Just add them to the &lt;code&gt;static&lt;/code&gt; folder and Zuzu will inject them into your HTML files. Make sure to include the path in the markdown file. Example: &lt;code&gt;....&amp;lt;link rel=&quot;stylesheet&quot; href=&quot;/static/css/style.css&quot;&amp;gt;...&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Front Matter&lt;/strong&gt;: Zuzu uses front matter to extract metadata from the markdown file. The front matter is written in YAML and is enclosed between &lt;code&gt;---&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;--- title: &apos;Zuzu&apos; 
date: &quot;29-05-2022&quot; 
description: &quot;Zuzu is a static site generator that converts all your markdown files into static html pages.
It uses Github-flavoured Markdown CSS and highlight.js to beautify code snippets.&quot; tag: &quot;tech&quot; 
---
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;RSS Feed&lt;/strong&gt;: Zuzu generates an RSS feed for your blog. Just add the &lt;code&gt;rss.xml&lt;/code&gt; file to the &lt;code&gt;static&lt;/code&gt; folder and Zuzu will take care of the rest.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PDF Generation&lt;/strong&gt;: Zuzu uses &lt;code&gt;md-to-pdf&lt;/code&gt; to convert your markdown files into PDFs. Just add the &lt;code&gt;pdf&lt;/code&gt; link to your markdown file and Zuzu will take care of the rest. Example: &lt;a href=&quot;/blog/documents/zuzu.pdf&quot;&gt;Download PDF&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Configurable&lt;/strong&gt;: Zuzu is highly configurable. You can change the theme, add your own CSS and JS files, and even add your own &lt;code&gt;static&lt;/code&gt; folders. The &lt;code&gt;config.toml&lt;/code&gt; looks like this:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;# Homepage
base_url = &quot;https://anubhavp.dev/zuzu/&quot;

# template
template = &quot;anubhavpgit&quot;

...

# Path to the directory containing the templates
template_dir = &quot;templates/anubhavpgit&quot;

# Path to the directory containing the static files
static_dir = &quot;static&quot;

...

# Theme
templateHTML = &quot;templates/anubhavpgit/template.html&quot;

&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;how-does-it-work&quot; tabindex=&quot;-1&quot;&gt;How does it work?&lt;/h2&gt;
&lt;p&gt;Zuzu leverages Node.js and a few packages to convert markdown files into HTML pages. It parses the markdown files, extracts the front matter, and converts the markdown content into HTML. The HTML is then injected into a template to generate the final HTML page. The final HTML page is then written to the output directory. The packages used are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/markdown-it&quot;&gt;MarkdownIt&lt;/a&gt; &lt;em&gt;Markdown parser done right.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/markdown-it-anchor&quot;&gt;MarkdownItAnchor&lt;/a&gt; &lt;em&gt;Header anchors for markdown-it.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/glob&quot;&gt;Glob&lt;/a&gt; &lt;em&gt;“Globs” are the patterns you type when you do stuff like ls .js on the command line, or put build/ in a .gitignore file.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/gray-matter&quot;&gt;Gray-Matter&lt;/a&gt; &lt;em&gt;Parse front-matter from a string or file.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://npmjs.com/package/mkdirp&quot;&gt;Mkdirp&lt;/a&gt; &lt;em&gt;Create Dirs if they do not exist.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nodejs.org/api/path.html&quot;&gt;Path&lt;/a&gt; &lt;em&gt;Provides utilities for working with file and directory paths.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://highlightjs.org/&quot;&gt;Highlight.js&lt;/a&gt; &lt;em&gt;Highlight.js is a syntax highlighter written in JavaScript. It works in the browser as well as on the server. It works with pretty much any markup, and doesn’t depend on any framework and has automatic language detection.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/md-to-pdf&quot;&gt;MDtoPDF&lt;/a&gt; &lt;em&gt;Converts markdown to pdf.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/rss&quot;&gt;RSS&lt;/a&gt; &lt;em&gt;RSS parser.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The generator consists of, but not limited to, the following functions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;slugify: Converts a string into a URL-friendly slug.&lt;/li&gt;
&lt;li&gt;readFile: Reads a markdown file, parses its front matter, and renders its content to HTML.&lt;/li&gt;
&lt;li&gt;templatize: Replaces placeholders in a template string with actual data.&lt;/li&gt;
&lt;li&gt;saveFile: Saves content to a file, creating necessary directories if they don’t exist.&lt;/li&gt;
&lt;li&gt;getOutputFilename: Generates the output HTML filename for a given input filename and output path.&lt;/li&gt;
&lt;li&gt;getOutputPdfname: Generates the output PDF filename for a given input filename and output path, ensuring the folder exists.&lt;/li&gt;
&lt;li&gt;processBlogFile: Processes a blog file, converting it to HTML and optionally to PDF, and updates a map of blog metadata.&lt;/li&gt;
&lt;li&gt;processDefaultFile: Processes a default file, converting it to HTML and optionally to PDF.&lt;/li&gt;
&lt;li&gt;buildBlogIndex: Builds the blog index from the map of blog metadata and updates the index file.&lt;/li&gt;
&lt;li&gt;copyAssets: Copies assets from the source folder to the destination folder.&lt;/li&gt;
&lt;li&gt;main: Orchestrates the processing of all markdown files, fetching metadata, and generating the static site.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The script follows this flow:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Initialization: Import necessary modules and define utility functions.&lt;/li&gt;
&lt;li&gt;MarkdownIt Setup: Initialize MarkdownIt with plugins for rendering markdown content.&lt;/li&gt;
&lt;li&gt;Main Function:
&lt;ul&gt;
&lt;li&gt;Define paths for source content, output directories, and templates.&lt;/li&gt;
&lt;li&gt;Fetch metadata from a remote URL.&lt;/li&gt;
&lt;li&gt;Clean and create necessary directories.&lt;/li&gt;
&lt;li&gt;Process markdown files in the source directory, converting them to HTML and optionally to PDF.&lt;/li&gt;
&lt;li&gt;Build the blog index from processed blog files.&lt;/li&gt;
&lt;li&gt;Copy static assets to the output directory.
Execution: The script is executed by calling the main function within an async IIFE, handling any errors that occur.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;getting-started&quot; tabindex=&quot;-1&quot;&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;To get started with Zuzu, clone the repository and install the dependencies:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git &lt;span class=&quot;hljs-built_in&quot;&gt;clone&lt;/span&gt; https://github.com/anubhavpgit/zuzu.git
&lt;span class=&quot;hljs-built_in&quot;&gt;cd&lt;/span&gt; zuzu
npm install
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This would be a good place to start your markdown files. The &lt;code&gt;content&lt;/code&gt; folder contains all the markdown files. The &lt;code&gt;templates&lt;/code&gt; folder contains the HTML templates. The &lt;code&gt;static&lt;/code&gt; folder contains the CSS and JS files.&lt;/p&gt;
&lt;p&gt;To generate the HTML files, run:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npm run generate
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can find two themes in the &lt;code&gt;templates&lt;/code&gt; folder: &lt;code&gt;anubhavpgit&lt;/code&gt; and &lt;code&gt;initial&lt;/code&gt;. To change the theme, change the &lt;code&gt;template&lt;/code&gt; in the &lt;code&gt;config.toml&lt;/code&gt; file, and the &lt;code&gt;templateHTML&lt;/code&gt; in the &lt;code&gt;config.toml&lt;/code&gt; file. Zuzu is highly configurable. You can add your own CSS and JS files to the &lt;code&gt;static&lt;/code&gt; folder and include them in the markdown file, or better, start with your own &lt;code&gt;theme&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;next&quot; tabindex=&quot;-1&quot;&gt;Next?&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&quot;https://github.com/anubhavpgit/zuzu&quot;&gt;zuzu&lt;/a&gt; repository is a good place to start. The latest version of zuzu might not updated in the original codebase, but instead you can always find all the features maintained here: &lt;a href=&quot;https://github.com/anubhavpgit/anubhavpgit.github.io&quot;&gt;anubhavpgit/anubhavpgit.github.io&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I am eagerly looking for someone to migrate all the features to the original codebase. Feel free to ping me if you’re interested.&lt;/p&gt;
&lt;p&gt;If you really dig zuzu, I would suggest you try Zuzu out, and then maybe contribute to the codebase. The codebase is open-source and contributions are welcome. Feel free to add comments, issues, or pull requests. Update the codebase, add new features, or even create your own theme. The world is your oyster, and zuzu is your playground.&lt;/p&gt;

            &lt;hr&gt;
            &lt;div class=&quot;footer&quot;&gt;
              &lt;i&gt;Feedback, Suggestions, Comments - &lt;/i&gt;
              &lt;div class=&quot;giscus-div&quot; id=&quot;comments&quot;&gt;
                &lt;script src=&quot;https://giscus.app/client.js&quot; data-repo=&quot;anubhavpgit/anubhavpgit.github.io&quot; data-repo-id=&quot;MDEwOlJlcG9zaXRvcnk0MDQ1ODEzMjc=&quot; data-category-id=&quot;DIC_kwDOGB1rz84Cer0j&quot; data-mapping=&quot;title&quot; data-strict=&quot;0&quot; data-reactions-enabled=&quot;1&quot; data-emit-metadata=&quot;0&quot; data-input-position=&quot;bottom&quot; data-theme=&quot;noborder_light&quot; data-lang=&quot;en&quot; data-loading=&quot;lazy&quot; crossorigin=&quot;anonymous&quot; async=&quot;&quot;&gt;&lt;/script&gt;
              &lt;/div&gt;
              Feel free to
              &lt;a id=&quot;mailtoLink&quot; href=&quot;mailto:anubhavp@duck.com?subject=Here&apos;s%20a%20suggestion/feedback!&quot;&gt;send
                me an email&lt;/a&gt;.
            &lt;/div&gt;
          &lt;/div&gt;
        </content:encoded>
            <subtitle>Zuzu is a static site generator that converts all your markdown files into static html pages. It uses Github-flavoured Markdown CSS and highlight.js to beautify code snippets.</subtitle>
        </item>
        <item>
            <title><![CDATA[Current odyssey]]></title>
            <description><![CDATA[Here's what I am up to these days]]></description>
            <link>https://anubhavp.dev/current.html</link>
            <guid isPermaLink="true">https://anubhavp.dev/current.html</guid>
            <dc:creator><![CDATA[Anubhab Patnaik]]></dc:creator>
            <pubDate>Wed, 01 Apr 2026 00:00:00 GMT</pubDate>
            <content:encoded>
        
        &lt;figure class=&quot;header-figure&quot;&gt;
          &lt;img src=&quot;/assets/img/current/head-1200.webp&quot; srcset=&quot;/assets/img/current/head-768.webp 768w, 
                    /assets/img/current/head-1200.webp 1200w, 
                    /assets/img/current/head-1920.webp 1920w&quot; sizes=&quot;(max-width: 768px) 100vw, (max-width: 1200px) 100vw, 100vw&quot; width=&quot;3440&quot; height=&quot;1440&quot; fetchpriority=&quot;high&quot; alt=&quot;Current odyssey&quot; class=&quot;blog-header-image&quot;&gt;
        &lt;/figure&gt;
        &lt;div class=&quot;content custom&quot;&gt;
          &lt;div class=&quot;search-container&quot;&gt;&lt;/div&gt;
          &lt;h5 id=&quot;current-2026&quot; tabindex=&quot;-1&quot;&gt;Current, 2026&lt;/h5&gt;
&lt;p&gt;&lt;span class=&quot;update-date-time&quot;&gt;&lt;span class=&quot;datetime&quot; id=&quot;datetime&quot;&gt;Wednesday, April 1&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h6 id=&quot;april&quot; tabindex=&quot;-1&quot;&gt;April&lt;/h6&gt;
&lt;p&gt;Settled in; the city is beautiful, and the weather is amazing, but I am still getting used to it. Most days feel tiring, and a little overwhelming and anxious. SF is calmer, more laid back, naturally beautiful, and has a lot of techies. Still trying to find my groove here, but excited to explore what it has to offer.&lt;/p&gt;
&lt;h6 id=&quot;march&quot; tabindex=&quot;-1&quot;&gt;March&lt;/h6&gt;
&lt;p&gt;March brings forth a few bittersweet changes. The sweet part: I am now the founding engineer at &lt;a href=&quot;https://www.voicebit.ai/&quot;&gt;Voicebit&lt;/a&gt;, a voice-based AI food ordering system :). We are replacing the friction in food ordering by creating an end-to-end voice-based AI system that allows users to discover restaurants, explore menus, and place orders seamlessly.&lt;/p&gt;
&lt;p&gt;With this, my journey at Authentic comes to an end. It has been an incredible ride and I’ll forever be grateful for getting to build this. The bitter part about all this is leaving New York.&lt;/p&gt;
&lt;p&gt;New York (&lt;em&gt;Technically, the bank of Hudson in Jersey City&lt;/em&gt;) has been my home for the past two years, and I have loved every. single. bit. of it. Growing up watching Friends and HIMYM, a life in NYC, living with a bunch of friends, was basically all I ever wanted.&lt;/p&gt;
&lt;p&gt;The best thing about New York, at least for me, is the people. NY instantly makes you feel at home. The city is home to a huge diaspora of diverse immigrants. You get to meet a lot of people, and every third person speaks a different language and comes from a different corner of the world. It instills a sense of belonging and stability — “you aren’t alone; see, all these people have also left their own countries and are living here with you.” It just feels like it’s nobody’s home… and everybody’s home. The rent and taxes drive you nuts, but the food, culture, and life experiences more than make up for it.&lt;/p&gt;
&lt;p&gt;NY had a ton of magic dust to sprinkle. Getting lost in the lives of people from around the world; walking with friends in the middle of the night; the ramen places always around the corner; the huge slices of pizza; the little deli shops with their sandwiches and energy drinks; the gelatos and cheesecakes; the halal carts and their shawarmas; the traffic and the jaywalking; watching the sunset from DUMBO; the feeling of never being alone because a million people are always walking with you; walking and exploring little nooks and corners with friends, talking about life; the little food festivals; the taco joints and their Indian-flavored tacos; watching the lives of people unfold in the subway are magical.&lt;/p&gt;
&lt;p&gt;The weather, although horrible at times, was something I was getting used to. I am not that bothered by the cold, but the gloomy, cloudy weather in winter and spring are unbearable. I am a big-time sun-worshipper, and the beautiful falls and the sweltering summers are some of the most magical days of my life that I will miss dearly.&lt;/p&gt;
&lt;figure style=&quot;justify-content: center; align-items: center; display: flex; flex-direction: column; gap: 10px;&quot;&gt;
	&lt;img alt=&quot;New York landscape&quot; src=&quot;../assets/img/current/nyc_last.webp&quot; style=&quot;max-width: 75%;&quot; loading=&quot;lazy&quot;&gt;
	&lt;figcaption style=&quot;text-align: center; font-size: 0.8em;&quot;&gt; The yellow hues on my last morning in New York.
	&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I still plan on (&lt;em&gt;or at least will try to&lt;/em&gt;) visit New York every month. Can’t stay away for too long.&lt;/p&gt;
&lt;p&gt;Ending this on a sweeter note: I am moving to San Francisco! Building and scaling a tech venture studio, SF is the best place to be. I have some experience here from last summer, when I was working at h011yw00d. Excited for what’s next — the unknown and the adventures are what make life worth living.&lt;/p&gt;
&lt;h6 id=&quot;february&quot; tabindex=&quot;-1&quot;&gt;February&lt;/h6&gt;
&lt;div class=&quot;x-embed&quot;&gt;
  &lt;div class=&quot;x-embed-header&quot;&gt;
    &lt;div class=&quot;x-embed-author&quot;&gt;
      &lt;span class=&quot;x-embed-name&quot;&gt;Anubhav&lt;/span&gt;
      &lt;span class=&quot;x-embed-handle&quot;&gt;@fuzzymfx&lt;/span&gt;
    &lt;/div&gt;
    &lt;svg class=&quot;x-embed-logo&quot; viewBox=&quot;0 0 24 24&quot; width=&quot;18&quot; height=&quot;18&quot; fill=&quot;currentColor&quot;&gt;&lt;path d=&quot;M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;
  &lt;/div&gt;
  &lt;div class=&quot;x-embed-subtitle&quot;&gt;A quick fun weekend-project at Authentic!&lt;/div&gt;
  &lt;div class=&quot;x-embed-body&quot;&gt;Friday was fun at Authentic headquarters. We got these sunset lights to jazz up the office vibe.&lt;br&gt;&lt;br&gt;Reverse engineered the bluetooth signals and built this custom CLI app that monitors production state of our app and can change colors based on CI failures and sentry logs. &lt;img src=&quot;/assets/img/current/x-2022476919137087549-0.jpg&quot; alt=&quot;Tweet media&quot; class=&quot;x-embed-media&quot; loading=&quot;lazy&quot;&gt;&lt;/div&gt;
  &lt;a href=&quot;https://x.com/fuzzymfx/status/2022476919137087549?s=20&quot; class=&quot;x-embed-date&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;February 14, 2026&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;It’s been a busy start to the year. The weather in New York has been extremely cold in the past month. Today’s high is -9°C and the low is -17°C with gusts making it feel like -26°C. The last two weeks have been extremely busy and productive. I have been working on multiple projects at work, and have been heads down on building.&lt;/p&gt;
&lt;p&gt;Running and scaling Luna has been good. Speaking to a couple of potential co-founders and trying out (&lt;em&gt;gambling&lt;/em&gt;) a few ideas.  The process is fun, but extremely exhausting. Will write about all of this in more detail.&lt;/p&gt;
&lt;p&gt;In the current economy, where tech starts underperforming NASDAQ, I have no idea what to expect in the next few weeks. A couple of models later, I think everything I do and think will be obsolete. I’d have to hunt for new jobs. I might try out astrophysics, or philosophy, or maybe even consider farming. Claude and GPT will be taking over the world anytime now.&lt;/p&gt;
&lt;p&gt;After the dust settles, I’d like to leave and explore the world for a bit. Spend some time vacationing somewhere warm.&lt;/p&gt;
&lt;figure style=&quot;justify-content: center; align-items: center; display: flex; flex-direction: column; gap: 10px;&quot;&gt;
	&lt;img alt=&quot;Github&quot; src=&quot;../assets/img/current/january_contributions.webp&quot; style=&quot;max-width: 100%;&quot; loading=&quot;lazy&quot;&gt;
	&lt;figcaption style=&quot;text-align: center; font-size: 0.8em;&quot;&gt; January/ February 1st week contributions look wild&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h6 id=&quot;january&quot; tabindex=&quot;-1&quot;&gt;January&lt;/h6&gt;
&lt;p&gt;Happy New Year! Kicking off 2026 with a renewed focus on personal growth and exploration. The new:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Authentic is now live on both app stores. Excited to see how you guys engage with it! (&lt;a href=&quot;https://apps.apple.com/us/app/authentic-social-media/id6748682732&quot;&gt;iOS&lt;/a&gt; | &lt;a href=&quot;https://play.google.com/store/apps/details?id=tech.authentic.app&quot;&gt;Android&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Tried snowboarding for the first time. Loved it. Planning to visit the mountains more often this year. Goal is to do a black diamond run in a year.&lt;/li&gt;
&lt;li&gt;Back to focusing on fitness. Set a goal to reach a certain body-fat percentage by mid-year.&lt;/li&gt;
&lt;li&gt;Engaged in a few exciting projects at work, including a new AI initiative plus a community platform. More details to come soon.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In other news, excited to launch &lt;a href=&quot;https://lunalabs.studio&quot;&gt;Luna&lt;/a&gt;, my venture studio! Luna is one month old, already generating revenue, has multiple projects in the pipeline, and is setting up a venture of its own. Looking forward to sharing more updates soon.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;a href=&quot;/blog/25.html&quot;&gt;2025&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;/blog/24.html&quot;&gt;2024&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;/blog/23.html&quot;&gt;2023&lt;/a&gt;&lt;/p&gt;

        &lt;/div&gt;
      </content:encoded>
            <subtitle>Here&apos;s what I am up to these days</subtitle>
        </item>
    </channel>
</rss>