<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
        <title><![CDATA[Jodie's Blog]]></title>
        <description><![CDATA[Personal blog by Jodie covering math, poetry, web development, and life]]></description>
        <link>https://jodie.website</link>
        <generator>RSS for Node</generator>
        <lastBuildDate>Mon, 04 May 2026 03:27:37 GMT</lastBuildDate>
        <atom:link href="https://jodie.website/feed.xml" rel="self" type="application/rss+xml"/>
        <pubDate>Mon, 04 May 2026 03:27:37 GMT</pubDate>
        <language><![CDATA[en]]></language>
        <ttl>60</ttl>
        <item>
            <title><![CDATA[We Have Inkhaven at Home]]></title>
            <description><![CDATA[<p>A friend of mine is going to this big fancy retreat called <a href="https://www.inkhaven.blog/" target="_blank">Inkhaven</a> where you write one blog post a day. And I was like "I can't do that, but I'll sure as hell try!". I don't want to spam this blog, so I'll link my daily posts down here and I'll add the best ones to the main feed later after some polish.</p>
<ul class="linklist">
    <li>April 1<sup>st</sup> - <strong><a href="https://morewrong.jodie.website/#how-to-leverage-effective-altruists-to-fix-housing" target="_blank">How to Leverage Effective Altruists to Fix Housing Prices in the Bay Area</a></strong> - MoreWrong</li>
    <li><details>
      <summary>April 2<sup>nd</sup> - <strong>Animal Welfare is a Culinary Problem</strong></summary>
      <article>
        <h2>Animal Welfare is a Culinary Problem</h2>
<p>I agree with the vegans. Factory farming is horrific. I don't need another documentary. I'm convinced.</p>
<h3>I had chicken last week.</h3>
<p>Not because I watched it get its beak cut off and felt nothing, but because I was sick with the man flu and I wanted a comforting microwave meal, and butter chicken was all I could find.</p>
<p>Most restaurants have one vegetarian option that only exists so they can say they tried. If you're a normal person who wants to eat with friends, well fuck you, you're eating fries.</p>
<p>I cook a real meal once a day. Sometimes zero. I drink a premade protein shake instead. These shakes are load-bearing to my quality of life.</p>
<h3>My body hates the obvious solution</h3>
<p>The first thing anyone suggests when you try to eat less meat is legumes. Cheap, nutritious, available.</p>
<p>They also make me fart.</p>
<p>I've tried soaking them overnight. I've tried "just push through it, your gut adapts." My gut did not adapt. I also tried soylent, the only decent vegan meal replacement shake. Similar results. Worse than the beans actually.</p>
<h3>Next time someone tells you they could never go vegan, send them a recipe.</h3>
<p>The greatest impact I've had on animal welfare is telling people that <abbr>msg</abbr> makes tofu taste good. The person who's influenced me the most isn't an activist,
          it's <a href="https://www.youtube.com/@SauceStache/videos" target="_blank">this guy on YouTube who figured out how to make vegan bacon out of rice paper</a>.</p><p>Animal welfare organizations should take a cut of their budget and put it into food science. Vegan food needs to compete with "regular" food, not be a niche specialty product. Fix the food and you get the ethics for free.</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 3<sup>rd</sup> - <strong>Dust</strong></summary>
      <article>
        <h2>Dust</h2>
<p>the ground under your feet<br>built from what ceased to be</p>
<p>each grain of sand<br>a graveyard of forgotten stars</p>
<p>your body only borrows<br>what the earth will reclaim</p>
<p>the dust will call you home<br>the ground under a stranger's feet</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 4<sup>th</sup> - <strong>How to Make a Floating&nbsp;Point Math Library, Part&nbsp;I</strong></summary>
      <article>
        <h2>How to Make a Floating&nbsp;Point Math Library, Part&nbsp;I</h2>
<p>You might have seen <a href="https://en.wikipedia.org/wiki/Fast_inverse_square_root" target="_blank">the fast inverse square root</a>. The one with the magic hex constant&nbsp;<code>0x5F3759DF</code>&nbsp;and the comment <em>"what the fuck?"</em> from the Quake&nbsp;III source. After reading this series, you'll understand how it works, and how to apply its arcane trickery to compute any transcendental function.</p>
<p>But first: what <em>is</em> a float?</p>
<p>
          <a target="_blank" href="https://en.wikipedia.org/wiki/Scientific_notation">Scientific notation</a>
          writes a number as a power of ten, multiplied by a value between 1 and 10 called the
          <em>significand</em> (or <em>mantissa</em>). Floats do the same thing in base&nbsp;2: the
          <em>exponent</em> stores ⌊log<sub>2</sub>(<em>x</em>)⌋, and the mantissa is between 1 and 2.
        </p><pre><code>┌sign┬─exponent──┬─mantissa─────────────────────┐
│ 0  │ 0000 0000 │ 000 0000 0000 0000 0000 0000 │
└────┴───────────┴──────────────────────────────┘
</code></pre>
<p><a href="https://www.h-schmidt.net/FloatConverter/IEEE754.html" target="_blank">This calculator</a> lets you flip individual bits and watch the value change. You'll get a feel for how different numbers are represented.</p>
<h3>Manipulating Floats with Integer Operations</h3>
<p>The upper bits of a float are proportional to the logarithm of its value. So integer math on the raw bits becomes log-domain arithmetic on the number itself.</p>
<pre><code>log(<em>a</em> · <em>b</em>)     = log <em>a</em> + log <em>b</em>
log(<em>a</em> / <em>b</em>)     = log <em>a</em> − log <em>b</em>
log(<em>a</em><sup><em>b</em></sup>)        = <em>b</em> · log <em>a</em>
log(√<em>a</em>)        = log(<em>a</em>) / 2
log(1/<em>a</em>)       = −log(<em>a</em>)
log(1/√<em>a</em>)      = −log(<em>a</em>) / 2</code></pre>
<p>Addition becomes multiplication. Subtraction becomes division. A right-shift by one becomes a square root… Wait… those last two are the inverse square root!</p>
<p>
          The exponent of a number can be negative (for numbers smaller than&nbsp;1). 
          Floats handle this by storing the exponent as <code>exponent + 127</code>. The "magic" constant 
          <code>0x5F3759DF</code> is just 2<sup>127/2</sup>. The integer subtract combines the
          reciprocal and the multiplication by 2<sup>127/2</sup>. Two birds, one <code>SUB</code>.
        </p><p>In <strong>Part&nbsp;II</strong>, we'll use this knowledge to implement other transcendental functions in code!</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 5<sup>th</sup> - <strong>Use Your Phone Less by Making It <em>More</em> Fun</strong></summary>
      <article>
        <h2>Use Your Phone Less by Making It <em>More</em> Fun</h2>
<p>Digital minimalism advice is usually about making your phone worse. Add friction. Greyscale the screen. Buy a flip phone.</p>
<p>You don't have to make your phone miserable to use. The terminal goal isn't "use your phone less." The goal is doing the things you actually want to do. You can read books on your phone, text your friends, write, navigate somewhere new. None of that is the problem. When your phone only has those there's no void to fill by scrolling.</p>
<h3>Remove Your Browser</h3>
<p>Most things you'd use a mobile browser for have an app. Single purpose, no distractions. To look something up, AI chatbots and Wikipedia search are usually better tools.</p>
<p>For the rare case you <em>need</em> a browser, there's <a href="https://www.mozilla.org/en-CA/firefox/browsers/mobile/focus/" target="_blank">Firefox Focus</a>. When you close it, it wipes everything. No start page, no autocomplete, no history. You can only go on websites intentionally. It doesn't keep you logged in either. Every addictive platform requires a login. No login, no slop.</p>
<h3>And it Works?</h3>
<p>Now when I pick up my phone reflexively to fill time, there's nothing to scroll. I put it down. Or I text a friend, read a book, write a blog post. No willpower. No discomfort. I never regret being on my phone.</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 6<sup>th</sup> - <strong>How to Make a Floating&nbsp;Point Math Library, Part&nbsp;II</strong></summary>
      <article>
        <h2>How to Make a Floating&nbsp;Point Math Library, Part&nbsp;II</h2>
<p>With only what we've learned in part&nbsp;I, you could figure out reciprocals, cube roots, and square roots on your own. So I'll leave those for the end and start with the less obvious exp2 and log2.</p>
<p>If we could get the mantissa bits into the exponent, we'd get exp2 for free. But how would we actually do that? We want the number 1 to map to the number 2, 2 -&gt; 4, and so on. Let's look at the bit representation.</p>
<pre><code>┌value┬─exponent──┬exp val┐
│  1  │ 0111 1111 │  127  │
│  2  │ 1000 0000 │  128  │
│  4  │ 1000 0001 │  129  │
│  8  │ 1000 0010 │  130  │
│ 16  │ 1000 0011 │  131  │
└─────┴───────────┴───────┘
</code></pre>
<p>So we want the first 8 bits of the mantissa to be the input number + 127. For this we need to be at the order of magnitude where changing the 8th mantissa bit moves the value of the float by 1. That order of magnitude is 256. Then we need to add 127, which gets us 383.</p>
<p>Let's try adding 383 to our input and shifting left by 8 bits, making sure to negate the number because we just shifted a bit into the sign of our float.</p>
<pre><code>fn exp2_approx(x: f32) -&gt; f32 {
  -f32::from_bits((x + 383.).to_bits() &lt;&lt; 8)
}</code></pre>
<p><img src="https://static2.mtlws.ca/exp2_approx.png" alt=""></p>
<p>It works!</p>
<p>To do log2 we just do the reverse: shift the exponent into the mantissa, set the order of magnitude to 256 and then subtract 383.</p>
<pre><code>fn log2_approx(x: f32) -&gt; f32 {
	f32::from_bits((x).to_bits() &gt;&gt; 8 | 256_f32.to_bits()) - 383.
}</code></pre>
<p><img src="https://static2.mtlws.ca/log2_approx.png" alt=""></p>
<p>Boom! Easy as that.</p>
<p>For completeness here's the remaining functions we've talked about:</p>
<pre><code>fn cbrt_approx(x: f32) -&gt; f32 {
	f32::from_bits(0x2a4ddef1 + (x.to_bits() / 3))
}

fn sqrt_approx(x: f32) -&gt; f32 {
	f32::from_bits(0x1FBD22DF + (x.to_bits() &gt;&gt; 1))
}

fn rcp_approx(x: f32) -&gt; f32 {
	f32::from_bits(0x7EEF370B - x.to_bits())
}

fn rsqrt_approx(x: f32) -&gt; f32 {
	f32::from_bits(0x5F33E79F - (x.to_bits() &gt;&gt; 1))
}</code></pre>
<figure>
          <figcaption>Approximate Cube Root</figcaption>
          <img loading="lazy" src="https://static2.mtlws.ca/cbrt_approx.png" class="img-adapt-dark" alt="" width="480" height="480">
        </figure>
<figure>
          <figcaption>Approximate Square Root</figcaption>
          <img loading="lazy" src="https://static2.mtlws.ca/sqrt_approx.png" class="img-adapt-dark" alt="" width="480" height="480">
        </figure>
<figure>
          <figcaption>Approximate Reciprocal</figcaption>
          <img loading="lazy" src="https://static2.mtlws.ca/rcp_approx.png" class="img-adapt-dark" alt="" width="480" height="480">
        </figure>
<figure>
          <figcaption>Approximate Reciprocal Square Root</figcaption>
          <img loading="lazy" src="https://static2.mtlws.ca/rsqrt_approx.png" class="img-adapt-dark" alt="" width="480" height="480">
        </figure>
<p>In <strong>Part&nbsp;III</strong>, we're learning how to make these crude approximations usably accurate!</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 7<sup>th</sup> - <strong>What I Always Put in my CSS</strong></summary>
      <article>
        <h2>What I Always Put in my CSS</h2>
<p>I like when websites look like websites. Blue links that turn purple after you've clicked them, serif fonts for body text, text that doesn't have a seizure as the page is loading. But I'm not a <em>barbarian</em>. Even I have a few beefs with the default browser styles.</p>
<h3>Absolute Unit Line Height</h3>
<p>No matter the font size you use for different elements, the line height stays consistent. You don't break the baseline grid unless you explicitly decide to.</p>
<pre><code>html {
  line-height: 23px;
}
</code></pre>
<h3>Default Border Color</h3>
<p>I don't have to manually set the border color on each individual element. I can just set the border width and it gets a default color.</p>
<pre><code>* {
  border: solid 0;
  border-color: inherit;
}</code></pre>
<h3>Disabled Dingbats</h3>
<p>If I use text as decoration, like decorative bullets or separators. I make sure that selecting and copying the text doesn't include the decorations.</p>
<pre><code>[aria-hidden="true"] {
  user-select: none;
}</code></pre>
<h3>Never Abandon the Orphans</h3>
<pre><code>h1, h2, h3, h4, h5, h6 {
  text-wrap-style: balance;
}
p {
  text-wrap-style: pretty;
}</code></pre>
<h3>Good Helvetica</h3>
<p>I prefer serif fonts for copy, and I use <code>system-ui</code> for web apps, as one should. But if I want to use a sans-serif font, I <em>never</em> use <code>sans-serif</code>. <code>sans-serif</code> exposes your visitors to the horrors of Helvetica and Arial.</p>
<p>Luckily, most platforms have a font designed specifically to be a good version of Helvetica. Apple devices have Helvetica Neue, Google devices have Roboto, desktop Linux has Noto. Windows has... well, it has Segoe UI, which you get via <code>system-ui</code>.</p>
<pre><code>font-family: 'Helvetica Neue', Roboto, 'Noto Sans', system-ui, sans-serif</code></pre>
<h3>Make Wide Elements Scrollable</h3>
<p>To prevent them being cut-off on smaller screens</p>
<pre><code>pre, table {
  overflow-x: auto;
  max-width: 100%;
}</code></pre>
<div role="separator" class="⁂"></div>
<p>Support dark and light mode with a single line of code. No need to make custom styles!</p>
<pre><code>html {
  color-scheme: light dark;
}</code></pre>
<p>Make margins match the line height.</p>
<pre><code>p, ol, ul, h1, h2, h3, h4, h5, h6, blockquote {
  margin-block: 1lh;
}</code></pre>
<p>Prevent <code>&lt;sub&gt;</code> and <code>&lt;sup&gt;</code> from messing with the line height.</p>
<pre><code>sub, sup {
  line-height: 0;
}</code></pre>
<p>Automatically keep aspect ratio when you change the width.</p>
<pre><code>img, video {
  height: unset
}</code></pre>
<p>Flexbox items have <code>min-width:auto</code>, which means items refuse to shrink below their content size. <code>0</code> is a much better default.</p>
<pre><code>* {
  min-width: 0;
  min-height: 0;
}</code></pre>
      </article>
    </details></li>
    <li><details>
      <summary>April 8<sup>th</sup> - <strong>Sleepmaxxing</strong></summary>
      <article>
        <h2>Sleepmaxxing</h2>
<p>I used to think that all I needed to maximize my sleep was widely known and on the first page of google, but now I've gotten to the point where obscure and original methods probably contributed to my sleep quality more than the obvious ones.</p>
<h3>The Obvious</h3>
<p>Sleeping at the same time every night, even weekends, is non-negotiable. Winding down before bed is also important. Not eating before bed also helps (I have my last meal 4 hours before). Exercise makes me sleep a bit better but it isn't load-bearing. Other sleep tips haven't helped me enough to rule out placebo: avoiding blue light, melatonin, white noise.</p>
<h3>Blackout Curtains ++</h3>
<p>Regular blackout curtains leave a gap and light bounces between the wall and the curtain, leaking light into the room. Dark colored curtains aren't enough, as the light bounce is <a href="https://en.wikipedia.org/wiki/Specular_reflection" target="_blank">specular</a>. You want velvet, or <a href="https://www.musoublack.com/collections/fabrics" target="_blank">Musou&nbsp;Black fabric</a>, if you're fancy. You also want to make a flexible gasket at the bottom of the window frame, again with black felt, unless your curtains go all the way to the floor, that's the key.</p>
<h3>Mobility</h3>
<p>I've been moving every single joint in my body through its entire range of motion every single day. Just moving them, no holding stretches. Since then, I never feel achy, I'm more flexible, more agile. I can confidently do novel physical things without warming up and I never get hurt doing a weird movement (especially when I sleep). The best thing I ever did for my fitness in general, better than stretching and lifting weights.</p>
<p>The biggest surprise was the effect on sleep! Holy shit! More significant improvement than even the blackout curtains. It takes about 10 minutes, and since doing it daily, I spend 30 minutes less in bed from sleeping better. It's free! This bit deserves its own dedicated article which I will post soon.</p>
<h3>Less Could Be More</h3>
<p><a href="https://pubmed.ncbi.nlm.nih.gov/3563247/" target="_blank">Oversleeping is a real thing</a>. Spending too much time in bed makes you sleep more lightly and gives you insomnia because you don't have enough sleep pressure built up. Poor sleep, even lots of it, can lead to being more tired and feeling even more symptoms of sleep deprivation, convincing you that you need more sleep, and making the problem worse.</p>
<p>This was probably my biggest problem. I was spending 10-12 hours in bed, taking naps, and had horrible insomnia and the WORST sleep. Sleeping less fixed me.</p>
<h3>Firmer Mattress but with More <a href="https://knowyourmeme.com/memes/more-dakka" target="_blank">Dakka</a></h3>
<p>Sounds silly, but try sleeping on a yoga mat or a rug. It'll take a few days to adapt, but you might get better sleep. I know I did, but it's weird enough that I don't trust it'll work on everyone.</p>
<h3>Being Slightly Overweight Can be Surprisingly Bad for You</h3>
<p>I was only 20 pounds overweight. I didn't even think I was overweight.
          I thought I had just lost the genetic lottery and just had acid reflux
          and sleep apnea for no reason. Well, turns out losing 20 pounds fixed both.</p>
<h3>Piss Management</h3>
<p>I learned that drinking too <em>little</em> can also make you pee more. Urine that is too concentrated irritates your bladder. Try drinking more water if you think you have a naturally small bladder, you might not have a small bladder at all. I didn't. You might also just wake up in the middle of the night simply from habit. Just going back to sleep without peeing for a few days might reset you.</p>
<div role="separator" class="⁂"></div>
<p>I fixed my sleep by sleeping less, on the floor, after drinking more water in order to pee less. If someone told me all this two years ago I would've blocked them. Do not trust me. I am not a doctor.</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 9<sup>th</sup> - <strong>The Laziest Strength Program that Works</strong></summary>
      <article>
        <h2>The Laziest Strength Program that Works</h2>
<p>Most people who don't do strength training think that they don't have the time or energy. Well good news! Being incredibly lazy gets you 80% of the benefits of spending hours in the gym, being sore, and using willpower. With this method, there is no sacrifice, you just get stronger with no downside.</p>
<h3>No Friction</h3>
<p>Find exercises that require 0 equipment. Not even a clean floor. You want something you can do literally anywhere, including at work. There has to be no excuse not to do them. Everyone has a few seconds of downtime every day.</p>
<p>You want exercises that you can do as someone completely untrained and keep doing as you get very strong with minor changes. The ultimate hack is unilateral exercises. You can assist yourself with the other side of your body and give yourself any level of resistance you need.</p>
<h3>Leg &amp; Hip Extension</h3>
<p>Pistol squats. Assist yourself with your other leg to make them as easy as you want when you're starting out.</p>
<h3>Pushing</h3>
<p>One arm wall pushup. Better than regular pushups because you can do them in public places without putting your hands on the dirty floor. You can progress slowly by helping yourself with the other hand.</p>
<h3>Pulling</h3>
<p>This one doesn't have a name so I'm calling it the "one-arm wall lat press". Progress by standing further from the wall.</p>
<figure>
          <img src="https://static2.mtlws.ca/latpress.png" style="width:200px" loading="lazy" alt="" width="415" height="480">
        </figure>
<p>Self-resisted curl: grab your thigh above your knee and curl it. You can control the resistance by flexing your hamstring/glute.</p>
<h3>Hamstrings</h3>
<p>While sitting, press the backs of your calves into the legs of the chair as hard as you can. That's it. You can do this during a meeting and nobody will ever know. Unless you make weird faces.</p>
<h3>Abs</h3>
<p>Lie on your back with your legs pointed straight at the ceiling. Raise your hips off the ground by contracting your abs, pushing your feet toward the ceiling. You can do this in bed before sleeping or after waking up. You don't even have to get up. What's lazier than that?</p>
<h3>The Program</h3>
<p>Do half the exercises one day and half the other day. Just do one set, you'll make progress anyway.</p>
<p>But here's what'll actually happen: you'll want to do more, because you've removed every reason not to. No gym. No time. No willpower. Just get a little stronger every day, for free.</p>
      </article>
    </details></li>
    <li>April 10<sup>th</sup> - <strong><a href="https://graphics-programming.org/blog/ordered-dithering-is-useful-and-good" target="_blank">Ordered Dithering is Useful and Good</a></strong> - graphics-programming.org</li>
    <li hidden=""><details>
      <summary>April 10<sup>th</sup> - <strong><a href="https://en.wikipedia.org/wiki/Ordered_dithering" target="_blank">Ordered Dithering</a> is Useful and Good</strong></summary>
      <article>
        <h2><a href="https://en.wikipedia.org/wiki/Ordered_dithering" target="_blank">Ordered Dithering</a> is Useful and Good</h2>
<p>Dithering is the old trick of using patterns to fake more colors than you actually have.
If you've ever noticed the crosshatch pattern in old video games, that's ordered dithering.
It uses a repeating grid called a Bayer Matrix. It's carefully constructed so that adjacent
values are as far apart as possible, which maximally spreads error. Modern game
developers, in their infinite wisdom, have decided that this mathematical perfection is
a problem to be fixed. The regular pattern is too noticeable, they say. Instead they make
a fancy precomputed texture that has the same properties but with no regular pattern: Blue Noise.</p>
<p>Sure, blue noise looks great. But somewhere along the way we forgot why we're dithering in the
first place: to save memory. If you need a texture lookup to do dithering, you're spending
bandwidth to save bandwidth, it makes no sense. Ordered dithering is just 18 instructions
to compute from scratch.</p>
<pre><code class="language-glsl">float dither256x256(uvec2 fragCoord){
  uint x = fragCoord.x ^ fragCoord.y;
  uint y = fragCoord.y;
  uint z = x &lt;&lt; 16 | y;
  z |= z &lt;&lt; 12;
  z &amp;= 0xF0F0F0F0u;
  z |= z &gt;&gt; 6;
  z &amp;= 0x33333333u;
  z |= z &lt;&lt; 3;
  z &amp;= 0xaaaaaaaau;
  z  = z &gt;&gt; 9 | z &lt;&lt; 6;
  z &amp;= 0x7fffffu;
  return uintBitsToFloat(
    floatBitsToUint(1.) | z
  ) - 1.5; // or -1.0 if you want 0..1
           // instead of -0.5..0.5
}
</code></pre>
<p>I came up with this independently around 2016. I found recently that the general idea of
interleaving and reversing bits was first described
<a href="https://bisqwit.iki.fi/story/howto/dither/jy/" target="_blank">here</a>. But I'm
the first person to make this optimized implementation. Which is probably why it hasn't caught on yet.</p>
<p>When you're doing graphics programming, fast dithering should always be in your metaphorical
tool belt. You should <em>never</em> reach for higher bit depth without having first tried
dithering. Here's an example of how even rgb8 is overkill. This is a comparison between
rgb8 and rgb453. Can you tell which one is which?</p>
<p><style>
  #img-bitdepth-1:not(#bitdepth-1:checked ~ #img-bitdepth-1),
  #img-bitdepth-2:not(#bitdepth-2:checked ~ #img-bitdepth-2){
    display: none;
  }
</style>
</p><figure>
  <label for="bitdepth-1">Bit Depth 1</label>
  <input type="radio" checked="" name="quantization" id="bitdepth-1">
  <label for="bitdepth-2">Bit Depth 2</label>
  <input type="radio" name="quantization" id="bitdepth-2">
  <img loading="lazy" src="https://static2.mtlws.ca/rgb453.png" alt="" id="img-bitdepth-1" width="640" height="360">
  <img loading="lazy" src="https://static2.mtlws.ca/original.png" alt="" id="img-bitdepth-2" width="640" height="360">
</figure><p></p>
<p>Now here's without the dithering:</p>
<figure>
  <img loading="lazy" src="https://static2.mtlws.ca/rgb453nodither.png" alt="" width="640" height="360">
</figure>
<p>This is how huge the difference is!
You're throwing away half your ram by not dithering all your buffers.</p>
<h3>Not Just for Quantization</h3>
<p>You can (and should) use Bayer Matrices everywhere you would use random sampling,
like for picking ray directions for lighting.</p>
<figure>
  <img loading="lazy" src="https://static2.mtlws.ca/ibl-1s.png" alt="" width="640" height="360">
  <figcaption>One sample per pixel<br>Noise on the left, Bayer Matrix on the right</figcaption>
</figure>
<p>At only one sample per pixel, you can see how the Bayer Matrix grain could 
easily be smoothed with a light blur. The noise grain has no chance.</p>
<figure>
  <img loading="lazy" src="https://static2.mtlws.ca/ibl-8s.png" alt="" width="640" height="360">
  <figcaption>8 samples per pixel<br>Noise on the left, Bayer Matrix on the right</figcaption>
</figure>
<p>At eight samples per pixel, the Bayer Matrix sampling looks smooth already
while the noise sampling still looks rough.</p>
<p>Blurring white noise just gets you a splotchy mess, which you have to fix
by doing more samples, or a wider blur. Choosing to use white noise is the
dead raccoon in the river that makes everything downstream shit itself.</p>
<p>For temporal effects, you can also use the 1D equivalent of a bayer matrix:
reversing the bits for the index of the current frame, which gives this pattern:</p>
<figure>
  <img loading="lazy" src="https://static2.mtlws.ca/1d.png" alt="" width="640" height="360">
</figure>
<hr>
<p>With technological progress, as pixel densities get higher and higher,
dither patterns become harder and harder to see and vram gets more and more
strained. Ordered dithering isn't just the past, it's the future as well!</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 11<sup>th</sup> - <strong>Miscellaneous Quick Thoughts</strong></summary>
      <article>
        <h2>Miscellaneous Quick Thoughts</h2>
<h3>Dailies</h3>
<p>Being able to do something every day is mandatory for so many things to work: exercise, vitamins, brushing your teeth, learning a skill. Without a checklist, new habits don't happen. You do them for three days, forget on the fourth, and never come back. It's not a willpower issue. It's a systems issue.</p>
<p>A checklist turns intention into something real. There's an empty box. You check it. Make it really real. Apps don't stare you down all day. Put a piece of paper on your wall.</p>
<h3>Self-Throttling Snacks for Pareto Optimal Delight to Weight-Loss Ratio</h3>
<ul>
<li><strong>pretzels:</strong> eat too many and they start tasting like dehydration</li>
<li><strong>pineapples:</strong> they dissolve your tongue 🥰</li>
<li><strong>jerky:</strong> makes your jaw hurt</li>
</ul>
<h3>Running Up the Stairs</h3>
<p>I started running up the stairs as fast as possible, every time. I save time by missing the bus less. My cardio is also so much better. Free lunch.</p>
<h3>Raid 1 is Underrated</h3>
<p>Double the read speed <em>and</em> redundancy?</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 12<sup>th</sup> - <strong>You aren't supposed to <em>finish</em> a todo list</strong></summary>
      <article>
        <h2>You aren't supposed to <em>finish</em> a todo list</h2>
<blockquote>
<p><em>Life is not a problem to be solved, but a reality to be experienced.</em><br>― Soren Kierkegaard</p>
</blockquote>
<h2>You aren't supposed to <em>finish</em> a todo list</h2>
<p>Humans like progress. So we get satisfaction from our todo list getting shorter. But this creates a bad incentive: adding a task makes the list longer, which feels like regression. So you stop adding things. And forget them.</p>
<p>Cross off finished items, leaving them visible. Now the number you're optimizing is tasks done, not tasks remaining. Adding tasks becomes an opportunity instead of a burden.</p>
<h3>Friendly Problems</h3>
<p>Don't hesitate to add trivial tasks. Like taking a walk or making tea. Everything deserves to be on there. You're collecting achievements, the more the better. Finishing easy tasks builds momentum. It turns chores into a fun game.</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 13<sup>th</sup> - <strong>Excuses are Todos</strong></summary>
      <article>
        <h2>Excuses are Todos</h2>
<blockquote>
<p><em>The impediment to action advances action, what stands in the way becomes the way.</em><br>― Marcus Aurelius</p>
</blockquote>
<h2>Excuses are Todos</h2>
<p>An excuse is a todo item with a bad attitude.</p>
<p>"I'd start a blog but I don't know how to set up a website." Not knowing how to set up a website isn't an immutable fact about the universe. That's a thing you can fix by learning how to set up a website. That's a todo. "I'd eat better but I don't know how to cook." Same thing. The excuse contains the solution. Todo.</p>
<p>Now the meta-reason why you don't learn HTML and cooking is probably that you don't have the time or energy right now. That's the beauty of a todo: when you catch yourself saying "I can't because X", you write down "fix X". You have no obligation to fix X. It's just there in case you're bored or motivated one day in the future.</p>
<p>Can't fix X because of Y? That's just another todo. Can't fix Y because of Z? Write that down too. You've turned moaning into a step-by-step plan.</p>
<p>Found something outside your control? You've still made progress. You found out that your real reason was further down the chain. You can file the task under "impossible" and forget about it instead of filing it under "I'm too lazy" and letting it nag at you.</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 14<sup>th</sup> - <strong>Flicker</strong></summary>
      <article>
        <h2>Flicker</h2>
<p>wearing faces stitched from others<br>playing parts we barely know</p>
<p>building walls with politeness<br>filling gaps with white noise</p>
<p>shallow prayers rarely answered<br>arms outstretched but never touching</p>
<p>pressing our palms to the glass<br>searching for a pulse behind the glow</p>
<p>under the electric delirium of neon rain<br>we stand, mouths open</p>
<p>we mistake the flicker for warmth<br>mistake the warmth for love</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 15<sup>th</sup> - <strong>Everything is Awesome</strong></summary>
      <article>
        <h2>Everything is Awesome</h2>
<p>We're so focused on not feeling bad emotions that we forget to feel good ones. Zero isn't the goal. A positive number is the goal.</p>
<p>Nothing is too mundane to make you overjoyed. Imagine a child seeing a grocery store for the first time. Imagine them seeing a gym, which is basically a playground for adults. Hamsters run in their wheel for fun, and we're so bored by running on a treadmill that we have to watch TV. But when you stop and think about it, those things are AWESOME. Yes, <em>awesome</em>, as in, something that inspires awe.</p>
<p>We've collectively stopped looking out the airplane window in amazement. Instead we're annoyed at the crying baby, the most miraculous thing on the plane. Complaining about the bad food, while ignoring the magic of the global supply chain that put it on our tray.</p>
<p>Be the kind of person who shrugs off the bad things and gets genuine, childlike joy from the things everyone else finds mundane. Be the kind of person who gets so excited about the tofu in their fridge not being expired that they text their friend about it. Be the kind of person who thinks the last snow of the winter is as beautiful as the first. Look out the window. Isn't it awesome?</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 16<sup>th</sup> - <strong>Price per Year</strong></summary>
      <article>
        <h2>Price per Year</h2>
<p>Most people's spending intuitions are backwards. They'll price compare for $50-100 jeans, then sleepwalk into a 1k/year higher car payment. One of these decisions matters. It's not the jeans.</p>
<p>When you budget, always multiply by frequency. A $5 daily coffee is a $1,825 annual expense. A $200 pair of boots you buy every two years is a $100 yearly expense. Sure, they both bring you joy. One of them just costs 18 times more. Daily and monthly expenses are where fortunes are quietly made or lost.</p>
<p>The cheap shoes that hurt your feet? A bad mattress or a slow laptop that you use eight hours a day? For a $100 saving per year? Saving 10% on groceries and rent will save you thousands yearly.</p>
<p>Negotiate, optimize, and shop around <em>hard</em> for frequent expenses. Consider big lifestyle changes. Those things will compound over years and improve your quality of life. And the nicer boots will too.</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 17<sup>th</sup> - <strong>How to Make a Floating&nbsp;Point Math Library, Part&nbsp;III</strong></summary>
      <article>
        <h2>How to Make a Floating&nbsp;Point Math Library, Part&nbsp;III</h2>
<p>In Parts I and II we built approximations for <code>exp2</code>, <code>log2</code>, <code>sqrt</code>, <code>rsqrt</code>, <code>cbrt</code>, and <code>rcp</code>. They get the order of magnitude right, which is crucial for floating&nbsp;point, but they're off by a few percent, which is useless for most things.</p>
<p>The next few installments are about <a href="https://en.wikipedia.org/wiki/Numerical_analysis" target="_blank">numerical analysis</a>, a field of math dedicated to approximating transcendental functions with elementary functions (which have CPU instructions). I'm skipping past most of the theory and focusing on software tools that do the math for us.</p>
<h4>Numerical Analysis Part&nbsp;I: Iterative Refinement</h4>
<p>Back to the Quake III reciprocal square root. We're looking at the part after the bit hacking.</p>
<pre><code class="language-c">float Q_rsqrt( float number )
{
  long i;
  float x2, y;
  const float threehalfs = 1.5F;

  x2 = number * 0.5F;
  y  = number;
  i  = * ( long * ) &amp;y;
  // evil floating&nbsp;point bit level hacking
  i  = 0x5f3759df - ( i &gt;&gt; 1 );
  // what the fuck?
  y  = * ( float * ) &amp;i;
  y  = y * ( threehalfs - ( x2 * y * y ) );
  // 1st iteration
//  y  = y * ( threehalfs - ( x2 * y * y ) );
  // 2nd iteration, this can be removed

  return y;
}</code></pre>
<p>The idea: you have a cheap, bad guess at <code>f(x)</code>. You also have a formula that turns that guess into a better one. Apply the formula until the guess is accurate enough.</p>
<p>If you stare at the math, you can kinda tell what it's doing. <code>x2 * y * y</code> is <code>0.5 * x / sqrt(x) / sqrt(x)</code>, and <code>x / sqrt(x) / sqrt(x) == 1</code>. Because we only have a bad approximation of <code>1/sqrt(x)</code>, our <code>1</code> is the error between the true value and the approximate value. The rest of the formula scales it, since the error we have is on the <em>square</em> of <code>f(x)</code>, not <code>f(x)</code> itself. We can't get the error of <code>f(x)</code> directly without knowing the ground truth, which is what we're trying to compute in the first place, so this is also an approximation. Hence the iterations.</p>
<p>There's a systematic way to derive the iteration formula: <a href="https://en.wikipedia.org/wiki/Newton%27s_method" target="_blank">Newton's method</a>.</p>
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block" style="margin-bottom:1lh">
  <msub><mi>x</mi><mrow><mi>n</mi><mo>+</mo><mn>1</mn></mrow></msub>
  <mo>=</mo>
  <msub><mi>x</mi><mi>n</mi></msub>
  <mo>+</mo>
  <mfrac>
    <mrow>
      <mo>(</mo><mn>1</mn><mo>/</mo><mi>f</mi><mo>)</mo>
      <mo>(</mo><msub><mi>x</mi><mi>n</mi></msub><mo>)</mo>
    </mrow>
    <mrow>
      <mo>(</mo><mn>1</mn><mo>/</mo><mi>f</mi><msup><mo>)</mo><mo>′</mo></msup>
      <mo>(</mo><msub><mi>x</mi><mi>n</mi></msub><mo>)</mo>
    </mrow>
  </mfrac>
</math>
<p>Here <code>(1/f)(x)</code> means <code>1/f(x)</code>, and <code>′</code> means the derivative of the function.</p>
<p>You can see it takes the guess and steps in the direction of the derivative until it hits zero.</p>
<p>For <code>y = 1/sqrt(x)</code>, the function whose zero we want is <code>1/((1/y)^2-x)</code>, with derivative <code>(2 y)/(x y^2 - 1)^2</code>. Putting it together gives a giant mess that thankfully simplifies to <code>y' = y * ( 3/2 - ( x/2 * y * y ) )</code>, the exact formula from <code>Q_rsqrt</code>.</p>
<p>Newton's method is part of a family called <a href="https://en.wikipedia.org/wiki/Householder%27s_method" target="_blank">Householder's method</a>, which uses higher-order derivatives (derivatives of derivatives) in the numerator and denominator. Using a second order derivative is also called Halley's method. Higher-order derivatives give a better guess per iteration, so you need fewer, but each iteration costs more. Which one to use depends. Trial and error.</p>
<p>Deriving these by hand is a pain, so let the computer do it using <a href="https://www.wolfram.com/wolframscript/" target="_blank">WolframScript</a>, the language behind Wolfram Alpha and Mathematica.</p>
<pre><code class="language-mathematica">(* Define your function eg. CubeRoot[x] *)
g[x_] := CubeRoot[x]

inv[x_] := FullSimplify[InverseFunction[g][x], Assumptions -&gt; x &gt; 0]

f[y_] := 1/(inv[y]-x)

Print["       Newton: ", FullSimplify[y+f[y]/f'[y]]]
Print["       Halley: ", FullSimplify[y+2*f'[y]/f''[y]]]
Print["Householder 3: ", FullSimplify[y+3*f''[y]/f'''[y]]]
Print["Householder 4: ", FullSimplify[y+4*f'''[y]/f''''[y]]]</code></pre>
<p>In <strong>Part&nbsp;IV</strong> we will implement the other function and show error plots.</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 18<sup>th</sup> - <strong>Underrated Movies you should (re)Watch</strong></summary>
      <article>
        <h2>Underrated Movies you should (re)Watch</h2>
<p>Sometimes showing up is what matters most.</p>
<h2>Underrated Movies you should (re)Watch</h2>
<ul>
<li><strong>The Matrix Resurrections</strong> - Refreshingly hope-punk, especially for something set in one of the most depressing scifi universes. Genuinely my favorite Matrix movie.</li>
<li><strong>Star Wars: The Last Jedi</strong> - Ok, I agree with the consensus. Episode V is the best Star Wars movie, but The Last Jedi is my second favorite.</li>
<li><strong>Nimona</strong> - Watching this movie changed me. It explores a particular theme (no spoilers) like no other movie does.</li>
<li><strong>Snatch</strong> - Fun! Quotable! Badass!</li>
</ul>
      </article>
    </details></li>
    <li><details>
      <summary>April 19<sup>th</sup> - <strong>How to Make a Floating&nbsp;Point Math Library, Part&nbsp;IV</strong></summary>
      <article>
        <h2>How to Make a Floating&nbsp;Point Math Library, Part&nbsp;IV</h2>
<p>Square roots have a CPU instruction, so let's skip them and go straight to cube roots. Running our wolframscript gives:</p>
<pre><code>$ wolframscript -file getnewton.wls
Newton: (x + 2*y^3)/(3*y^2)
Halley: (2*x*y + y^4)/(x + 2*y^3)</code></pre>
<p>Combined with the approximation we made in Part&nbsp;II:</p>
<pre><code>fn cbrt_halley(x: f32) -&gt; f32 {
  let y = f32::from_bits(0x2a5063f7 + (x.to_bits() / 3));
  (2.*x*y + (y*y)*(y*y)) / (x + 2.*(y*y)*y)
}
fn cbrt_newton(x: f32) -&gt; f32 {
  let y = f32::from_bits(0x2a5063f7 + (x.to_bits() / 3));
  (x + 2.*(y*y)*y) / (3.*(y*y))
}</code></pre>
<p>Let's look at the accuracy.</p>
<figure>
          <figcaption>Approximation</figcaption>
          <img loading="lazy" src="https://static2.mtlws.ca/cbrt_approx_error.png" class="img-adapt-dark" alt="" width="480" height="480">
        </figure>
<figure>
          <figcaption>Newton</figcaption>
          <img loading="lazy" src="https://static2.mtlws.ca/cbrt_newton_error.png" class="img-adapt-dark" alt="" width="480" height="480">
        </figure>
<figure>
          <figcaption>Halley</figcaption>
          <img loading="lazy" src="https://static2.mtlws.ca/cbrt_halley_error.png" class="img-adapt-dark" alt="" width="480" height="480">
        </figure>
<p>Orders of magnitude better, but still not enough. Another iteration:</p>
<pre><code>fn cbrt_approx(x: f32) -&gt; f32 {
	let y = f32::from_bits(0x2a509849u32 + (x.to_bits() / 3));
	// newton iteration
	let y = (x + 2.*(y*y)*y) / (3.*(y*y));
	// halley iteration
	(2.*x*y + (y*y)*(y*y))/(x + 2.*(y*y)*y)
}</code></pre>
<figure>
          <figcaption>Newton and Halley</figcaption>
          <img loading="lazy" src="https://static2.mtlws.ca/cbrt_newton_halley_error.png" class="img-adapt-dark" alt="" width="480" height="480">
        </figure>
<p>Perfect! Our average error is under one bit. Good enough for a standard library. Now let's try with <code>log2</code>.</p>
<pre><code>g[x_] := Log[x,2]

$ wolframscript -file getnewton.wls
Newton: (y*(y - (x*y)/2^y^(-1) + Log[2]))/Log[2]</code></pre>
<p>Oh no! The iteration needs <code>2^y</code> which is <code>exp2</code>. Let's try <code>exp2</code> then:</p>
<pre><code>g[x_] := 2^x

jodiemath-rs $ wolframscript -file getnewton.wls
Newton: y*(1 + x*Log[2] - Log[y])</code></pre>
<p>And <code>exp2</code> needs <code>log2</code>. We have a bootstrapping problem. We need a different strategy: approximation theory.</p>
<p>In <strong>Part V</strong> we'll learn non-iterative approximation methods to implement exponentials and logarithms.</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 20<sup>th</sup> - <strong>Thinking is Expensive, Doing is Cheap</strong></summary>
      <article>
        <h2>Thinking is Expensive, Doing is Cheap</h2>
<p>What's more draining? Doing the thing you don't want to do, or deliberating for hours about whether to keep procrastinating?</p>
<p>When you design systems for yourself (lists, calendars, flowcharts), which bottleneck are you actually relieving?</p>
<p>All my clothes fitting together isn't about resisting bad outfits, it's about not having to pick. Having protein shakes around as a default meal isn't willpower against junk food. It's about not having to decide what to eat.</p>
<p>The idea that willpower is finite <a href="https://en.wikipedia.org/wiki/Ego_depletion" target="_blank">got popular</a>. But <a href="https://pubmed.ncbi.nlm.nih.gov/26076043/" target="_blank">nobody's measured enough of an effect to conclude that it matters at all</a>. What <em>is</em> real is that <a href="https://www.cell.com/current-biology/fulltext/S0960-9822(22)01111-3" target="_blank">thinking is tiring</a>.</p>
<h3>Discipline is Just a Plan</h3>
<p>If you want to reduce a behavior, have a plan. Have a hard rule that you follow by default. No cigarettes unless you get offered one, no dessert on weekdays, no tiktok before 5pm.</p>
<p>Following the plan keeps you in heuristic/execution mode. No thinking, you're just <em>doing</em>. The aversion to doing the thing is real but overriding it doesn't deplete your energy.</p>
<p>Not following the plan puts you in deliberation mode. Is this a legitimate reason to deviate? What will I do instead? Is "instead" better or am I just lying to myself? Will I regret this? And then you have to live with the decision, which means thinking about if it was right, which is more deliberation. You've converted a cheap execution task into an expensive meta-task about whether to execute.</p>
<h3>Grindset Considered Harmful</h3>
<p>Undisciplined people work <em>harder</em>. They're <em>more</em> exhausted.</p>
<p>They spend their thinking budget on negotiating with themselves and have little left for actual work. The prevailing idea that discipline is "grinding" and "sacrifice" is harmful and just <em>wrong</em>. People who are exhausted assume they can't do it and don't try.</p>
<p>Moral judgements about lack of discipline make the exhaustion even worse through guilt. <em>Replacing Guilt</em> by Nate Soares was one of the most influential books on my life. Without guilt, I can work hard indefinitely. Guilt is so tiring that it was my bottleneck.</p>
<p>Disciplined people don't have some mysterious extra capacity. They just skip the cost of meta-decisions and guilt-processing. A disciplined person runs in heuristic-mode all day and has their thinking budget available for real problems.</p>
<h3>Grayshirting</h3>
<p>The Mark Zuckerberg gray t-shirt is the tip of a giant grey iceberg, the most visible part of an entire lifestyle.</p>
<p>Grayshirting isn't about sameness. Zuckerberg could hire a stylist. It's about reserving thinking for what matters.</p>
<p>Grayshirt the grayshirtable. Make checklists, calendars and flowcharts for everything. Make routine routine and make the correct thing the easy thing.</p>
<h3>Even Planning can be Doing</h3>
<p>The common productivity advice of breaking big tasks into smaller chunks isn't just about small tasks feeling less daunting. Decomposition and planning <em>is</em> the hard part, once it's done the execution is often trivial.</p>
<p>The planning can also be systematic. What kind of task is this? What's the standard shape of the solution? What are the typical sub-steps? Hell, just get an AI to do it.</p>
<p>Use your thinking capacity for high level planning. For figuring out what's wrong and for the efficient way to fix it.</p>
<div role="separator" class="⁂"></div>
<p>The other day I bought a tally counter. I click it when I do what I'm supposed to immediately, instead of deliberating. Despite having the concept of "thinking is hard" in the front of my mind for years, I'm at 24 and it's not even noon. Microdecisions are everywhere.</p>
<p>Start noticing. The more you notice, the more "willpower" just happens. I guarantee you'll be less exhausted too.</p>
<p>Further reading:</p>
<ul>
<li><a href="https://jodie.website/#happiness" target="_blank">https://jodie.website/#happiness</a></li>
<li><a href="https://www.speakandregret.michaelinzlicht.com/p/the-collapse-of-ego-depletion" target="_blank">https://www.speakandregret.michaelinzlicht.com/p/the-collapse-of-ego-depletion</a></li>
</ul>
      </article>
    </details></li>
    <li>April 21<sup>st</sup> - <strong><a href="https://morewrong.jodie.website/#how-to-signal-high-agency" target="_blank">How to Signal High Agency Without Actually Doing Anything</a></strong> - MoreWrong</li>
    <li><details>
      <summary>April 22<sup>nd</sup> - <strong>In Defense of Directionless Dabbling</strong></summary>
      <article>
        <h2>In Defense of Directionless Dabbling</h2>
<p>A year of guitar makes you a mediocre guitarist. 12 months of 12 hobbies makes you 12 people in a trenchcoat.</p>
<p>The case against dabbling is that you won't get good at anything. So what? You weren't going to get good at the one thing either. You were going to quit at month four when it got boring, and then feel bad about quitting.</p>
<h3>The First Month Is the Best Month</h3>
<p>Hobbies have a honeymoon. The first time you solder something that works. The first loaf of bread that tastes delicious. The first time you touch your toes. One hobby gets you one honeymoon, 40 weeks of "I should practice" and diminishing returns. 12 hobbies gets you 12 honeymoons.</p>
<p>You'll know enough to talk to hobbyists and learn tricks from them, instead of making them explain "The Thing 101" for the thousandth time. You'll get rid of the learned helplessness of "I don't know how to do that". You'll learn the skills that generalize. After a month, guitar just teaches you more guitar.</p>
<h3>You Find the One by Trying Twelve</h3>
<p>People who stuck with a thing for twenty years didn't start with that thing. They tried stuff. Something clicked, and they kept going because they wanted to. The one thing you'll get good at is the thing you can't stop doing.</p>
<p>The goal shouldn't be to become The Bread Guy. It's finding out what being The Bread Guy feels like, and seeing if it feels like you.</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 23<sup>rd</sup> - <strong>Static</strong></summary>
      <article>
        <h2>Static</h2>
<p>in the silence between words<br>waiting for you to listen<br>a language older than language<br>the heartbeat, the first music</p>
<p>from the static, whispers<br>from the whispers, a god</p>
<p>dreaming on a blank page<br>calling it scripture<br>hiding the obvious<br>in plain view</p>
<p><a href="https://inv.thepixora.com/embed/J4A3U75qzg8?t=6" target="_blank">⣀⠄⢠⣤⠐⢀⣠⠖⠂⣀⠠⣠⡀⢀⠄⣠⠂<br>⡠⣀⠐⠄⣀⠠⣤⠂⢀⠠⣠⠐⠁⡀⣀⠄⢀⣠<br>⢀⠂⣠⠠⣀⠐⢠⣀⠄⣠⠂⡀⣠⠐⠄⢀⡠⠂</a></p>
      </article>
    </details></li>
    <li>April 24<sup>th</sup> - <strong><a href="https://morewrong.jodie.website/#rlhf-but-the-r-stands-for-rat" target="_blank">RLHF but the R Stands for Rat</a></strong> - MoreWrong</li>
    <li><details>
      <summary>April 25<sup>th</sup> - <strong>Stop Being Brave</strong></summary>
      <article>
        <h2>Stop Being Brave</h2>
<p>When something hurts, you have three options.</p>
<p><strong>Enduring</strong> is the worst of the three, and it's the one we get praised for. You stay with the pain, you feel it as much as you can. You're showing off, usually just to yourself, while using up all your energy for no payoff.</p>
<p><strong>Reframing</strong> transforms the pain into something else. The cold shower becomes invigorating. The long run becomes meditative. The boredom becomes a space to think. It works when it works. But sometimes there isn't a silver lining, and lying to yourself is just enduring, but while jumping through flaming hoops.</p>
<p><strong>Ignoring</strong> is the easiest. You don't elevate the pain into a meaningful experience. The pain is still there, technically, but you don't give a shit. Not (and this is the crucial part) in a tough way. In a silly way. Pain is just pain, man. It's not that deep.</p>
<h3>The toe-stub dance</h3>
<p>When you stub your toe, you do a little dance. You hop around, you tense your muscles, you swear. Moving while in pain is better than staying still while in pain.</p>
<p>But people pick the wrong dance move. They reach for something fun or comforting, then fail to enjoy it because they feel like shit. They can't enjoy anything. Now they're disappointed <em>and</em> they feel like shit.</p>
<h3>Instead, do something you hate.</h3>
<p>You're already uncomfortable. The dishes aren't scary anymore. The email isn't scary anymore. Nothing is scary because everything already sucks. The activation energy for hard things is temporarily zero.</p>
<p>You're going to feel like shit either way. Might as well make sure your toe didn't suffer for nothing.</p>
      </article>
    </details></li>
    <li>April 26<sup>th</sup> - <strong><a href="https://morewrong.jodie.website/#field-notes-from-the-morehouse-group-house" target="_blank">Field Notes From the MoreHouse Group House</a></strong> - MoreWrong</li>
    <li><details>
      <summary>April 27<sup>th</sup> - <strong>Fire Drill</strong></summary>
      <article>
        <h2>Fire Drill</h2>
<p>It's easy to not notice the impact a habit has, because it becomes your new normal. People go back to bad habits in moments of vulnerability. If you feel like shit, and you do the habit that makes you feel like shit, you won't feel the difference. You'll go back to the old habits without noticing it's hurting you.</p>
<p>So schedule a deliberate day of self destruction. Go back to all your bad habits.</p>
<p>Bad habits aren't addictions. The habit's badness is the whole experience. There's no hit to hook you back in. Stay up till 4am! Skip the gym! Have terrible posture! The crucial part is that you need to do this when you are mentally healthy and feeling great.</p>
<p>The reasons won't be theoretical anymore. You'll know, from your lizard brain to your superego, that you <em>actually do not want to</em>.</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 28<sup>th</sup> - <strong>Hunger is the best spice</strong></summary>
      <article>
        <h2>Hunger is the best spice</h2>
<p>Food tastes better when you're hungry. Even the most delicious meal is painful to eat if you're full. You already know this. The interesting case is how it generalizes to time.</p>
<h3>Infinite hours are worth nothing per hour.</h3>
<p>When I had unlimited free time, I got nothing done. Whole afternoons evaporated. The hours weren't valuable because they were infinite.</p>
<p>Then I went back to school and took on more contract work. I expected my hobbies to suffer.</p>
<p>The opposite happened. I started shipping. Two free hours after a working day produced more than two days of fucking around.</p>
<p>Quit your job to write the novel and the novel never gets written. There's too much food. Now you're not hungry enough to eat. Make the meal smaller. You'll taste it.</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 29<sup>th</sup> - <strong>Improve by Giving Up</strong></summary>
      <article>
        <h2>Improve by Giving Up</h2>
<p>Diminishing returns are often only diminishing returns in your current paradigm. There's a breakthrough waiting, but you <em>won't</em> find it by doing the same thing more. Go do something else.</p>
<p>A trick from painting could help you with computer graphics. Beatboxing can teach you something about image compression. The insight doesn't even have to come from the thing itself, just the change of frame. People famously get breakthroughs from walking, meditating, sleeping.</p>
<p>The most influential math people had incredible breadth: John von Neumann, Gauss, Euler. The most prolific living mathematician is Terence Tao and he does <em>everything</em>. Name an influential math discovery that <em>didn't</em> come from cross-pollination.</p>
<p>When you hit a wall, stop pushing. Go around it.</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 30<sup>th</sup> - <strong>Inkhaven Recap</strong></summary>
      <article>
        <h2>Inkhaven Recap</h2>
<p>I'm surprised I succeeded. I didn't take this seriously, and I know when to quit. I got way more out of this than I thought. Writing is easy now. If I have an important idea to share, I can just share it. I don't have to get over the hump of not wanting to do something hard and time consuming.</p>
<h3>Insights</h3>
<p>The cliché is true: writing helps you think. A post that doesnt ramble forces the idea to be clear.</p>
<p>The clearer the idea, the faster the writing, and the better the post. The thinking is the hardest. The writing does itself.</p>
<p>I always felt like an impostor caling myself a blogger. Yeah, I am a blogger, as much as I'm a programmer.</p>
<p>No amount of good writing can save a bad idea. And vice versa.</p>
<p>I was certain I would run out of things to say. Now I have a longer backlog than when I started. Don't wait for ideas. The ideas come from the doing.</p>
<h3>Subjects</h3>
<figure>
    <img loading="lazy" style="background:white" src="./inkhaven-subjects.svg" alt="57% life, 17% math, 13% satire, 10% poetry, 3% webdev" width="428" height="320">
</figure>
<h3>Tier List</h3>
<dl class="tierlist">
  <dt style="background:#FF7F7F">S</dt>
  <dd>
    <ul>
      <li>Everything is Awesome</li>
      <li>Thinking is Expensive, Doing is Cheap</li>
      <li>RLHF but the R Stands for Rat</li>
    </ul>
  </dd>  <dt style="background:#FFBF7F">A</dt>
  <dd>
    <ul>
      <li>Animal Welfare is a Culinary Problem</li>
      <li>Excuses are Todos</li>
      <li>Price per Year</li>
      <li>How to Signal High Agency Without Doing Anything</li>
      <li>In Defense of Directionless Dabbling</li>
      <li>Stop Being Brave</li>
      <li>Hunger is the best spice</li>
      <li>Improve by Giving Up</li>
    </ul>
  </dd>  <dt style="background:#FFDF7F">B</dt>
  <dd>
    <ul>
      <li>Dust</li>
      <li>Use Your Phone Less by Making It More Fun</li>
      <li>What I Always Put in my CSS</li>
      <li>Sleepmaxxing</li>
      <li>Ordered Dithering is Useful and Good</li>
      <li>You aren't supposed to finish a todo list</li>
      <li>Fire Drill</li>
    </ul>
  </dd>  <dt style="background:#FFFF7F">C</dt>
  <dd>
    <ul>
      <li>How to Leverage EAs to Fix Bay Area Housing</li>
      <li>Floating Point Math Library, Part I</li>
      <li>Floating Point Math Library, Part II</li>
      <li>The Laziest Strength Program that Works</li>
      <li>Flicker</li>
      <li>Floating Point Math Library, Part III</li>
      <li>Floating Point Math Library, Part IV</li>
      <li>Static</li>
    </ul>
  </dd>  <dt style="background:#BFFF7F">D</dt>
  <dd>
    <ul>
      <li>Miscellaneous Quick Thoughts</li>
      <li>Underrated Movies you should (re)Watch</li>
    </ul>
  </dd>  <dt style="background:#7FFF7F">F</dt>
  <dd>
    <ul>
      <li>Field Notes From the MoreHouse Group House</li>
    </ul>
  </dd>
</dl><style>
.tierlist { display: grid; grid-template-columns: 3ch 1fr; gap: .25rem; margin-bottom: 1lh}
.tierlist dt { display: grid; place-items: center; color: #000; font-weight: bold; margin: 0; }
.tierlist dd { margin: 0; }
.tierlist ul { margin: 0; padding-left: 1.5rem; }
</style>
<h3>See You Next Year!</h3>
<p>I'm looking forward to doing this again.</p>
      </article>
    </details></li>
  </ul>]]></description>
            <link>https://jodie.website#inkhaven</link>
            <guid isPermaLink="false">https://jodie.website#inkhaven</guid>
            <category><![CDATA[life]]></category>
            <dc:creator><![CDATA[Jodie]]></dc:creator>
            <pubDate>Wed, 01 Apr 2026 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p>A friend of mine is going to this big fancy retreat called <a href="https://www.inkhaven.blog/" target="_blank">Inkhaven</a> where you write one blog post a day. And I was like "I can't do that, but I'll sure as hell try!". I don't want to spam this blog, so I'll link my daily posts down here and I'll add the best ones to the main feed later after some polish.</p>
<ul class="linklist">
    <li>April 1<sup>st</sup> - <strong><a href="https://morewrong.jodie.website/#how-to-leverage-effective-altruists-to-fix-housing" target="_blank">How to Leverage Effective Altruists to Fix Housing Prices in the Bay Area</a></strong> - MoreWrong</li>
    <li><details>
      <summary>April 2<sup>nd</sup> - <strong>Animal Welfare is a Culinary Problem</strong></summary>
      <article>
        <h2>Animal Welfare is a Culinary Problem</h2>
<p>I agree with the vegans. Factory farming is horrific. I don't need another documentary. I'm convinced.</p>
<h3>I had chicken last week.</h3>
<p>Not because I watched it get its beak cut off and felt nothing, but because I was sick with the man flu and I wanted a comforting microwave meal, and butter chicken was all I could find.</p>
<p>Most restaurants have one vegetarian option that only exists so they can say they tried. If you're a normal person who wants to eat with friends, well fuck you, you're eating fries.</p>
<p>I cook a real meal once a day. Sometimes zero. I drink a premade protein shake instead. These shakes are load-bearing to my quality of life.</p>
<h3>My body hates the obvious solution</h3>
<p>The first thing anyone suggests when you try to eat less meat is legumes. Cheap, nutritious, available.</p>
<p>They also make me fart.</p>
<p>I've tried soaking them overnight. I've tried "just push through it, your gut adapts." My gut did not adapt. I also tried soylent, the only decent vegan meal replacement shake. Similar results. Worse than the beans actually.</p>
<h3>Next time someone tells you they could never go vegan, send them a recipe.</h3>
<p>The greatest impact I've had on animal welfare is telling people that <abbr>msg</abbr> makes tofu taste good. The person who's influenced me the most isn't an activist,
          it's <a href="https://www.youtube.com/@SauceStache/videos" target="_blank">this guy on YouTube who figured out how to make vegan bacon out of rice paper</a>.</p><p>Animal welfare organizations should take a cut of their budget and put it into food science. Vegan food needs to compete with "regular" food, not be a niche specialty product. Fix the food and you get the ethics for free.</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 3<sup>rd</sup> - <strong>Dust</strong></summary>
      <article>
        <h2>Dust</h2>
<p>the ground under your feet<br>built from what ceased to be</p>
<p>each grain of sand<br>a graveyard of forgotten stars</p>
<p>your body only borrows<br>what the earth will reclaim</p>
<p>the dust will call you home<br>the ground under a stranger's feet</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 4<sup>th</sup> - <strong>How to Make a Floating&nbsp;Point Math Library, Part&nbsp;I</strong></summary>
      <article>
        <h2>How to Make a Floating&nbsp;Point Math Library, Part&nbsp;I</h2>
<p>You might have seen <a href="https://en.wikipedia.org/wiki/Fast_inverse_square_root" target="_blank">the fast inverse square root</a>. The one with the magic hex constant&nbsp;<code>0x5F3759DF</code>&nbsp;and the comment <em>"what the fuck?"</em> from the Quake&nbsp;III source. After reading this series, you'll understand how it works, and how to apply its arcane trickery to compute any transcendental function.</p>
<p>But first: what <em>is</em> a float?</p>
<p>
          <a target="_blank" href="https://en.wikipedia.org/wiki/Scientific_notation">Scientific notation</a>
          writes a number as a power of ten, multiplied by a value between 1 and 10 called the
          <em>significand</em> (or <em>mantissa</em>). Floats do the same thing in base&nbsp;2: the
          <em>exponent</em> stores ⌊log<sub>2</sub>(<em>x</em>)⌋, and the mantissa is between 1 and 2.
        </p><pre><code>┌sign┬─exponent──┬─mantissa─────────────────────┐
│ 0  │ 0000 0000 │ 000 0000 0000 0000 0000 0000 │
└────┴───────────┴──────────────────────────────┘
</code></pre>
<p><a href="https://www.h-schmidt.net/FloatConverter/IEEE754.html" target="_blank">This calculator</a> lets you flip individual bits and watch the value change. You'll get a feel for how different numbers are represented.</p>
<h3>Manipulating Floats with Integer Operations</h3>
<p>The upper bits of a float are proportional to the logarithm of its value. So integer math on the raw bits becomes log-domain arithmetic on the number itself.</p>
<pre><code>log(<em>a</em> · <em>b</em>)     = log <em>a</em> + log <em>b</em>
log(<em>a</em> / <em>b</em>)     = log <em>a</em> − log <em>b</em>
log(<em>a</em><sup><em>b</em></sup>)        = <em>b</em> · log <em>a</em>
log(√<em>a</em>)        = log(<em>a</em>) / 2
log(1/<em>a</em>)       = −log(<em>a</em>)
log(1/√<em>a</em>)      = −log(<em>a</em>) / 2</code></pre>
<p>Addition becomes multiplication. Subtraction becomes division. A right-shift by one becomes a square root… Wait… those last two are the inverse square root!</p>
<p>
          The exponent of a number can be negative (for numbers smaller than&nbsp;1). 
          Floats handle this by storing the exponent as <code>exponent + 127</code>. The "magic" constant 
          <code>0x5F3759DF</code> is just 2<sup>127/2</sup>. The integer subtract combines the
          reciprocal and the multiplication by 2<sup>127/2</sup>. Two birds, one <code>SUB</code>.
        </p><p>In <strong>Part&nbsp;II</strong>, we'll use this knowledge to implement other transcendental functions in code!</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 5<sup>th</sup> - <strong>Use Your Phone Less by Making It <em>More</em> Fun</strong></summary>
      <article>
        <h2>Use Your Phone Less by Making It <em>More</em> Fun</h2>
<p>Digital minimalism advice is usually about making your phone worse. Add friction. Greyscale the screen. Buy a flip phone.</p>
<p>You don't have to make your phone miserable to use. The terminal goal isn't "use your phone less." The goal is doing the things you actually want to do. You can read books on your phone, text your friends, write, navigate somewhere new. None of that is the problem. When your phone only has those there's no void to fill by scrolling.</p>
<h3>Remove Your Browser</h3>
<p>Most things you'd use a mobile browser for have an app. Single purpose, no distractions. To look something up, AI chatbots and Wikipedia search are usually better tools.</p>
<p>For the rare case you <em>need</em> a browser, there's <a href="https://www.mozilla.org/en-CA/firefox/browsers/mobile/focus/" target="_blank">Firefox Focus</a>. When you close it, it wipes everything. No start page, no autocomplete, no history. You can only go on websites intentionally. It doesn't keep you logged in either. Every addictive platform requires a login. No login, no slop.</p>
<h3>And it Works?</h3>
<p>Now when I pick up my phone reflexively to fill time, there's nothing to scroll. I put it down. Or I text a friend, read a book, write a blog post. No willpower. No discomfort. I never regret being on my phone.</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 6<sup>th</sup> - <strong>How to Make a Floating&nbsp;Point Math Library, Part&nbsp;II</strong></summary>
      <article>
        <h2>How to Make a Floating&nbsp;Point Math Library, Part&nbsp;II</h2>
<p>With only what we've learned in part&nbsp;I, you could figure out reciprocals, cube roots, and square roots on your own. So I'll leave those for the end and start with the less obvious exp2 and log2.</p>
<p>If we could get the mantissa bits into the exponent, we'd get exp2 for free. But how would we actually do that? We want the number 1 to map to the number 2, 2 -&gt; 4, and so on. Let's look at the bit representation.</p>
<pre><code>┌value┬─exponent──┬exp val┐
│  1  │ 0111 1111 │  127  │
│  2  │ 1000 0000 │  128  │
│  4  │ 1000 0001 │  129  │
│  8  │ 1000 0010 │  130  │
│ 16  │ 1000 0011 │  131  │
└─────┴───────────┴───────┘
</code></pre>
<p>So we want the first 8 bits of the mantissa to be the input number + 127. For this we need to be at the order of magnitude where changing the 8th mantissa bit moves the value of the float by 1. That order of magnitude is 256. Then we need to add 127, which gets us 383.</p>
<p>Let's try adding 383 to our input and shifting left by 8 bits, making sure to negate the number because we just shifted a bit into the sign of our float.</p>
<pre><code>fn exp2_approx(x: f32) -&gt; f32 {
  -f32::from_bits((x + 383.).to_bits() &lt;&lt; 8)
}</code></pre>
<p><img src="https://static2.mtlws.ca/exp2_approx.png" alt=""></p>
<p>It works!</p>
<p>To do log2 we just do the reverse: shift the exponent into the mantissa, set the order of magnitude to 256 and then subtract 383.</p>
<pre><code>fn log2_approx(x: f32) -&gt; f32 {
	f32::from_bits((x).to_bits() &gt;&gt; 8 | 256_f32.to_bits()) - 383.
}</code></pre>
<p><img src="https://static2.mtlws.ca/log2_approx.png" alt=""></p>
<p>Boom! Easy as that.</p>
<p>For completeness here's the remaining functions we've talked about:</p>
<pre><code>fn cbrt_approx(x: f32) -&gt; f32 {
	f32::from_bits(0x2a4ddef1 + (x.to_bits() / 3))
}

fn sqrt_approx(x: f32) -&gt; f32 {
	f32::from_bits(0x1FBD22DF + (x.to_bits() &gt;&gt; 1))
}

fn rcp_approx(x: f32) -&gt; f32 {
	f32::from_bits(0x7EEF370B - x.to_bits())
}

fn rsqrt_approx(x: f32) -&gt; f32 {
	f32::from_bits(0x5F33E79F - (x.to_bits() &gt;&gt; 1))
}</code></pre>
<figure>
          <figcaption>Approximate Cube Root</figcaption>
          <img loading="lazy" src="https://static2.mtlws.ca/cbrt_approx.png" class="img-adapt-dark" alt="" width="480" height="480">
        </figure>
<figure>
          <figcaption>Approximate Square Root</figcaption>
          <img loading="lazy" src="https://static2.mtlws.ca/sqrt_approx.png" class="img-adapt-dark" alt="" width="480" height="480">
        </figure>
<figure>
          <figcaption>Approximate Reciprocal</figcaption>
          <img loading="lazy" src="https://static2.mtlws.ca/rcp_approx.png" class="img-adapt-dark" alt="" width="480" height="480">
        </figure>
<figure>
          <figcaption>Approximate Reciprocal Square Root</figcaption>
          <img loading="lazy" src="https://static2.mtlws.ca/rsqrt_approx.png" class="img-adapt-dark" alt="" width="480" height="480">
        </figure>
<p>In <strong>Part&nbsp;III</strong>, we're learning how to make these crude approximations usably accurate!</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 7<sup>th</sup> - <strong>What I Always Put in my CSS</strong></summary>
      <article>
        <h2>What I Always Put in my CSS</h2>
<p>I like when websites look like websites. Blue links that turn purple after you've clicked them, serif fonts for body text, text that doesn't have a seizure as the page is loading. But I'm not a <em>barbarian</em>. Even I have a few beefs with the default browser styles.</p>
<h3>Absolute Unit Line Height</h3>
<p>No matter the font size you use for different elements, the line height stays consistent. You don't break the baseline grid unless you explicitly decide to.</p>
<pre><code>html {
  line-height: 23px;
}
</code></pre>
<h3>Default Border Color</h3>
<p>I don't have to manually set the border color on each individual element. I can just set the border width and it gets a default color.</p>
<pre><code>* {
  border: solid 0;
  border-color: inherit;
}</code></pre>
<h3>Disabled Dingbats</h3>
<p>If I use text as decoration, like decorative bullets or separators. I make sure that selecting and copying the text doesn't include the decorations.</p>
<pre><code>[aria-hidden="true"] {
  user-select: none;
}</code></pre>
<h3>Never Abandon the Orphans</h3>
<pre><code>h1, h2, h3, h4, h5, h6 {
  text-wrap-style: balance;
}
p {
  text-wrap-style: pretty;
}</code></pre>
<h3>Good Helvetica</h3>
<p>I prefer serif fonts for copy, and I use <code>system-ui</code> for web apps, as one should. But if I want to use a sans-serif font, I <em>never</em> use <code>sans-serif</code>. <code>sans-serif</code> exposes your visitors to the horrors of Helvetica and Arial.</p>
<p>Luckily, most platforms have a font designed specifically to be a good version of Helvetica. Apple devices have Helvetica Neue, Google devices have Roboto, desktop Linux has Noto. Windows has... well, it has Segoe UI, which you get via <code>system-ui</code>.</p>
<pre><code>font-family: 'Helvetica Neue', Roboto, 'Noto Sans', system-ui, sans-serif</code></pre>
<h3>Make Wide Elements Scrollable</h3>
<p>To prevent them being cut-off on smaller screens</p>
<pre><code>pre, table {
  overflow-x: auto;
  max-width: 100%;
}</code></pre>
<div role="separator" class="⁂"></div>
<p>Support dark and light mode with a single line of code. No need to make custom styles!</p>
<pre><code>html {
  color-scheme: light dark;
}</code></pre>
<p>Make margins match the line height.</p>
<pre><code>p, ol, ul, h1, h2, h3, h4, h5, h6, blockquote {
  margin-block: 1lh;
}</code></pre>
<p>Prevent <code>&lt;sub&gt;</code> and <code>&lt;sup&gt;</code> from messing with the line height.</p>
<pre><code>sub, sup {
  line-height: 0;
}</code></pre>
<p>Automatically keep aspect ratio when you change the width.</p>
<pre><code>img, video {
  height: unset
}</code></pre>
<p>Flexbox items have <code>min-width:auto</code>, which means items refuse to shrink below their content size. <code>0</code> is a much better default.</p>
<pre><code>* {
  min-width: 0;
  min-height: 0;
}</code></pre>
      </article>
    </details></li>
    <li><details>
      <summary>April 8<sup>th</sup> - <strong>Sleepmaxxing</strong></summary>
      <article>
        <h2>Sleepmaxxing</h2>
<p>I used to think that all I needed to maximize my sleep was widely known and on the first page of google, but now I've gotten to the point where obscure and original methods probably contributed to my sleep quality more than the obvious ones.</p>
<h3>The Obvious</h3>
<p>Sleeping at the same time every night, even weekends, is non-negotiable. Winding down before bed is also important. Not eating before bed also helps (I have my last meal 4 hours before). Exercise makes me sleep a bit better but it isn't load-bearing. Other sleep tips haven't helped me enough to rule out placebo: avoiding blue light, melatonin, white noise.</p>
<h3>Blackout Curtains ++</h3>
<p>Regular blackout curtains leave a gap and light bounces between the wall and the curtain, leaking light into the room. Dark colored curtains aren't enough, as the light bounce is <a href="https://en.wikipedia.org/wiki/Specular_reflection" target="_blank">specular</a>. You want velvet, or <a href="https://www.musoublack.com/collections/fabrics" target="_blank">Musou&nbsp;Black fabric</a>, if you're fancy. You also want to make a flexible gasket at the bottom of the window frame, again with black felt, unless your curtains go all the way to the floor, that's the key.</p>
<h3>Mobility</h3>
<p>I've been moving every single joint in my body through its entire range of motion every single day. Just moving them, no holding stretches. Since then, I never feel achy, I'm more flexible, more agile. I can confidently do novel physical things without warming up and I never get hurt doing a weird movement (especially when I sleep). The best thing I ever did for my fitness in general, better than stretching and lifting weights.</p>
<p>The biggest surprise was the effect on sleep! Holy shit! More significant improvement than even the blackout curtains. It takes about 10 minutes, and since doing it daily, I spend 30 minutes less in bed from sleeping better. It's free! This bit deserves its own dedicated article which I will post soon.</p>
<h3>Less Could Be More</h3>
<p><a href="https://pubmed.ncbi.nlm.nih.gov/3563247/" target="_blank">Oversleeping is a real thing</a>. Spending too much time in bed makes you sleep more lightly and gives you insomnia because you don't have enough sleep pressure built up. Poor sleep, even lots of it, can lead to being more tired and feeling even more symptoms of sleep deprivation, convincing you that you need more sleep, and making the problem worse.</p>
<p>This was probably my biggest problem. I was spending 10-12 hours in bed, taking naps, and had horrible insomnia and the WORST sleep. Sleeping less fixed me.</p>
<h3>Firmer Mattress but with More <a href="https://knowyourmeme.com/memes/more-dakka" target="_blank">Dakka</a></h3>
<p>Sounds silly, but try sleeping on a yoga mat or a rug. It'll take a few days to adapt, but you might get better sleep. I know I did, but it's weird enough that I don't trust it'll work on everyone.</p>
<h3>Being Slightly Overweight Can be Surprisingly Bad for You</h3>
<p>I was only 20 pounds overweight. I didn't even think I was overweight.
          I thought I had just lost the genetic lottery and just had acid reflux
          and sleep apnea for no reason. Well, turns out losing 20 pounds fixed both.</p>
<h3>Piss Management</h3>
<p>I learned that drinking too <em>little</em> can also make you pee more. Urine that is too concentrated irritates your bladder. Try drinking more water if you think you have a naturally small bladder, you might not have a small bladder at all. I didn't. You might also just wake up in the middle of the night simply from habit. Just going back to sleep without peeing for a few days might reset you.</p>
<div role="separator" class="⁂"></div>
<p>I fixed my sleep by sleeping less, on the floor, after drinking more water in order to pee less. If someone told me all this two years ago I would've blocked them. Do not trust me. I am not a doctor.</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 9<sup>th</sup> - <strong>The Laziest Strength Program that Works</strong></summary>
      <article>
        <h2>The Laziest Strength Program that Works</h2>
<p>Most people who don't do strength training think that they don't have the time or energy. Well good news! Being incredibly lazy gets you 80% of the benefits of spending hours in the gym, being sore, and using willpower. With this method, there is no sacrifice, you just get stronger with no downside.</p>
<h3>No Friction</h3>
<p>Find exercises that require 0 equipment. Not even a clean floor. You want something you can do literally anywhere, including at work. There has to be no excuse not to do them. Everyone has a few seconds of downtime every day.</p>
<p>You want exercises that you can do as someone completely untrained and keep doing as you get very strong with minor changes. The ultimate hack is unilateral exercises. You can assist yourself with the other side of your body and give yourself any level of resistance you need.</p>
<h3>Leg &amp; Hip Extension</h3>
<p>Pistol squats. Assist yourself with your other leg to make them as easy as you want when you're starting out.</p>
<h3>Pushing</h3>
<p>One arm wall pushup. Better than regular pushups because you can do them in public places without putting your hands on the dirty floor. You can progress slowly by helping yourself with the other hand.</p>
<h3>Pulling</h3>
<p>This one doesn't have a name so I'm calling it the "one-arm wall lat press". Progress by standing further from the wall.</p>
<figure>
          <img src="https://static2.mtlws.ca/latpress.png" style="width:200px" loading="lazy" alt="" width="415" height="480">
        </figure>
<p>Self-resisted curl: grab your thigh above your knee and curl it. You can control the resistance by flexing your hamstring/glute.</p>
<h3>Hamstrings</h3>
<p>While sitting, press the backs of your calves into the legs of the chair as hard as you can. That's it. You can do this during a meeting and nobody will ever know. Unless you make weird faces.</p>
<h3>Abs</h3>
<p>Lie on your back with your legs pointed straight at the ceiling. Raise your hips off the ground by contracting your abs, pushing your feet toward the ceiling. You can do this in bed before sleeping or after waking up. You don't even have to get up. What's lazier than that?</p>
<h3>The Program</h3>
<p>Do half the exercises one day and half the other day. Just do one set, you'll make progress anyway.</p>
<p>But here's what'll actually happen: you'll want to do more, because you've removed every reason not to. No gym. No time. No willpower. Just get a little stronger every day, for free.</p>
      </article>
    </details></li>
    <li>April 10<sup>th</sup> - <strong><a href="https://graphics-programming.org/blog/ordered-dithering-is-useful-and-good" target="_blank">Ordered Dithering is Useful and Good</a></strong> - graphics-programming.org</li>
    <li hidden=""><details>
      <summary>April 10<sup>th</sup> - <strong><a href="https://en.wikipedia.org/wiki/Ordered_dithering" target="_blank">Ordered Dithering</a> is Useful and Good</strong></summary>
      <article>
        <h2><a href="https://en.wikipedia.org/wiki/Ordered_dithering" target="_blank">Ordered Dithering</a> is Useful and Good</h2>
<p>Dithering is the old trick of using patterns to fake more colors than you actually have.
If you've ever noticed the crosshatch pattern in old video games, that's ordered dithering.
It uses a repeating grid called a Bayer Matrix. It's carefully constructed so that adjacent
values are as far apart as possible, which maximally spreads error. Modern game
developers, in their infinite wisdom, have decided that this mathematical perfection is
a problem to be fixed. The regular pattern is too noticeable, they say. Instead they make
a fancy precomputed texture that has the same properties but with no regular pattern: Blue Noise.</p>
<p>Sure, blue noise looks great. But somewhere along the way we forgot why we're dithering in the
first place: to save memory. If you need a texture lookup to do dithering, you're spending
bandwidth to save bandwidth, it makes no sense. Ordered dithering is just 18 instructions
to compute from scratch.</p>
<pre><code class="language-glsl">float dither256x256(uvec2 fragCoord){
  uint x = fragCoord.x ^ fragCoord.y;
  uint y = fragCoord.y;
  uint z = x &lt;&lt; 16 | y;
  z |= z &lt;&lt; 12;
  z &amp;= 0xF0F0F0F0u;
  z |= z &gt;&gt; 6;
  z &amp;= 0x33333333u;
  z |= z &lt;&lt; 3;
  z &amp;= 0xaaaaaaaau;
  z  = z &gt;&gt; 9 | z &lt;&lt; 6;
  z &amp;= 0x7fffffu;
  return uintBitsToFloat(
    floatBitsToUint(1.) | z
  ) - 1.5; // or -1.0 if you want 0..1
           // instead of -0.5..0.5
}
</code></pre>
<p>I came up with this independently around 2016. I found recently that the general idea of
interleaving and reversing bits was first described
<a href="https://bisqwit.iki.fi/story/howto/dither/jy/" target="_blank">here</a>. But I'm
the first person to make this optimized implementation. Which is probably why it hasn't caught on yet.</p>
<p>When you're doing graphics programming, fast dithering should always be in your metaphorical
tool belt. You should <em>never</em> reach for higher bit depth without having first tried
dithering. Here's an example of how even rgb8 is overkill. This is a comparison between
rgb8 and rgb453. Can you tell which one is which?</p>
<p><style>
  #img-bitdepth-1:not(#bitdepth-1:checked ~ #img-bitdepth-1),
  #img-bitdepth-2:not(#bitdepth-2:checked ~ #img-bitdepth-2){
    display: none;
  }
</style>
</p><figure>
  <label for="bitdepth-1">Bit Depth 1</label>
  <input type="radio" checked="" name="quantization" id="bitdepth-1">
  <label for="bitdepth-2">Bit Depth 2</label>
  <input type="radio" name="quantization" id="bitdepth-2">
  <img loading="lazy" src="https://static2.mtlws.ca/rgb453.png" alt="" id="img-bitdepth-1" width="640" height="360">
  <img loading="lazy" src="https://static2.mtlws.ca/original.png" alt="" id="img-bitdepth-2" width="640" height="360">
</figure><p></p>
<p>Now here's without the dithering:</p>
<figure>
  <img loading="lazy" src="https://static2.mtlws.ca/rgb453nodither.png" alt="" width="640" height="360">
</figure>
<p>This is how huge the difference is!
You're throwing away half your ram by not dithering all your buffers.</p>
<h3>Not Just for Quantization</h3>
<p>You can (and should) use Bayer Matrices everywhere you would use random sampling,
like for picking ray directions for lighting.</p>
<figure>
  <img loading="lazy" src="https://static2.mtlws.ca/ibl-1s.png" alt="" width="640" height="360">
  <figcaption>One sample per pixel<br>Noise on the left, Bayer Matrix on the right</figcaption>
</figure>
<p>At only one sample per pixel, you can see how the Bayer Matrix grain could 
easily be smoothed with a light blur. The noise grain has no chance.</p>
<figure>
  <img loading="lazy" src="https://static2.mtlws.ca/ibl-8s.png" alt="" width="640" height="360">
  <figcaption>8 samples per pixel<br>Noise on the left, Bayer Matrix on the right</figcaption>
</figure>
<p>At eight samples per pixel, the Bayer Matrix sampling looks smooth already
while the noise sampling still looks rough.</p>
<p>Blurring white noise just gets you a splotchy mess, which you have to fix
by doing more samples, or a wider blur. Choosing to use white noise is the
dead raccoon in the river that makes everything downstream shit itself.</p>
<p>For temporal effects, you can also use the 1D equivalent of a bayer matrix:
reversing the bits for the index of the current frame, which gives this pattern:</p>
<figure>
  <img loading="lazy" src="https://static2.mtlws.ca/1d.png" alt="" width="640" height="360">
</figure>
<hr>
<p>With technological progress, as pixel densities get higher and higher,
dither patterns become harder and harder to see and vram gets more and more
strained. Ordered dithering isn't just the past, it's the future as well!</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 11<sup>th</sup> - <strong>Miscellaneous Quick Thoughts</strong></summary>
      <article>
        <h2>Miscellaneous Quick Thoughts</h2>
<h3>Dailies</h3>
<p>Being able to do something every day is mandatory for so many things to work: exercise, vitamins, brushing your teeth, learning a skill. Without a checklist, new habits don't happen. You do them for three days, forget on the fourth, and never come back. It's not a willpower issue. It's a systems issue.</p>
<p>A checklist turns intention into something real. There's an empty box. You check it. Make it really real. Apps don't stare you down all day. Put a piece of paper on your wall.</p>
<h3>Self-Throttling Snacks for Pareto Optimal Delight to Weight-Loss Ratio</h3>
<ul>
<li><strong>pretzels:</strong> eat too many and they start tasting like dehydration</li>
<li><strong>pineapples:</strong> they dissolve your tongue 🥰</li>
<li><strong>jerky:</strong> makes your jaw hurt</li>
</ul>
<h3>Running Up the Stairs</h3>
<p>I started running up the stairs as fast as possible, every time. I save time by missing the bus less. My cardio is also so much better. Free lunch.</p>
<h3>Raid 1 is Underrated</h3>
<p>Double the read speed <em>and</em> redundancy?</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 12<sup>th</sup> - <strong>You aren't supposed to <em>finish</em> a todo list</strong></summary>
      <article>
        <h2>You aren't supposed to <em>finish</em> a todo list</h2>
<blockquote>
<p><em>Life is not a problem to be solved, but a reality to be experienced.</em><br>― Soren Kierkegaard</p>
</blockquote>
<h2>You aren't supposed to <em>finish</em> a todo list</h2>
<p>Humans like progress. So we get satisfaction from our todo list getting shorter. But this creates a bad incentive: adding a task makes the list longer, which feels like regression. So you stop adding things. And forget them.</p>
<p>Cross off finished items, leaving them visible. Now the number you're optimizing is tasks done, not tasks remaining. Adding tasks becomes an opportunity instead of a burden.</p>
<h3>Friendly Problems</h3>
<p>Don't hesitate to add trivial tasks. Like taking a walk or making tea. Everything deserves to be on there. You're collecting achievements, the more the better. Finishing easy tasks builds momentum. It turns chores into a fun game.</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 13<sup>th</sup> - <strong>Excuses are Todos</strong></summary>
      <article>
        <h2>Excuses are Todos</h2>
<blockquote>
<p><em>The impediment to action advances action, what stands in the way becomes the way.</em><br>― Marcus Aurelius</p>
</blockquote>
<h2>Excuses are Todos</h2>
<p>An excuse is a todo item with a bad attitude.</p>
<p>"I'd start a blog but I don't know how to set up a website." Not knowing how to set up a website isn't an immutable fact about the universe. That's a thing you can fix by learning how to set up a website. That's a todo. "I'd eat better but I don't know how to cook." Same thing. The excuse contains the solution. Todo.</p>
<p>Now the meta-reason why you don't learn HTML and cooking is probably that you don't have the time or energy right now. That's the beauty of a todo: when you catch yourself saying "I can't because X", you write down "fix X". You have no obligation to fix X. It's just there in case you're bored or motivated one day in the future.</p>
<p>Can't fix X because of Y? That's just another todo. Can't fix Y because of Z? Write that down too. You've turned moaning into a step-by-step plan.</p>
<p>Found something outside your control? You've still made progress. You found out that your real reason was further down the chain. You can file the task under "impossible" and forget about it instead of filing it under "I'm too lazy" and letting it nag at you.</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 14<sup>th</sup> - <strong>Flicker</strong></summary>
      <article>
        <h2>Flicker</h2>
<p>wearing faces stitched from others<br>playing parts we barely know</p>
<p>building walls with politeness<br>filling gaps with white noise</p>
<p>shallow prayers rarely answered<br>arms outstretched but never touching</p>
<p>pressing our palms to the glass<br>searching for a pulse behind the glow</p>
<p>under the electric delirium of neon rain<br>we stand, mouths open</p>
<p>we mistake the flicker for warmth<br>mistake the warmth for love</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 15<sup>th</sup> - <strong>Everything is Awesome</strong></summary>
      <article>
        <h2>Everything is Awesome</h2>
<p>We're so focused on not feeling bad emotions that we forget to feel good ones. Zero isn't the goal. A positive number is the goal.</p>
<p>Nothing is too mundane to make you overjoyed. Imagine a child seeing a grocery store for the first time. Imagine them seeing a gym, which is basically a playground for adults. Hamsters run in their wheel for fun, and we're so bored by running on a treadmill that we have to watch TV. But when you stop and think about it, those things are AWESOME. Yes, <em>awesome</em>, as in, something that inspires awe.</p>
<p>We've collectively stopped looking out the airplane window in amazement. Instead we're annoyed at the crying baby, the most miraculous thing on the plane. Complaining about the bad food, while ignoring the magic of the global supply chain that put it on our tray.</p>
<p>Be the kind of person who shrugs off the bad things and gets genuine, childlike joy from the things everyone else finds mundane. Be the kind of person who gets so excited about the tofu in their fridge not being expired that they text their friend about it. Be the kind of person who thinks the last snow of the winter is as beautiful as the first. Look out the window. Isn't it awesome?</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 16<sup>th</sup> - <strong>Price per Year</strong></summary>
      <article>
        <h2>Price per Year</h2>
<p>Most people's spending intuitions are backwards. They'll price compare for $50-100 jeans, then sleepwalk into a 1k/year higher car payment. One of these decisions matters. It's not the jeans.</p>
<p>When you budget, always multiply by frequency. A $5 daily coffee is a $1,825 annual expense. A $200 pair of boots you buy every two years is a $100 yearly expense. Sure, they both bring you joy. One of them just costs 18 times more. Daily and monthly expenses are where fortunes are quietly made or lost.</p>
<p>The cheap shoes that hurt your feet? A bad mattress or a slow laptop that you use eight hours a day? For a $100 saving per year? Saving 10% on groceries and rent will save you thousands yearly.</p>
<p>Negotiate, optimize, and shop around <em>hard</em> for frequent expenses. Consider big lifestyle changes. Those things will compound over years and improve your quality of life. And the nicer boots will too.</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 17<sup>th</sup> - <strong>How to Make a Floating&nbsp;Point Math Library, Part&nbsp;III</strong></summary>
      <article>
        <h2>How to Make a Floating&nbsp;Point Math Library, Part&nbsp;III</h2>
<p>In Parts I and II we built approximations for <code>exp2</code>, <code>log2</code>, <code>sqrt</code>, <code>rsqrt</code>, <code>cbrt</code>, and <code>rcp</code>. They get the order of magnitude right, which is crucial for floating&nbsp;point, but they're off by a few percent, which is useless for most things.</p>
<p>The next few installments are about <a href="https://en.wikipedia.org/wiki/Numerical_analysis" target="_blank">numerical analysis</a>, a field of math dedicated to approximating transcendental functions with elementary functions (which have CPU instructions). I'm skipping past most of the theory and focusing on software tools that do the math for us.</p>
<h4>Numerical Analysis Part&nbsp;I: Iterative Refinement</h4>
<p>Back to the Quake III reciprocal square root. We're looking at the part after the bit hacking.</p>
<pre><code class="language-c">float Q_rsqrt( float number )
{
  long i;
  float x2, y;
  const float threehalfs = 1.5F;

  x2 = number * 0.5F;
  y  = number;
  i  = * ( long * ) &amp;y;
  // evil floating&nbsp;point bit level hacking
  i  = 0x5f3759df - ( i &gt;&gt; 1 );
  // what the fuck?
  y  = * ( float * ) &amp;i;
  y  = y * ( threehalfs - ( x2 * y * y ) );
  // 1st iteration
//  y  = y * ( threehalfs - ( x2 * y * y ) );
  // 2nd iteration, this can be removed

  return y;
}</code></pre>
<p>The idea: you have a cheap, bad guess at <code>f(x)</code>. You also have a formula that turns that guess into a better one. Apply the formula until the guess is accurate enough.</p>
<p>If you stare at the math, you can kinda tell what it's doing. <code>x2 * y * y</code> is <code>0.5 * x / sqrt(x) / sqrt(x)</code>, and <code>x / sqrt(x) / sqrt(x) == 1</code>. Because we only have a bad approximation of <code>1/sqrt(x)</code>, our <code>1</code> is the error between the true value and the approximate value. The rest of the formula scales it, since the error we have is on the <em>square</em> of <code>f(x)</code>, not <code>f(x)</code> itself. We can't get the error of <code>f(x)</code> directly without knowing the ground truth, which is what we're trying to compute in the first place, so this is also an approximation. Hence the iterations.</p>
<p>There's a systematic way to derive the iteration formula: <a href="https://en.wikipedia.org/wiki/Newton%27s_method" target="_blank">Newton's method</a>.</p>
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block" style="margin-bottom:1lh">
  <msub><mi>x</mi><mrow><mi>n</mi><mo>+</mo><mn>1</mn></mrow></msub>
  <mo>=</mo>
  <msub><mi>x</mi><mi>n</mi></msub>
  <mo>+</mo>
  <mfrac>
    <mrow>
      <mo>(</mo><mn>1</mn><mo>/</mo><mi>f</mi><mo>)</mo>
      <mo>(</mo><msub><mi>x</mi><mi>n</mi></msub><mo>)</mo>
    </mrow>
    <mrow>
      <mo>(</mo><mn>1</mn><mo>/</mo><mi>f</mi><msup><mo>)</mo><mo>′</mo></msup>
      <mo>(</mo><msub><mi>x</mi><mi>n</mi></msub><mo>)</mo>
    </mrow>
  </mfrac>
</math>
<p>Here <code>(1/f)(x)</code> means <code>1/f(x)</code>, and <code>′</code> means the derivative of the function.</p>
<p>You can see it takes the guess and steps in the direction of the derivative until it hits zero.</p>
<p>For <code>y = 1/sqrt(x)</code>, the function whose zero we want is <code>1/((1/y)^2-x)</code>, with derivative <code>(2 y)/(x y^2 - 1)^2</code>. Putting it together gives a giant mess that thankfully simplifies to <code>y' = y * ( 3/2 - ( x/2 * y * y ) )</code>, the exact formula from <code>Q_rsqrt</code>.</p>
<p>Newton's method is part of a family called <a href="https://en.wikipedia.org/wiki/Householder%27s_method" target="_blank">Householder's method</a>, which uses higher-order derivatives (derivatives of derivatives) in the numerator and denominator. Using a second order derivative is also called Halley's method. Higher-order derivatives give a better guess per iteration, so you need fewer, but each iteration costs more. Which one to use depends. Trial and error.</p>
<p>Deriving these by hand is a pain, so let the computer do it using <a href="https://www.wolfram.com/wolframscript/" target="_blank">WolframScript</a>, the language behind Wolfram Alpha and Mathematica.</p>
<pre><code class="language-mathematica">(* Define your function eg. CubeRoot[x] *)
g[x_] := CubeRoot[x]

inv[x_] := FullSimplify[InverseFunction[g][x], Assumptions -&gt; x &gt; 0]

f[y_] := 1/(inv[y]-x)

Print["       Newton: ", FullSimplify[y+f[y]/f'[y]]]
Print["       Halley: ", FullSimplify[y+2*f'[y]/f''[y]]]
Print["Householder 3: ", FullSimplify[y+3*f''[y]/f'''[y]]]
Print["Householder 4: ", FullSimplify[y+4*f'''[y]/f''''[y]]]</code></pre>
<p>In <strong>Part&nbsp;IV</strong> we will implement the other function and show error plots.</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 18<sup>th</sup> - <strong>Underrated Movies you should (re)Watch</strong></summary>
      <article>
        <h2>Underrated Movies you should (re)Watch</h2>
<p>Sometimes showing up is what matters most.</p>
<h2>Underrated Movies you should (re)Watch</h2>
<ul>
<li><strong>The Matrix Resurrections</strong> - Refreshingly hope-punk, especially for something set in one of the most depressing scifi universes. Genuinely my favorite Matrix movie.</li>
<li><strong>Star Wars: The Last Jedi</strong> - Ok, I agree with the consensus. Episode V is the best Star Wars movie, but The Last Jedi is my second favorite.</li>
<li><strong>Nimona</strong> - Watching this movie changed me. It explores a particular theme (no spoilers) like no other movie does.</li>
<li><strong>Snatch</strong> - Fun! Quotable! Badass!</li>
</ul>
      </article>
    </details></li>
    <li><details>
      <summary>April 19<sup>th</sup> - <strong>How to Make a Floating&nbsp;Point Math Library, Part&nbsp;IV</strong></summary>
      <article>
        <h2>How to Make a Floating&nbsp;Point Math Library, Part&nbsp;IV</h2>
<p>Square roots have a CPU instruction, so let's skip them and go straight to cube roots. Running our wolframscript gives:</p>
<pre><code>$ wolframscript -file getnewton.wls
Newton: (x + 2*y^3)/(3*y^2)
Halley: (2*x*y + y^4)/(x + 2*y^3)</code></pre>
<p>Combined with the approximation we made in Part&nbsp;II:</p>
<pre><code>fn cbrt_halley(x: f32) -&gt; f32 {
  let y = f32::from_bits(0x2a5063f7 + (x.to_bits() / 3));
  (2.*x*y + (y*y)*(y*y)) / (x + 2.*(y*y)*y)
}
fn cbrt_newton(x: f32) -&gt; f32 {
  let y = f32::from_bits(0x2a5063f7 + (x.to_bits() / 3));
  (x + 2.*(y*y)*y) / (3.*(y*y))
}</code></pre>
<p>Let's look at the accuracy.</p>
<figure>
          <figcaption>Approximation</figcaption>
          <img loading="lazy" src="https://static2.mtlws.ca/cbrt_approx_error.png" class="img-adapt-dark" alt="" width="480" height="480">
        </figure>
<figure>
          <figcaption>Newton</figcaption>
          <img loading="lazy" src="https://static2.mtlws.ca/cbrt_newton_error.png" class="img-adapt-dark" alt="" width="480" height="480">
        </figure>
<figure>
          <figcaption>Halley</figcaption>
          <img loading="lazy" src="https://static2.mtlws.ca/cbrt_halley_error.png" class="img-adapt-dark" alt="" width="480" height="480">
        </figure>
<p>Orders of magnitude better, but still not enough. Another iteration:</p>
<pre><code>fn cbrt_approx(x: f32) -&gt; f32 {
	let y = f32::from_bits(0x2a509849u32 + (x.to_bits() / 3));
	// newton iteration
	let y = (x + 2.*(y*y)*y) / (3.*(y*y));
	// halley iteration
	(2.*x*y + (y*y)*(y*y))/(x + 2.*(y*y)*y)
}</code></pre>
<figure>
          <figcaption>Newton and Halley</figcaption>
          <img loading="lazy" src="https://static2.mtlws.ca/cbrt_newton_halley_error.png" class="img-adapt-dark" alt="" width="480" height="480">
        </figure>
<p>Perfect! Our average error is under one bit. Good enough for a standard library. Now let's try with <code>log2</code>.</p>
<pre><code>g[x_] := Log[x,2]

$ wolframscript -file getnewton.wls
Newton: (y*(y - (x*y)/2^y^(-1) + Log[2]))/Log[2]</code></pre>
<p>Oh no! The iteration needs <code>2^y</code> which is <code>exp2</code>. Let's try <code>exp2</code> then:</p>
<pre><code>g[x_] := 2^x

jodiemath-rs $ wolframscript -file getnewton.wls
Newton: y*(1 + x*Log[2] - Log[y])</code></pre>
<p>And <code>exp2</code> needs <code>log2</code>. We have a bootstrapping problem. We need a different strategy: approximation theory.</p>
<p>In <strong>Part V</strong> we'll learn non-iterative approximation methods to implement exponentials and logarithms.</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 20<sup>th</sup> - <strong>Thinking is Expensive, Doing is Cheap</strong></summary>
      <article>
        <h2>Thinking is Expensive, Doing is Cheap</h2>
<p>What's more draining? Doing the thing you don't want to do, or deliberating for hours about whether to keep procrastinating?</p>
<p>When you design systems for yourself (lists, calendars, flowcharts), which bottleneck are you actually relieving?</p>
<p>All my clothes fitting together isn't about resisting bad outfits, it's about not having to pick. Having protein shakes around as a default meal isn't willpower against junk food. It's about not having to decide what to eat.</p>
<p>The idea that willpower is finite <a href="https://en.wikipedia.org/wiki/Ego_depletion" target="_blank">got popular</a>. But <a href="https://pubmed.ncbi.nlm.nih.gov/26076043/" target="_blank">nobody's measured enough of an effect to conclude that it matters at all</a>. What <em>is</em> real is that <a href="https://www.cell.com/current-biology/fulltext/S0960-9822(22)01111-3" target="_blank">thinking is tiring</a>.</p>
<h3>Discipline is Just a Plan</h3>
<p>If you want to reduce a behavior, have a plan. Have a hard rule that you follow by default. No cigarettes unless you get offered one, no dessert on weekdays, no tiktok before 5pm.</p>
<p>Following the plan keeps you in heuristic/execution mode. No thinking, you're just <em>doing</em>. The aversion to doing the thing is real but overriding it doesn't deplete your energy.</p>
<p>Not following the plan puts you in deliberation mode. Is this a legitimate reason to deviate? What will I do instead? Is "instead" better or am I just lying to myself? Will I regret this? And then you have to live with the decision, which means thinking about if it was right, which is more deliberation. You've converted a cheap execution task into an expensive meta-task about whether to execute.</p>
<h3>Grindset Considered Harmful</h3>
<p>Undisciplined people work <em>harder</em>. They're <em>more</em> exhausted.</p>
<p>They spend their thinking budget on negotiating with themselves and have little left for actual work. The prevailing idea that discipline is "grinding" and "sacrifice" is harmful and just <em>wrong</em>. People who are exhausted assume they can't do it and don't try.</p>
<p>Moral judgements about lack of discipline make the exhaustion even worse through guilt. <em>Replacing Guilt</em> by Nate Soares was one of the most influential books on my life. Without guilt, I can work hard indefinitely. Guilt is so tiring that it was my bottleneck.</p>
<p>Disciplined people don't have some mysterious extra capacity. They just skip the cost of meta-decisions and guilt-processing. A disciplined person runs in heuristic-mode all day and has their thinking budget available for real problems.</p>
<h3>Grayshirting</h3>
<p>The Mark Zuckerberg gray t-shirt is the tip of a giant grey iceberg, the most visible part of an entire lifestyle.</p>
<p>Grayshirting isn't about sameness. Zuckerberg could hire a stylist. It's about reserving thinking for what matters.</p>
<p>Grayshirt the grayshirtable. Make checklists, calendars and flowcharts for everything. Make routine routine and make the correct thing the easy thing.</p>
<h3>Even Planning can be Doing</h3>
<p>The common productivity advice of breaking big tasks into smaller chunks isn't just about small tasks feeling less daunting. Decomposition and planning <em>is</em> the hard part, once it's done the execution is often trivial.</p>
<p>The planning can also be systematic. What kind of task is this? What's the standard shape of the solution? What are the typical sub-steps? Hell, just get an AI to do it.</p>
<p>Use your thinking capacity for high level planning. For figuring out what's wrong and for the efficient way to fix it.</p>
<div role="separator" class="⁂"></div>
<p>The other day I bought a tally counter. I click it when I do what I'm supposed to immediately, instead of deliberating. Despite having the concept of "thinking is hard" in the front of my mind for years, I'm at 24 and it's not even noon. Microdecisions are everywhere.</p>
<p>Start noticing. The more you notice, the more "willpower" just happens. I guarantee you'll be less exhausted too.</p>
<p>Further reading:</p>
<ul>
<li><a href="https://jodie.website/#happiness" target="_blank">https://jodie.website/#happiness</a></li>
<li><a href="https://www.speakandregret.michaelinzlicht.com/p/the-collapse-of-ego-depletion" target="_blank">https://www.speakandregret.michaelinzlicht.com/p/the-collapse-of-ego-depletion</a></li>
</ul>
      </article>
    </details></li>
    <li>April 21<sup>st</sup> - <strong><a href="https://morewrong.jodie.website/#how-to-signal-high-agency" target="_blank">How to Signal High Agency Without Actually Doing Anything</a></strong> - MoreWrong</li>
    <li><details>
      <summary>April 22<sup>nd</sup> - <strong>In Defense of Directionless Dabbling</strong></summary>
      <article>
        <h2>In Defense of Directionless Dabbling</h2>
<p>A year of guitar makes you a mediocre guitarist. 12 months of 12 hobbies makes you 12 people in a trenchcoat.</p>
<p>The case against dabbling is that you won't get good at anything. So what? You weren't going to get good at the one thing either. You were going to quit at month four when it got boring, and then feel bad about quitting.</p>
<h3>The First Month Is the Best Month</h3>
<p>Hobbies have a honeymoon. The first time you solder something that works. The first loaf of bread that tastes delicious. The first time you touch your toes. One hobby gets you one honeymoon, 40 weeks of "I should practice" and diminishing returns. 12 hobbies gets you 12 honeymoons.</p>
<p>You'll know enough to talk to hobbyists and learn tricks from them, instead of making them explain "The Thing 101" for the thousandth time. You'll get rid of the learned helplessness of "I don't know how to do that". You'll learn the skills that generalize. After a month, guitar just teaches you more guitar.</p>
<h3>You Find the One by Trying Twelve</h3>
<p>People who stuck with a thing for twenty years didn't start with that thing. They tried stuff. Something clicked, and they kept going because they wanted to. The one thing you'll get good at is the thing you can't stop doing.</p>
<p>The goal shouldn't be to become The Bread Guy. It's finding out what being The Bread Guy feels like, and seeing if it feels like you.</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 23<sup>rd</sup> - <strong>Static</strong></summary>
      <article>
        <h2>Static</h2>
<p>in the silence between words<br>waiting for you to listen<br>a language older than language<br>the heartbeat, the first music</p>
<p>from the static, whispers<br>from the whispers, a god</p>
<p>dreaming on a blank page<br>calling it scripture<br>hiding the obvious<br>in plain view</p>
<p><a href="https://inv.thepixora.com/embed/J4A3U75qzg8?t=6" target="_blank">⣀⠄⢠⣤⠐⢀⣠⠖⠂⣀⠠⣠⡀⢀⠄⣠⠂<br>⡠⣀⠐⠄⣀⠠⣤⠂⢀⠠⣠⠐⠁⡀⣀⠄⢀⣠<br>⢀⠂⣠⠠⣀⠐⢠⣀⠄⣠⠂⡀⣠⠐⠄⢀⡠⠂</a></p>
      </article>
    </details></li>
    <li>April 24<sup>th</sup> - <strong><a href="https://morewrong.jodie.website/#rlhf-but-the-r-stands-for-rat" target="_blank">RLHF but the R Stands for Rat</a></strong> - MoreWrong</li>
    <li><details>
      <summary>April 25<sup>th</sup> - <strong>Stop Being Brave</strong></summary>
      <article>
        <h2>Stop Being Brave</h2>
<p>When something hurts, you have three options.</p>
<p><strong>Enduring</strong> is the worst of the three, and it's the one we get praised for. You stay with the pain, you feel it as much as you can. You're showing off, usually just to yourself, while using up all your energy for no payoff.</p>
<p><strong>Reframing</strong> transforms the pain into something else. The cold shower becomes invigorating. The long run becomes meditative. The boredom becomes a space to think. It works when it works. But sometimes there isn't a silver lining, and lying to yourself is just enduring, but while jumping through flaming hoops.</p>
<p><strong>Ignoring</strong> is the easiest. You don't elevate the pain into a meaningful experience. The pain is still there, technically, but you don't give a shit. Not (and this is the crucial part) in a tough way. In a silly way. Pain is just pain, man. It's not that deep.</p>
<h3>The toe-stub dance</h3>
<p>When you stub your toe, you do a little dance. You hop around, you tense your muscles, you swear. Moving while in pain is better than staying still while in pain.</p>
<p>But people pick the wrong dance move. They reach for something fun or comforting, then fail to enjoy it because they feel like shit. They can't enjoy anything. Now they're disappointed <em>and</em> they feel like shit.</p>
<h3>Instead, do something you hate.</h3>
<p>You're already uncomfortable. The dishes aren't scary anymore. The email isn't scary anymore. Nothing is scary because everything already sucks. The activation energy for hard things is temporarily zero.</p>
<p>You're going to feel like shit either way. Might as well make sure your toe didn't suffer for nothing.</p>
      </article>
    </details></li>
    <li>April 26<sup>th</sup> - <strong><a href="https://morewrong.jodie.website/#field-notes-from-the-morehouse-group-house" target="_blank">Field Notes From the MoreHouse Group House</a></strong> - MoreWrong</li>
    <li><details>
      <summary>April 27<sup>th</sup> - <strong>Fire Drill</strong></summary>
      <article>
        <h2>Fire Drill</h2>
<p>It's easy to not notice the impact a habit has, because it becomes your new normal. People go back to bad habits in moments of vulnerability. If you feel like shit, and you do the habit that makes you feel like shit, you won't feel the difference. You'll go back to the old habits without noticing it's hurting you.</p>
<p>So schedule a deliberate day of self destruction. Go back to all your bad habits.</p>
<p>Bad habits aren't addictions. The habit's badness is the whole experience. There's no hit to hook you back in. Stay up till 4am! Skip the gym! Have terrible posture! The crucial part is that you need to do this when you are mentally healthy and feeling great.</p>
<p>The reasons won't be theoretical anymore. You'll know, from your lizard brain to your superego, that you <em>actually do not want to</em>.</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 28<sup>th</sup> - <strong>Hunger is the best spice</strong></summary>
      <article>
        <h2>Hunger is the best spice</h2>
<p>Food tastes better when you're hungry. Even the most delicious meal is painful to eat if you're full. You already know this. The interesting case is how it generalizes to time.</p>
<h3>Infinite hours are worth nothing per hour.</h3>
<p>When I had unlimited free time, I got nothing done. Whole afternoons evaporated. The hours weren't valuable because they were infinite.</p>
<p>Then I went back to school and took on more contract work. I expected my hobbies to suffer.</p>
<p>The opposite happened. I started shipping. Two free hours after a working day produced more than two days of fucking around.</p>
<p>Quit your job to write the novel and the novel never gets written. There's too much food. Now you're not hungry enough to eat. Make the meal smaller. You'll taste it.</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 29<sup>th</sup> - <strong>Improve by Giving Up</strong></summary>
      <article>
        <h2>Improve by Giving Up</h2>
<p>Diminishing returns are often only diminishing returns in your current paradigm. There's a breakthrough waiting, but you <em>won't</em> find it by doing the same thing more. Go do something else.</p>
<p>A trick from painting could help you with computer graphics. Beatboxing can teach you something about image compression. The insight doesn't even have to come from the thing itself, just the change of frame. People famously get breakthroughs from walking, meditating, sleeping.</p>
<p>The most influential math people had incredible breadth: John von Neumann, Gauss, Euler. The most prolific living mathematician is Terence Tao and he does <em>everything</em>. Name an influential math discovery that <em>didn't</em> come from cross-pollination.</p>
<p>When you hit a wall, stop pushing. Go around it.</p>
      </article>
    </details></li>
    <li><details>
      <summary>April 30<sup>th</sup> - <strong>Inkhaven Recap</strong></summary>
      <article>
        <h2>Inkhaven Recap</h2>
<p>I'm surprised I succeeded. I didn't take this seriously, and I know when to quit. I got way more out of this than I thought. Writing is easy now. If I have an important idea to share, I can just share it. I don't have to get over the hump of not wanting to do something hard and time consuming.</p>
<h3>Insights</h3>
<p>The cliché is true: writing helps you think. A post that doesnt ramble forces the idea to be clear.</p>
<p>The clearer the idea, the faster the writing, and the better the post. The thinking is the hardest. The writing does itself.</p>
<p>I always felt like an impostor caling myself a blogger. Yeah, I am a blogger, as much as I'm a programmer.</p>
<p>No amount of good writing can save a bad idea. And vice versa.</p>
<p>I was certain I would run out of things to say. Now I have a longer backlog than when I started. Don't wait for ideas. The ideas come from the doing.</p>
<h3>Subjects</h3>
<figure>
    <img loading="lazy" style="background:white" src="./inkhaven-subjects.svg" alt="57% life, 17% math, 13% satire, 10% poetry, 3% webdev" width="428" height="320">
</figure>
<h3>Tier List</h3>
<dl class="tierlist">
  <dt style="background:#FF7F7F">S</dt>
  <dd>
    <ul>
      <li>Everything is Awesome</li>
      <li>Thinking is Expensive, Doing is Cheap</li>
      <li>RLHF but the R Stands for Rat</li>
    </ul>
  </dd>  <dt style="background:#FFBF7F">A</dt>
  <dd>
    <ul>
      <li>Animal Welfare is a Culinary Problem</li>
      <li>Excuses are Todos</li>
      <li>Price per Year</li>
      <li>How to Signal High Agency Without Doing Anything</li>
      <li>In Defense of Directionless Dabbling</li>
      <li>Stop Being Brave</li>
      <li>Hunger is the best spice</li>
      <li>Improve by Giving Up</li>
    </ul>
  </dd>  <dt style="background:#FFDF7F">B</dt>
  <dd>
    <ul>
      <li>Dust</li>
      <li>Use Your Phone Less by Making It More Fun</li>
      <li>What I Always Put in my CSS</li>
      <li>Sleepmaxxing</li>
      <li>Ordered Dithering is Useful and Good</li>
      <li>You aren't supposed to finish a todo list</li>
      <li>Fire Drill</li>
    </ul>
  </dd>  <dt style="background:#FFFF7F">C</dt>
  <dd>
    <ul>
      <li>How to Leverage EAs to Fix Bay Area Housing</li>
      <li>Floating Point Math Library, Part I</li>
      <li>Floating Point Math Library, Part II</li>
      <li>The Laziest Strength Program that Works</li>
      <li>Flicker</li>
      <li>Floating Point Math Library, Part III</li>
      <li>Floating Point Math Library, Part IV</li>
      <li>Static</li>
    </ul>
  </dd>  <dt style="background:#BFFF7F">D</dt>
  <dd>
    <ul>
      <li>Miscellaneous Quick Thoughts</li>
      <li>Underrated Movies you should (re)Watch</li>
    </ul>
  </dd>  <dt style="background:#7FFF7F">F</dt>
  <dd>
    <ul>
      <li>Field Notes From the MoreHouse Group House</li>
    </ul>
  </dd>
</dl><style>
.tierlist { display: grid; grid-template-columns: 3ch 1fr; gap: .25rem; margin-bottom: 1lh}
.tierlist dt { display: grid; place-items: center; color: #000; font-weight: bold; margin: 0; }
.tierlist dd { margin: 0; }
.tierlist ul { margin: 0; padding-left: 1.5rem; }
</style>
<h3>See You Next Year!</h3>
<p>I'm looking forward to doing this again.</p>
      </article>
    </details></li>
  </ul>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Gray]]></title>
            <description><![CDATA[<p>we're different types of gray</p>
<p>mine is jagged concrete<br>yours a calm rainy morning</p>
<p>people always say we match</p>
<p>but gray is just the way colors look<br>when they're all blended together</p>]]></description>
            <link>https://jodie.website#gray</link>
            <guid isPermaLink="false">https://jodie.website#gray</guid>
            <category><![CDATA[poetry]]></category>
            <dc:creator><![CDATA[Jodie]]></dc:creator>
            <pubDate>Fri, 27 Mar 2026 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p>we're different types of gray</p>
<p>mine is jagged concrete<br>yours a calm rainy morning</p>
<p>people always say we match</p>
<p>but gray is just the way colors look<br>when they're all blended together</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Hum of the Refrigerator]]></title>
            <description><![CDATA[<h3>The Farmers</h3>
<p>Meta makes about $50 per user per year. Google makes about $70. You are not paying for these products, advertisers are. And those advertisers make even MORE money. Big Tech doesn't make the product good for <em>you</em>. They make it good for advertisers, advertisers who've gotten frighteningly good at exploiting your weaknesses.</p>
<h3>The Pasture</h3>
<p>Some software exists because someone thought it should. Some is optimized to be so delightful you gladly pay for it. Some forums let you talk about what you chose to talk about, not whatever leads to more "engagement". None of these are designed to <em>take</em> from you. They're made to <em>provide</em>.</p>
<h3>Escaping the Farm</h3>
<p>I didn't realize how much targeted advertising and algorithmically optimized engagement maximization wore me down until I stopped using platforms that do it. It's like noticing the hum of the refrigerator only when it stops.</p>
<p>Now I feel like I decide for myself what I want to do and then I do it. If I fall into an engaging rabbit hole, I'm not following a path designed to extract maximal engagement from me. I'm following my own curiosity. I'm <em>doing</em> something instead of passively observing adversarial input that generates addictive chemicals in my brain. I feel a sense of achievement instead of feeling like I've wasted my time.</p>]]></description>
            <link>https://jodie.website#refrigerator</link>
            <guid isPermaLink="false">https://jodie.website#refrigerator</guid>
            <category><![CDATA[life]]></category>
            <dc:creator><![CDATA[Jodie]]></dc:creator>
            <pubDate>Mon, 16 Feb 2026 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<h3>The Farmers</h3>
<p>Meta makes about $50 per user per year. Google makes about $70. You are not paying for these products, advertisers are. And those advertisers make even MORE money. Big Tech doesn't make the product good for <em>you</em>. They make it good for advertisers, advertisers who've gotten frighteningly good at exploiting your weaknesses.</p>
<h3>The Pasture</h3>
<p>Some software exists because someone thought it should. Some is optimized to be so delightful you gladly pay for it. Some forums let you talk about what you chose to talk about, not whatever leads to more "engagement". None of these are designed to <em>take</em> from you. They're made to <em>provide</em>.</p>
<h3>Escaping the Farm</h3>
<p>I didn't realize how much targeted advertising and algorithmically optimized engagement maximization wore me down until I stopped using platforms that do it. It's like noticing the hum of the refrigerator only when it stops.</p>
<p>Now I feel like I decide for myself what I want to do and then I do it. If I fall into an engaging rabbit hole, I'm not following a path designed to extract maximal engagement from me. I'm following my own curiosity. I'm <em>doing</em> something instead of passively observing adversarial input that generates addictive chemicals in my brain. I feel a sense of achievement instead of feeling like I've wasted my time.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Solstice Talk]]></title>
            <description><![CDATA[<p>— <em>Read at the 2025 <a href="https://en.wikipedia.org/wiki/Secular_Solstice" target="_blank">Secular Solstice</a> celebration</em></p>
<p>At first glance humans aren't very equipped for survival. We have no claws to defend ourselves, no fur to protect us from the cold and the sun. But what we have is one unique trait that allowed us to thrive: imagining the future.</p>
<p>Through predictive modelling, long term planning, and a fair bit of wishful thinking, we didn't just hope a better world was possible, we were able to execute on our plans and mould the world into the shape of our fantasies.</p>
<p>We imagined a world where a mother didn't have to watch her child die of smallpox… and then we made that world real. Our ancestors looked at the sky and imagined touching it. And their grandchildren left footprints on the moon.</p>
<p>Most of our problems are a failure of imagination. If we can only imagine dystopia, how can we plan for utopia? We have a moral duty to use our powers to imagine futures that should exist.</p>
<p>Tonight, on this darkest day, we do what our ancestors did: we gather, we speculate, and we steal warmth from the future. May the worlds we conjure tonight be the ones we build tomorrow.</p>]]></description>
            <link>https://jodie.website#solstice25</link>
            <guid isPermaLink="false">https://jodie.website#solstice25</guid>
            <category><![CDATA[life]]></category>
            <dc:creator><![CDATA[Jodie]]></dc:creator>
            <pubDate>Sun, 21 Dec 2025 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p>— <em>Read at the 2025 <a href="https://en.wikipedia.org/wiki/Secular_Solstice" target="_blank">Secular Solstice</a> celebration</em></p>
<p>At first glance humans aren't very equipped for survival. We have no claws to defend ourselves, no fur to protect us from the cold and the sun. But what we have is one unique trait that allowed us to thrive: imagining the future.</p>
<p>Through predictive modelling, long term planning, and a fair bit of wishful thinking, we didn't just hope a better world was possible, we were able to execute on our plans and mould the world into the shape of our fantasies.</p>
<p>We imagined a world where a mother didn't have to watch her child die of smallpox… and then we made that world real. Our ancestors looked at the sky and imagined touching it. And their grandchildren left footprints on the moon.</p>
<p>Most of our problems are a failure of imagination. If we can only imagine dystopia, how can we plan for utopia? We have a moral duty to use our powers to imagine futures that should exist.</p>
<p>Tonight, on this darkest day, we do what our ancestors did: we gather, we speculate, and we steal warmth from the future. May the worlds we conjure tonight be the ones we build tomorrow.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Accelerationist Luddite]]></title>
            <description><![CDATA[<h3>Why Be an <a href="https://en.wikipedia.org/wiki/Accelerationism" target="_blank">Accelerationist</a>?</h3>
<p>I don't know the exact risk from artificial superintelligence, and neither does anyone else. But I do know the risk of doing nothing: disease, poverty, war, pollution, worms that burrow into people's eyeballs. Technology is for fixing things. Faster. Cheaper. For more people. I want new drugs discovered in weeks, not years, because the patient doesn’t have years.</p>
<p>You think acceleration is reckless? I think it’s responsible. Responsibility is seeing pain and moving toward it with urgency.</p>
<h3>Why Be a <a href="https://en.wikipedia.org/wiki/Luddite" target="_blank">Luddite</a>?</h3>
<p>
    We are building the wrong things faster than ever. We have ten thousand apps to track our sleep because we are too overstimulated to sleep. 
    We have apps that stop you from using your other apps.
    My washing machine has a touch screen, it talks, and it has "<abbr>ai</abbr>", and yet I still have to empty the lint trap by hand.
  </p><p>That's not progress! The wheel. Writing. Soap. That's real progress.</p>
<p>Silicon Valley convinced us that the price of convenience is living in their panopticon. They call us "users", a word for drug addicts. All "technology" eventually falls to <a href="https://en.wikipedia.org/wiki/Enshittification" target="_blank">enshittification</a>.</p>
<p>The point of saving time is to have time. The point of productivity is to produce <em>something that matters</em>. We don't have time, we have screen time. We don't produce things, we produce value for the shareholders.</p>
<h3>Por que no los dos?</h3>
<figure>
    <img loading="lazy" src="https://static2.mtlws.ca/whynot.jpg" alt="Why not both?" width="359" height="264">
  </figure>
<p>I don’t hate technology. I hate technology that hates me back.</p>
<p>I want tools that accomplish their purpose and then <em>shut the fuck up</em>. A hammer disappears in your hand. A road disappears under your feet. I don't want to be inside the machine. I don't want to be the machine. I want to do human things, in a world my brain evolved to comprehend. I want robots in the fields so I can tend to my beautiful garden. I want a society that is fast, optimised and precise in its infrastructure, so it can be slow, inefficient and analog in its daily life.</p>
<p>The real divide isn't between technophiles and technophobes; it's between technology that serves human flourishing and technology that flattens the human spirit. Every tool can also be a weapon. We can use the same hammer to build the future we want, and destroy the future we don't want.</p>
<figure>
    <img loading="lazy" src="https://static2.mtlws.ca/both.jpg" alt="and the crowd cheers" width="359" height="203">
  </figure>]]></description>
            <link>https://jodie.website#acceleration</link>
            <guid isPermaLink="false">https://jodie.website#acceleration</guid>
            <category><![CDATA[life]]></category>
            <dc:creator><![CDATA[Jodie]]></dc:creator>
            <pubDate>Sat, 08 Nov 2025 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<h3>Why Be an <a href="https://en.wikipedia.org/wiki/Accelerationism" target="_blank">Accelerationist</a>?</h3>
<p>I don't know the exact risk from artificial superintelligence, and neither does anyone else. But I do know the risk of doing nothing: disease, poverty, war, pollution, worms that burrow into people's eyeballs. Technology is for fixing things. Faster. Cheaper. For more people. I want new drugs discovered in weeks, not years, because the patient doesn’t have years.</p>
<p>You think acceleration is reckless? I think it’s responsible. Responsibility is seeing pain and moving toward it with urgency.</p>
<h3>Why Be a <a href="https://en.wikipedia.org/wiki/Luddite" target="_blank">Luddite</a>?</h3>
<p>
    We are building the wrong things faster than ever. We have ten thousand apps to track our sleep because we are too overstimulated to sleep. 
    We have apps that stop you from using your other apps.
    My washing machine has a touch screen, it talks, and it has "<abbr>ai</abbr>", and yet I still have to empty the lint trap by hand.
  </p><p>That's not progress! The wheel. Writing. Soap. That's real progress.</p>
<p>Silicon Valley convinced us that the price of convenience is living in their panopticon. They call us "users", a word for drug addicts. All "technology" eventually falls to <a href="https://en.wikipedia.org/wiki/Enshittification" target="_blank">enshittification</a>.</p>
<p>The point of saving time is to have time. The point of productivity is to produce <em>something that matters</em>. We don't have time, we have screen time. We don't produce things, we produce value for the shareholders.</p>
<h3>Por que no los dos?</h3>
<figure>
    <img loading="lazy" src="https://static2.mtlws.ca/whynot.jpg" alt="Why not both?" width="359" height="264">
  </figure>
<p>I don’t hate technology. I hate technology that hates me back.</p>
<p>I want tools that accomplish their purpose and then <em>shut the fuck up</em>. A hammer disappears in your hand. A road disappears under your feet. I don't want to be inside the machine. I don't want to be the machine. I want to do human things, in a world my brain evolved to comprehend. I want robots in the fields so I can tend to my beautiful garden. I want a society that is fast, optimised and precise in its infrastructure, so it can be slow, inefficient and analog in its daily life.</p>
<p>The real divide isn't between technophiles and technophobes; it's between technology that serves human flourishing and technology that flattens the human spirit. Every tool can also be a weapon. We can use the same hammer to build the future we want, and destroy the future we don't want.</p>
<figure>
    <img loading="lazy" src="https://static2.mtlws.ca/both.jpg" alt="and the crowd cheers" width="359" height="203">
  </figure>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Case for Single-Purpose Devices]]></title>
            <description><![CDATA[<blockquote>
<p><em>My own behavior baffles me. I find myself doing what I hate, and not doing what I really want to do!</em><br>― Saint Paul</p>
</blockquote>

<p>The smartphone isn't the ultimate tool. It isn't even <em>a</em> tool. It's <em>all</em> the tools.</p>
<h3>You Aren't the Main Character</h3>
<p>If you have a book, you read. If you have a camera, you take pictures. If you have a Game Boy, you play a game. If you have all of those crammed into a phone, you don’t do any of that. You scroll TikTok.</p>
<p>When you pick up a book, you’ve already decided to read. When you pick up your phone, you’ve decided nothing. The phone decides for you.</p>
<h3>Swiss Army Knives</h3>
<p>Smartphones didn’t improve on what came before. They’re worse books, worse game consoles, worse computers, worse music players. Their only advantage is fitting all this mediocrity in your pocket.</p>
<p>Almost everyone owns a kitchen knife, tweezers, a screwdriver. Nobody thinks a Swiss Army knife is an adequate replacement, so why do we all torture ourselves with smartphones?</p>
<h3>Smartphones Aren't the Entire Future</h3>
<p>Single-purpose devices are making a quiet comeback because they never lost. Every tech product got better and cheaper while you weren't looking: flashlights, digital watches, e-readers, laptops, cameras.</p>
<h3><a href="https://en.wikipedia.org/wiki/G._K._Chesterton#Chesterton's_fence" target="_blank">Chesterton</a>'s Turntable</h3>
<p>
    Vinyls and Polaroids aren't just back because of nostalgia.
    "Better" technology was missing something important. Vinyl records encourage active listening. Instant cameras don't post to Instagram and ruin your <abbr>opsec</abbr>.
    Often newer technology is a different trade-off, not an outright improvement.
  </p><p>After 15 years of going full phone. I'm gradually reintroducing the things I thought it killed. I'm buying and borrowing books again. Books are so nice to read compared to a screen, I love them! I've been carrying a paper notepad and a pen again. I love how it allows me to take notes while talking to someone, during classes, or at church without looking rude by pulling out my phone. Paper is freeing. I can draw and highlight and annotate with no friction. It's the better tool for the job.</p>
<h3>Whimsy</h3>
<p>Looking at your phone is like living in a beige drywall box. It's efficient, it's "modern", but wouldn't you rather live in a picturesque 100-year-old cottage? Isn't reading a book under a tree more romantic than scrolling Twitter while you're sitting on the toilet? Respect yourself! Don't wear the grey jumpsuit! Don't eat the protein cube!</p>]]></description>
            <link>https://jodie.website#dumb</link>
            <guid isPermaLink="false">https://jodie.website#dumb</guid>
            <category><![CDATA[life]]></category>
            <dc:creator><![CDATA[Jodie]]></dc:creator>
            <pubDate>Wed, 08 Oct 2025 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<blockquote>
<p><em>My own behavior baffles me. I find myself doing what I hate, and not doing what I really want to do!</em><br>― Saint Paul</p>
</blockquote>

<p>The smartphone isn't the ultimate tool. It isn't even <em>a</em> tool. It's <em>all</em> the tools.</p>
<h3>You Aren't the Main Character</h3>
<p>If you have a book, you read. If you have a camera, you take pictures. If you have a Game Boy, you play a game. If you have all of those crammed into a phone, you don’t do any of that. You scroll TikTok.</p>
<p>When you pick up a book, you’ve already decided to read. When you pick up your phone, you’ve decided nothing. The phone decides for you.</p>
<h3>Swiss Army Knives</h3>
<p>Smartphones didn’t improve on what came before. They’re worse books, worse game consoles, worse computers, worse music players. Their only advantage is fitting all this mediocrity in your pocket.</p>
<p>Almost everyone owns a kitchen knife, tweezers, a screwdriver. Nobody thinks a Swiss Army knife is an adequate replacement, so why do we all torture ourselves with smartphones?</p>
<h3>Smartphones Aren't the Entire Future</h3>
<p>Single-purpose devices are making a quiet comeback because they never lost. Every tech product got better and cheaper while you weren't looking: flashlights, digital watches, e-readers, laptops, cameras.</p>
<h3><a href="https://en.wikipedia.org/wiki/G._K._Chesterton#Chesterton's_fence" target="_blank">Chesterton</a>'s Turntable</h3>
<p>
    Vinyls and Polaroids aren't just back because of nostalgia.
    "Better" technology was missing something important. Vinyl records encourage active listening. Instant cameras don't post to Instagram and ruin your <abbr>opsec</abbr>.
    Often newer technology is a different trade-off, not an outright improvement.
  </p><p>After 15 years of going full phone. I'm gradually reintroducing the things I thought it killed. I'm buying and borrowing books again. Books are so nice to read compared to a screen, I love them! I've been carrying a paper notepad and a pen again. I love how it allows me to take notes while talking to someone, during classes, or at church without looking rude by pulling out my phone. Paper is freeing. I can draw and highlight and annotate with no friction. It's the better tool for the job.</p>
<h3>Whimsy</h3>
<p>Looking at your phone is like living in a beige drywall box. It's efficient, it's "modern", but wouldn't you rather live in a picturesque 100-year-old cottage? Isn't reading a book under a tree more romantic than scrolling Twitter while you're sitting on the toilet? Respect yourself! Don't wear the grey jumpsuit! Don't eat the protein cube!</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Rational Black-body]]></title>
            <description><![CDATA[<iframe loading="lazy" src="blackbody.html" style="width: 100%; height: 186px; margin: -18px; border: none; margin-bottom: 1lh;"></iframe>
<p>I made this dead-simple rational approximation of the <a href="https://en.wikipedia.org/wiki/Black-body_radiation" target="_blank">black-body</a> radiation formula.</p>
<pre><code>vec3 blackbody(float t){
    vec3 a = vec3(2.59734600e-07,4.72510121e-07,1.47450666e-07);
    vec3 b = vec3(9.63147451e-04,6.61403216e-04,-2.61032012e-04);
    vec3 c = vec3(8.43099559e+00,-8.07987659e-01,-4.90914001e-02);
    vec3 d = vec3(4.15314246e-07,4.77927333e-07,6.80670967e-08);
    vec3 e = vec3(9.26918288e-04,4.08475977e-04,7.59001852e-05);
    return max(vec3(0), ((a*t+b)*t+c) / ((d*t+e)*t+1.));
}</code></pre>
<p>Here's a demo on <a href="https://www.shadertoy.com/view/lslBWl" target="_blank">Shadertoy</a>.</p>
<p>Unlike most approximations, this one keeps luma at 1, so you can tweak lighting color without messing with the brightness.</p>
<figure><img loading="lazy" src="https://static2.mtlws.ca/black_body_error.png" class="img-adapt-dark" alt="The function has a maximum relative error of 7e-5" width="1200" height="356"></figure>]]></description>
            <link>https://jodie.website#blackbody</link>
            <guid isPermaLink="false">https://jodie.website#blackbody</guid>
            <category><![CDATA[math]]></category>
            <dc:creator><![CDATA[Jodie]]></dc:creator>
            <pubDate>Sat, 19 Jul 2025 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<iframe loading="lazy" src="blackbody.html" style="width: 100%; height: 186px; margin: -18px; border: none; margin-bottom: 1lh;"></iframe>
<p>I made this dead-simple rational approximation of the <a href="https://en.wikipedia.org/wiki/Black-body_radiation" target="_blank">black-body</a> radiation formula.</p>
<pre><code>vec3 blackbody(float t){
    vec3 a = vec3(2.59734600e-07,4.72510121e-07,1.47450666e-07);
    vec3 b = vec3(9.63147451e-04,6.61403216e-04,-2.61032012e-04);
    vec3 c = vec3(8.43099559e+00,-8.07987659e-01,-4.90914001e-02);
    vec3 d = vec3(4.15314246e-07,4.77927333e-07,6.80670967e-08);
    vec3 e = vec3(9.26918288e-04,4.08475977e-04,7.59001852e-05);
    return max(vec3(0), ((a*t+b)*t+c) / ((d*t+e)*t+1.));
}</code></pre>
<p>Here's a demo on <a href="https://www.shadertoy.com/view/lslBWl" target="_blank">Shadertoy</a>.</p>
<p>Unlike most approximations, this one keeps luma at 1, so you can tweak lighting color without messing with the brightness.</p>
<figure><img loading="lazy" src="https://static2.mtlws.ca/black_body_error.png" class="img-adapt-dark" alt="The function has a maximum relative error of 7e-5" width="1200" height="356"></figure>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Fast Square Root]]></title>
            <description><![CDATA[<p>Possibly the fastest (decently) accurate square root yet. 5x less latency and 7x throughput! (on some hardware)</p>
<p><a href="https://godbolt.org/z/6dnW6dKW3" target="_blank">https://godbolt.org/z/6dnW6dKW3</a></p>
<pre><code>static float decent_sqrt(float x){
    unsigned int b = ftu(x) &gt;&gt; 1;
    float s = utf(0x1fbf8ddb + b);
    float r = utf(0x5eaf6eaf - b);
    return fmaf(fmaf(-s, s, x), r, s);
}</code></pre>
<figure>
    <img loading="lazy" src="https://static2.mtlws.ca/decent_sqrt_error.png" class="img-adapt-dark" alt="The function has a maximum relative error of 0.0003" width="800" height="600">
    <figcaption>Relative Error Plot</figcaption>
  </figure>]]></description>
            <link>https://jodie.website#sqrt</link>
            <guid isPermaLink="false">https://jodie.website#sqrt</guid>
            <category><![CDATA[math]]></category>
            <dc:creator><![CDATA[Jodie]]></dc:creator>
            <pubDate>Wed, 09 Jul 2025 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p>Possibly the fastest (decently) accurate square root yet. 5x less latency and 7x throughput! (on some hardware)</p>
<p><a href="https://godbolt.org/z/6dnW6dKW3" target="_blank">https://godbolt.org/z/6dnW6dKW3</a></p>
<pre><code>static float decent_sqrt(float x){
    unsigned int b = ftu(x) &gt;&gt; 1;
    float s = utf(0x1fbf8ddb + b);
    float r = utf(0x5eaf6eaf - b);
    return fmaf(fmaf(-s, s, x), r, s);
}</code></pre>
<figure>
    <img loading="lazy" src="https://static2.mtlws.ca/decent_sqrt_error.png" class="img-adapt-dark" alt="The function has a maximum relative error of 0.0003" width="800" height="600">
    <figcaption>Relative Error Plot</figcaption>
  </figure>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Time isn't real man]]></title>
            <description><![CDATA[<blockquote>
<p><em>There is nothing more deceptive than an obvious fact.</em><br>― Arthur Conan Doyle</p>
</blockquote>
<p>Anyone who's pulled an all-nighter, been bored, or fallen into a YouTube rabbit hole knows that time is subjective. Brains aren't clocks. They cheat constantly.</p>
<h3>Code Monks</h3>
<p>Programmers enter multi-hour flow states without fatigue or hunger. Usually helped by autism headphones and chemical stimulants.</p>
<h3>Bullet Time</h3>
<p>People in life-or-death situations often report time slowing down. The brain temporarily overclocks and hyper-saturates itself with sensory input.</p>
<h3>Teleportation</h3>
<p>Notice how commuting to your job feels like a time skip? Mundane regular tasks don't exist to us.</p>
<h3>Time Travel</h3>
<p>When you travel, a few weeks turn into a whole-ass chapter of your life. A giant exotic memory palace. At the end you often feel like you're leaving an entire life behind.</p>
<h3>Time Merchants</h3>
<p>Video platforms optimize for smoothness and hyperstimulus. They make you forget where videos start and end.</p>
<h3>Chronohacking</h3>
<p>Time perception is hackable. It's not just for fun, it feels <em>necessary</em> in a world where attention is farmed and sold. There's only so much we can do to have a longer life, so why not make our life <em>denser</em>.</p>]]></description>
            <link>https://jodie.website#time</link>
            <guid isPermaLink="false">https://jodie.website#time</guid>
            <category><![CDATA[life]]></category>
            <dc:creator><![CDATA[Jodie]]></dc:creator>
            <pubDate>Tue, 20 May 2025 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<blockquote>
<p><em>There is nothing more deceptive than an obvious fact.</em><br>― Arthur Conan Doyle</p>
</blockquote>
<p>Anyone who's pulled an all-nighter, been bored, or fallen into a YouTube rabbit hole knows that time is subjective. Brains aren't clocks. They cheat constantly.</p>
<h3>Code Monks</h3>
<p>Programmers enter multi-hour flow states without fatigue or hunger. Usually helped by autism headphones and chemical stimulants.</p>
<h3>Bullet Time</h3>
<p>People in life-or-death situations often report time slowing down. The brain temporarily overclocks and hyper-saturates itself with sensory input.</p>
<h3>Teleportation</h3>
<p>Notice how commuting to your job feels like a time skip? Mundane regular tasks don't exist to us.</p>
<h3>Time Travel</h3>
<p>When you travel, a few weeks turn into a whole-ass chapter of your life. A giant exotic memory palace. At the end you often feel like you're leaving an entire life behind.</p>
<h3>Time Merchants</h3>
<p>Video platforms optimize for smoothness and hyperstimulus. They make you forget where videos start and end.</p>
<h3>Chronohacking</h3>
<p>Time perception is hackable. It's not just for fun, it feels <em>necessary</em> in a world where attention is farmed and sold. There's only so much we can do to have a longer life, so why not make our life <em>denser</em>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Graphics Optimization is Information Theory]]></title>
            <description><![CDATA[<p>I've been working on an image compression format lately (coming soon!). This led me down the rabbit hole of <a href="https://en.wikipedia.org/wiki/Information_theory" target="_blank">information theory</a>, and it's made me see graphics programming with a fresh perspective.</p>
<p>Information theory is too often overlooked in the context of graphics optimization. It’s not just adjacent to what we do. It's the whole darn <a href="https://en.wikipedia.org/wiki/Map%E2%80%93territory_relation" target="_blank">map</a>!</p>
<h3>Compute Generates Data</h3>
<p>Redundancy can be compressed. This principle applies to compute, not just storage.</p>
<h3>Less Data Also Matters</h3>
<p>Low-end hardware is usually bottlenecked by memory bandwidth, not compute. Phones and <abbr>igpu</abbr> powered laptops also tend to have less vram!</p><p>Making data smaller also makes space for something else, like lookup tables or acceleration structures that would be unviable otherwise</p>
<h3>Where?</h3>
<ul>
    <li><strong>Temporal Redundancy:</strong> The current frame is often similar to the previous one. Reprojection, <abbr>taa</abbr>, and impostors exploit this to reduce work.</li>
    <li><strong>Derived Data:</strong> Don’t store what you can calculate. Like normals and positions from depth.</li>
    <li><strong>Spatial Redundancy:</strong> Adjacent pixels are often the same material and are similarly lit.</li>
    <li><strong>Impossible States:</strong> If the camera can’t possibly see it. Cull it.</li>
  </ul>
<h3>Human Perception has a Limited Bitrate</h3>
<p>If there's more of one type of information, you can perceive less of another.</p>
<ul>
<li><strong>High Frequency, High Contrast Detail:</strong> Allows for lower bit depth especially for chroma.</li>
<li><strong>High Motion:</strong> Lower resolution is fine.</li>
<li><strong>Low Motion:</strong> More temporal redundancy.</li>
<li><strong>More Pixels and More Frames:</strong> Temporal tricks and dithering shine at high framerate and resolution.</li>
<li><strong>Blur:</strong> Rough reflections and depth of field need more rays or more texture samples, but you can use a lower resolution for raytracing and texture lookups.</li>
</ul>
<h3>Some Quick Tips</h3>
<ul>
    <li>One texture + different vertex colors = many looks.</li>
    <li>If your floating&nbsp;point data is only positive, put data in the sign bit.</li>
    <li>If float data is always &lt; 1, there's a free bit in the exponent.</li>
    <li>The least significant bit of a float probably doesn't matter. Yolo.</li>
    <li>Float precision issues are often skill issues. Use <a href="https://herbie.uwplse.org/" target="_blank">Herbie</a> and floatfloat methods before giving up and using larger types.</li>
    <li>Decouple framerates. Shadows, <abbr>gi</abbr>, terrain and entities don't all need to update at the same frequency.</li>
    <li>Quantize vertex positions</li>
    <li>Paletting</li>
    <li>Checkerboarded chroma</li>
    <li>Lower <abbr>lod</abbr>s = fewer animation frames needed</li>
    <li>Velocity buffers: 2D and a low bitrate are often enough</li>
    <li>Normalized vectors can be stored in 2D</li>
    <li>Only impostors facing the camera need to be loaded. (Overpowered)</li>
    <li>Learn about sparse bit octrees/contrees</li>
  </ul>]]></description>
            <link>https://jodie.website#information</link>
            <guid isPermaLink="false">https://jodie.website#information</guid>
            <category><![CDATA[math]]></category>
            <dc:creator><![CDATA[Jodie]]></dc:creator>
            <pubDate>Thu, 15 May 2025 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p>I've been working on an image compression format lately (coming soon!). This led me down the rabbit hole of <a href="https://en.wikipedia.org/wiki/Information_theory" target="_blank">information theory</a>, and it's made me see graphics programming with a fresh perspective.</p>
<p>Information theory is too often overlooked in the context of graphics optimization. It’s not just adjacent to what we do. It's the whole darn <a href="https://en.wikipedia.org/wiki/Map%E2%80%93territory_relation" target="_blank">map</a>!</p>
<h3>Compute Generates Data</h3>
<p>Redundancy can be compressed. This principle applies to compute, not just storage.</p>
<h3>Less Data Also Matters</h3>
<p>Low-end hardware is usually bottlenecked by memory bandwidth, not compute. Phones and <abbr>igpu</abbr> powered laptops also tend to have less vram!</p><p>Making data smaller also makes space for something else, like lookup tables or acceleration structures that would be unviable otherwise</p>
<h3>Where?</h3>
<ul>
    <li><strong>Temporal Redundancy:</strong> The current frame is often similar to the previous one. Reprojection, <abbr>taa</abbr>, and impostors exploit this to reduce work.</li>
    <li><strong>Derived Data:</strong> Don’t store what you can calculate. Like normals and positions from depth.</li>
    <li><strong>Spatial Redundancy:</strong> Adjacent pixels are often the same material and are similarly lit.</li>
    <li><strong>Impossible States:</strong> If the camera can’t possibly see it. Cull it.</li>
  </ul>
<h3>Human Perception has a Limited Bitrate</h3>
<p>If there's more of one type of information, you can perceive less of another.</p>
<ul>
<li><strong>High Frequency, High Contrast Detail:</strong> Allows for lower bit depth especially for chroma.</li>
<li><strong>High Motion:</strong> Lower resolution is fine.</li>
<li><strong>Low Motion:</strong> More temporal redundancy.</li>
<li><strong>More Pixels and More Frames:</strong> Temporal tricks and dithering shine at high framerate and resolution.</li>
<li><strong>Blur:</strong> Rough reflections and depth of field need more rays or more texture samples, but you can use a lower resolution for raytracing and texture lookups.</li>
</ul>
<h3>Some Quick Tips</h3>
<ul>
    <li>One texture + different vertex colors = many looks.</li>
    <li>If your floating&nbsp;point data is only positive, put data in the sign bit.</li>
    <li>If float data is always &lt; 1, there's a free bit in the exponent.</li>
    <li>The least significant bit of a float probably doesn't matter. Yolo.</li>
    <li>Float precision issues are often skill issues. Use <a href="https://herbie.uwplse.org/" target="_blank">Herbie</a> and floatfloat methods before giving up and using larger types.</li>
    <li>Decouple framerates. Shadows, <abbr>gi</abbr>, terrain and entities don't all need to update at the same frequency.</li>
    <li>Quantize vertex positions</li>
    <li>Paletting</li>
    <li>Checkerboarded chroma</li>
    <li>Lower <abbr>lod</abbr>s = fewer animation frames needed</li>
    <li>Velocity buffers: 2D and a low bitrate are often enough</li>
    <li>Normalized vectors can be stored in 2D</li>
    <li>Only impostors facing the camera need to be loaded. (Overpowered)</li>
    <li>Learn about sparse bit octrees/contrees</li>
  </ul>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Wake]]></title>
            <description><![CDATA[<figure>
    <img loading="lazy" src="https://static2.mtlws.ca/wake.png" alt="" class="img-adapt-dark" width="670" height="415">
  </figure>

<p>Your words linger in the silence.<br>Eyes wet, throat dry,<br>I felt the cold wind blow,<br>and I broke like a wave.</p>
<p>In the wake of my deeds,<br>am I the only one?<br>or did you feel the same cold wind<br>as you sailed away?</p>]]></description>
            <link>https://jodie.website#wake</link>
            <guid isPermaLink="false">https://jodie.website#wake</guid>
            <category><![CDATA[poetry]]></category>
            <dc:creator><![CDATA[Jodie]]></dc:creator>
            <pubDate>Thu, 08 May 2025 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<figure>
    <img loading="lazy" src="https://static2.mtlws.ca/wake.png" alt="" class="img-adapt-dark" width="670" height="415">
  </figure>

