<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://jsigman.github.io/feed.xml" rel="self" type="application/atom+xml"/><link href="https://jsigman.github.io/" rel="alternate" type="text/html" hreflang="en"/><updated>2026-01-25T00:41:32+00:00</updated><id>https://jsigman.github.io/feed.xml</id><title type="html">blank</title><subtitle>My personal website</subtitle><entry><title type="html">Link to Remote in Emacs</title><link href="https://jsigman.github.io/blog/2025/link-to-remote-el/" rel="alternate" type="text/html" title="Link to Remote in Emacs"/><published>2025-03-11T00:00:00+00:00</published><updated>2025-03-11T00:00:00+00:00</updated><id>https://jsigman.github.io/blog/2025/link-to-remote-el</id><content type="html" xml:base="https://jsigman.github.io/blog/2025/link-to-remote-el/"><![CDATA[<h2 id="link-to-remoteel"><code class="language-plaintext highlighter-rouge">link-to-remote.el</code></h2> <p>When you’re sharing code and documentation with teammates, it can be slow to page over to your forge and navigate to the file you want and select a link. To solve this, I’m sharing <a href="https://github.com/jsigman/link-to-remote.el">link-to-remote.el</a>, an Emacs package that creates shareable links to your current file in its remote repository. It offers branch selection via <code class="language-plaintext highlighter-rouge">completing-read</code> and provides multiple actions through a <code class="language-plaintext highlighter-rouge">transient</code> menu.</p> <p>You can install <code class="language-plaintext highlighter-rouge">link-to-remote.el</code> using <code class="language-plaintext highlighter-rouge">straight.el</code>:</p> <div class="language-emacs-lisp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">use-package</span> <span class="nv">link-to-remote</span>
  <span class="ss">:straight</span> <span class="p">(</span><span class="ss">:host</span> <span class="nv">github</span> <span class="ss">:repo</span> <span class="s">"jsigman/link-to-remote.el"</span><span class="p">)</span>
  <span class="ss">:bind</span> <span class="p">(</span><span class="s">"C-c l"</span> <span class="o">.</span> <span class="nv">link-to-remote</span><span class="p">))</span>
</code></pre></div></div>]]></content><author><name></name></author><category term="emacs"/><category term="git"/><category term="github"/><category term="gitlab"/><category term="bitbucket"/><summary type="html"><![CDATA[Link your current file to its repository URL with branch selection and multiple actions]]></summary></entry><entry><title type="html">Unison Sync in Emacs</title><link href="https://jsigman.github.io/blog/2024/unison-sync-mode/" rel="alternate" type="text/html" title="Unison Sync in Emacs"/><published>2024-08-11T00:00:00+00:00</published><updated>2024-08-11T00:00:00+00:00</updated><id>https://jsigman.github.io/blog/2024/unison-sync-mode</id><content type="html" xml:base="https://jsigman.github.io/blog/2024/unison-sync-mode/"><![CDATA[<h2 id="unison-sync-mode"><code class="language-plaintext highlighter-rouge">unison-sync-mode</code></h2> <p>Working across multiple machines often means juggling file versions. To solve this, I’m sharing <code class="language-plaintext highlighter-rouge">unison-sync-mode</code>, an Emacs package that integrates Unison file synchronization directly into your workflow. It automatically syncs files on save, supports excluding specific patterns, and even offers one-way sync options.</p> <p>You can install <code class="language-plaintext highlighter-rouge">unison-sync-mode</code> using <code class="language-plaintext highlighter-rouge">straight.el</code>:</p> <div class="language-emacs-lisp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nv">straight-use-package</span>
 <span class="o">'</span><span class="p">(</span><span class="nv">unison-sync-mode</span> <span class="ss">:type</span> <span class="nv">git</span> <span class="ss">:host</span> <span class="nv">github</span> <span class="ss">:repo</span> <span class="s">"jsigman/unison-sync-mode"</span><span class="p">))</span>
