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.