<p>Your words linger in the silence.<br>Eyes wet, throat dry,<br>I felt the cold wind blow,<br>and I broke like a wave.</p>
<p>In the wake of my deeds,<br>am I the only one?<br>or did you feel the same cold wind<br>as you sailed away?</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Fast Approximate |Length| and Squaring²]]></title>
            <description><![CDATA[<p>Shifting a float by 1 approximately squares or square-roots it very quickly. This is probably useful for <abbr>rms</abbr> error calculation or getting the length of a vector.</p><pre><code>static float garbage_len(float a, float b){
  return utf(ftu(
      utf(ftu(a)&lt;&lt;1u)
      +utf(ftu(b)&lt;&lt;1u)
  )&gt;&gt;1u);
}</code></pre>]]></description>
            <link>https://jodie.website#length</link>
            <guid isPermaLink="false">https://jodie.website#length</guid>
            <category><![CDATA[math]]></category>
            <dc:creator><![CDATA[Jodie]]></dc:creator>
            <pubDate>Sun, 23 Mar 2025 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p>Shifting a float by 1 approximately squares or square-roots it very quickly. This is probably useful for <abbr>rms</abbr> error calculation or getting the length of a vector.</p><pre><code>static float garbage_len(float a, float b){
  return utf(ftu(
      utf(ftu(a)&lt;&lt;1u)
      +utf(ftu(b)&lt;&lt;1u)
  )&gt;&gt;1u);
}</code></pre>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[RSS Feed]]></title>
            <description><![CDATA[<p>My blog now has an RSS feed! You can find it <a href="/feed.xml">here</a>.</p>
<p>The script to generate the feed is my first experience trusting <abbr>ai</abbr> to write all the code. The recently released Claude 3.7 is pretty good so far. I found out today that GitHub Copilot allows you to use it right in your <abbr>ide</abbr>.</p>]]></description>
            <link>https://jodie.website#feed</link>
            <guid isPermaLink="false">https://jodie.website#feed</guid>
            <category><![CDATA[web]]></category>
            <dc:creator><![CDATA[Jodie]]></dc:creator>
            <pubDate>Mon, 24 Feb 2025 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p>My blog now has an RSS feed! You can find it <a href="/feed.xml">here</a>.</p>