</code></pre></div></div> <p>Check out the <a href="https://github.com/jsigman/unison-sync-mode">GitHub repository</a> for more details on configuration and usage. I’m excited to see how this tool evolves and welcome any feedback or contributions from the Emacs community.</p>]]></content><author><name></name></author><category term="emacs"/><category term="unison"/><category term="sync"/><summary type="html"><![CDATA[Seamless one- and two-way file synchronization in Emacs with Unison]]></summary></entry><entry><title type="html">Studying Eigenvalues of Rotation Group Matrices</title><link href="https://jsigman.github.io/blog/2024/spectra-of-rotation-groups/" rel="alternate" type="text/html" title="Studying Eigenvalues of Rotation Group Matrices"/><published>2024-01-18T00:00:00+00:00</published><updated>2024-01-18T00:00:00+00:00</updated><id>https://jsigman.github.io/blog/2024/spectra-of-rotation-groups</id><content type="html" xml:base="https://jsigman.github.io/blog/2024/spectra-of-rotation-groups/"><![CDATA[<h1 id="table-of-contents">Table of Contents</h1> <ol> <li><a href="#org98f6ab0">$ \text{SU}(2) $ Matrices</a> <ol> <li><a href="#org78c4d37">Pulling random elements of the quaternions</a></li> <li><a href="#org186d325">Mapping to $ \text{SU}(2) $ matrices</a></li> </ol> </li> <li><a href="#org71eb0db">$ \text{SO}(3) $ Matrices</a></li> <li><a href="#org199071a">Spectra comparison</a> <ol> <li><a href="#orge875ea2">$ \text{SU}(2) $</a></li> <li><a href="#orge7a6657">$ \text{SO}(3) $</a></li> </ol> </li> <li><a href="#orgc16b6c1">Determinants</a> In this exploration, I mess around with the spectra of two different rotation groups. I wanted to develop intuition for the elements of each group, and especially to discover through experimentation how \( \text{SU}(2) \) is a double cover of \( \text{SO}(3) \). Because my background is in numerical methods and not mathematics, I like to develop this through code, empirical visualization, and experimentation.</li> </ol> <p>This is also a live test of some tweaking I’ve been doing to my tweaks to <a href="https://github.com/peterewills/ox-jekyll-lite">Org-Jekyll-Lite</a> in order to run code and \(\LaTeX\) in Org documents and export it to web page.</p> <p><a id="org98f6ab0"></a></p> <h1 id="-textsu2--matrices">\( \text{SU}(2) \) Matrices</h1> <p><a id="org78c4d37"></a></p> <h2 id="pulling-random-elements-of-the-quaternions">Pulling random elements of the quaternions</h2> <p>Since elements of the group \( \text{SU}(2) \) are isomorphic to the unit quaternions, \(\mathbb{H}\), we will draw a unit quaternion and map it onto the matrix representation of SU(2).</p> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="k">def</span> <span class="nf">random_quaternion</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">np</span><span class="p">.</span><span class="n">ndarray</span><span class="p">:</span>
    <span class="n">u1</span><span class="p">,</span> <span class="n">u2</span><span class="p">,</span> <span class="n">u3</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">random</span><span class="p">.</span><span class="nf">random</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
    <span class="n">q0</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">sqrt</span><span class="p">(</span><span class="mi">1</span> <span class="o">-</span> <span class="n">u1</span><span class="p">)</span> <span class="o">*</span> <span class="n">np</span><span class="p">.</span><span class="nf">sin</span><span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">np</span><span class="p">.</span><span class="n">pi</span> <span class="o">*</span> <span class="n">u2</span><span class="p">)</span>
    <span class="n">q1</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">sqrt</span><span class="p">(</span><span class="mi">1</span> <span class="o">-</span> <span class="n">u1</span><span class="p">)</span> <span class="o">*</span> <span class="n">np</span><span class="p">.</span><span class="nf">cos</span><span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">np</span><span class="p">.</span><span class="n">pi</span> <span class="o">*</span> <span class="n">u2</span><span class="p">)</span>
    <span class="n">q2</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">sqrt</span><span class="p">(</span><span class="n">u1</span><span class="p">)</span> <span class="o">*</span> <span class="n">np</span><span class="p">.</span><span class="nf">sin</span><span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">np</span><span class="p">.</span><span class="n">pi</span> <span class="o">*</span> <span class="n">u3</span><span class="p">)</span>
    <span class="n">q3</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">sqrt</span><span class="p">(</span><span class="n">u1</span><span class="p">)</span> <span class="o">*</span> <span class="n">np</span><span class="p">.</span><span class="nf">cos</span><span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">np</span><span class="p">.</span><span class="n">pi</span> <span class="o">*</span> <span class="n">u3</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">np</span><span class="p">.</span><span class="nf">array</span><span class="p">([</span><span class="n">q0</span><span class="p">,</span> <span class="n">q1</span><span class="p">,</span> <span class="n">q2</span><span class="p">,</span> <span class="n">q3</span><span class="p">])</span>

</code></pre></div></div> <p><a id="org186d325"></a></p> <h2 id="mapping-to--textsu2--matrices">Mapping to \( \text{SU}(2) \) matrices</h2> <p>The general form of the \( \text{SU}(2) \) matrix for a quaternion \( (q_0, q_1, q_2, q_3) \) is given by:</p> <p>\( \begin{bmatrix} q_0 + iq_3 &amp; q_2 + iq_1 \ -q_2 + iq_1 &amp; q_0 - iq_3 \end{bmatrix} \)</p> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">quaternion_to_su2</span><span class="p">(</span><span class="n">quaternion</span><span class="p">:</span> <span class="n">np</span><span class="p">.</span><span class="n">ndarray</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">np</span><span class="p">.</span><span class="n">ndarray</span><span class="p">:</span>
    <span class="c1"># Convert a quaternion into its SU(2) matrix representation.
</span>    <span class="n">q0</span><span class="p">,</span> <span class="n">q1</span><span class="p">,</span> <span class="n">q2</span><span class="p">,</span> <span class="n">q3</span> <span class="o">=</span> <span class="n">quaternion</span>
    <span class="k">return</span> <span class="n">np</span><span class="p">.</span><span class="nf">array</span><span class="p">([[</span><span class="n">q0</span> <span class="o">+</span> <span class="mf">1j</span><span class="o">*</span><span class="n">q3</span><span class="p">,</span> <span class="n">q2</span> <span class="o">+</span> <span class="mf">1j</span><span class="o">*</span><span class="n">q1</span><span class="p">],</span>
                     <span class="p">[</span><span class="o">-</span><span class="n">q2</span> <span class="o">+</span> <span class="mf">1j</span><span class="o">*</span><span class="n">q1</span><span class="p">,</span> <span class="n">q0</span> <span class="o">-</span> <span class="mf">1j</span><span class="o">*</span><span class="n">q3</span><span class="p">]])</span>

<span class="k">def</span> <span class="nf">draw_random_su2</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">np</span><span class="p">.</span><span class="n">ndarray</span><span class="p">:</span>
    <span class="k">return</span> <span class="nf">quaternion_to_su2</span><span class="p">(</span><span class="nf">random_quaternion</span><span class="p">())</span>

</code></pre></div></div> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">pandas</span> <span class="k">as</span> <span class="n">pd</span>

<span class="n">pd</span><span class="p">.</span><span class="nc">DataFrame</span><span class="p">(</span><span class="nf">quaternion_to_su2</span><span class="p">(</span><span class="nf">random_quaternion</span><span class="p">()))</span>

</code></pre></div></div> <table> <thead> <tr> <th> </th> <th>0</th> <th>1</th> </tr> </thead> <tbody> <tr> <td>0</td> <td>-0.706679+0.640604j</td> <td>0.141797+0.264810j</td> </tr> <tr> <td>1</td> <td>-0.141797+0.264810j</td> <td>-0.706679-0.640604j</td> </tr> </tbody> </table> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">pd</span><span class="p">.</span><span class="nc">DataFrame</span><span class="p">(</span><span class="nf">quaternion_to_su2</span><span class="p">(</span><span class="nf">random_quaternion</span><span class="p">()))</span>

