Notes

There's a total of 84 notes.




Mon, Oct 13, 2025

Learning a Language

I've been learning French on my own for almost two years. I'm not fluent yet, but I can understand and speak it with relative comfort. In this article, I share my journey of learning a new language as an adult.
Sat, Jun 21, 2025

Tmux to Zellij (and back)

Tips that helped me when trying Zellij and why I went back to Tmux. I outline key requirements such as organized workspaces with easy pane management, seamless integration with Neovim, and efficient session switching. I describe my experience adopting Zellij, highlighting its vi-like modes and custom keybindings for navigation. I then explore session management with a script for quickly switching between preferred and active Zellij sessions, mirroring my previous Tmux workflow.
Sun, Dec 1, 2024

Creating a Backing Track from Your Favorite Song for an Open Mic

I perform in open mics in my spare time. When I decide to perform a cover of a song, I usually play the guitar and sing. Therefore, I prepare a backing track without the tracks I use as background music during the performance. In this article, I show how to create a backing track using yt-dlp, Demucs, and FFmpeg.
Sun, Nov 17, 2024

Bachata

This is my bachata dancing journey. I talk about how I first got started with bachata and what motivated me to keep going. I talk about my experiences at bachata festivals and how they've helped me to grow as a dancer. Finally, I also share some of my favorite bachata dancers and bachata combos that I've learned over the years.
Sun, Nov 10, 2024

Documenting my life

Ordinary moments don't have value right now, but they will have value over time. We might think that mundane things will stay the same forever, but they don't. I decided to document my life by journaling, printing pictures, and making vlogs.
Sun, Apr 30, 2023

Kubernetes

Kubernetes is an open-source container orchestration platform that automates the deployment, scaling, and management of containerized applications.
Wed, May 11, 2022

Productivity

I try to improve my productivity every day to get better use of my time. This article summarizes the things I'm used to doing every day at work. These are divided into: getting used to multitasking, having time for deep focus and for breaks, handling incoming emails, task management, and development tools.
Mon, Oct 12, 2020

Preparation for a Software Engineer Interview

This is my interview preparation plan for a software engineering role. I share a summary of my preparation, a plan of problems to tackle for coding interviews, the topics to study for system design interviews, and the questions to prepare for the behavioral section.
Sat, Aug 8, 2020

Back of the envelope calculations

When designing a system, it's important to consider the limitations of the technologies chosen. Making some approximate calculations when the system is designed helps us decide on the tradeoffs of the different approaches. These approximations include: This article has a table with latency comparison numbers, common numbers used in system design calculations, and some challenges to put all of this info into practice.
Thu, Jun 25, 2020

Introduction to Machine Learning

A very brief introduction to what ML is for and the problems to which it can be applied, along with some example applications.
Mon, May 25, 2020

Machine Learning Glossary

A glossary of terms used in machine learning. For an up-to-date glossary, also check https://developers.google.com/machine-learning/glossary.
Mon, May 25, 2020

Hyperparameter tuning

Hyperparameter tuning is the process of finding the optimal hyperparameters (the parameters fed into the model for it to change its inner parameters) for a model to converge efficiently through trial and error.
Sat, May 9, 2020

Data structures for massive datasets

The algorithms that we use every day to manipulate data assume that we have access to all the data we need. What if there's more data than can fit on a single computer, or if accessing the data itself to do searches is expensive? If so, we can use specialized data structures that can help us "estimate" the actual value without actually computing it. In some cases, an estimate might be good enough. These data structures include the count-min sketch, bloom filters, and reservoir sampling.
Mon, Mar 16, 2020

Expectation maximization

Expectation maximization is a method of finding maximum likelihood estimates of the parameters of a model. The method alternates between making an expectation (E) step based on the current estimate of the parameters and a maximization (M) step, which computes new parameters.
Thu, Mar 5, 2020

Bayesian Networks

A Bayesian network is a directed graph in which each node is annotated with quantitative probability information. This article covers the definition of a Bayesian network with a graphical representation, the determination of independence between variables, and the problem of finding the probability distribution of a set of query values given some observed events.
Sat, Feb 29, 2020

Kafka