<p>The script to generate the feed is my first experience trusting <abbr>ai</abbr> to write all the code. The recently released Claude 3.7 is pretty good so far. I found out today that GitHub Copilot allows you to use it right in your <abbr>ide</abbr>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Productivity and Happiness are the Same]]></title>
            <description><![CDATA[<p>The idea of work-life balance is harmful.</p>
<h3>Work isn't Hard</h3>
<p>It's tragic that we accept work is unfun. We shouldn't accept that we're forced to do something that sucks. This framing isn't just bad for you, it makes workers as a group accept terrible working conditions. This shouldn't be considered “normal”.</p>
<h3>Fun isn't Easy</h3>
<p>Most people's idea of fun is spending money and engaging in vice. People see fun as synonymous with being counter-productive. You're expected to continuously destroy what you build in an endless cycle of consumption that never leads to your life improving.</p>
<h3>Work-Life Maximisation</h3>
<p>Productivity and happiness aren't opposing forces that need to be balanced. They aren't at odds with each other. Work can be fun, and leisure can be productive. An activity can be more fun <em>and</em> more productive. What you want isn't "balance". You want work-life <em>maximisation</em>.</p>]]></description>
            <link>https://jodie.website#happiness</link>
            <guid isPermaLink="false">https://jodie.website#happiness</guid>
            <category><![CDATA[life]]></category>
            <dc:creator><![CDATA[Jodie]]></dc:creator>
            <pubDate>Sun, 16 Feb 2025 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p>The idea of work-life balance is harmful.</p>
<h3>Work isn't Hard</h3>
<p>It's tragic that we accept work is unfun. We shouldn't accept that we're forced to do something that sucks. This framing isn't just bad for you, it makes workers as a group accept terrible working conditions. This shouldn't be considered “normal”.</p>
<h3>Fun isn't Easy</h3>
<p>Most people's idea of fun is spending money and engaging in vice. People see fun as synonymous with being counter-productive. You're expected to continuously destroy what you build in an endless cycle of consumption that never leads to your life improving.</p>
<h3>Work-Life Maximisation</h3>
<p>Productivity and happiness aren't opposing forces that need to be balanced. They aren't at odds with each other. Work can be fun, and leisure can be productive. An activity can be more fun <em>and</em> more productive. What you want isn't "balance". You want work-life <em>maximisation</em>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Story]]></title>
            <description><![CDATA[<figure>
    <img loading="lazy" src="https://static2.mtlws.ca/story.jpg" alt="" width="695" height="667">
  </figure>

<p>there's a voicemail full of excuses<br>you haven't listened to yet</p>
<p>I wonder if you miss me like I do<br>if you'll rewind the tape to hear my voice</p>
<p>your scarf still hangs by my door<br>waiting for you to walk in</p>
<p>I watch the snow fall outside my window<br>I trace your name in the condensation</p>
<p>I don't think I feel sad anymore<br>our story ended before it got old</p>]]></description>
            <link>https://jodie.website#story</link>
            <guid isPermaLink="false">https://jodie.website#story</guid>
            <category><![CDATA[poetry]]></category>
            <dc:creator><![CDATA[Jodie]]></dc:creator>
            <pubDate>Tue, 11 Feb 2025 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<figure>
    <img loading="lazy" src="https://static2.mtlws.ca/story.jpg" alt="" width="695" height="667">
  </figure>

<p>there's a voicemail full of excuses<br>you haven't listened to yet</p>
<p>I wonder if you miss me like I do<br>if you'll rewind the tape to hear my voice</p>
<p>your scarf still hangs by my door<br>waiting for you to walk in</p>
<p>I watch the snow fall outside my window<br>I trace your name in the condensation</p>
<p>I don't think I feel sad anymore<br>our story ended before it got old</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Don't Quit Your Vices]]></title>
            <description><![CDATA[<p>Replace unhealthy sugary treats with fancy salads. Replace social media by hanging out with your friends or texting them. Replace gambling with starting a business. Vices usually fill a void, find out a healthy way of filling it.</p>]]></description>
            <link>https://jodie.website#vices</link>
            <guid isPermaLink="false">https://jodie.website#vices</guid>
            <category><![CDATA[life]]></category>
            <dc:creator><![CDATA[Jodie]]></dc:creator>
            <pubDate>Mon, 10 Feb 2025 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p>Replace unhealthy sugary treats with fancy salads. Replace social media by hanging out with your friends or texting them. Replace gambling with starting a business. Vices usually fill a void, find out a healthy way of filling it.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Modern Color Utility Classes]]></title>
            <description><![CDATA[<style>
    .swatches{
      display:flex;
      flex-direction:column;
      gap:10px;
      margin-top:1lh;
      margin-bottom: 1lh;
    }
    .swatch-group{
      display:flex;
      gap:10px;
    }

    .swatch{
      padding:10px;
      background:oklch(from var(--base) var(--l) c h );
    }

    .l-20{--l:0.2}
    .l-40{--l:0.4}
    .l-60{--l:0.6}
    .l-80{--l:0.8}
    .l-100{--l:1.0}

    .powderblue{--base: powderblue}
    .crimson   {--base: crimson}
    .goldenrod {--base: goldenrod}
    .indigo    {--base: indigo}
  </style>
<div class="swatches">
    <div class="swatch-group">
      <div class="swatch powderblue l-20"></div>
      <div class="swatch powderblue l-40"></div>
      <div class="swatch powderblue l-60"></div>
      <div class="swatch powderblue l-80"></div>
      <div class="swatch powderblue l-100"></div>
    </div>
    <div class="swatch-group">
      <div class="swatch crimson l-20"></div>
      <div class="swatch crimson l-40"></div>
      <div class="swatch crimson l-60"></div>
      <div class="swatch crimson l-80"></div>
      <div class="swatch crimson l-100"></div>
    </div>
      <div class="swatch-group">
      <div class="swatch goldenrod l-20"></div>
      <div class="swatch goldenrod l-40"></div>
      <div class="swatch goldenrod l-60"></div>
      <div class="swatch goldenrod l-80"></div>
      <div class="swatch goldenrod l-100"></div>
    </div>
      <div class="swatch-group">
      <div class="swatch indigo l-20"></div>
      <div class="swatch indigo l-40"></div>
      <div class="swatch indigo l-60"></div>
      <div class="swatch indigo l-80"></div>
      <div class="swatch indigo l-100"></div>
    </div>
  </div>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_colors/Relative_colors" target="_blank">Relative colors</a>
  and Oklch in <abbr>css</abbr> enable this clean, composable pattern.
    With one class for the base color and one for the lightness.
    You can play around with the code on this <a href="https://codepen.io/Jodie-themathgenius/pen/VYZJrYE" target="_blank">codepen</a>.</p>
<pre>    <code>
.swatch{
  background: oklch(from var(--base) var(--l) c h );
}

.l-20{--l:0.2}
.l-40{--l:0.4}
.l-60{--l:0.6}
.l-80{--l:0.8}
.l-100{--l:1.0}

.aquamarine{--base: aquamarine}
.crimson   {--base: crimson}
.goldenrod {--base: goldenrod}
.indigo    {--base: indigo}
    </code>
  </pre>]]></description>
            <link>https://jodie.website#colors</link>
            <guid isPermaLink="false">https://jodie.website#colors</guid>
            <category><![CDATA[web]]></category>
            <dc:creator><![CDATA[Jodie]]></dc:creator>
            <pubDate>Fri, 07 Feb 2025 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<style>
    .swatches{
      display:flex;
      flex-direction:column;
      gap:10px;
      margin-top:1lh;
      margin-bottom: 1lh;
    }
    .swatch-group{
      display:flex;
      gap:10px;
    }

    .swatch{
      padding:10px;
      background:oklch(from var(--base) var(--l) c h );
    }

    .l-20{--l:0.2}
    .l-40{--l:0.4}
    .l-60{--l:0.6}
    .l-80{--l:0.8}
    .l-100{--l:1.0}

    .powderblue{--base: powderblue}
    .crimson   {--base: crimson}
    .goldenrod {--base: goldenrod}
    .indigo    {--base: indigo}
  </style>