</code></pre></div></div> <table> <thead> <tr> <th> </th> <th>0</th> <th>1</th> </tr> </thead> <tbody> <tr> <td>0</td> <td>0.020562+0.599385j</td> <td>-0.636772+0.484599j</td> </tr> <tr> <td>1</td> <td>0.636772+0.484599j</td> <td>0.020562-0.599385j</td> </tr> </tbody> </table> <p><a id="org71eb0db"></a></p> <h1 id="-textso3--matrices">\( \text{SO}(3) \) Matrices</h1> <p>\( \text{SO}(3) \) matrices are 3x3 orthogonal matrices with determinant 1. They represent rotations in 3D space.</p> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">quaternion_to_so3</span><span class="p">(</span><span class="n">quat</span><span class="p">:</span> <span class="n">np</span><span class="p">.</span><span class="n">ndarray</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">np</span><span class="p">.</span><span class="n">ndarray</span><span class="p">:</span>
    <span class="n">w</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">z</span> <span class="o">=</span> <span class="n">quat</span>
    <span class="k">return</span> <span class="n">np</span><span class="p">.</span><span class="nf">array</span><span class="p">([</span>
        <span class="p">[</span><span class="mi">1</span> <span class="o">-</span> <span class="mi">2</span><span class="o">*</span><span class="n">y</span><span class="o">**</span><span class="mi">2</span> <span class="o">-</span> <span class="mi">2</span><span class="o">*</span><span class="n">z</span><span class="o">**</span><span class="mi">2</span><span class="p">,</span>     <span class="mi">2</span><span class="o">*</span><span class="n">x</span><span class="o">*</span><span class="n">y</span> <span class="o">-</span> <span class="mi">2</span><span class="o">*</span><span class="n">z</span><span class="o">*</span><span class="n">w</span><span class="p">,</span>       <span class="mi">2</span><span class="o">*</span><span class="n">x</span><span class="o">*</span><span class="n">z</span> <span class="o">+</span> <span class="mi">2</span><span class="o">*</span><span class="n">y</span><span class="o">*</span><span class="n">w</span><span class="p">],</span>
        <span class="p">[</span><span class="mi">2</span><span class="o">*</span><span class="n">x</span><span class="o">*</span><span class="n">y</span> <span class="o">+</span> <span class="mi">2</span><span class="o">*</span><span class="n">z</span><span class="o">*</span><span class="n">w</span><span class="p">,</span>           <span class="mi">1</span> <span class="o">-</span> <span class="mi">2</span><span class="o">*</span><span class="n">x</span><span class="o">**</span><span class="mi">2</span> <span class="o">-</span> <span class="mi">2</span><span class="o">*</span><span class="n">z</span><span class="o">**</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="o">*</span><span class="n">y</span><span class="o">*</span><span class="n">z</span> <span class="o">-</span> <span class="mi">2</span><span class="o">*</span><span class="n">x</span><span class="o">*</span><span class="n">w</span><span class="p">],</span>
        <span class="p">[</span><span class="mi">2</span><span class="o">*</span><span class="n">x</span><span class="o">*</span><span class="n">z</span> <span class="o">-</span> <span class="mi">2</span><span class="o">*</span><span class="n">y</span><span class="o">*</span><span class="n">w</span><span class="p">,</span>           <span class="mi">2</span><span class="o">*</span><span class="n">y</span><span class="o">*</span><span class="n">z</span> <span class="o">+</span> <span class="mi">2</span><span class="o">*</span><span class="n">x</span><span class="o">*</span><span class="n">w</span><span class="p">,</span>       <span class="mi">1</span> <span class="o">-</span> <span class="mi">2</span><span class="o">*</span><span class="n">x</span><span class="o">**</span><span class="mi">2</span> <span class="o">-</span> <span class="mi">2</span><span class="o">*</span><span class="n">y</span><span class="o">**</span><span class="mi">2</span><span class="p">]</span>
    <span class="p">])</span>

<span class="k">def</span> <span class="nf">draw_random_so3</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">np</span><span class="p">.</span><span class="n">ndarray</span><span class="p">:</span>
    <span class="n">quat</span> <span class="o">=</span> <span class="nf">random_quaternion</span><span class="p">()</span>
    <span class="k">return</span> <span class="nf">quaternion_to_so3</span><span class="p">(</span><span class="n">quat</span><span class="p">)</span>

</code></pre></div></div> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">pd</span><span class="p">.</span><span class="nc">DataFrame</span><span class="p">(</span><span class="nf">draw_random_so3</span><span class="p">())</span>

</code></pre></div></div> <table> <thead> <tr> <th> </th> <th>0</th> <th>1</th> <th>2</th> </tr> </thead> <tbody> <tr> <td>0</td> <td>-0.387516</td> <td>-0.605739</td> <td>-0.694918</td> </tr> <tr> <td>1</td> <td>0.468365</td> <td>0.519912</td> <td>-0.714371</td> </tr> <tr> <td>2</td> <td>0.794019</td> <td>-0.602305</td> <td>0.082233</td> </tr> </tbody> </table> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">pd</span><span class="p">.</span><span class="nc">DataFrame</span><span class="p">(</span><span class="nf">draw_random_so3</span><span class="p">())</span>