Kafka is a distributed event streaming platform designed for building high-throughput, fault-tolerant, and scalable data streaming applications. This article covers key designs in Kafka, such as how messages for a topic are shared into partitions assigned to brokers. Then, we see some guarantees about producers, consumers, and consumer groups.
Sat, Feb 29, 2020

Memtable & SSTable (Sorted String Table)

The pattern of batching data in memory, tracking it in a write-ahead log, and periodically flushing it to disk is ubiquitous today. Open-source examples include LevelDB, Cassandra, InfluxDB, and HBase. In this article, I implement a tiny memtable for a time-series database in Go and briefly talk about how it can be compressed into a sorted string table.
Fri, Feb 28, 2020

Cassandra

Cassandra is a highly scalable, distributed NoSQL (non-relational) database management system designed for handling large amounts of data across multiple commodity servers. This article covers key design features of Cassandra, such as the usage of consistent hashing, the write pattern to a write-ahead log and a memtable, the read pattern from the memtable and from SSTables, and, most importantly, some examples of data modeling for different types of queries.
Mon, Jan 8, 2018

Partitioning

Data partitioning refers to the process of dividing a system's data into smaller, more manageable subsets, which are distributed across multiple storage locations or nodes. This article covers several strategies for partitioning, including random partitioning, by hash key, by range, and a hybrid approach for skewed workloads. It also discusses strategies to rebalance partitions, whether there's a static or dynamic number of partitions.
Tue, Jan 2, 2018

Non Functional Requirements

Non-functional requirements refer to quality attributes or system characteristics that describe how well a software system or solution performs or behaves. This article covers well-known non-functional requirements such as reliability, availability, scalability, performance, and durability.
Sat, Sep 16, 2017

Implementing an A+ Conformant Promise Library in JavaScript the TDD Way

Futures/promises refer to constructs used to synchronize program execution. Learning how they work under the hood by implementing them is a great fundamental skill to have. This article is about writing an A+ Promise implementation from scratch, following the A+ promise spec in JavaScript the TDD way.
Sun, May 21, 2017

Divisibility

Let $a,b \in \mathbb{Z}$. We say that $a$ _**divides**_ $b$, written $a \given b$, if there's an integer $n$ such that $b = na$. If $a$ divides $b$, then $b$ is _**divisible**_ by $a$, and $a$ is a _**divisor or factor**_ of $b$. Also, $b$ is called a _**multiple**_ of $a$. This article covers the greatest common divisor and how to find it using the Euclidean Algorithm, the Extended Euclidean Algorithm to find solutions to the equation $ax + by = gcd(a, b)$ where $x, y$ are unknowns.
Thu, Jun 9, 2016

Flat Shading

Flat shading is the simplest shading model. We cover the advantages/disadvantages and a simple implementation in GLSL.
Fri, Jun 3, 2016

Diffuse Shading

