<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="andyyyyuuu.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="andyyyyuuu.github.io/" rel="alternate" type="text/html" /><updated>2026-07-19T02:19:44+00:00</updated><id>andyyyyuuu.github.io/feed.xml</id><title type="html">Andy S Yu</title><subtitle>Blog to dump the things I read, build, discover, and think about. </subtitle><entry><title type="html">What kinds of outputs are unattainable by LLMs?</title><link href="andyyyyuuu.github.io/2026/07/13/llm-expressivity-p1.html" rel="alternate" type="text/html" title="What kinds of outputs are unattainable by LLMs?" /><published>2026-07-13T13:49:00+00:00</published><updated>2026-07-13T13:49:00+00:00</updated><id>andyyyyuuu.github.io/2026/07/13/llm-expressivity-p1</id><content type="html" xml:base="andyyyyuuu.github.io/2026/07/13/llm-expressivity-p1.html"><![CDATA[<p><em>The code for this project can be found in the <a href="https://github.com/AndyyyYuuu/llm-expressivity" target="_blank">repo</a>.</em></p>

<p>LLMs<sup>1</sup> model text by outputting a probability distribution for the next token, over the \(M\) tokens in a vocabulary. Funnily enough, it is a well-proven fact that this output can only express a limited set of values. In fact, nearly all \(M\)-element probability distributions <strong>cannot</strong> be output by any LLM no matter what we input.</p>

<p>That can be a problem, because it means that, although we want LLMs to perfectly capture all patterns in natural language, they probably can’t.<sup>2</sup></p>

<p>I will be elaborating on the reason for this bottleneck in another blog post. But for this project, we’re not mainly interested in why there is a bottleneck. We’re more interested in the <em>characteristics</em> of distributions that this bottleneck limits.</p>

<h3 id="experiment">Experiment</h3>

<p><a href="https://doi.org/10.48550/arXiv.2505.12244" target="_blank">Wang et al. (2025)</a> points out that the <a href="https://en.wikipedia.org/wiki/Entropy_(information_theory)" target="_blank">entropy</a> of a distribution seems to be a governing factor in how closely an LLM is able to approximate it. I reproduced the experiment on <a href="https://huggingface.co/meta-llama/Llama-3.2-1B" target="_blank">Llama 3.2 1B</a> and confirmed the results in my figure below:</p>

<p><img src="https://raw.githubusercontent.com/AndyyyYuuu/llm-expressivity/refs/heads/main/results/figures/vanilla_embed.png" alt="Figure" /></p>

<p>This is surprisingly clean. Low-entropy and high-entropy distributions both prove easy to produce, whereas the LLM is not able to closely approximate medium entropy distributions.</p>

<details>
  <summary>More details on methods</summary>
  <div class="details-body">

    <p>My methods reproduce <em>soft prompt tuning for vanilla distributions</em> as laid out by <a href=" https://doi.org/10.48550/arXiv.2505.12244" target="_blank">Wang et al. (2025)</a>.</p>

    <ol>
      <li>I synthesize a set of <em>target</em> probability distributions over the vocabulary, with entropies ranging from the theoretical minimum to the maximum. I use gradient descent to optimize for the entropy of each distribution.</li>
      <li>I use soft prompt tuning to find the input that would elicit an LLM output matching each target distributions as closely as possible.</li>
      <li>I compute the KL-divergence between the LLM’s output and the target, and plot it relative to the entropy of the target.</li>
    </ol>
  </div>
</details>

<p>Wang et al. notes that the same phenomenon occurs in randomly-initialized models, and so I may rule out the role of pre-training and limit its cause to the architecture. But for the most part, the <em>why</em> question remains unanswered; I take a stab at it in the next blog post.</p>

\[\blacksquare\]

<hr />

<div class="footnotes">
  <ol>
    <li>
      <p>In this post, I use LLMs to refer more specifically to transformer-based autoregressive language models.</p>
    </li>
    <li>
      <p>Though, as <a href="https://openreview.net/forum?id=DgJqQk6y19" target="_blank">Basri and Jacobs (2026)</a> demonstrates, it’s not as <em>huge</em> of a problem in practice.</p>
    </li>
  </ol>