</code></pre></div></div> <table> <thead> <tr> <th> </th> <th>0</th> <th>1</th> <th>2</th> </tr> </thead> <tbody> <tr> <td>0</td> <td>-0.965783</td> <td>-0.034937</td> <td>-0.256986</td> </tr> <tr> <td>1</td> <td>-0.036723</td> <td>0.999323</td> <td>0.002155</td> </tr> <tr> <td>2</td> <td>0.256737</td> <td>0.011518</td> <td>-0.966413</td> </tr> </tbody> </table> <p><a id="org199071a"></a></p> <h1 id="spectra-comparison">Spectra comparison</h1> <p><a id="orge875ea2"></a></p> <h2 id="-textsu2-">\( \text{SU}(2) \)</h2> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="n">numpy.linalg</span> <span class="kn">import</span> <span class="n">eigvals</span>
<span class="n">su2_eigs</span> <span class="o">=</span><span class="n">np</span><span class="p">.</span><span class="nf">array</span><span class="p">([</span><span class="nf">eigvals</span><span class="p">(</span><span class="nf">draw_random_su2</span><span class="p">())</span> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">10</span><span class="p">)])</span>
<span class="n">pd</span><span class="p">.</span><span class="nc">DataFrame</span><span class="p">(</span><span class="n">su2_eigs</span><span class="p">)</span>

</code></pre></div></div> <table> <thead> <tr> <th> </th> <th>0</th> <th>1</th> </tr> </thead> <tbody> <tr> <td>0</td> <td>-0.206546+0.978437j</td> <td>-0.206546-0.978437j</td> </tr> <tr> <td>1</td> <td>-0.388936+0.921265j</td> <td>-0.388936-0.921265j</td> </tr> <tr> <td>2</td> <td>0.024305-0.999705j</td> <td>0.024305+0.999705j</td> </tr> <tr> <td>3</td> <td>0.025415+0.999677j</td> <td>0.025415-0.999677j</td> </tr> <tr> <td>4</td> <td>-0.629142-0.777290j</td> <td>-0.629142+0.777290j</td> </tr> <tr> <td>5</td> <td>0.483896-0.875125j</td> <td>0.483896+0.875125j</td> </tr> <tr> <td>6</td> <td>-0.498570+0.866850j</td> <td>-0.498570-0.866850j</td> </tr> <tr> <td>7</td> <td>-0.136583+0.990629j</td> <td>-0.136583-0.990629j</td> </tr> <tr> <td>8</td> <td>-0.331002+0.943630j</td> <td>-0.331002-0.943630j</td> </tr> <tr> <td>9</td> <td>-0.224566+0.974459j</td> <td>-0.224566-0.974459j</td> </tr> </tbody> </table> <p>So the eigenvalues of \( \text{SU}(2) \) matrices are always complex conjugates of each other, and lie on the unit circle.</p> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">pandas</span> <span class="k">as</span> <span class="n">pd</span>
<span class="kn">import</span> <span class="n">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="n">pd</span><span class="p">.</span><span class="nc">DataFrame</span><span class="p">(</span><span class="n">np</span><span class="p">.</span><span class="nf">abs</span><span class="p">(</span><span class="n">su2_eigs</span><span class="p">[:</span><span class="mi">5</span><span class="p">]))</span>

</code></pre></div></div> <table> <thead> <tr> <th> </th> <th>0</th> <th>1</th> </tr> </thead> <tbody> <tr> <td>0</td> <td>1.0</td> <td>1.0</td> </tr> <tr> <td>1</td> <td>1.0</td> <td>1.0</td> </tr> <tr> <td>2</td> <td>1.0</td> <td>1.0</td> </tr> <tr> <td>3</td> <td>1.0</td> <td>1.0</td> </tr> <tr> <td>4</td> <td>1.0</td> <td>1.0</td> </tr> </tbody> </table> <p><a id="orge7a6657"></a></p> <h2 id="-textso3-">\( \text{SO}(3) \)</h2> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">from</span> <span class="n">numpy.linalg</span> <span class="kn">import</span> <span class="n">eigvals</span>
<span class="n">so3_eigs</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">array</span><span class="p">([</span><span class="nf">eigvals</span><span class="p">(</span><span class="nf">draw_random_so3</span><span class="p">())</span> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">10</span><span class="p">)])</span>
<span class="n">pd</span><span class="p">.</span><span class="nc">DataFrame</span><span class="p">(</span><span class="n">so3_eigs</span><span class="p">)</span>

</code></pre></div></div> <table> <thead> <tr> <th> </th> <th>0</th> <th>1</th> <th>2</th> </tr> </thead> <tbody> <tr> <td>0</td> <td>-0.368758+0.929525j</td> <td>-0.368758-0.929525j</td> <td>1.000000+0.000000j</td> </tr> <tr> <td>1</td> <td>-0.197081+0.980387j</td> <td>-0.197081-0.980387j</td> <td>1.000000+0.000000j</td> </tr> <tr> <td>2</td> <td>0.436682+0.899616j</td> <td>0.436682-0.899616j</td> <td>1.000000+0.000000j</td> </tr> <tr> <td>3</td> <td>1.000000+0.000000j</td> <td>-0.935815+0.352491j</td> <td>-0.935815-0.352491j</td> </tr> <tr> <td>4</td> <td>-0.318919+0.947782j</td> <td>-0.318919-0.947782j</td> <td>1.000000+0.000000j</td> </tr> <tr> <td>5</td> <td>-0.739021+0.673682j</td> <td>-0.739021-0.673682j</td> <td>1.000000+0.000000j</td> </tr> <tr> <td>6</td> <td>1.000000+0.000000j</td> <td>-0.997412+0.071897j</td> <td>-0.997412-0.071897j</td> </tr> <tr> <td>7</td> <td>1.000000+0.000000j</td> <td>-0.019389+0.999812j</td> <td>-0.019389-0.999812j</td> </tr> <tr> <td>8</td> <td>-0.816935+0.576729j</td> <td>-0.816935-0.576729j</td> <td>1.000000+0.000000j</td> </tr> <tr> <td>9</td> <td>1.000000+0.000000j</td> <td>-0.692390+0.721524j</td> <td>-0.692390-0.721524j</td> </tr> </tbody> </table> <p>Two of the eigenvalues of \( \text{SO}(3) \) matrices are also always complex conjugates of each other, with the other unity.</p> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">numpy</span> <span class="k">as</span> <span class="n">np</span>
<span class="n">np</span><span class="p">.</span><span class="nf">abs</span><span class="p">(</span><span class="n">pd</span><span class="p">.</span><span class="nc">DataFrame</span><span class="p">(</span><span class="n">so3_eigs</span><span class="p">[:</span><span class="mi">5</span><span class="p">]))</span>