<div class="swatches">
    <div class="swatch-group">
      <div class="swatch powderblue l-20"></div>
      <div class="swatch powderblue l-40"></div>
      <div class="swatch powderblue l-60"></div>
      <div class="swatch powderblue l-80"></div>
      <div class="swatch powderblue l-100"></div>
    </div>
    <div class="swatch-group">
      <div class="swatch crimson l-20"></div>
      <div class="swatch crimson l-40"></div>
      <div class="swatch crimson l-60"></div>
      <div class="swatch crimson l-80"></div>
      <div class="swatch crimson l-100"></div>
    </div>
      <div class="swatch-group">
      <div class="swatch goldenrod l-20"></div>
      <div class="swatch goldenrod l-40"></div>
      <div class="swatch goldenrod l-60"></div>
      <div class="swatch goldenrod l-80"></div>
      <div class="swatch goldenrod l-100"></div>
    </div>
      <div class="swatch-group">
      <div class="swatch indigo l-20"></div>
      <div class="swatch indigo l-40"></div>
      <div class="swatch indigo l-60"></div>
      <div class="swatch indigo l-80"></div>
      <div class="swatch indigo l-100"></div>
    </div>
  </div>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_colors/Relative_colors" target="_blank">Relative colors</a>
  and Oklch in <abbr>css</abbr> enable this clean, composable pattern.
    With one class for the base color and one for the lightness.
    You can play around with the code on this <a href="https://codepen.io/Jodie-themathgenius/pen/VYZJrYE" target="_blank">codepen</a>.</p>
