<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Max Slater</title><link>https://thenumb.at/</link><description>Recent content on Max Slater</description><generator>Hugo</generator><language>en-US</language><lastBuildDate>Sat, 02 Aug 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://thenumb.at/index.xml" rel="self" type="application/rss+xml"/><item><title>Monte Carlo Crash Course</title><link>https://thenumb.at/QMC/</link><pubDate>Sat, 02 Aug 2025 00:00:00 +0000</pubDate><guid>https://thenumb.at/QMC/</guid><description>&lt;ul&gt;
&lt;li&gt;&lt;a href="https://thenumb.at/Probability"&gt;Continuous Probability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thenumb.at/Monte-Carlo"&gt;Exponentially Better Integration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thenumb.at/Sampling"&gt;Sampling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thenumb.at/Rendering"&gt;Case Study: Rendering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://thenumb.at/QMC"&gt;Quasi-Monte Carlo&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Coming Soon&amp;hellip;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- - [Importance Sampling](/Importance) --&gt;
&lt;!-- - [Markov Chain Monte Carlo](/MCMC) --&gt;
&lt;hr&gt;
&lt;h1 id="quasi-monte-carlo"&gt;Quasi-Monte Carlo&lt;/h1&gt;
&lt;p&gt;We&amp;rsquo;ve learned how to define and apply Monte Carlo integration—fundamentally, it&amp;rsquo;s the only tool we need.
In the remaining chapters, we&amp;rsquo;ll explore ways to reduce variance and successfully sample difficult distributions.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#variance--correlation"&gt;Variance &amp;amp; Correlation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#stratified-sampling"&gt;Stratified Sampling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#adaptive-sampling"&gt;Adaptive Sampling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#latin-hypercube"&gt;Latin Hypercube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#quasi-monte-carlo-1"&gt;Quasi-Monte Carlo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#low-discrepancy-sequences"&gt;Low-Discrepancy Sequences&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="variance--correlation"&gt;Variance &amp;amp; Correlation&lt;/h2&gt;
&lt;p&gt;In &lt;a href="https://thenumb.at/Monte-Carlo/#escaping-the-curse"&gt;chapter two&lt;/a&gt;, we determined that the variance of a Monte Carlo estimator is inversely proportional to its sample count.
Empirically, we confirmed that our integrators&amp;rsquo; expected error scaled with $$\frac{1}{\sqrt{N}}$$ in any dimension.&lt;/p&gt;</description></item><item><title>Monte Carlo Crash Course</title><link>https://thenumb.at/Rendering/</link><pubDate>Sat, 19 Apr 2025 00:00:00 +0000</pubDate><guid>https://thenumb.at/Rendering/</guid><description>&lt;ul&gt;
&lt;li&gt;&lt;a href="https://thenumb.at/Probability"&gt;Continuous Probability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thenumb.at/Monte-Carlo"&gt;Exponentially Better Integration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thenumb.at/Sampling"&gt;Sampling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://thenumb.at/Rendering"&gt;Case Study: Rendering&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thenumb.at/QMC"&gt;Quasi-Monte Carlo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Coming Soon&amp;hellip;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- - [Importance Sampling](/Importance) --&gt;
&lt;!-- - [Markov Chain Monte Carlo](/MCMC) --&gt;
&lt;hr&gt;
&lt;h1 id="case-study-rendering"&gt;Case Study: Rendering&lt;/h1&gt;
&lt;p&gt;So far, we&amp;rsquo;ve explored Monte Carlo methods using simple examples, like sampling the unit disk and sphere.
Now, we&amp;rsquo;ll apply Monte Carlo to a more realistic task: simulating light traveling through a scene, or &lt;a href="https://github.com/TheNumbat/Diopter?tab=readme-ov-file#renders"&gt;&lt;em&gt;rendering&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#direct-lighting"&gt;Direct Lighting&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#indirect-lighting"&gt;Indirect Lighting&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#specular-reflection"&gt;Specular Reflection&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#challenges"&gt;Challenges&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="direct-lighting"&gt;Direct Lighting&lt;/h2&gt;
&lt;p&gt;To keep our focus on Monte Carlo methods, we&amp;rsquo;ll use a simplified model of light transport in two dimensions.&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;
In particular, we will only define one quantity: &lt;em&gt;radiance&lt;/em&gt;.
Denoted as $$\mathcal{L}_i(\mathbf{x},\theta)$$, radiance measures the amount of light arriving at a point $$\mathbf{x}$$ from an incoming direction $$\theta$$.&lt;/p&gt;</description></item><item><title>Monte Carlo Crash Course</title><link>https://thenumb.at/Sampling/</link><pubDate>Sat, 12 Apr 2025 00:00:00 +0000</pubDate><guid>https://thenumb.at/Sampling/</guid><description>&lt;ul&gt;
&lt;li&gt;&lt;a href="https://thenumb.at/Probability"&gt;Continuous Probability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thenumb.at/Monte-Carlo"&gt;Exponentially Better Integration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://thenumb.at/Sampling"&gt;Sampling&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thenumb.at/Rendering"&gt;Case Study: Rendering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thenumb.at/QMC"&gt;Quasi-Monte Carlo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Coming Soon&amp;hellip;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- - [Importance Sampling](/Importance) --&gt;
&lt;!-- - [Markov Chain Monte Carlo](/MCMC) --&gt;
&lt;hr&gt;
&lt;h1 id="sampling"&gt;Sampling&lt;/h1&gt;
&lt;p&gt;In the previous chapter, we assumed that we can uniformly randomly sample our domain.
However, it&amp;rsquo;s not obvious how to actually do so—in fact, how can a deterministic computer even generate random numbers?&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#pseudo-random-numbers"&gt;Pseudo-Random Numbers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#uniform-rejection-sampling"&gt;Uniform Rejection Sampling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#non-uniform-rejection-sampling"&gt;Non-Uniform Rejection Sampling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#inversion-sampling"&gt;Inversion Sampling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#changes-of-coordinates"&gt;Changes of Coordinates&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="pseudo-random-numbers"&gt;Pseudo-Random Numbers&lt;/h2&gt;
&lt;p&gt;Fortunately, Monte Carlo methods don&amp;rsquo;t need truly random numbers.
Instead, we can use a &lt;em&gt;pseudo-random number generator&lt;/em&gt;, or PRNG.
Given a random initial state (the &lt;em&gt;seed&lt;/em&gt;), a PRNG produces a deterministic stream of numbers that look uniformly random:&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;</description></item><item><title>Monte Carlo Crash Course</title><link>https://thenumb.at/Monte-Carlo/</link><pubDate>Sat, 05 Apr 2025 00:00:00 +0000</pubDate><guid>https://thenumb.at/Monte-Carlo/</guid><description>&lt;ul&gt;
&lt;li&gt;&lt;a href="https://thenumb.at/Probability"&gt;Continuous Probability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://thenumb.at/Monte-Carlo"&gt;Exponentially Better Integration&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thenumb.at/Sampling"&gt;Sampling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thenumb.at/Rendering"&gt;Case Study: Rendering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thenumb.at/QMC"&gt;Quasi-Monte Carlo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Coming Soon&amp;hellip;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- - [Importance Sampling](/Importance) --&gt;
&lt;!-- - [Markov Chain Monte Carlo](/MCMC) --&gt;
&lt;hr&gt;
&lt;h1 id="exponentially-better-integration"&gt;Exponentially Better Integration&lt;/h1&gt;
&lt;p&gt;By introducing randomness, Monte Carlo methods let us integrate high-dimensional functions &lt;em&gt;exponentially faster&lt;/em&gt; than traditional algorithms.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#integration"&gt;Integration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#quadrature"&gt;Quadrature&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#the-curse-of-dimensionality"&gt;The Curse of Dimensionality&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#monte-carlo-integration"&gt;Monte Carlo Integration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#why-monte-carlo"&gt;Why Monte Carlo?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#bias-and-consistency"&gt;Bias and Consistency&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#non-uniform-sampling"&gt;Non-Uniform Sampling&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="integration"&gt;Integration&lt;/h2&gt;
&lt;p&gt;Many interesting quantities can be computed by evaluating an integral.
For example:&lt;/p&gt;</description></item><item><title>Monte Carlo Crash Course</title><link>https://thenumb.at/Probability/</link><pubDate>Sat, 29 Mar 2025 00:00:00 +0000</pubDate><guid>https://thenumb.at/Probability/</guid><description>&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://thenumb.at/Probability"&gt;Continuous Probability&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thenumb.at/Monte-Carlo"&gt;Exponentially Better Integration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thenumb.at/Sampling"&gt;Sampling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thenumb.at/Rendering"&gt;Case Study: Rendering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thenumb.at/QMC"&gt;Quasi-Monte Carlo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Coming Soon&amp;hellip;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- - [Importance Sampling](/Importance) --&gt;
&lt;!-- - [Markov Chain Monte Carlo](/MCMC) --&gt;
&lt;hr&gt;
&lt;h1 id="continuous-probability"&gt;Continuous Probability&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;Prerequisites: &lt;a href="https://www.youtube.com/playlist?list=PLMrJAkhIeNNR3sNYvfgiKgcStwuPSts9V"&gt;Discrete Probability&lt;/a&gt;, &lt;a href="https://www.youtube.com/playlist?list=PLSQl0a2vh4HC5feHa6Rc5c0wbRTx56nF7"&gt;Multivariable Calculus&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This chapter is a condensed review of continuous probability.
If you&amp;rsquo;re comfortable working with continuous random variables, you may want to skip it.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#random-variables"&gt;Random Variables&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#probability-mass-vs-probability-density"&gt;Probability Mass vs. Probability Density&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#cumulative-distributions"&gt;Cumulative Distributions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#joint-distributions"&gt;Joint Distributions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#dependence"&gt;Dependence&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#expectation"&gt;Expectation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#probability-bounds"&gt;Probability Bounds&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#variance"&gt;Variance&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#covariance"&gt;Covariance&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#dirac-delta-distributions"&gt;Dirac Delta Distributions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="random-variables"&gt;Random Variables&lt;/h2&gt;
&lt;p&gt;In the discrete world, a &lt;em&gt;random variable&lt;/em&gt; represents a random process with &lt;a href="https://en.wikipedia.org/wiki/Countable_set"&gt;countably many&lt;/a&gt; outcomes.
The classic example is flipping a fair coin: let&amp;rsquo;s say $$X$$ evaluates to $$1$$ if our coin comes up heads, otherwise $$0$$.
Because there are only two possibilities, $$X$$ is a &lt;em&gt;discrete&lt;/em&gt; random variable.&lt;/p&gt;</description></item><item><title>Oxidizing C++</title><link>https://thenumb.at/rpp/</link><pubDate>Sat, 06 Jan 2024 00:00:00 +0000</pubDate><guid>https://thenumb.at/rpp/</guid><description>&lt;p&gt;I recently rewrote the C++20 infrastructure I use for personal projects, so I decided to snapshot its design in the style of &lt;a href="https://nullprogram.com/blog/2023/10/08/"&gt;another recent article&lt;/a&gt;.
The library (&lt;em&gt;rpp&lt;/em&gt;) is primarily inspired by Rust, and may be found on &lt;a href="https://github.com/TheNumbat/rpp"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I use &lt;em&gt;rpp&lt;/em&gt; as an STL replacement, and I&amp;rsquo;m currently developing a &lt;a href="https://github.com/TheNumbat/Diopter"&gt;real-time path tracer&lt;/a&gt; with it.
&lt;em&gt;rpp&lt;/em&gt; attempts to provide the following features, roughly in priority order:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Fast Compilation&lt;/p&gt;
&lt;p&gt;Including &lt;em&gt;rpp&lt;/em&gt; should not increase compilation time by more than 250ms.
It must not pull in any STL or system headers—they&amp;rsquo;re what&amp;rsquo;s really slow, not templates.&lt;/p&gt;</description></item><item><title>Functions are Vectors</title><link>https://thenumb.at/Functions-are-Vectors/</link><pubDate>Sat, 29 Jul 2023 00:00:00 +0000</pubDate><guid>https://thenumb.at/Functions-are-Vectors/</guid><description>&lt;script src="https://thenumb.at/js/geometry-processing/linear-algebra-asm.js"&gt;&lt;/script&gt;
&lt;script src="https://thenumb.at/js/geometry-processing/vector.js"&gt;&lt;/script&gt;
&lt;script src="https://thenumb.at/js/geometry-processing/complex.js"&gt;&lt;/script&gt;
&lt;script src="https://thenumb.at/js/geometry-processing/emscripten-memory-manager.js"&gt;&lt;/script&gt;
&lt;script&gt; let memoryManager = new EmscriptenMemoryManager(); &lt;/script&gt;
&lt;script src="https://thenumb.at/js/geometry-processing/dense-matrix.js"&gt;&lt;/script&gt;
&lt;script src="https://thenumb.at/js/geometry-processing/sparse-matrix.js"&gt;&lt;/script&gt;
&lt;script src="https://thenumb.at/js/geometry-processing/complex-dense-matrix.js"&gt;&lt;/script&gt;
&lt;script src="https://thenumb.at/js/geometry-processing/complex-sparse-matrix.js"&gt;&lt;/script&gt;
&lt;script src="https://thenumb.at/js/geometry-processing/vertex.js"&gt;&lt;/script&gt;
&lt;script src="https://thenumb.at/js/geometry-processing/edge.js"&gt;&lt;/script&gt;
&lt;script src="https://thenumb.at/js/geometry-processing/face.js"&gt;&lt;/script&gt;
&lt;script src="https://thenumb.at/js/geometry-processing/halfedge.js"&gt;&lt;/script&gt;
&lt;script src="https://thenumb.at/js/geometry-processing/corner.js"&gt;&lt;/script&gt;
&lt;script src="https://thenumb.at/js/geometry-processing/mesh.js"&gt;&lt;/script&gt;
&lt;script src="https://thenumb.at/js/geometry-processing/geometry.js"&gt;&lt;/script&gt;
&lt;script src="https://thenumb.at/js/geometry-processing/meshio.js"&gt;&lt;/script&gt;
&lt;script src="https://thenumb.at/js/d3.v7.min.js"&gt;&lt;/script&gt;
&lt;script type="module" src="./js/functions-are-vectors.js"&gt;&lt;/script&gt;
&lt;p&gt;Conceptualizing functions as infinite-dimensional vectors lets us apply the tools of linear algebra to a vast landscape of new problems, from image and geometry processing to curve fitting and machine learning.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Prerequisites: &lt;a href="https://www.youtube.com/playlist?list=PLZHQObOWTQDPD3MizzM2xVFitgF8hE_ab"&gt;introductory linear algebra&lt;/a&gt;, &lt;a href="https://www.youtube.com/playlist?list=PLZHQObOWTQDMsr9K-rj53DwVRMYO3t5Yr"&gt;introductory calculus&lt;/a&gt;, &lt;a href="https://www.youtube.com/playlist?list=PLZHQObOWTQDNPOjrT6KVlfJuKtYTftqH6"&gt;introductory differential equations&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This article received an honorable mention in 3Blue1Brown&amp;rsquo;s &lt;a href="https://www.youtube.com/watch?v=6a1fLEToyvU"&gt;Summer of Math Exposition 3&lt;/a&gt;!&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#functions-as-vectors"&gt;Functions as Vectors&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#vector-spaces"&gt;Vector Spaces&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#linear-operators"&gt;Linear Operators&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#diagonalization"&gt;Diagonalization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#inner-product-spaces"&gt;Inner Product Spaces&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#the-spectral-theorem"&gt;The Spectral Theorem&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#applications"&gt;Applications&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#fourier-series"&gt;Fourier Series&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#image-compression"&gt;Image Compression&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#geometry-processing"&gt;Geometry Processing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#further-reading"&gt;Further Reading&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr style="margin-top: 25px; margin-bottom: 20px"&gt;
&lt;h1 id="functions-as-vectors"&gt;Functions as Vectors&lt;/h1&gt;
&lt;p&gt;Vectors are often first introduced as lists of real numbers—i.e. the familiar notation we use for points, directions, and more.&lt;/p&gt;</description></item><item><title>Optimizing Open Addressing</title><link>https://thenumb.at/Hashtables/</link><pubDate>Sun, 08 Jan 2023 00:00:00 +0000</pubDate><guid>https://thenumb.at/Hashtables/</guid><description>&lt;p&gt;Your default hash table should be open-addressed, using Robin Hood linear probing with backward-shift deletion.
When prioritizing deterministic performance over memory efficiency, two-way chaining is also a good choice.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Code for this article may be found on &lt;a href="https://github.com/TheNumbat/hashtables"&gt;GitHub&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#open-addressing-vs-separate-chaining"&gt;Open Addressing vs. Separate Chaining&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#benchmark-setup"&gt;Benchmark Setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#discussion"&gt;Discussion&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#separate-chaining"&gt;Separate Chaining&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#linear-probing"&gt;Linear Probing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#quadratic-probing"&gt;Quadratic Probing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#double-hashing"&gt;Double Hashing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#robin-hood-linear-probing"&gt;Robin Hood Linear Probing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#two-way-chaining"&gt;Two Way Chaining&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#unrolling-prefetching-and-simd"&gt;Unrolling, Prefetching, and SIMD&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#benchmark-data"&gt;Benchmark Data&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="open-addressing-vs-separate-chaining"&gt;Open Addressing vs. Separate Chaining&lt;/h1&gt;
&lt;p&gt;Most people first encounter hash tables implemented using &lt;em&gt;separate chaining&lt;/em&gt;, a model simple to understand and analyze mathematically.
In separate chaining, a hash function is used to map each key to one of $$K$$ &lt;em&gt;buckets&lt;/em&gt;.
Each bucket holds a linked list, so to retrieve a key, one simply traverses its corresponding bucket.&lt;/p&gt;</description></item><item><title>Spherical Integration</title><link>https://thenumb.at/Spherical-Integration/</link><pubDate>Sun, 08 Jan 2023 00:00:00 +0000</pubDate><guid>https://thenumb.at/Spherical-Integration/</guid><description>&lt;p&gt;&lt;em&gt;Or, where does that $$\sin\theta$$ come from?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Integrating functions over spheres is a ubiquitous task in graphics—and a common source of confusion for beginners. In particular, understanding why integration in spherical coordinates requires multiplying by $$\sin\theta$$ takes some thought.&lt;/p&gt;
&lt;h1 id="the-confusion"&gt;The Confusion&lt;/h1&gt;
&lt;p&gt;So, we want to integrate a function $$f$$ over the unit sphere. For simplicity, let&amp;rsquo;s assume $$f = 1$$. Integrating $$1$$ over any surface computes the area of that surface: for a unit sphere, we should end up with $$4\pi$$.&lt;/p&gt;</description></item><item><title>Exploring Neural Graphics Primitives</title><link>https://thenumb.at/Neural-Graphics/</link><pubDate>Sun, 27 Nov 2022 00:00:00 +0000</pubDate><guid>https://thenumb.at/Neural-Graphics/</guid><description>&lt;script async type="module" src="./neural-graphics.js"&gt;&lt;/script&gt;
&lt;p&gt;Neural fields have quickly become an interesting and useful application of machine learning to computer graphics. The fundamental idea is quite straightforward: we can use neural models to represent all sorts of digital signals, including images, light fields, signed distance functions, and volumes.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#neural-networks"&gt;Neural Networks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#compression"&gt;Compression&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#a-basic-network"&gt;A Basic Network&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#activations"&gt;Activations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#input-encodings"&gt;Input Encodings&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#positional-encoding"&gt;Positional Encoding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#instant-neural-graphics-primitives"&gt;Instant Neural Graphics Primitives&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#more-applications"&gt;More Applications&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#neural-sdfs"&gt;SDFs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#neural-radiance-fields"&gt;NeRFs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#references"&gt;References&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="neural-networks"&gt;Neural Networks&lt;/h1&gt;
&lt;p&gt;This post assumes a basic knowledge of &lt;a href="https://www.youtube.com/watch?v=aircAruvnKk"&gt;neural networks&lt;/a&gt;, but let&amp;rsquo;s briefly recap how they work.&lt;/p&gt;</description></item><item><title>Differentiable Programming from Scratch</title><link>https://thenumb.at/Autodiff/</link><pubDate>Sun, 31 Jul 2022 00:00:00 +0000</pubDate><guid>https://thenumb.at/Autodiff/</guid><description>&lt;link rel="stylesheet" type="text/css" href="https://thenumb.at/js/prism/prism.min.css" /&gt;
&lt;script src="https://thenumb.at/js/prism/prism.min.js"&gt;&lt;/script&gt;
&lt;script type="module" src="./autodiff.js"&gt;&lt;/script&gt;
&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Differentiable_programming"&gt;Differentiable programming&lt;/a&gt; has become a hot research topic, and not only due to the popularity of machine learning frameworks like TensorFlow, PyTorch, and JAX. Many fields apart from machine learning are finding differentiable programming to be a useful tool for solving optimization problems. In computer graphics, differentiable &lt;a href="https://www.youtube.com/watch?v=Tou8or1ed6E"&gt;rendering&lt;/a&gt;, differentiable &lt;a href="https://physicsbaseddeeplearning.org/diffphys.html"&gt;physics&lt;/a&gt;, and &lt;a href="https://thenumb.at/Neural-Graphics/"&gt;neural representations&lt;/a&gt; are all gaining popularity.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This article received an honorable mention in 3Blue1Brown&amp;rsquo;s &lt;a href="https://www.youtube.com/watch?v=cDofhN-RJqg"&gt;Summer of Math Exposition 2&lt;/a&gt;!&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#prerequisites"&gt;Prerequisites&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#differentiation"&gt;Differentiation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#optimization"&gt;Optimization&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#differentiating-code"&gt;Differentiating Code&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#numerical"&gt;Numerical&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#symbolic"&gt;Symbolic&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#automatic-differentiation"&gt;Automatic Differentiation&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#forward-mode"&gt;Forward Mode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#backward-mode"&gt;Backward Mode&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#de-blurring-an-image"&gt;De-blurring an Image&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#further-reading"&gt;Further Reading&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="prerequisites"&gt;Prerequisites&lt;/h1&gt;
&lt;h2 id="differentiation"&gt;Differentiation&lt;/h2&gt;
&lt;p&gt;It all starts with the definition you learn in calculus class:&lt;/p&gt;</description></item><item><title>Exponentially Better Rotations</title><link>https://thenumb.at/Exponential-Rotations/</link><pubDate>Fri, 15 Apr 2022 00:00:00 +0000</pubDate><guid>https://thenumb.at/Exponential-Rotations/</guid><description>&lt;script type="module" src="./rotations.js"&gt;&lt;/script&gt;
&lt;p&gt;If you&amp;rsquo;ve done any 3D programming, you&amp;rsquo;ve likely encountered the zoo of techniques and representations used when working with 3D rotations. Some of them are better than others, depending on the situation.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Based on &lt;a href="http://15462.courses.cs.cmu.edu/"&gt;CMU 15-462&lt;/a&gt; course materials by &lt;a href="https://www.cs.cmu.edu/~kmcrane/"&gt;Keenan Crane&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#representations"&gt;Representations&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#rotation-matrices"&gt;Rotation Matrices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#euler-angles"&gt;Euler Angles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#quaternions"&gt;Quaternions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#axisangle-rotations"&gt;Axis/Angle&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#the-exponential-and-logarithmic-maps"&gt;The Exponential and Logarithmic Maps&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#axisangle-in-2d"&gt;Axis/Angle in 2D&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#axisangle-in-3d"&gt;Axis/Angle in 3D&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#averaging-rotations"&gt;Averaging Rotations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#quaternions-again"&gt;Quaternions (Again)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#further-reading"&gt;Further Reading&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="representations"&gt;Representations&lt;/h1&gt;
&lt;h2 id="rotation-matrices"&gt;Rotation Matrices&lt;/h2&gt;
&lt;p&gt;Linear-algebra-wise, the most straightforward representation is an orthonormal 3x3 matrix (with positive determinant). The three columns of a rotation matrix specify where the x, y, and z axes end up after the rotation.&lt;/p&gt;</description></item><item><title>Graphics Blogroll</title><link>https://thenumb.at/Graphics-Blogroll/</link><pubDate>Mon, 04 Apr 2022 00:00:00 +0000</pubDate><guid>https://thenumb.at/Graphics-Blogroll/</guid><description>&lt;p&gt;In no particular order, my list of cool computer graphics (or adjacent) blogs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.redblobgames.com/"&gt;Amit Patel&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Interactive algorithm visualizations&lt;/li&gt;
&lt;li&gt;Highlight: &lt;a href="https://www.redblobgames.com/pathfinding/a-star/introduction.html"&gt;Introduction to A*&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://iquilezles.org/"&gt;Inigo Quilez&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;3D SDF rendering and &lt;a href="https://www.shadertoy.com/"&gt;shadertoy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Highlight: &lt;a href="https://iquilezles.org/www/articles/distfunctions/distfunctions.htm"&gt;3D SDF Index&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://fgiesen.wordpress.com/"&gt;Fabian Giesen&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Graphics programming, compression, comp arch, optimization&lt;/li&gt;
&lt;li&gt;Highlight: &lt;a href="https://fgiesen.wordpress.com/2011/07/09/a-trip-through-the-graphics-pipeline-2011-index/"&gt;A trip through the Graphics Pipeline 2011&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bartwronski.com/"&gt;Bart Wronski&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Image/signal processing, real-time rendering, linear algebra&lt;/li&gt;
&lt;li&gt;Highlight: &lt;a href="https://bartwronski.com/2020/12/27/why-are-video-games-graphics-still-a-challenge-productionizing-rendering-algorithms/"&gt;Why are video game graphics still a challenge?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ncase.me/"&gt;Nicky Case&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&amp;lsquo;Explorable&amp;rsquo; real-world models, mental health&lt;/li&gt;
&lt;li&gt;Highlight: &lt;a href="https://ncase.me/polygons/"&gt;Parable of the Polygons&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ciechanow.ski/archives/"&gt;Bartosz Ciechanowski&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Highly detailed interactive explainers&lt;/li&gt;
&lt;li&gt;Highlight: &lt;a href="https://ciechanow.ski/cameras-and-lenses/"&gt;Cameras and Lenses&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.alanzucconi.com/"&gt;Alan Zucconi&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Misc. game dev&lt;/li&gt;
&lt;li&gt;Highlight: &lt;a href="http://www.alanzucconi.com/2017/04/17/procedural-animations/"&gt;Introduction to Procedural Animations&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://marctenbosch.com/"&gt;Marc Ten Bosch&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Higher-dimensional physics, math&lt;/li&gt;
&lt;li&gt;Highlight: &lt;a href="https://marctenbosch.com/quaternions/"&gt;Let&amp;rsquo;s remove Quaternions from every 3D Engine&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.demofox.org/"&gt;Alan Wolfe&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Image/signal processing, real-time graphics, math&lt;/li&gt;
&lt;li&gt;Highlight: &lt;a href="https://blog.demofox.org/2016/02/29/fast-voronoi-diagrams-and-distance-dield-textures-on-the-gpu-with-the-jump-flooding-algorithm/"&gt;Fast Voronoi Diagrams and Distance Fields with Jump Flooding&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://fabiensanglard.net/"&gt;Fabien Sanglard&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Retro game dev, graphics programming, game engines&lt;/li&gt;
&lt;li&gt;Highlight: &lt;a href="https://fabiensanglard.net/postcard_pathtracer/index.html"&gt;Deciphering the Postcard Sized Pathtracer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://therealmjp.github.io/posts/"&gt;Matt Pettineo&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Graphics programming, real-time rendering&lt;/li&gt;
&lt;li&gt;Highlight: &lt;a href="https://therealmjp.github.io/posts/attack-of-the-depth-buffer/"&gt;Attack of the Depth Buffer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aras-p.info/"&gt;Aras Pranckevičius&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Misc. graphics, optimization, compilers&lt;/li&gt;
&lt;li&gt;Highlight: &lt;a href="https://aras-p.info/blog/2018/12/28/Modern-C-Lamentations/"&gt;&amp;ldquo;Modern&amp;rdquo; C++ Lamentations&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bgolus.medium.com/"&gt;Ben Golus&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Graphics programming, shaders&lt;/li&gt;
&lt;li&gt;Highlight: &lt;a href="https://bgolus.medium.com/the-quest-for-very-wide-outlines-ba82ed442cd9"&gt;The Quest for Very Wide Outlines&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://interplayoflight.wordpress.com/"&gt;Kostas Anagnostou&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Graphics programming, rendering&lt;/li&gt;
&lt;li&gt;Highlight: &lt;a href="https://interplayoflight.wordpress.com/2022/03/26/raytraced-global-illumination-denoising/"&gt;Raytraced Global Illumination Denoising&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.adriancourreges.com/blog/"&gt;Adrian Courrèges&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Real-time rendering&lt;/li&gt;
&lt;li&gt;Highlight: &lt;a href="http://www.adriancourreges.com/blog/2016/09/09/doom-2016-graphics-study/"&gt;DOOM 2016 Graphics Study&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://raphlinus.github.io/"&gt;Raph Levien&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;2D rendering, GPU programming&lt;/li&gt;
&lt;li&gt;Highlight: &lt;a href="https://raphlinus.github.io/ui/graphics/gpu/2021/10/22/swapchain-frame-pacing.html"&gt;Swapchains and Frame Pacing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pharr.org/matt/blog/"&gt;Matt Pharr&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Rendering, optimization&lt;/li&gt;
&lt;li&gt;Highlight: &lt;a href="http://pharr.org/matt/blog/2018/07/16/moana-island-pbrt-all.html"&gt;Rendering Moana with pbrt&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://wickedengine.net/category/devblog/"&gt;János Turánszki&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Real-time rendering, game engines&lt;/li&gt;
&lt;li&gt;Highlight: &lt;a href="https://wickedengine.net/2017/08/30/voxel-based-global-illumination/"&gt;Voxel-based Global Illumination&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://zeux.io/"&gt;Arseny Kapoulkine&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Real-time rendering, optimization&lt;/li&gt;
&lt;li&gt;Highlight: &lt;a href="https://zeux.io/2020/02/27/writing-an-efficient-vulkan-renderer/"&gt;Writing an efficient Vulkan renderer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="http://theorangeduck.com/page/all"&gt;Daniel Holden&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Animation, geometry, game dev&lt;/li&gt;
&lt;li&gt;Highlight: &lt;a href="http://theorangeduck.com/page/spring-roll-call"&gt;Game Developer&amp;rsquo;s Spring-Roll-Call&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.tuxedolabs.com/"&gt;Dennis Gustafsson&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Real-time rendering, game dev, GPU programming&lt;/li&gt;
&lt;li&gt;Highlight: &lt;a href="https://blog.tuxedolabs.com/2018/05/04/bokeh-depth-of-field-in-single-pass.html"&gt;Bokeh depth of field in a single pass&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://michaelmoroz.github.io/"&gt;Mykhailo Moroz&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Computational physics, rendering and other random stuff&lt;/li&gt;
&lt;li&gt;Highlight: &lt;a href="https://michaelmoroz.github.io/TracingGeodesics/"&gt;Visualizing General Relativity&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.jeremyong.com/"&gt;Jeremy Ong&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Computer graphics, C++&lt;/li&gt;
&lt;li&gt;Highlight: &lt;a href="https://www.jeremyong.com/cpp/2021/05/20/graphics-pipelines-for-young-bloods/"&gt;Graphics Pipelines for Young Bloods&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="inactive"&gt;Inactive&lt;/h3&gt;
&lt;p&gt;These blogs are very infrequently updated or haven&amp;rsquo;t been updated in years.&lt;/p&gt;</description></item><item><title>Hamming Hats</title><link>https://thenumb.at/Hamming-Hats/</link><pubDate>Tue, 29 Mar 2022 00:00:00 +0000</pubDate><guid>https://thenumb.at/Hamming-Hats/</guid><description>&lt;p&gt;&lt;em&gt;I first encountered the &lt;a href="https://www.nytimes.com/2001/04/10/science/why-mathematicians-now-care-about-their-hat-color.html"&gt;Hat Problem&lt;/a&gt; in &lt;a href="http://www.cs.cmu.edu/~15251/"&gt;CMU 15-251&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id="the-game"&gt;The Game&lt;/h2&gt;
&lt;p&gt;Consider a 31-person game in which each player is assigned a red or blue hat, determined by an independent coin flip. The players can see everyone else&amp;rsquo;s hat color, but &lt;strong&gt;not&lt;/strong&gt; their own.&lt;/p&gt;
&lt;p&gt;Once the game begins, no communication is allowed between the players. After looking at the other hats, all players must &lt;em&gt;simultaneously&lt;/em&gt; either announce the color of their hat or abstain from guessing. If at least one player correctly announces their hat color, and no players incorrectly announce theirs, the group wins.&lt;/p&gt;</description></item><item><title>A Compiler Bug</title><link>https://thenumb.at/Compiler-Bug/</link><pubDate>Sun, 26 Dec 2021 00:00:00 +0000</pubDate><guid>https://thenumb.at/Compiler-Bug/</guid><description>&lt;p&gt;While I was working on &lt;a href="https://thenumb.at/projects/dawn"&gt;Dawn&lt;/a&gt;, I ran into a curious bug in the Visual Studio 2019 C++ compiler. I reported it to the bug tracker, where it was confirmed to be an interference analysis issue. It was eventually fixed nearly a year later in 2020. Today, let&amp;rsquo;s investigate what the issue really was.&lt;/p&gt;
&lt;p&gt;The problem arose upon implementing a Perlin noise type for procedural solid texturing. My type just so happened to include a 4-kilobyte array of pre-initialized random data, and this precise size caused writes to the data to interfere with a preceding struct member. The resulting bug ended up bricking the output of my path tracer—but only with optimizations enabled!&lt;/p&gt;</description></item><item><title>Exile: Voxel Rendering Pipeline</title><link>https://thenumb.at/Voxel-Meshing-in-Exile/</link><pubDate>Sun, 26 Aug 2018 00:00:00 +0000</pubDate><guid>https://thenumb.at/Voxel-Meshing-in-Exile/</guid><description>&lt;p&gt;No, &lt;a href="https://github.com/TheNumbat/exile"&gt;Exile&lt;/a&gt; is not technically a &amp;ldquo;voxel&amp;rdquo; engine. A real voxel engine unifies objects, textures, and more into colored voxel data, rendering them via raymarching/&lt;a href="https://en.wikipedia.org/wiki/Marching_cubes"&gt;marching cubes&lt;/a&gt;/&lt;a href="https://upvoid.com/devblog/2013/05/terrain-engine-part-1-dual-contouring/"&gt;dual contouring&lt;/a&gt;/etc., and can target realism. Instead, Exile is a &amp;ldquo;voxel&amp;rdquo; engine in that it&amp;rsquo;s a traditional 3D engine that happens to focus on representing and drawing textured cubes (like Minecraft and related games). Some have worked around this linguistic confusion by christening the technique &lt;a href="https://yave.handmade.network/"&gt;&amp;ldquo;Swedish cubes,&amp;rdquo;&lt;/a&gt; but for the purposes of this post, please assume that voxels imply textured cubes.&lt;/p&gt;</description></item><item><title>Exile: Reflection</title><link>https://thenumb.at/Reflection-in-Exile/</link><pubDate>Tue, 14 Aug 2018 00:00:00 +0000</pubDate><guid>https://thenumb.at/Reflection-in-Exile/</guid><description>&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Reflection_(computer_programming)"&gt;Reflection&lt;/a&gt;, specifically type introspection, is an immensely useful feature provided by many modern languages. By enabling a way to inspect the properties of types—for example, the types of the members of a data structure—introspection allows one to write much more general and effective generic code, enforce interfaces/contracts, and more.&lt;/p&gt;
&lt;p&gt;Though most obviously found in dynamic languages, introspection is just as powerful in compiled, statically typed languages such as &lt;a href="https://blog.golang.org/laws-of-reflection"&gt;Go&lt;/a&gt; and &lt;a href="https://www.youtube.com/watch?v=JoNkttD_MUs"&gt;Jai&lt;/a&gt;. Unfortunately, C++ does not support run-time reflection as a language feature, and template-based compile-time reflection is neither standardized, elegant, nor robust. Standards proposals have been put forward to add reflection features, but an implementation is still rather far off. Further, &lt;a href="https://github.com/rttrorg/rttr"&gt;libraries&lt;/a&gt; aiming to provide run-time reflection typically require laborious setup for each type you wish to make reflect-able.&lt;/p&gt;</description></item><item><title>Exile: Hot Reloading</title><link>https://thenumb.at/Hot-Reloading-in-Exile/</link><pubDate>Wed, 25 Jul 2018 00:00:00 +0000</pubDate><guid>https://thenumb.at/Hot-Reloading-in-Exile/</guid><description>&lt;p&gt;In game development, one of the main appeals of implementing game logic in a managed language (e.g. Lua) is the convenient ability to make changes to the source, reload the logic on the fly, and test the changes without restarting the game. A similar technique is also often used to refresh shader programs, asset files, and the like.&lt;/p&gt;
&lt;p&gt;However, supporting a secondary scripting language—or using one from the start—is not the only way to implement such a system. While more complicated, implementing the ability to reload code on a binary level allows one to make potentially deep changes to the entire source and have them appear instantly. Further, any language that can export C ABI compatible functions can be dynamically loaded in this manner, using good old-fashioned dynamic link libraries/shared objects.&lt;/p&gt;</description></item></channel></rss>