</code></pre></div></div> <table> <thead> <tr> <th> </th> <th>0</th> <th>1</th> <th>2</th> </tr> </thead> <tbody> <tr> <td>0</td> <td>1.0</td> <td>1.0</td> <td>1.0</td> </tr> <tr> <td>1</td> <td>1.0</td> <td>1.0</td> <td>1.0</td> </tr> <tr> <td>2</td> <td>1.0</td> <td>1.0</td> <td>1.0</td> </tr> <tr> <td>3</td> <td>1.0</td> <td>1.0</td> <td>1.0</td> </tr> <tr> <td>4</td> <td>1.0</td> <td>1.0</td> <td>1.0</td> </tr> </tbody> </table> <p>Also, the eigenvalues of \( \text{SO}(3) \) also lie on the unit circle. So far, though, I have not yet seen how \( \text{SU}(2) \) is a covers \( \text{SO}(3) \) doubly.</p> <p><a id="orgc16b6c1"></a></p> <h1 id="determinants">Determinants</h1> <p>\( \text{SU}(2) \) matrices have determinant 1 by definition (“Special”). \( \text{SO}(3) \) matrices also have determinant 1 by definition (“Orthogonal”). So this is not a good way to distinguish between the two groups.</p> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">pd</span><span class="p">.</span><span class="nc">DataFrame</span><span class="p">({</span><span class="sh">"</span><span class="s">SU2</span><span class="sh">"</span><span class="p">:</span><span class="n">np</span><span class="p">.</span><span class="n">linalg</span><span class="p">.</span><span class="nf">det</span><span class="p">([</span><span class="nf">draw_random_su2</span><span class="p">()</span> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">5</span><span class="p">)]),</span> <span class="sh">"</span><span class="s">SO3</span><span class="sh">"</span><span class="p">:</span><span class="n">np</span><span class="p">.</span><span class="n">linalg</span><span class="p">.</span><span class="nf">det</span><span class="p">([</span><span class="nf">draw_random_so3</span><span class="p">()</span> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">5</span><span class="p">)])})</span>

</code></pre></div></div> <table> <thead> <tr> <th> </th> <th>SU2</th> <th>SO3</th> </tr> </thead> <tbody> <tr> <td>0</td> <td>1.0+0.0j</td> <td>1.0</td> </tr> <tr> <td>1</td> <td>1.0+0.0j</td> <td>1.0</td> </tr> <tr> <td>2</td> <td>1.0+0.0j</td> <td>1.0</td> </tr> <tr> <td>3</td> <td>1.0+0.0j</td> <td>1.0</td> </tr> <tr> <td>4</td> <td>1.0-0.0j</td> <td>1.0</td> </tr> </tbody> </table> ]]></content><author><name></name></author><category term="post"/><category term="math"/></entry><entry><title type="html">Why we can interpret softmax scores as probabilities</title><link href="https://jsigman.github.io/blog/2024/binary-classifier-derivation/" rel="alternate" type="text/html" title="Why we can interpret softmax scores as probabilities"/><published>2024-01-05T00:00:00+00:00</published><updated>2024-01-05T00:00:00+00:00</updated><id>https://jsigman.github.io/blog/2024/binary-classifier-derivation</id><content type="html" xml:base="https://jsigman.github.io/blog/2024/binary-classifier-derivation/"><![CDATA[<h1 id="foreword">Foreword</h1> <p>I wrote this short essay when I was a postdoc. I started writing it to convince myself that I could interpret softmax scores as probabilities, and not just scores. I hope you find it as useful as I did thinking through it.</p> <h1 id="motivation">Motivation</h1> <p>Suppose we possess data and labels, \(\{(x^{(1)},c^{(1)}),…,(x^{(m)},c^{(m)})\}\), collected from the joint distribution \((x,c) \sim p(x,c)\), with only two possible classes: \(c \in \{A,B\}\).</p> <p>The loss function for a binary classifier \(f_{\theta}(x)=p(A \mid x)\) is given by the well-known<sup id="fnref:fn1"><a href="#fn:fn1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup>:</p> <div class="LATEX" id="orgda0f2ca"> \begin{align} \mathcal{L}(\theta) &amp;= -\sum_{c=A}\log [f_\theta(x)] - \sum_{c=B}\log [1- f_\theta(x)] \end{align} </div> <p>But where does these expressions come from? It is visible upon inspection that minimizing Equation 1 will yield an effective classifier. If the neural network \(f_\theta\) is terminated with a sigmoid function<sup id="fnref:fn2"><a href="#fn:fn2" class="footnote" rel="footnote" role="doc-noteref">2</a></sup>, then examples of class \(A\) will push \(f_\theta(x)\) towards 1 for their values of \(x\), and examples of class \(B\) will be driven toward 0.</p> <p>However, this observation is not enough to say with confidence that the output of the classifier is a good approximation of the conditional <em>probability</em> of the class label, \(P(c \mid x)\).</p> <h1 id="derivation">Derivation</h1> <p>To build such a classifier, we will minimize the KL divergence between our target distribution for a binary classifier, \(P(c \mid x)\), and our model distribution parameterized by \(\theta\), \(f_\theta(c,x)\).</p> <p>For the sake of clarity, while in Equation 1, we used \(f_\theta(x)\) to denote our classifier, here we indicate matching the <em>distribution</em> over all the classes \(\{A,B\}\), and so will use \(f_\theta(c,x)\) instead. There is no real need for the argument \(c\), since we are only interested in the single output \(f_\theta(A,x) = P(A \mid x) = 1 - P(B \mid x)\), and we will make this substitution later to simplify the derived loss.</p> <p>The KL divergence of conditional distributions is the expectation of the distribution of KL divergences taken over each conditional variable:</p> <div class="LATEX" id="orgc36a54c"> \begin{align} D_{KL}(P(c \mid x)||f_\theta(c,x)) = \mathbb{E}_{p(x)}\left[ \mathbb{E}_{P(c \mid x)}\log\left(\frac{P(c \mid x)}{f_\theta(c,x)}\right)\right] \end{align} </div> <p>And to motivate choice of parameters:</p> <div class="LATEX" id="orgef8fd4e"> \begin{align} \hat{\theta} &amp;= \arg \min_{\theta} D_{KL}(P(c \mid x)||f_\theta(c,x))\\ &amp;= \arg \min_{\theta} \mathbb{E}_{p(x)}\left[ \mathbb{E}_{P(c \mid x)}\log(\frac{P(c \mid x)}{f_\theta(c,x)}\right]\\ &amp;= \arg \min_{\theta} \mathbb{E}_{p(x)}\left[ \mathbb{E}_{P(c \mid x)}\log(P(c \mid x)) - \log(f_\theta(c,x)\right] \end{align} </div> <p>Taking an expectation over \(p(x)\) and then \(P(c \mid x)\) is the same as drawing samples from and calculating an expectation over samples from the joint distribution, so we can write:</p> <div class="LATEX" id="org9987a74"> \begin{align} \hat{\theta} &amp;= \arg \min_{\theta} \mathbb{E}_{p(c,x)}\left[ \log(P(c \mid x)) - \log(f_\theta(c,x))\right] \end{align} </div> <p>And after dropping terms not involving \(\theta\):</p> <div class="LATEX" id="orgafb0d1e"> \begin{align} \hat{\theta} &amp;= \arg \min_{\theta} -\mathbb{E}_{p(c,x)}\log\left(f_\theta(c,x)\right) \end{align} </div> <p>Interestingly enough, at this point, minimizing the KL divergence statement of Equation 2 in order to produce \(P(c \mid x)\) looks as if we were trying to match the joint distribution \(p(c,x)\), because we’ve dropped any terms indicating conditional probability. It must be, therefore, that some feature in the architecture of \(f_{\theta}\) is the reason we say it mimics the conditional distribution, and not the joint.</p> <p>By the law of large numbers, we can estimate the expectation in Equation 3 by summing over samples:</p> <div class="LATEX" id="orga4497a3"> \begin{align} \hat{\theta} &amp;= \arg \min_{\theta} - \frac{1}{N_A} \sum_{A} \log \left(f_\theta(A,x)\right) -\frac{1}{N_B} \sum_{B} \log\left(f_\theta(B,x)\right) \end{align} </div> <p>where \(\sum_A, \sum_B\) indicate taking the sum using examples of classes \(A\) and \(B\), and \(N_A\) and \(N_B\) are the number of samples of each class. If there are equal number of samples of each class \(N_A=N_B\), so the prior \(P( c) = P(A) = P(B) = .5\), as we do in GAN:</p> <div class="LATEX" id="org6963f64"> \begin{align} \hat{\theta} &amp;= \arg \min_{\theta} - \sum_{A} \log \left(f_\theta(A,x)\right) -\sum_{B} \log\left(f_\theta(B,x)\right) \end{align} </div> <p>Choice of architecture allows us to say \(f_{\theta}\) approximates \(P(c \mid x)\), not objective function. Here, we choose \(f_{\theta}\) to be a legitimate probability distribution over class labels \(c\) by defining \(f_{\theta}(A,x) = 1 - f_{\theta}(B,x)\), and for simplicity, write \(f_{\theta}(A,x)\) as \(f_{\theta}(x)\). If we choose \(f_{\theta}\) so its output is between 0 and 1, by use of a sigmoid activation function, then we can learn a valid approximator for the conditional probability function \(P(c \mid x)\) by minimizing:</p> <div class="LATEX" id="org544d7b8"> \begin{align} \mathcal{L}(\theta) &amp;= -\sum_{A}\log [f_\theta(x)] - \sum_{B}\log [1- f_\theta(x)] \end{align} </div> <div class="footnotes" role="doc-endnotes"> <ol> <li id="fn:fn1"> <p>This is the same as the discriminator network of a GAN, whose loss function is given: \(\mathcal{L}(\psi)=-\mathbb{E}_{p(z)}\log\sigma(g_{\psi}(f_\theta(z))) - \mathbb{E}_{q(x)}\log[1 - \sigma(g_{\psi}(x))]\) <a href="#fnref:fn1" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> <li id="fn:fn2"> <p>Without loss of generality, we can consider binary classifiers of one channel terminated by sigmoid instead of softmax. <a href="#fnref:fn2" class="reversefootnote" role="doc-backlink">&#8617;</a></p> </li> </ol> </div>]]></content><author><name></name></author><category term="post"/><category term="machine\_learning,"/><category term="math"/><summary type="html"><![CDATA[Something from postdoc days]]></summary></entry><entry><title type="html">Indicating which blocks are loaded in webpage literate elisp</title><link href="https://jsigman.github.io/blog/2023/greyed-out-source-blocks/" rel="alternate" type="text/html" title="Indicating which blocks are loaded in webpage literate elisp"/><published>2023-07-23T00:00:00+00:00</published><updated>2023-07-23T00:00:00+00:00</updated><id>https://jsigman.github.io/blog/2023/greyed-out-source-blocks</id><content type="html" xml:base="https://jsigman.github.io/blog/2023/greyed-out-source-blocks/"><![CDATA[<h2 id="the-need-for-indicating-what-source-is-run">The need for indicating what source is run</h2> <p>My literate elisp webpage has a problem. It does not tell the reader what source code is loaded at startup, and what source code is vestigial, and only there to remind me that I configured a package but didn’t like it. I’d like the webpage to show this to the user.</p> <h2 id="how-to-display-to-the-user">How to display to the user</h2> <p>I solved this by dynamically converting <code class="language-plaintext highlighter-rouge">emacs-lisp</code> blocks to <code class="language-plaintext highlighter-rouge">plaintext</code> blocks at org-export time. This way, the emacs lisp code will look like:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>(print "This code will not be run!")
</code></pre></div></div> <p>if it is skipped, and</p> <div class="language-emacs-lisp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">print</span> <span class="s">"This code is run in my config!"</span><span class="p">)</span>
</code></pre></div></div> <p>if it is loaded by the <code class="language-plaintext highlighter-rouge">literate-elisp</code> library.</p> <h2 id="the-solution">The solution</h2> <p>Replacing header blocks that look like <code class="language-plaintext highlighter-rouge">#+begin_src emacs-lisp :load no</code> with header blocks that look like <code class="language-plaintext highlighter-rouge">#+begin_src plaintext</code> will achieve this in the <code class="language-plaintext highlighter-rouge">rouge</code> syntax highlighting system. I can do this (somewhat) hackily with some very simple regular expressions over the pure org source before export.</p> <div class="language-emacs-lisp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="nb">defun</span> <span class="nv">my/org-export-filter-src-blocks</span> <span class="p">(</span><span class="nv">backend</span><span class="p">)</span>
  <span class="p">(</span><span class="nb">when</span> <span class="p">(</span><span class="nb">eq</span> <span class="nv">backend</span> <span class="ss">'jekyll</span><span class="p">)</span>
    <span class="p">(</span><span class="nv">goto-char</span> <span class="p">(</span><span class="nv">point-min</span><span class="p">))</span>
    <span class="p">(</span><span class="nv">while</span> <span class="p">(</span><span class="nv">re-search-forward</span> <span class="s">"^#\\+begin_src\\s-+emacs-lisp\\(.*:load\\s-+no.*\\)$"</span> <span class="no">nil</span> <span class="no">t</span><span class="p">)</span>
      <span class="p">(</span><span class="nv">replace-match</span> <span class="s">"#+begin_src plaintext"</span><span class="p">))))</span>