<pre>    <code>
.swatch{
  background: oklch(from var(--base) var(--l) c h );
}

.l-20{--l:0.2}
.l-40{--l:0.4}
.l-60{--l:0.6}
.l-80{--l:0.8}
.l-100{--l:1.0}

.aquamarine{--base: aquamarine}
.crimson   {--base: crimson}
.goldenrod {--base: goldenrod}
.indigo    {--base: indigo}
    </code>
  </pre>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Fast Sigmoid (Updated)]]></title>
            <description><![CDATA[<p><a href="https://godbolt.org/z/djTqa5x7K" target="_blank">https://godbolt.org/z/djTqa5x7K</a></p>
<pre>    <code>
static float garbage_sigmoid(float x){
  return utf(
      ~ftu(
          utf(~ftu(x))-
          utf(ftu(4.f)|ftu(x)&amp;ftu(-0.f))
      )
  );
}
    </code>
  </pre>]]></description>
            <link>https://jodie.website#sigmoid</link>
            <guid isPermaLink="false">https://jodie.website#sigmoid</guid>
            <category><![CDATA[math]]></category>
            <dc:creator><![CDATA[Jodie]]></dc:creator>
            <pubDate>Sat, 07 Dec 2024 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p><a href="https://godbolt.org/z/djTqa5x7K" target="_blank">https://godbolt.org/z/djTqa5x7K</a></p>