</div>]]></content><author><name></name></author><category term="project" /><category term="nlp" /><summary type="html"><![CDATA[The code for this project can be found in the repo.]]></summary></entry><entry><title type="html">Binet’s Formula w/ Power Series</title><link href="andyyyyuuu.github.io/2026/07/02/binet-s-formula-w-power-series.html" rel="alternate" type="text/html" title="Binet’s Formula w/ Power Series" /><published>2026-07-02T18:24:00+00:00</published><updated>2026-07-02T18:24:00+00:00</updated><id>andyyyyuuu.github.io/2026/07/02/binet-s-formula-w-power-series</id><content type="html" xml:base="andyyyyuuu.github.io/2026/07/02/binet-s-formula-w-power-series.html"><![CDATA[<p>As a first post, I thought I’d share a derivation that may be of interest to anybody who has recently taken first-year college calculus. This piece of math amazed me when it was first shown to me during a lecture.</p>

<p>For ease of reading, I’ve separated this derivation into sections using horizontal lines, where each section builds upon the conclusion of the previous section. It goes something like this.</p>

<hr />

<p>Let \(\{F_n\}_{n=0}^\infty\) be the Fibonacci Sequence. This is defined by base cases</p>

\[F_0 = 0, \quad F_1 = 1\]

<p>and for all \(n \geq 2\), the Sequence is defined recurrently by</p>

\[F_n = F_{n-1} + F_{n-2}.\]

<hr />

<p>We first establish that \(F_n\) is an increasing sequence (you can prove this rigorously using induction), and therefore, that \(F_n \geq 0.\)</p>

<p>Then, for all \(n \geq 2\), we have from the definition that \(F_n=F_{n-1}+F_{n-2} \leq F_{n-1} + F_{n-1} = 2F_{n-1}\), so \(F_n \leq 2F_{n-1}\). A little intuition tells us that since the next item in the Sequence is less than or equal to double the previous, the growth speed of this function at most follows \(2^n\). Indeed, \(F_n \leq 2^n\), and you can again prove this using induction if you like.</p>

<p>We bound \(0 \leq F_n \leq 2^n\) from the last two paragraphs. Then, for \(n \geq 0\),</p>

\[\displaylines{
\frac{0}{4^n} \leq \frac{F_n}{4^n} \leq \frac{2^n}{4^n}\\
0 \leq \frac{F_n}{4^n} \leq \frac1{2^n}.
}\]

<p>Therefore, by the comparison test, since \(\sum\limits_{n=0}^\infty\frac1{2^n}\) converges, the series \(\sum\limits_{n=0}^\infty\frac{F_n}{4^n}\) also converges.</p>

<p>Okay, stay with me.</p>

<hr />

<p>Consider now a power series with Fibonacci coefficients:</p>

\[\sum\limits_{n=0}^\infty F_nx^n\]

<p>Note that we can plug in \(\frac14\) to get \(\sum\limits_{n=0}^\infty\frac{F_n}{4^n}\), which we just proved converges, and the series converges to \(0\) trivially when \(x=0\). Using a few theorems from Calculus on radii of convergence, we know that this series converges on at least a radius of \(\frac14\) around \(0\). So for some function \(f\),</p>

\[f(x) = \sum\limits_{n=0}^\infty F_nx^n\]

<p>when \(-\frac14 &lt; x \leq \frac14\).</p>

<p>By the uniqueness of power series representations, any function that adheres to its power series on an interval has a <strong>unique</strong> power series representation on that interval. We can thus claim that within \((-\frac14, \frac14]\), \(\sum\limits_{n=0}^\infty F_nx^n\) is not only a power series representation of \(f(x)\), it is the <strong>unique</strong> one.</p>

<hr />

<p>That’s a cool result, but let’s try and obtain more information about this mysterious \(f(x)\). Of course, the below calculations are bounded on our working interval of \((-\frac14, \frac14]\). We first separate out the first two elements of the series:</p>

\[f(x) = \sum\limits_{n=0}^\infty F_nx^n = F_0 x^0 + F_1 x^1 + \sum\limits_{n=2}^\infty F_nx^n.\]

<p>Substituting \(F_0, F_1,\) and \(F_n\) out for their definitions from earlier and simplifying, we have</p>

\[f(x) = 0 + x + \sum\limits_{n=2}^\infty (F_{n-1} + F_{n-2}) x^n.\]

<p>We then split up the remaining series by distributive property and reindex them:</p>

\[f(x) = x + \sum\limits_{n=2}^\infty F_{n-1} x^n + \sum\limits_{n=2}^\infty F_{n-2} x^n = x + \sum\limits_{n=1}^\infty F_{n} x^{n+1} + \sum\limits_{n=0}^\infty F_{n} x^{n+2}.\]

<p>Factor out \(x\) and \(x^2\):</p>

\[f(x) = x + x \sum\limits_{n=1}^\infty F_{n} x^n + x^2\sum\limits_{n=0}^\infty F_{n} x^n.\]

<p>We can then substitute in \(\sum\limits_{n=0}^\infty F_{n} x^n = f(x)\) to obtain:</p>

\[f(x) = x + xf(x) + x^2f(x),\]

<p>completely removing any infinite sequences from the equation.</p>

<hr />

<p>Let’s solve for \(f(x)\). Rearranging the equation yields</p>

\[f(x) = \frac{x}{1-x-x^2}.\]

<p>We then decompose the fraction to get</p>

\[f(x) = \frac{\frac{1}{\sqrt5}}{1-\frac{1+\sqrt5}{2}x}-\frac{\frac{1}{\sqrt5}}{1-\frac{1-\sqrt5}{2}x}.\]

<p>(You’re just gonna have to take my prof’s word on this one, because I don’t want to spend time decomposing this)</p>

<p>At this point, we notice that these forms may look very familiar from the formula \(\frac{a}{1-r} = \sum\limits_{n=0}^\infty ar^n\), so we apply it on the fractions above to get back to infinite series:</p>

\[f(x) = \sum\limits_{n=0}^\infty\frac1{\sqrt5}\left(\frac{1+\sqrt5}{2}x\right)^n-\sum\limits_{n=0}^\infty\frac1{\sqrt5}\left(\frac{1-\sqrt5}{2}x\right)^n = \sum\limits_{x=0}^\infty\left[\frac1{\sqrt{5}}\left(\frac{1+\sqrt5}2\right)^n-\frac1{\sqrt{5}}\left(\frac{1-\sqrt5}2\right)^n\right]x^n.\]

<p>We now have two power series representations for \(f(x)\) on its domain:</p>

\[\displaylines{
    f(x) = \sum\limits_{n=0}^\infty F_nx^n \\
    f(x) = \sum\limits_{n=0}^\infty\left[\frac1{\sqrt{5}}\left(\frac{1+\sqrt5}2\right)^n-\frac1{\sqrt{5}}\left(\frac{1-\sqrt5}2\right)^n\right]x^n.
}\]

<p>Since \(f(x)\) has a unique power series representation, these two series must have the same coefficients; so, we can equate</p>

\[F_n = \frac1{\sqrt{5}}\left(\frac{1+\sqrt5}2\right)^n-\frac1{\sqrt{5}}\left(\frac{1-\sqrt5}2\right)^n,\]

<p>and bam, we have a closed form for the Fibonacci Sequence! \(~\square\)</p>

<p>It turns out that, after some further reading, this technique of using generating functions to find closed forms for sequences is not uncommon. But it did surprise me, and I hope you found it interesting too.</p>

<p>Thanks for reading!</p>

\[\blacksquare\]]]></content><author><name></name></author><category term="math" /><summary type="html"><![CDATA[As a first post, I thought I’d share a derivation that may be of interest to anybody who has recently taken first-year college calculus. This piece of math amazed me when it was first shown to me during a lecture.]]></summary></entry><entry><title type="html">Hello World!!</title><link href="andyyyyuuu.github.io/2026/06/25/hello-world.html" rel="alternate" type="text/html" title="Hello World!!" /><published>2026-06-25T23:29:00+00:00</published><updated>2026-06-25T23:29:00+00:00</updated><id>andyyyyuuu.github.io/2026/06/25/hello-world</id><content type="html" xml:base="andyyyyuuu.github.io/2026/06/25/hello-world.html"><![CDATA[<p>I just got this thing set up. Figured I could dump updates and thoughts here.</p>

<p>In the meantime, we can approximate \(e^x\) by</p>

\[e^x = \sum\limits_{i=0}^\infty \frac{x^n}{n!},\]

<p>from which we see that MathJax seems to be working.</p>

<hr />

<p>I can also paste some code.</p>

<div class="language-py highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">entropy</span><span class="p">(</span><span class="n">x</span><span class="p">:</span> <span class="n">torch</span><span class="p">.</span><span class="n">Tensor</span><span class="p">,</span> <span class="n">dim</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">alpha</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mi">1</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">torch</span><span class="p">.</span><span class="n">Tensor</span><span class="p">:</span>
    <span class="k">if</span> <span class="n">alpha</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span> 
        <span class="k">return</span> <span class="o">-</span><span class="n">torch</span><span class="p">.</span><span class="nb">sum</span><span class="p">(</span><span class="n">x</span> <span class="o">*</span> <span class="n">torch</span><span class="p">.</span><span class="n">log</span><span class="p">(</span><span class="n">x</span><span class="p">),</span> <span class="n">dim</span><span class="o">=</span><span class="n">dim</span><span class="p">)</span>
    <span class="k">elif</span> <span class="n">alpha</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span> 
        <span class="k">return</span> <span class="n">torch</span><span class="p">.</span><span class="n">log</span><span class="p">((</span><span class="n">x</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">).</span><span class="nb">sum</span><span class="p">(</span><span class="n">dim</span><span class="o">=</span><span class="n">dim</span><span class="p">).</span><span class="nb">float</span><span class="p">())</span>
    <span class="k">return</span> <span class="n">torch</span><span class="p">.</span><span class="n">log</span><span class="p">(</span><span class="n">torch</span><span class="p">.</span><span class="nb">sum</span><span class="p">(</span><span class="n">x</span> <span class="o">**</span> <span class="n">alpha</span><span class="p">,</span> <span class="n">dim</span><span class="o">=</span><span class="n">dim</span><span class="p">))</span> <span class="o">/</span> <span class="p">(</span><span class="mi">1</span> <span class="o">-</span> <span class="n">alpha</span><span class="p">)</span>
</code></pre></div></div>

<p>Neat.</p>]]></content><author><name></name></author><category term="meta" /><summary type="html"><![CDATA[I just got this thing set up. Figured I could dump updates and thoughts here.]]></summary></entry></feed>