<span class="p">(</span><span class="nv">add-hook</span> <span class="ss">'org-export-before-processing-hook</span> <span class="ss">'my/org-export-filter-src-blocks</span><span class="p">)</span>
</code></pre></div></div> <p><a href="https://github.com/jsigman/emacs-config/blob/main/.github/publish.el#L10">See where the code is run in the workflow code for automated export of the tangled config.</a></p> <p><a href="https://www.johnsigman.com/projects/emacs_config/">See the literate elisp webpage</a></p> <p><a href="https://www.johnsigman.com/blog/2023/announcing-my-emacs-config/">Another TODO down</a></p>]]></content><author><name></name></author><category term="emacs"/><summary type="html"><![CDATA[The need for indicating what source is run]]></summary></entry><entry><title type="html">Hosting my CV with github actions</title><link href="https://jsigman.github.io/blog/2023/hosting-my-CV-with-github-actions/" rel="alternate" type="text/html" title="Hosting my CV with github actions"/><published>2023-06-02T00:00:00+00:00</published><updated>2023-06-02T00:00:00+00:00</updated><id>https://jsigman.github.io/blog/2023/hosting-my-CV-with-github-actions</id><content type="html" xml:base="https://jsigman.github.io/blog/2023/hosting-my-CV-with-github-actions/"><![CDATA[<h2 id="the-goal">The Goal</h2> <p>I want to host the PDF of my CV on this site. I want it to link to the latest compiled version from where it’s tracked on github (private repo).</p> <h2 id="how-i-was-doing-it-before">How I was doing it before</h2> <p>I linked to a public shared folder on my Dropbox. This meant that every time I update the CV locally, I have to upload the new version to github.</p> <h2 id="the-solution">The solution</h2> <h3 id="building-the-document-and-releasing-it">Building the document and releasing it</h3> <p>First, I created a new github action to build the PDF of the CV from <code class="language-plaintext highlighter-rouge">.tex</code> like this (only the <code class="language-plaintext highlighter-rouge">jobs</code> section necessary to show here):</p> <div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">jobs</span><span class="pi">:</span>
  <span class="na">publish</span><span class="pi">:</span>
    <span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
    <span class="na">steps</span><span class="pi">:</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Checkout repository</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v3</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Compile</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">xu-cheng/latex-action@v2</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">working-directory</span><span class="pi">:</span> <span class="s2">"</span><span class="s">CV"</span>
          <span class="na">root_file</span><span class="pi">:</span> <span class="pi">|</span>
            <span class="s">John_Brevard_Sigman_CV.tex</span>
          <span class="na">pre_compile</span><span class="pi">:</span> <span class="pi">|</span>
            <span class="s">make build-bib</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Create Release</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">softprops/action-gh-release@v1</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">tag_name</span><span class="pi">:</span> <span class="s">latest</span>
          <span class="na">files</span><span class="pi">:</span> <span class="s">John_Brevard_Sigman_CV.pdf</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Clear old releases</span>
        <span class="na">uses</span><span class="pi">:</span> <span class="s">dev-drprasad/delete-older-releases@v0.2.1</span>
        <span class="na">with</span><span class="pi">:</span>
          <span class="na">keep_latest</span><span class="pi">:</span> <span class="m">1</span>
        <span class="na">env</span><span class="pi">:</span>
          <span class="na">GITHUB_TOKEN</span><span class="pi">:</span> <span class="s">$</span>
      <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Close</span>
        <span class="na">run</span><span class="pi">:</span> <span class="s">exit </span><span class="m">0</span>