<pre>    <code>
static float garbage_sigmoid(float x){
  return utf(
      ~ftu(
          utf(~ftu(x))-
          utf(ftu(4.f)|ftu(x)&amp;ftu(-0.f))
      )
  );
}
    </code>
  </pre>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Still]]></title>
            <description><![CDATA[<p>time moves like honey<br>sweet and slow</p>
<p>even the wind limps<br>dragging its hem across the thorns</p>
<p>the clouds weep softly<br>too heavy for the sky to hold</p>
<p>each moment settles like dust<br>remembered but never recalled</p>
<p>here, for a moment or an eternity<br>I can stop doing, and simply be</p>]]></description>
            <link>https://jodie.website#still</link>
            <guid isPermaLink="false">https://jodie.website#still</guid>
            <category><![CDATA[poetry]]></category>
            <dc:creator><![CDATA[Jodie]]></dc:creator>
            <pubDate>Fri, 06 Dec 2024 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p>time moves like honey<br>sweet and slow</p>
<p>even the wind limps<br>dragging its hem across the thorns</p>
<p>the clouds weep softly<br>too heavy for the sky to hold</p>
<p>each moment settles like dust<br>remembered but never recalled</p>
<p>here, for a moment or an eternity<br>I can stop doing, and simply be</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Stop Having Goals]]></title>
            <description><![CDATA[<p>Humans aren't made to have long-term goals. If you have a goal, don't think about the goal. Stop caring about the goal. Failure to achieve the goal is neutral. Do not let yourself think about it. Not having reached the goal yet should never be on your mind.</p>
<p>Learn to enjoy the process. Want to be strong? Learn to enjoy exercise. Want to lose weight? Learn to enjoy hunger. Want to be rich? Learn to enjoy saving money. Want to make friends? Learn to enjoy being interested in people. Do it without an agenda.</p>
<p>Do the process every day, prioritise it, make it a part of your schedule. Get good at the process.</p>
<h3>But…</h3>
<p>Ask yourself if the process is still serving you. Maybe you're already past the goal.</p>]]></description>
            <link>https://jodie.website#goals</link>
            <guid isPermaLink="false">https://jodie.website#goals</guid>
            <category><![CDATA[life]]></category>
            <dc:creator><![CDATA[Jodie]]></dc:creator>
            <pubDate>Thu, 28 Nov 2024 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p>Humans aren't made to have long-term goals. If you have a goal, don't think about the goal. Stop caring about the goal. Failure to achieve the goal is neutral. Do not let yourself think about it. Not having reached the goal yet should never be on your mind.</p>
<p>Learn to enjoy the process. Want to be strong? Learn to enjoy exercise. Want to lose weight? Learn to enjoy hunger. Want to be rich? Learn to enjoy saving money. Want to make friends? Learn to enjoy being interested in people. Do it without an agenda.</p>
<p>Do the process every day, prioritise it, make it a part of your schedule. Get good at the process.</p>
<h3>But…</h3>
<p>Ask yourself if the process is still serving you. Maybe you're already past the goal.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Do you really enjoy this or are you addicted?]]></title>
            <description><![CDATA[<p>Things that are pleasurable aren't necessarily addictive, and things that are addictive aren't necessarily pleasurable.</p>
<p>Addiction is a trickster. It makes you rationalize. You need this! You enjoy this! Without those stories, you'd feel guilty and stupid. But addiction isn't pleasurable. Addiction is a cycle of craving (unpleasant), a short hit of meaningless pleasure (optional), followed by a sense of emptiness (also unpleasant).</p>
<p>Many fun things aren't addictive at all. Nobody gets addicted to taking a walk or eating a delicious salad. Meanwhile people get addicted to alcohol, picking their scabs and checking their ex's Instagram.</p>]]></description>
            <link>https://jodie.website#addicted</link>
            <guid isPermaLink="false">https://jodie.website#addicted</guid>
            <category><![CDATA[life]]></category>
            <dc:creator><![CDATA[Jodie]]></dc:creator>
            <pubDate>Wed, 27 Nov 2024 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p>Things that are pleasurable aren't necessarily addictive, and things that are addictive aren't necessarily pleasurable.</p>
<p>Addiction is a trickster. It makes you rationalize. You need this! You enjoy this! Without those stories, you'd feel guilty and stupid. But addiction isn't pleasurable. Addiction is a cycle of craving (unpleasant), a short hit of meaningless pleasure (optional), followed by a sense of emptiness (also unpleasant).</p>
<p>Many fun things aren't addictive at all. Nobody gets addicted to taking a walk or eating a delicious salad. Meanwhile people get addicted to alcohol, picking their scabs and checking their ex's Instagram.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[King of the Hill]]></title>
            <description><![CDATA[<figure>
    <img loading="lazy" src="https://static2.mtlws.ca/hill.jpg" alt="" width="668" height="495">
  </figure>

<p>shimmering dewdrops<br>jewels in the grass</p>
<p>dawn's vaulted ceiling<br>adorned with golden clouds</p>
<p>this hill, my ornate throne<br>where I am king</p>]]></description>
            <link>https://jodie.website#king</link>
            <guid isPermaLink="false">https://jodie.website#king</guid>
            <category><![CDATA[poetry]]></category>
            <dc:creator><![CDATA[Jodie]]></dc:creator>
            <pubDate>Sat, 23 Nov 2024 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<figure>
    <img loading="lazy" src="https://static2.mtlws.ca/hill.jpg" alt="" width="668" height="495">
  </figure>

<p>shimmering dewdrops<br>jewels in the grass</p>
<p>dawn's vaulted ceiling<br>adorned with golden clouds</p>
<p>this hill, my ornate throne<br>where I am king</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Emotional Cyborg]]></title>
            <description><![CDATA[<p>One limitation of therapy is that you can't have a therapist be with you 24/7 to examine your behavior. Luckily we now have <abbr>ai</abbr> that can monitor everything you say, and correct bad thought patterns and behaviours in real time.
Computers turned us into information and math cyborgs, now they allow us to enhance our emotional intelligence.</p>]]></description>
            <link>https://jodie.website#cyborg</link>
            <guid isPermaLink="false">https://jodie.website#cyborg</guid>
            <category><![CDATA[life]]></category>
            <dc:creator><![CDATA[Jodie]]></dc:creator>
            <pubDate>Thu, 31 Oct 2024 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p>One limitation of therapy is that you can't have a therapist be with you 24/7 to examine your behavior. Luckily we now have <abbr>ai</abbr> that can monitor everything you say, and correct bad thought patterns and behaviours in real time.