Diffuse shading is a technique to render the surface of objects that are not shiny. As an example, in the [picture (credits to Marc Kleen)](https://unsplash.com/photos/8hU6vtwY8l8), we see a real-life car with a matte coating, which we want to emulate using the Lambertian shading model.
Fri, Jun 3, 2016

Introduction to Surface Shading

Surface shading is a process to color a surface. In computer graphic applications, this is done to mimic how objects look in real life. This article covers the variables available in the rendering pipeline.
Fri, Apr 29, 2016

Building a First-Person Shot Camera in C++

A first-person camera captures objects from the viewpoint of a player's character. Some aspects have to be considered, like the characteristics of the camera (orbiting with the mouse and translation with keyboard keys), as well as how we could capture all these characteristics with math and linear algebra. In this article, I analyze the math needed to design and implement a first-person shot camera in C++.
Tue, Apr 26, 2016

Quaternions

Quaternions are an alternate way to describe orientation or rotations in 3D space using an ordered set of four numbers. They have the ability to uniquely describe any 3D rotation about an arbitrary axis and do not suffer from a problem using Euler angles called gimbal lock.
Tue, Apr 5, 2016

gcc

GCC is a suite of compilers for various programming languages, including C and C++. In this article, I cover the compilation stages and the flags used to compile source code into a binary.
Thu, Mar 31, 2016

make

`Make` is a build automation tool commonly used in software development to compile source code and create executable programs or other output files. It automates the process of building complex software projects, including compiling source code, linking object files, and creating executable files or other types of output. In this article, I cover the following: targets and prerequisites, variables, recipes to build an out-of-date target, and finally, an example of how to use it in a simple C++ project.
Thu, Mar 31, 2016

CMake

CMake is a cross-platform build system generator of `Makefile`s. Projects specify their build process with platform-independent CMake listfiles included in each directory of a source tree with the name `CMakeLists.txt`. This article explains how to use CMake to build projects.
Sat, Mar 26, 2016

C++ refresher

Refresher notes on C++, including the mechanics of a C++ program, program structure, pointers, functions, classes, and miscellaneous operations.
Wed, Mar 16, 2016

Culling & Clipping

The math behind culling and clipping and how it's related to the camera and what it sees. - **Culling** is a process where geometry that’s not visible from the camera is discarded to save processing time. - **Clipping** is a process that removes parts of primitives that are outside the view volume (clipping against the six faces of the view volume).
Tue, Mar 15, 2016

Affine spaces

An affine space is a generalization of the notion of a vector space, but without the requirement of a fixed origin or a notion of "zero".
Mon, Mar 14, 2016

Vector spaces

A vector space is a set whose elements are called "vectors" (denoted as $\v{v}$ or $\mathbf{v}$), which have two operations defined on them: addition of vectors and multiplication of a scalar by a vector. This article covers some examples of vector spaces, bases of vector spaces, and linear maps.
Thu, Mar 10, 2016

Triangle in affine spaces

In an affine space, any point can be represented by the sum of an origin point plus a set of scaled vectors. This article covers defining all the points in a triangle within an affine space.
Wed, Mar 9, 2016

Geometric tests

Different algorithms to test geometric properties, such as finding the intersection of two lines.
Tue, Mar 8, 2016

Transformation Matrix to Transform Objects from NDC Coordinates to Screen Coordinates (Viewport Transform)

One matrix transformation in the 3D to 2D transformation pipeline is the viewport transform, where objects are transformed from normalized device coordinates (NDC) to screen coordinates (SC). In short, it's the transformation of numbers in the range [-1, 1] to numbers corresponding to pixels on the screen, which is a linear mapping computed with linear interpolation. In this article, I cover the math behind the generation of the viewport transformation matrix.
Tue, Mar 8, 2016

Normals

A **normal vector** to a curve at a particular point is a vector perpendicular to the *tangent* vector of the curve at that point (also called a *gradient*).
Mon, Mar 7, 2016

Eigenvalues and eigenvectors

An eigenvalue represents how an object scales (or stretches/compresses) a particular direction (or eigenvector) when acted upon by the object. This article covers how to find these values in a square matrix, as well as their applicability in computer graphics.
Fri, Mar 4, 2016

Projective space

In projective geometry, unlike Euclidean geometry, two parallel lines meet at a point. Desargues introduced the concept of a line at infinity where a point at infinity can be defined. This article covers the need for a point at infinity in projective space, the line at infinity, and the projective plane.
Fri, Feb 26, 2016

Ray Tracing

Ray tracing is the process of identifying the color of all the pixels on a 2D screen by emitting rays from all the pixels, simulating how light travels in real life. This article covers the math for ray generation from each pixel for both orthographic and perspective cameras.
Fri, Feb 26, 2016

Rendering

Rendering is a process that takes as input a set of objects and produces as its output an array of pixels (image), each of which stores information about the color of the image at a particular point in a grid (determined by the target width and height).
Sun, Feb 14, 2016

Transformation Matrix for Projection of 3D Objects into a 2D Plane (Projection Transform)

In computer graphics, 3D objects created in an abstract 3D world will eventually need to be displayed on a screen. To view these objects on a 2D plane like a screen, objects will need to be projected from the 3D space to the 2D plane with a transformation matrix. In this article, I cover two types of transformations: orthographic projection and perspective projection, and analyze the math behind the transformation matrices.
Sat, Feb 13, 2016

Transformation Matrix to Transform 3D Objects from World Space to View Space (View Transform)

One matrix transformation in the 3D to 2D transformation pipeline is the view transform, where objects are transformed from world space to view space using a transformation matrix. In this article, I cover the math behind the generation of this transformation matrix.
Wed, Feb 10, 2016

Combining Matrix Transformations

Taking multiple matrices, each encoding a single transformation, and combining them is how we transform vectors between different spaces. This article covers creating a transformation matrix that combines a rotation followed by a translation, a translation followed by a rotation, and creating transformation matrices to transform between different coordinate systems.
Sat, Feb 6, 2016

Perspective Projection

Perspective projection is a fundamental projection technique that transforms objects in a higher dimension to a lower dimension. This transformation is usually used for objects in a 3D world to be rendered into a screen (a 2D surface). In the transformation, these objects give the realistic impression of depth. This article covers the math behind it and how to generate the transformation matrix to achieve the transformation.
Fri, Feb 5, 2016

Orthographic Projection

Orthographic projection is a fundamental projection technique that transforms objects in a higher dimension to a lower dimension. This transformation is usually used for objects in a 3D world to be rendered into a screen (a 2D surface) and in the process keeps parallel lines parallel in the lower dimension. This article covers the math behind it and how to generate the transformation matrix to achieve the transformation.
Fri, Feb 5, 2016

Translating Objects with a Transformation Matrix

We build different types of transformation matrices to translate objects along cardinal axes and arbitrary axes in 2D and 3D with matrix multiplication!
Fri, Feb 5, 2016

Euler Angles

Euler angles are a way to describe the orientation of a rigid body with three values. These values represent three angles: - *Yaw* - Rotation around the vertical axis - *Pitch* - Rotation around the side-to-side axis - *Roll* - Rotation around the front-to-back axis
Fri, Feb 5, 2016

Shearing Objects with a Transformation Matrix

Shearing is a transformation that skews the coordinate space. The idea is to add a multiple of one coordinate to another.
Tue, Dec 15, 2015

Introduction to Rotation for Computer Graphics

The basics of rotation in 2D and 3D for computer graphics, with a focus on 3D rotation about cardinal axes and 3D rotation with quaternions. For quaternions, please also look at [https://eater.net/quaternions](https://eater.net/quaternions) for amazing animations!
Tue, Oct 20, 2015

Scaling Objects with a Transformation Matrix

We build different types of transformation matrices to scale objects along cardinal axes and arbitrary axes in 2D and 3D with matrix multiplication!
Thu, Oct 15, 2015

Transformation Matrix

A linear transformation can be represented with a matrix that transforms vectors from one space to another. Transformation matrices allow arbitrary transformations to be displayed in the same format. Also, matrices can be multiplied to enable [composition](../combining-transformations). This article covers how to think and reason about these matrices and the way we can represent them (row vectors vs. column vectors).
Thu, Oct 15, 2015

Coordinate systems and transformations between them

The position and orientation of an object in real life can be described with direction and magnitude, e.g., the TV is 3 meters in front of me. While that description is good for me, it might be that for someone else in a room, the TV is 5 meters to the right of that person. Information about objects is given in the context of a reference frame. Usually, in Computer Graphics, objects need to be expressed with respect to the camera frame. This article covers why we need to have multiple reference frames and the math needed to express objects in a different reference frame.
Tue, Sep 8, 2015

Quaternions

Quaternions are a set of 4-dimensional vectors that are used to represent rotations in computer graphics. They were discovered by William Hamilton as an extension of 2D complex numbers to a 3D equivalent. This article covers the definition of a quaternion, its notation, and operations.
Tue, Sep 8, 2015

Complex Numbers

Imaginary numbers were invented to solve problems for equations with no real roots. Complex numbers extend imaginary numbers by adding a real number. This article covers the definition of complex numbers and operations such as addition, product, norm, conjugate, inverse, and square root. Finally, this article covers the geometric and polar representations of complex numbers.
Tue, Jul 7, 2015

Hamiltonian Graphs

Hamiltonian graphs and Hamiltonian cycles.
Sun, Jul 5, 2015

Eulerian Graph and Eulerian Trails

This article discusses Eulerian circuits and trails in graphs. An Eulerian circuit is a closed trail that contains every edge of a graph, and an Eulerian trail is an open trail that contains all the edges of a graph but doesn't end in the same start vertex. This article also explains the Königsberg Bridge Problem and why it's impossible to find a trail in it. Finally, there are two implementations in C++ to find Eulerian trails in directed and undirected graphs.
Fri, Jul 3, 2015

Single Source Shortest Path (SSSP) in a graph

Given a weighted graph $G$ with $V$ vertices and $E$ edges, where all the weights are non-negative, and a source vertex $s$, the single-source shortest path problem consists of finding the distance from $s$ to all other vertices. In this article, I describe the problem in a weighted and unweighted graph, as well as implementations using BFS for unweighted graphs and Dijkstra's algorithm for weighted graphs using an array and a priority queue.
Tue, Jun 30, 2015

Introduction to Trees in Graph Theory

An introduction to trees in graph theory.
Thu, Jun 25, 2015

Strongly Connected Components in Graph Theory

A strongly connected component of a directed graph is a subgraph in which there exists a path from every vertex to every other vertex in the subgraph. In this article, I implement Tarjan's algorithm to find strongly connected components in a graph.
Wed, Jun 24, 2015

Minimum Spanning Tree

This article covers the minimum spanning tree (MST). MSTs have important applications; for example, they can be used to minimize the cost of building a communication network or to identify important features or patterns in a dataset. I implement the Prim and Kruskal algorithms to find the minimum spanning tree in a graph, with different implementations for sparse and dense graphs. With the theory covered, I also implement an algorithm to find the number of minimal spanning trees in a graph.
Wed, Jun 24, 2015

Cut-vertices (articulation points) in Graph Theory

A vertex $v$ in a connected graph $G$ is called a **cut-vertex** if $G - v$ results in a disconnected graph. Note that $G - v$ is an induced subgraph of $G$ (meaning that $G - v$ contains all the vertices of $G$ except $v$ and a set of edges $G - E_v$, where $E_v$ consists of all the edges incident to $v$). In this article, I implement an algorithm to find the articulation points in an undirected graph. I also explain biconnected components in an undirected graph and concepts such as edge connectivity and vertex connectivity.
Wed, Jun 24, 2015

Cut-edges (bridges) in Graph Theory

An edge $e = uv$ of a connected graph $G$ is called a bridge if $G - e$ is disconnected (it increases the number of components). In this article, I implement an algorithm to find the bridges of an undirected graph using DFS. Next, I describe an algorithm to find strong bridges in directed graphs.
Wed, Jun 24, 2015

Topological sorting of a graph

Topological sorting is a linear ordering of the vertices of a directed acyclic graph (DAG) such that for every directed edge (u, v), vertex u comes before vertex v in the ordering. In other words, it is a way to order the vertices of a DAG such that there are no directed cycles. In this article, I implement the topological sorting algorithm and provide an example of how to use it to find the shortest path in a directed acyclic graph.
Wed, Jun 24, 2015

Traversal of graphs

There are many ways to traverse a graph. For example, through breadth-first search and depth-first search. Exploring it with a breadth-first search has interesting properties, like implicitly computing the distance from a source $s$ to all the reachable vertices. Exploring it with a depth-first search has properties related to edges, like finding back edges, forward edges, and cross edges. This article has implementations for both BFS and DFS.
Mon, Jun 22, 2015

Introduction to Graph Theory

Graph theory has numerous applications in real life. It can be used in problems found in social networks, transportation networks, the internet, chemistry, computer science, and electrical networks, among others. In general, any problem that involves relationships between objects can be modeled as a graph.
Sun, Jun 14, 2015

Integer Factorization

Integer factorization is the process of decomposing a *composite* number into a product of smaller integers, if these integers are restricted to be prime numbers then the process is called **prime factorization**. This article covers factorization using trial division and fermat factorization through Pollard's Rho algorithm and using the sieve of eratosthenes.
Sat, Jun 13, 2015

Divisor Function

The divisor function returns the number of divisors of an integer. This article covers important relations of the divisor function and prime numbers.
Thu, Jun 11, 2015

Primality Test

A prime number is a natural number greater than $1$ which has no positive divisors other than $1$ and itself. This article covers different algorithms for checking if a number is prime or not, including a naive test, the Eratosthenes Sieve, the Euler Primality Test, and the Miller-Rabin Primality Test.
Tue, Jun 9, 2015

Prime factors of a factorial

This article describes and implements a solution for the following problem: given two numbers $n$ and $k$ find the greatest power of $k$ that divides $n!$
Tue, Jun 9, 2015

Special factorial modulo p

Let $n!_{\\%p}$ be a special factorial where $n!$ is divided by the maximum exponent of $p$ that divides $n!$. This article describes this problem and its solution, with an implementation in C++.
Mon, Jun 8, 2015

Discrete Logarithm

The discrete logarithm finds a solution for $x$ in the congruence $a^x \equiv b \pmod{n}$ where $a$, $b$, and $n$ are **integers**, $a$ and $n$ are coprime. This article covers two algorithms to solve this problem: by trial multiplication and using Baby Step Giant Step.
Fri, Jun 5, 2015

Chinese Remainder Theorem

The Chinese Remainder Theorem (CRT) is a theorem that deals with finding a solution to a system of congruences. This article covers the definition of the CRT and an example implementation in C++.
Thu, Jun 4, 2015

Modular Arithmetic

Modular arithmetic is a type of arithmetic that deals with integers and remains within a fixed range of values. It involves performing arithmetic operations such as addition, subtraction, multiplication, and division, but with the added concept of a "modulus" or a "mod" value. This article covers the definition of a congruence relation, and some of its properties like addition, multiplication, exponentiation, and inverse. Next, I show how we can use the Extended Euclidean Algorithm to find the modular multiplicative inverse in a general case and in the case of coprime numbers.
Tue, Jun 2, 2015

Extended Euclidean Algorithm

The Extended Euclidean Algorithm finds solutions to the equation $ax + by = gcd(a, b)$ where $x, y$ are unknowns. This article covers a few applications of the Extended Euclidean Algorithm like finding the modular multiplicative inverse of a number and finding solutions for linear congruence equations.
Mon, Jun 1, 2015

Binary Exponentiation

Given two numbers $a$ and $n$, finding $a^n$ involves performing $n$ multiplications of $a$. However, it's possible to do this in $log(n)$ operations using binary exponentiation.
Mon, Jun 1, 2015

Eratosthenes Sieve

The Eratosthenes Sieve is an algorithm to find prime numbers up to a positive number $n$ using $O(n)$ space.
Mon, Jun 1, 2015

Euclidean Algorithm

The Euclidean Algorithm finds the greatest common divisor of two numbers. In this article I implement the algorithm from scratch in C++.
Mon, Jun 1, 2015

Euler's phi function

*Euler's phi function* represented as $\phi(n)$ gives, for a number $n$, the number of coprimes in the range $[1..n]$; in other words, the quantity of numbers in the range $[1..n]$ whose greatest common divisor with $n$ is the unity. In this article, I try to explain how it works and implement it in C++.
Thu, Apr 2, 2015

Derivative

The derivative is a concept that represents the rate of change or the slope of a function at a particular point. It is a fundamental concept in calculus and is used to analyze how a function changes with respect to its input as the input changes very slightly. This article covers the physical and geometric interpretation of the derivative, as well as some applications like finding maxima and minima in a function and the Newton-Raphson method.
Thu, Apr 2, 2015

Integral

An integral is a mathematical concept that represents the accumulation or summing up of quantities over a certain interval or region. In this article, we'll discuss the properties of the integral by looking at an example of antidifferentiation and some examples of evaluating definite integrals.
Thu, Apr 2, 2015

Taylor's Theorem and Infinite Series

Taylor series help approximate the value of a definite integral for a function whose antiderivative is hard to find. This article explains the key ideas behind Taylor's Theorem and an example of approximating its value with a polynomial function.
Tue, Mar 31, 2015

Introduction to Calculus

This article gives an introduction to calculus, starting with the concept of a function and how calculus helps us solve problems related to determining tangents to curves (expressed as functions), finding the minima/maxima like determining the maximum range of a projectile, and finding the length of curves, areas, and volumes.