</code></pre></div></div> <p>I use <a href="https://github.com/xu-cheng/latex-action">xu-cheng/latex-action@v2</a> to compile to PDF, preceded by running <code class="language-plaintext highlighter-rouge">build-bib</code> from the make target (see below):</p> <div class="language-makefile highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nl">build-bib</span><span class="o">:</span>
	latex John_Brevard_Sigman_CV.tex
	latex John_Brevard_Sigman_CV.tex
	bibtex John_Brevard_Sigman_CV1-blx
	bibtex John_Brevard_Sigman_CV2-blx
	bibtex John_Brevard_Sigman_CV3-blx
</code></pre></div></div> <p>The three calls to <code class="language-plaintext highlighter-rouge">bibtex</code> are to compile separate bibliographies <code class="language-plaintext highlighter-rouge">papers.bib</code>, <code class="language-plaintext highlighter-rouge">patents.bib</code>, and <code class="language-plaintext highlighter-rouge">government_reports.bib</code> from the auxiliary files <code class="language-plaintext highlighter-rouge">*CV[X]-blx</code>. These files were generated by the two calls to <code class="language-plaintext highlighter-rouge">latex</code>.</p> <h3 id="fetching-the-release-from-the-website">Fetching the release from the website</h3> <p>I next modified the deployment action for this github pages website so that it would fetch the latest release of the CV repo.</p> <h4 id="personal-access-token">Personal Access Token</h4> <p>First, make a personal access token with fine-grained read-only permission to the CV repo. Then, upload this as an encrypted secret (<code class="language-plaintext highlighter-rouge">CV_ACCESS_TOKEN</code>) of the website repo.</p> <h4 id="action-to-pull-the-release">Action to pull the release</h4> <div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Get latest CV release</span>
  <span class="na">uses</span><span class="pi">:</span> <span class="s">robinraju/release-downloader@v1.8</span>
  <span class="na">with</span><span class="pi">:</span>
    <span class="na">repository</span><span class="pi">:</span> <span class="s2">"</span><span class="s">jsigman/CV"</span>
    <span class="na">latest</span><span class="pi">:</span> <span class="kc">true</span>
    <span class="na">fileName</span><span class="pi">:</span> <span class="s2">"</span><span class="s">John_Brevard_Sigman_CV.pdf"</span>
    <span class="na">out-file-path</span><span class="pi">:</span> <span class="s2">"</span><span class="s">assets/pdf/"</span>
    <span class="na">token</span><span class="pi">:</span> <span class="s">${{ secrets.CV_ACCESS_TOKEN }}</span>