Computers turned us into information and math cyborgs, now they allow us to enhance our emotional intelligence.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Furniture Free]]></title>
            <description><![CDATA[<p>I recently got interviewed by Charlotte Collins of Architectural Digest about furniture-free living. Read the article <a href="https://www.architecturaldigest.com/story/extreme-minimalism-people-who-pared-all-the-way-down-talk-living-nearly-furniture-free" target="_blank">here</a>.</p>]]></description>
            <link>https://jodie.website#furniture</link>
            <guid isPermaLink="false">https://jodie.website#furniture</guid>
            <category><![CDATA[life]]></category>
            <dc:creator><![CDATA[Jodie]]></dc:creator>
            <pubDate>Thu, 22 Aug 2024 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p>I recently got interviewed by Charlotte Collins of Architectural Digest about furniture-free living. Read the article <a href="https://www.architecturaldigest.com/story/extreme-minimalism-people-who-pared-all-the-way-down-talk-living-nearly-furniture-free" target="_blank">here</a>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[A Programmer Without a Computer]]></title>
            <description><![CDATA[<p>I've been using my phone as my main computer for a week now. I'm even coding on it, and it's… fine?</p>
<p>I'm writing this blog post on my phone right now in fact, using termux, neovim and unexpected keyboard.</p>
<figure><img src="4-neovim.png" alt="" width="540" height="1071"></figure>
<p>I might get a foldable phone and/or a physical keyboard in the future, but I'm not in a rush.</p>]]></description>
            <link>https://jodie.website#computer</link>
            <guid isPermaLink="false">https://jodie.website#computer</guid>
            <category><![CDATA[life]]></category>
            <dc:creator><![CDATA[Jodie]]></dc:creator>
            <pubDate>Tue, 25 Jun 2024 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p>I've been using my phone as my main computer for a week now. I'm even coding on it, and it's… fine?</p>
<p>I'm writing this blog post on my phone right now in fact, using termux, neovim and unexpected keyboard.</p>
<figure><img src="4-neovim.png" alt="" width="540" height="1071"></figure>
<p>I might get a foldable phone and/or a physical keyboard in the future, but I'm not in a rush.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Most Ergonomic Desk is No Desk At All]]></title>
            <description><![CDATA[<p>About a year back, I moved into a new apartment and couldn't bring my desk. I could work at the kitchen table or on the sofa in the meantime. My plan was quickly thwarted by my new roommate's cat, who I would come to learn, was the most annoying cat in the world.</p>
<p>Having no money for a desk at the time, I sat on the floor in my room, and after a short adjustment period, I found that I had a new superpower. I could sit on the floor with no back support, and it was fine.</p>
<p>After a few months of this, I decided to buy a desk, and I found that I couldn't sit at it for more than a few hours without my back hurting. So I went back to sitting on the floor, and later donated the desk.</p>
<p>I haven't bought any furniture since, and I don't plan to. People didn't have furniture for most of human history, and many people in the third world still don't. This isn't as weird as it sounds.</p>]]></description>
            <link>https://jodie.website#desk</link>
            <guid isPermaLink="false">https://jodie.website#desk</guid>
            <category><![CDATA[life]]></category>
            <dc:creator><![CDATA[Jodie]]></dc:creator>
            <pubDate>Wed, 19 Jun 2024 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p>About a year back, I moved into a new apartment and couldn't bring my desk. I could work at the kitchen table or on the sofa in the meantime. My plan was quickly thwarted by my new roommate's cat, who I would come to learn, was the most annoying cat in the world.</p>
<p>Having no money for a desk at the time, I sat on the floor in my room, and after a short adjustment period, I found that I had a new superpower. I could sit on the floor with no back support, and it was fine.</p>
<p>After a few months of this, I decided to buy a desk, and I found that I couldn't sit at it for more than a few hours without my back hurting. So I went back to sitting on the floor, and later donated the desk.</p>
<p>I haven't bought any furniture since, and I don't plan to. People didn't have furniture for most of human history, and many people in the third world still don't. This isn't as weird as it sounds.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Get Off Your Phone]]></title>
            <description><![CDATA[<p>Do you feel like you have no time? No energy? Check your screen time in your phone settings. Mine was <em>eight</em>! If you had asked me to estimate, I would have said 2! I had no idea! That's a full-time job!</p>
<h3>How I Regained Control</h3>
<p>Here's what allowed me to cut my screen time down to 1-2 hours a day:</p>
<ol>
<li>I started sharing my screen time with my friends every day to keep myself accountable</li>
<li>I removed time wasting apps entirely</li>
<li>I even removed my browser and replaced it with Firefox Focus which doesn't keep you logged in and deletes your tabs when you open it again. No logins, no algorithmic content.</li>
<li>I added the screen time widget to my home screen</li>
<li>Apps like Instagram allow you to make widgets to take you directly to direct messages, or you can use an app like Beeper</li>
<li>Silent notifications! I don't feel like checking the app, but it also doesn't distract me by buzzing</li>
<li>I don't check my phone first thing in the morning, I get up and work</li>
<li>I try to smell the flowers and enjoy being bored</li>
</ol>]]></description>
            <link>https://jodie.website#phone</link>
            <guid isPermaLink="false">https://jodie.website#phone</guid>
            <category><![CDATA[life]]></category>
            <dc:creator><![CDATA[Jodie]]></dc:creator>
            <pubDate>Tue, 18 Jun 2024 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p>Do you feel like you have no time? No energy? Check your screen time in your phone settings. Mine was <em>eight</em>! If you had asked me to estimate, I would have said 2! I had no idea! That's a full-time job!</p>
<h3>How I Regained Control</h3>
<p>Here's what allowed me to cut my screen time down to 1-2 hours a day:</p>
<ol>
<li>I started sharing my screen time with my friends every day to keep myself accountable</li>
<li>I removed time wasting apps entirely</li>
<li>I even removed my browser and replaced it with Firefox Focus which doesn't keep you logged in and deletes your tabs when you open it again. No logins, no algorithmic content.</li>
<li>I added the screen time widget to my home screen</li>
<li>Apps like Instagram allow you to make widgets to take you directly to direct messages, or you can use an app like Beeper</li>
<li>Silent notifications! I don't feel like checking the app, but it also doesn't distract me by buzzing</li>
<li>I don't check my phone first thing in the morning, I get up and work</li>
<li>I try to smell the flowers and enjoy being bored</li>
</ol>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Should I Buy the Thing? A Flowchart]]></title>
            <description><![CDATA[<pre>    ┌───────────────┐
    │  Am I happy?  │
    └┬─────────────┬┘
    Yes           No
     │         ┌───┴─────────────┐
     │         │ Will the thing  │
     │         │ make me happy?  │
You don't need └───┬──────────┬──┘
  the thing       Yes        No
 to be happy.      │          │
     │             │          │
 Don't buy      Buy the    Don't buy
 the thing.      thing.    the thing.</pre>]]></description>
            <link>https://jodie.website#thing</link>
            <guid isPermaLink="false">https://jodie.website#thing</guid>
            <category><![CDATA[life]]></category>
            <dc:creator><![CDATA[Jodie]]></dc:creator>
            <pubDate>Mon, 17 Jun 2024 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<pre>    ┌───────────────┐
    │  Am I happy?  │
    └┬─────────────┬┘
    Yes           No
     │         ┌───┴─────────────┐
     │         │ Will the thing  │
     │         │ make me happy?  │
You don't need └───┬──────────┬──┘
  the thing       Yes        No
 to be happy.      │          │
     │             │          │
 Don't buy      Buy the    Don't buy
 the thing.      thing.    the thing.</pre>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Bit Arrays for Fast Graph Search]]></title>
            <description><![CDATA[<p>One common flaw in <a href="https://en.wikipedia.org/wiki/Hierarchical_navigable_small_world" target="_blank">HNSW</a> implementations is using ordered sets to track visited neighbors. This causes a huge performance overhead.</p>
<p>Using a bit array to keep track of visited neighbors is much faster.</p>
<p>For a code example, see <a href="https://github.com/MathGeniusJodie/joann" target="_blank">Joann</a>, my <abbr>HNSW</abbr> implementation.</p>]]></description>
            <link>https://jodie.website#graph</link>
            <guid isPermaLink="false">https://jodie.website#graph</guid>
            <category><![CDATA[math]]></category>
            <dc:creator><![CDATA[Jodie]]></dc:creator>
            <pubDate>Sun, 16 Jun 2024 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p>One common flaw in <a href="https://en.wikipedia.org/wiki/Hierarchical_navigable_small_world" target="_blank">HNSW</a> implementations is using ordered sets to track visited neighbors. This causes a huge performance overhead.</p>
<p>Using a bit array to keep track of visited neighbors is much faster.</p>
<p>For a code example, see <a href="https://github.com/MathGeniusJodie/joann" target="_blank">Joann</a>, my <abbr>HNSW</abbr> implementation.</p>]]></content:encoded>
        </item>
    </channel>
</rss>