</code></pre></div></div> <p>I use <a href="https://github.com/robinraju/release-downloader">robinraju/release-downloader@v1.8</a> fetch the latest release, and it’s ready to be shared on the website. This setup is clean and hands off!</p>]]></content><author><name></name></author><category term="latex,"/><category term="github"/><summary type="html"><![CDATA[A clean way to automatically host the latest version of my CV]]></summary></entry><entry><title type="html">Company Announcement about LLM Project</title><link href="https://jsigman.github.io/blog/2023/hybrid-llm-idp/" rel="alternate" type="text/html" title="Company Announcement about LLM Project"/><published>2023-05-30T00:00:00+00:00</published><updated>2023-05-30T00:00:00+00:00</updated><id>https://jsigman.github.io/blog/2023/hybrid-llm-idp</id><content type="html" xml:base="https://jsigman.github.io/blog/2023/hybrid-llm-idp/"><![CDATA[<p>It’s a little bit marketing-ese, but we published something about some work we’re doing using Large Language Models (LLMs) to automate entity extraction and the Data Science process in Documents. <a href="https://infiniaml.com/hybrid-idp-with-generative-ai/">You can read about it here</a>.</p>]]></content><author><name></name></author><category term="idp,"/><category term="llm"/><summary type="html"><![CDATA[It’s a little bit marketing-ese, but we published something about some work we’re doing using Large Language Models (LLMs) to automate entity extraction and the Data Science process in Documents. You can read about it here.]]></summary></entry><entry><title type="html">Literate emacs config as a webpage</title><link href="https://jsigman.github.io/blog/2023/announcing-my-emacs-config/" rel="alternate" type="text/html" title="Literate emacs config as a webpage"/><published>2023-05-22T00:00:00+00:00</published><updated>2023-05-22T00:00:00+00:00</updated><id>https://jsigman.github.io/blog/2023/announcing-my-emacs-config</id><content type="html" xml:base="https://jsigman.github.io/blog/2023/announcing-my-emacs-config/"><![CDATA[<h2 id="a-fun-new-project">A fun new project</h2> <p>With unclear readership, I’m starting my tech blog about emacs, python, and machine learning. I hope that others enjoy my tips and perspective, but I’m mostly excited to gain some skills around web technologies and social media (not the instagram kind).</p> <p>For a few years, I’ve been sharing my emacs configuration <a href="https://github.com/jsigman/emacs-config">on github</a>. I make this public, but its real use is that I can clone and track this across different machines. Less than a year ago, I migrated to <a href="https://github.com/jingtaozf/literate-elisp">literate elisp</a> so that I could weave comments in with the lisp code. Who doesn’t love an excuse to learn <a href="https://orgmode.org/">org mode</a> a little better?</p> <p>Most recently, I played with github actions to release a tangled version of the entire configuration code, and I share it <a href="https://www.johnsigman.com/projects/emacs_config/">on this website as a project</a>. Take a look, there are about 10 years of tinkering in that one document. Tinkering from grad school, through a postdoc, and continued as a professional.</p> <h2 id="already-good-for">Already good for</h2> <ul> <li>Easily reviewable and consumable</li> <li>Syncs with the latest commit of the `main` github branch</li> <li>Web searchable</li> </ul> <h2 id="todos">Todos</h2> <ul> <li><strike>Add better comments to the code and explanations about what I like and don't like</strike></li> <li><strike>Make org export whether a code block is loaded at run time or not. Many of the blocks seen in the web page are vestigial, and not loaded at startup</strike></li> <li><strike>Explain how I made scripts and github actions to sync the project document to the latest export of literate elisp</strike></li> <li>Learn footnotes in Jekyll to ape David Foster Wallace</li> <li>Make the web page re-build on every release action of the config repo</li> <li>Find a way to link to subsections of the web version from blog posts</li> </ul>]]></content><author><name></name></author><category term="emacs"/><summary type="html"><![CDATA[Starting the blog with emacs]]></summary></entry></feed>