<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>circuit - Crowded Space</title>
    <subtitle>Writing on the mathematics inside neural networks</subtitle>
    <link rel="self" type="application/atom+xml" href="https://circuit.khalilli.ai/series/crowded-space/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://circuit.khalilli.ai"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-07-23T00:00:00+00:00</updated>
    <id>https://circuit.khalilli.ai/series/crowded-space/atom.xml</id>
    <entry xml:lang="en">
        <title>Almost Orthogonal</title>
        <published>2026-07-23T00:00:00+00:00</published>
        <updated>2026-07-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              alikhalilli
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://circuit.khalilli.ai/blog/almost-orthogonal/"/>
        <id>https://circuit.khalilli.ai/blog/almost-orthogonal/</id>
        
        <content type="html" xml:base="https://circuit.khalilli.ai/blog/almost-orthogonal/">&lt;h2 id=&quot;the-neural-storage-problem&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-neural-storage-problem&quot; aria-label=&quot;Anchor link for: the-neural-storage-problem&quot;&gt;The neural storage problem&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Here&#x27;s a strange fact about large language models. A single model knows
about millions of things: names, places, languages, programming syntax,
old chess openings. But everything it holds at any one point of the text is a single
list of a few thousand numbers &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-1&quot;&gt;1&lt;&#x2F;a&gt;, &lt;a href=&quot;#ref-15&quot;&gt;15&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;. Millions of things, a few thousand
slots. This series is about how that&#x27;s even possible, and what it costs.&lt;&#x2F;p&gt;
&lt;p&gt;The clearest sign that something odd is happening comes from watching
individual neurons. First, two quick definitions, so that nothing here is
magic. A language model is a mathematical function: you give it a piece
of text, and it gives back a probability for every possible next token,
where a token is a word or a piece of a word. Inside, the function has a
huge number of adjustable values, and training means tuning those values
on enormous amounts of real text until the predictions become good. A
neuron is one of the function&#x27;s smallest parts, and it&#x27;s a tiny function
itself: it takes the numbers flowing through the model and produces a
single number of its own. The exact formula is short, and it appears
later in this article. For now, the only thing that matters is that
watching a neuron means watching one number.&lt;&#x2F;p&gt;

&lt;figure class=&quot;drawing wide&quot; style=&quot;--dw: 898px;&quot;&gt;
  &lt;div class=&quot;drawing-card&quot;&gt;
    &lt;img class=&quot;drawing-light&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;familiar-picture-light.svg?h=0d7107df00f5a95c03be&quot;
         alt=&quot;a piece of text flows into layers of circles connected by lines, and out comes a probability for every possible next token drawn as bars, with one glowing orange circle in a middle layer and a zoom bubble showing what that unit really is: several numbers arrive, one number leaves&quot; width=&quot;898&quot; height=&quot;508&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
    &lt;img class=&quot;drawing-dark&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;familiar-picture-dark.svg?h=0c26d2aeae578aade2a8&quot;
         alt=&quot;a piece of text flows into layers of circles connected by lines, and out comes a probability for every possible next token drawn as bars, with one glowing orange circle in a middle layer and a zoom bubble showing what that unit really is: several numbers arrive, one number leaves&quot; width=&quot;898&quot; height=&quot;508&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
  &lt;&#x2F;div&gt;
  &lt;figcaption&gt;&lt;span class=&quot;fig-label&quot;&gt;Figure 1.&lt;&#x2F;span&gt; the picture you already know, and what one unit of it really is: numbers arrive, one number leaves&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;In 2023, researchers at Anthropic trained a small model on purpose: one
layer, 512 neurons, small enough to study closely &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-2&quot;&gt;2&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;. One neuron&#x27;s
number became large whenever the text was an academic citation. The same
number became large on English dialogue. And on HTTP requests. And on
Korean text &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-2&quot;&gt;2&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;. Four completely unrelated kinds of text, and one number
that rises for all of them.&lt;&#x2F;p&gt;

&lt;figure class=&quot;drawing wide&quot; style=&quot;--dw: 973px;&quot;&gt;
  &lt;div class=&quot;drawing-card&quot;&gt;
    &lt;img class=&quot;drawing-light&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;one-number-light.svg?h=c48af580c5661fff3eca&quot;
         alt=&quot;four small cards in a row, each a real input: an academic citation, English dialogue, an HTTP request, and Korean text, with a dashed arrow from each card down to a single orange trace of one neuron&amp;#x27;s number, rising to the same dashed level line under every card, and quiet in between&quot; width=&quot;973&quot; height=&quot;410&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
    &lt;img class=&quot;drawing-dark&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;one-number-dark.svg?h=e8b2db37bc301619b7dd&quot;
         alt=&quot;four small cards in a row, each a real input: an academic citation, English dialogue, an HTTP request, and Korean text, with a dashed arrow from each card down to a single orange trace of one neuron&amp;#x27;s number, rising to the same dashed level line under every card, and quiet in between&quot; width=&quot;973&quot; height=&quot;410&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
  &lt;&#x2F;div&gt;
  &lt;figcaption&gt;&lt;span class=&quot;fig-label&quot;&gt;Figure 2.&lt;&#x2F;span&gt; four completely unrelated kinds of text, and one number that rises for all of them&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;The natural reaction is that the neuron is broken. The model was too
small, the training too short.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s a name for neurons like this, and it comes from Greek: &lt;em&gt;poly&lt;&#x2F;em&gt;,
many, &lt;em&gt;sema&lt;&#x2F;em&gt;, meaning. A &lt;em&gt;polysemantic&lt;&#x2F;em&gt; neuron is one unit carrying many
meanings at once &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-2&quot;&gt;2&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;. And they aren&#x27;t rare. In large models, polysemantic
neurons are the norm, and a neuron with one clean meaning is the
exception &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-2&quot;&gt;2&lt;&#x2F;a&gt;, &lt;a href=&quot;#ref-3&quot;&gt;3&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Which is why one odd neuron deserves six articles. A model that predicts
text well has to track far more things than it has neurons, so sharing
isn&#x27;t optional &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-1&quot;&gt;1&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;. And linear algebra, at least the way most of us
remember it, says sharing shouldn&#x27;t work: a space holds only as many
independent quantities as it has dimensions. The models clearly didn&#x27;t
read that theorem. Something in the usual understanding of dimension is
incomplete.&lt;&#x2F;p&gt;
&lt;p&gt;That gap is what this article is about. Closing it takes four ideas, each
rebuilt from the ground: space, dimension, the dot product, and
orthogonality. You probably use all four every week. You&#x27;ve probably
never had to examine any of them closely. I hadn&#x27;t either.&lt;&#x2F;p&gt;
&lt;p&gt;One promise before we start. By the end of these six parts, you&#x27;ll read
the research papers this series is built on, Anthropic&#x27;s superposition
papers above all, the way you&#x27;d read a colleague&#x27;s notes. Each part ends
by naming exactly which sections of those papers just became readable, so
you can check.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-a-space-is&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-a-space-is&quot; aria-label=&quot;Anchor link for: what-a-space-is&quot;&gt;What a space is&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;&quot;Space&quot; might be the most casually used word in mathematics, and it
doesn&#x27;t mean the room around you. A space is a collection of things that
we agree to treat as locations. The points of a line are a space. So are
the points of a plane, and so is the set of all lists of three numbers.
In a few pages, a set of functions will be one too.&lt;&#x2F;p&gt;

&lt;figure class=&quot;drawing wide&quot; style=&quot;--dw: 1082px;&quot;&gt;
  &lt;div class=&quot;drawing-card&quot;&gt;
    &lt;img class=&quot;drawing-light&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;spaces-light.svg?h=375509b228a12e674e3c&quot;
         alt=&quot;four panels asking one question: two points on a line, two points on a plane, two lists of three numbers, and two function curves, each pair joined by an orange dashed distance; the lists panel computes it, the answer is 3, and the functions panel asks how far apart are these two&quot; width=&quot;1082&quot; height=&quot;250&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
    &lt;img class=&quot;drawing-dark&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;spaces-dark.svg?h=e05efcb51daa1cea40e5&quot;
         alt=&quot;four panels asking one question: two points on a line, two points on a plane, two lists of three numbers, and two function curves, each pair joined by an orange dashed distance; the lists panel computes it, the answer is 3, and the functions panel asks how far apart are these two&quot; width=&quot;1082&quot; height=&quot;250&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
  &lt;&#x2F;div&gt;
  &lt;figcaption&gt;&lt;span class=&quot;fig-label&quot;&gt;Figure 3.&lt;&#x2F;span&gt; four collections, one move: treat the members as locations, choose a distance, and geometry begins&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;The word is this broad on purpose. Whenever you can point at the members
of a collection and say here&#x27;s one, here&#x27;s another, you can treat the
collection as a space, and once you add a rule for measuring distance,
you can do geometry with it. That pattern never changes. Euclidean
spaces, metric spaces, every exotic space you&#x27;ll ever meet: some
collection of locations, plus some chosen structure on it.&lt;&#x2F;p&gt;
&lt;p&gt;One distinction is worth fixing early, because it prevents half the
confusion people have about dimension. An object is not the space that
holds it. A cube gets called &quot;the third dimension&quot; all the time, and it&#x27;s
neither a dimension nor a space. It&#x27;s a three-dimensional object, one
shape out of the infinitely many that three-dimensional space can hold
&lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-4&quot;&gt;4&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;. Objects sit in spaces. The space is everywhere they could be.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-dimension-is&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-dimension-is&quot; aria-label=&quot;Anchor link for: what-dimension-is&quot;&gt;What dimension is&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;The cleanest way I know to build dimension is with motion.&lt;&#x2F;p&gt;
&lt;p&gt;Take a point. It has no length, no width, no depth, just a location. Zero
dimensions.&lt;&#x2F;p&gt;
&lt;p&gt;Drag it in one direction, and its path is a line segment, which has
length and nothing else. That&#x27;s one dimension. Drag the segment
perpendicular to itself, and it traces a square: length and width, two
dimensions. Drag the square perpendicular to its own plane, and you get a
cube. Three.&lt;&#x2F;p&gt;

&lt;figure class=&quot;drawing wide&quot; style=&quot;--dw: 1107px;&quot;&gt;
  &lt;div class=&quot;drawing-card&quot;&gt;
    &lt;img class=&quot;drawing-light&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;dimension-build-light.svg?h=08ae8844cca5f7e94a17&quot;
         alt=&quot;five panels: point, segment, square, cube, tesseract, each drawn from the previous one by a perpendicular motion, with the start copy in gray, the stop copy in blue, the newly drawn parts in orange, and part counts under each panel&quot; width=&quot;1107&quot; height=&quot;340&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
    &lt;img class=&quot;drawing-dark&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;dimension-build-dark.svg?h=29b47bd9e98758fc8f6f&quot;
         alt=&quot;five panels: point, segment, square, cube, tesseract, each drawn from the previous one by a perpendicular motion, with the start copy in gray, the stop copy in blue, the newly drawn parts in orange, and part counts under each panel&quot; width=&quot;1107&quot; height=&quot;340&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
  &lt;&#x2F;div&gt;
  &lt;figcaption&gt;&lt;span class=&quot;fig-label&quot;&gt;Figure 4.&lt;&#x2F;span&gt; one motion, repeated: each object drags perpendicular to everything it already has&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;Notice that every step is the same step: move the object perpendicular to
every direction it already has. And nothing stops the next one. Drag the
cube perpendicular to all three of its directions, and it traces a
four-dimensional object called the tesseract. Our world has no room for
that motion, and nobody has ever seen a tesseract. But you can still
count its parts.&lt;&#x2F;p&gt;

&lt;div class=&quot;widget widget-builder&quot; data-widget=&quot;dimension-builder&quot;&gt;
  &lt;div class=&quot;w-frame&quot;&gt;
    &lt;span class=&quot;w-tag&quot;&gt;Interactive&lt;&#x2F;span&gt;
    &lt;div class=&quot;w-stage w-stage-builder&quot;&gt;
      &lt;svg viewBox=&quot;0 0 460 240&quot; aria-label=&quot;the object built so far&quot;&gt;&lt;&#x2F;svg&gt;
    &lt;&#x2F;div&gt;
    &lt;p class=&quot;w-actions&quot;&gt;&lt;button type=&quot;button&quot;&gt;move perpendicular&lt;&#x2F;button&gt; &lt;button type=&quot;button&quot; class=&quot;w-quiet w-reset&quot;&gt;reset&lt;&#x2F;button&gt;&lt;&#x2F;p&gt;
    &lt;table&gt;
      &lt;thead&gt;&lt;tr&gt;&lt;th&gt;object&lt;&#x2F;th&gt;&lt;th&gt;points&lt;&#x2F;th&gt;&lt;th&gt;edges&lt;&#x2F;th&gt;&lt;th&gt;squares&lt;&#x2F;th&gt;&lt;th&gt;cubes&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;
      &lt;tbody&gt;&lt;&#x2F;tbody&gt;
    &lt;&#x2F;table&gt;
  &lt;&#x2F;div&gt;
  &lt;div class=&quot;w-caption&quot;&gt;
    &lt;p class=&quot;w-cap&quot;&gt;&lt;span class=&quot;fig-label&quot;&gt;Figure 5.&lt;&#x2F;span&gt;
Build dimension with one motion.
&lt;span class=&quot;w-hint&quot;&gt;Before each press, predict the next row of the table.
The rule: a copy at the start, a copy at the stop, one new part per moving part.&lt;&#x2F;span&gt;&lt;&#x2F;p&gt;
    &lt;div class=&quot;w-legend&quot;&gt;
      &lt;span style=&quot;--sw: var(--c-gray)&quot;&gt;where it started&lt;&#x2F;span&gt;
      &lt;span style=&quot;--sw: var(--c-blue)&quot;&gt;where it stopped&lt;&#x2F;span&gt;
      &lt;span style=&quot;--sw: var(--c-orange)&quot;&gt;drawn by the motion&lt;&#x2F;span&gt;
    &lt;&#x2F;div&gt;
  &lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;
&lt;script src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;widgets.js?h=186ab988df8e56b4745e&quot; defer&gt;&lt;&#x2F;script&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Object&lt;&#x2F;th&gt;&lt;th&gt;Points&lt;&#x2F;th&gt;&lt;th&gt;Edges&lt;&#x2F;th&gt;&lt;th&gt;Squares&lt;&#x2F;th&gt;&lt;th&gt;Cubes&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Point&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Segment&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Square&lt;&#x2F;td&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Cube&lt;&#x2F;td&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;12&lt;&#x2F;td&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Tesseract&lt;&#x2F;td&gt;&lt;td&gt;?&lt;&#x2F;td&gt;&lt;td&gt;?&lt;&#x2F;td&gt;&lt;td&gt;?&lt;&#x2F;td&gt;&lt;td&gt;?&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Before you try the last row, test the method on a step you can actually
see: the square becoming a cube.&lt;&#x2F;p&gt;
&lt;p&gt;Count the cube&#x27;s edges. The square&#x27;s 4 edges sit where the motion
started. Another 4 sit where it stopped. And each of the 4 corners drew
one new edge as it moved. $4 + 4 + 4 = 12$. A cube has exactly 12 edges,
so the method works.&lt;&#x2F;p&gt;
&lt;p&gt;Count the square faces the same way. One square at the start. One at the
stop. And 4 new ones, drawn by the 4 moving edges. $1 + 1 + 4 = 6$.
Correct again.&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s the whole rule. Every count has three pieces: a copy at the
start, a copy at the stop, and one new part drawn by each moving part
one level below.&lt;&#x2F;p&gt;
&lt;p&gt;Now the tesseract, by the same rule and nothing else:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Corners: 8 at the start, 8 at the stop. 16.&lt;&#x2F;li&gt;
&lt;li&gt;Edges: 12 + 12, plus 8 new ones drawn by the moving corners. 32.&lt;&#x2F;li&gt;
&lt;li&gt;Squares: 6 + 6, plus 12 drawn by the moving edges. 24.&lt;&#x2F;li&gt;
&lt;li&gt;Cubes: 1 + 1, plus 6 drawn by the moving squares. 8.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;You couldn&#x27;t see the object, and you counted its parts anyway. All four
numbers are exact.&lt;&#x2F;p&gt;
&lt;p&gt;Someone always asks at this point whether the fourth direction is time.
In physics it can be. Here it never is: the fourth direction is one more
direction of the ordinary kind, exactly as spatial as the first three.&lt;&#x2F;p&gt;
&lt;p&gt;Spaces grow by the same motion as objects. A moving line traces the
plane, a moving plane traces our familiar space, and moving all of that
in a fourth perpendicular direction gives four-dimensional space. A point
in $n$-dimensional space is nothing more exotic than a list of $n$ numbers,
and the formulas don&#x27;t care what $n$ is. For distance, this article uses
the standard Euclidean rule, the square root of the sum of squared
coordinate differences &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-4&quot;&gt;4&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;. There are other distance rules, and two
sections from now you&#x27;ll see where this one actually comes from. From
here on, $\mathbb{R}^{n}$ is the usual name for $n$-dimensional space with real
coordinates.&lt;&#x2F;p&gt;
&lt;p&gt;And notice that nobody had to give us a definition. It emerged from the
construction on its own: the dimension of a space is the number of
independent directions in it, or equivalently, the smallest number of
coordinates it takes to name a location &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-4&quot;&gt;4&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;. Objects have a dimension in
the same sense. A sheet of paper in a three-dimensional room is a
two-dimensional object, because two numbers are enough to name any point
on it.&lt;&#x2F;p&gt;
&lt;p&gt;Two warnings before we continue. Dimension counts independent directions,
not things; a line holds infinitely many points and still has exactly one
direction. And &quot;I can&#x27;t imagine ten thousand dimensions&quot; is a statement
about human vision, not about the space. You just handled a tesseract
without seeing it, and $\mathbb{R}^{10000}$ is no different. The real danger runs the
other way, and it&#x27;s the point of this whole article: the pictures we can
see mislead us about the spaces we can&#x27;t.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;vectors-and-the-dot-product&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#vectors-and-the-dot-product&quot; aria-label=&quot;Anchor link for: vectors-and-the-dot-product&quot;&gt;Vectors and the dot product&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;So what&#x27;s a vector? The honest definition is broader than the arrow you
learned to draw. A vector is anything you can do two things with: add it
to another of its kind, and scale it by a number. Lists of numbers
qualify, added entry by entry, and that makes $\mathbb{R}^{n}$ a vector space whose
vectors are the lists themselves. Functions qualify too, since you can
add two functions and you can scale one. Remember that; it matters in a
few pages.&lt;&#x2F;p&gt;
&lt;p&gt;A list in $\mathbb{R}^{n}$ can be read two ways: as a location, or as a movement, where
from any starting point you shift by these amounts along each coordinate.
The movement reading is why a vector has a direction. A vector of length
one is called a unit vector, and it&#x27;s pure direction with no size.&lt;&#x2F;p&gt;
&lt;p&gt;The central operation on vectors multiplies matching coordinates and adds
everything:&lt;&#x2F;p&gt;
&lt;p&gt;$$\operatorname{dot}(u, v) = u_1v_1 + u_2v_2 + \cdots + u_nv_n$$&lt;&#x2F;p&gt;
&lt;p&gt;That produces one number, and the number means three things at once, all
of them exactly true. Algebraically, it&#x27;s just the formula: multiply and
add. Geometrically, $\operatorname{dot}(u, v) = \operatorname{length}(u) \cdot \operatorname{length}(v) \cdot \cos\theta$, where $\theta$ is
the angle between the two vectors &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-4&quot;&gt;4&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;, so for unit vectors the dot
product simply is the cosine of the angle. And there&#x27;s a third reading,
the one this article depends on: when $u$ is a unit vector, $\operatorname{dot}(u, x)$
tells you how much of direction $u$ is present in $x$. You&#x27;re asking $x$ a
question, and the answer is a single number.&lt;&#x2F;p&gt;

&lt;figure class=&quot;drawing&quot; style=&quot;--dw: 453px;&quot;&gt;
  &lt;div class=&quot;drawing-card&quot;&gt;
    &lt;img class=&quot;drawing-light&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;projection-light.svg?h=c707540d023d1e336802&quot;
         alt=&quot;a unit direction u drawn horizontal, a vector x at an angle above it, a dashed perpendicular dropped from the tip of x onto the line of u, and the landing segment labeled dot(u, x)&quot; width=&quot;453&quot; height=&quot;275&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
    &lt;img class=&quot;drawing-dark&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;projection-dark.svg?h=286f108977ec36a77389&quot;
         alt=&quot;a unit direction u drawn horizontal, a vector x at an angle above it, a dashed perpendicular dropped from the tip of x onto the line of u, and the landing segment labeled dot(u, x)&quot; width=&quot;453&quot; height=&quot;275&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
  &lt;&#x2F;div&gt;
  &lt;figcaption&gt;&lt;span class=&quot;fig-label&quot;&gt;Figure 6.&lt;&#x2F;span&gt; the dot product is the part of x that lies along u&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;Three terms cause endless confusion around this operation, so let&#x27;s
separate them once and be done. An &lt;em&gt;inner product&lt;&#x2F;em&gt; is any rule
$\operatorname{inner}(u, v)$ that turns two vectors into a number while keeping three
properties. Order of the inputs doesn&#x27;t matter. The rule respects
addition and scaling in each input. And $\operatorname{inner}(x, x) &amp;gt; 0$ for every
nonzero $x$ &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-5&quot;&gt;5&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;. The &lt;em&gt;dot product&lt;&#x2F;em&gt; is one member of that family, the most
familiar one. And &lt;em&gt;Euclidean space&lt;&#x2F;em&gt; isn&#x27;t a different set of points at
all; it&#x27;s just $\mathbb{R}^{n}$ once you&#x27;ve chosen the dot product as your rule.&lt;&#x2F;p&gt;
&lt;p&gt;Does the choice matter? The rule $\operatorname{inner}(p, q) = 3p_1q_1 + p_2q_2$ passes
all three requirements, so it&#x27;s a perfectly legal inner product on $\mathbb{R}^{2}$.
Under the ordinary dot product, the vector $(1, 1)$ has length $\sqrt{2}$, and the
pair $(1, 0), (1, 1)$ sit $45^\circ$ apart. Under the new rule, the same vector
has length 2, and the same pair sit $30^\circ$ apart. Same lists, different
geometry. Length and angle never belonged to the lists. They come from
the rule you choose.&lt;&#x2F;p&gt;
&lt;p&gt;Distance comes from the same choice, since $\operatorname{length}(x)$ is $\sqrt{\operatorname{inner}(x, x)}$ and
the distance between two points is the length of their difference. That
Euclidean distance rule from the last section? It was the dot product all
along.&lt;&#x2F;p&gt;
&lt;p&gt;We&#x27;ll stay with the plain dot product from here. But the main point stays
with us: angle is a chosen measurement, not a given one. And everything
ahead is about what happens when angles are allowed to be slightly wrong.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;storing-numbers-in-a-space&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#storing-numbers-in-a-space&quot; aria-label=&quot;Anchor link for: storing-numbers-in-a-space&quot;&gt;Storing numbers in a space&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Orthogonal just means $\operatorname{dot}(u, v) = 0$, which in Euclidean space is the
familiar $90^\circ$. Why does anyone care? Because of what it does for storage.
Let me show you the whole scheme in two dimensions, with numbers small
enough to check by hand. Then we&#x27;ll give the scheme the opening neuron&#x27;s
job.&lt;&#x2F;p&gt;
&lt;p&gt;Take the plane, and two perpendicular unit directions: $u = (1, 0)$ and
$v = (0, 1)$. Say we want one vector to carry two separate quantities, a 3
and a 5. Give each quantity its own direction, scale, and add:&lt;&#x2F;p&gt;
&lt;p&gt;$$x = 3\cdot u + 5\cdot v = (3, 5)$$&lt;&#x2F;p&gt;
&lt;p&gt;One vector now holds both numbers. Reading them back is the question
from the last section. Ask $x$ how much of direction $u$ it contains:&lt;&#x2F;p&gt;
&lt;p&gt;$$\operatorname{dot}(u, x) = \operatorname{dot}((1, 0), (3, 5)) = 1\cdot 3 + 0\cdot 5 = 3$$&lt;&#x2F;p&gt;
&lt;p&gt;The reading is 3, exact. Ask with $v$ instead, and the reading is 5,
exact. Nothing interfered with anything. The vector is the storage. The
dot product is the reading.&lt;&#x2F;p&gt;

&lt;figure class=&quot;drawing&quot; style=&quot;--dw: 426px;&quot;&gt;
  &lt;div class=&quot;drawing-card&quot;&gt;
    &lt;img class=&quot;drawing-light&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;two-slots-light.svg?h=3e541621c7420f13c3a9&quot;
         alt=&quot;the plane with u horizontal and v vertical, the stored vector x = (3, 5), and dashed drops from its tip landing at reading 3 along u and reading 5 along v&quot; width=&quot;426&quot; height=&quot;364&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
    &lt;img class=&quot;drawing-dark&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;two-slots-dark.svg?h=383a02cb700a78585936&quot;
         alt=&quot;the plane with u horizontal and v vertical, the stored vector x = (3, 5), and dashed drops from its tip landing at reading 3 along u and reading 5 along v&quot; width=&quot;426&quot; height=&quot;364&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
  &lt;&#x2F;div&gt;
  &lt;figcaption&gt;&lt;span class=&quot;fig-label&quot;&gt;Figure 7.&lt;&#x2F;span&gt; two numbers stored in one vector, each read back perfectly&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;Why did that work so cleanly? Write the reading in general form and
watch it, one line at a time. Store an amount $k$ along $u$ and an amount $c$
along $v$, so $x = k \cdot u + c \cdot v$. Then:&lt;&#x2F;p&gt;
&lt;p&gt;$$\begin{aligned} \operatorname{dot}(u, x) &amp;amp;= \operatorname{dot}(u, k\cdot u + c\cdot v) \\ &amp;amp;= k\cdot \operatorname{dot}(u, u) + c\cdot \operatorname{dot}(u, v) \\ &amp;amp;= k + c\cdot \operatorname{dot}(u, v) \end{aligned}$$&lt;&#x2F;p&gt;
&lt;p&gt;The first line is the question applied to what we stored. The second
uses the fact that the dot product respects addition and scaling. The
third uses $\operatorname{dot}(u, u) = 1$, true for every unit vector. So every reading
returns $k$, the number you wanted, plus one extra term: the other amount
times the overlap between the two directions. In our example the
overlap $\operatorname{dot}(u, v)$ was exactly 0, so the extra term vanished and the
reading was perfect.&lt;&#x2F;p&gt;
&lt;p&gt;That extra term has a standard name, &lt;em&gt;interference&lt;&#x2F;em&gt; &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-1&quot;&gt;1&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;, and it&#x27;s the
cost behind everything in this series.&lt;&#x2F;p&gt;
&lt;p&gt;Now break the scheme, gently. Tilt $v$ toward $u$ until their overlap is
$\operatorname{dot}(u, v) = 0.1$. That&#x27;s a tilt of about $6^\circ$; to the eye, the two
directions still look perpendicular. Store the same 3 and 5, and read:&lt;&#x2F;p&gt;
&lt;p&gt;$$\text{reading along } u = k + c\cdot \operatorname{dot}(u, v) = 3 + 5\cdot 0.1 = 3.5$$&lt;&#x2F;p&gt;
&lt;p&gt;You stored 3. You read 3.5. Half a unit of the other quantity leaked
into your answer, and nothing in the reading tells you it happened.&lt;&#x2F;p&gt;

&lt;figure class=&quot;drawing wide&quot; style=&quot;--dw: 804px;&quot;&gt;
  &lt;div class=&quot;drawing-card&quot;&gt;
    &lt;img class=&quot;drawing-light&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;leak-light.svg?h=506092705ba257a396aa&quot;
         alt=&quot;two panels: with u and v perpendicular the reading lands exactly on 3; with v tilted 6 degrees the same construction lands on 3.5, and the extra segment from 3 to 3.5 is drawn in red and labeled interference&quot; width=&quot;804&quot; height=&quot;374&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
    &lt;img class=&quot;drawing-dark&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;leak-dark.svg?h=54176e59446d31540701&quot;
         alt=&quot;two panels: with u and v perpendicular the reading lands exactly on 3; with v tilted 6 degrees the same construction lands on 3.5, and the extra segment from 3 to 3.5 is drawn in red and labeled interference&quot; width=&quot;804&quot; height=&quot;374&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
  &lt;&#x2F;div&gt;
  &lt;figcaption&gt;&lt;span class=&quot;fig-label&quot;&gt;Figure 8.&lt;&#x2F;span&gt; a 6° tilt, invisible to the eye, and every reading is wrong by half a unit&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;Here&#x27;s the same leak with meaning attached. Give the two slots the
opening neuron&#x27;s jobs: $k$ is how strongly the current text is Korean, $c$
is how strongly it&#x27;s an academic citation. Feed the model a pure
citation, &quot;(Smith et al., 2020)&quot;. The true amounts are $k = 0$ and $c = 5$.
With the tilted $v$, the Korean reading is $0 + 5 \cdot 0.1 = 0.5$. The model now
holds a signal saying this text is slightly Korean. Nothing Korean
exists in the input. The overlap invented it.&lt;&#x2F;p&gt;

&lt;div class=&quot;widget widget-leak&quot; data-widget=&quot;leak&quot;&gt;
  &lt;div class=&quot;w-frame&quot;&gt;
    &lt;span class=&quot;w-tag&quot;&gt;Interactive&lt;&#x2F;span&gt;
    &lt;div class=&quot;w-stage w-stage-leak&quot;&gt;
      &lt;svg viewBox=&quot;0 88 420 312&quot; class=&quot;grabbable&quot; tabindex=&quot;0&quot;
           aria-label=&quot;the plane with u, v, and the stored vector x; drag the tip of v, or press the arrow keys, to tilt it&quot;&gt;&lt;&#x2F;svg&gt;
    &lt;&#x2F;div&gt;
    &lt;p class=&quot;w-formula&quot; aria-live=&quot;polite&quot;&gt;&lt;&#x2F;p&gt;
  &lt;&#x2F;div&gt;
  &lt;div class=&quot;w-caption&quot;&gt;
    &lt;p class=&quot;w-cap&quot;&gt;&lt;span class=&quot;fig-label&quot;&gt;Figure 9.&lt;&#x2F;span&gt;
Store 3 and 5, then tilt the second direction. Drag the tip of $v$: the
stored vector is always $x = 3 \cdot u + 5 \cdot v$, and the live line under
the stage is the reading $\operatorname{dot}(u, x) = 3 + 5 \cdot \operatorname{dot}(u, v)$.
While the two directions stay perpendicular the reading is exactly 3; every
degree of tilt leaks the other quantity into it.&lt;&#x2F;p&gt;
  &lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;
&lt;script src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;widgets.js?h=186ab988df8e56b4745e&quot; defer&gt;&lt;&#x2F;script&gt;
&lt;p&gt;The general picture is one step away. In $\mathbb{R}^{n}$ you can pick $n$ directions
that are mutually orthogonal, and no more than $n$, because orthogonal
nonzero vectors are independent and $\mathbb{R}^{n}$ can hold at most $n$ independent
vectors. Store one quantity along each, and every reading is perfect;
nothing leaks anywhere. So $n$ dimensions give you $n$ slots of perfect
storage, and the supply ends at exactly $n$. That&#x27;s the sense in which
dimension is capacity. Everything ahead either uses that fact or breaks
it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;inside-a-neuron&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#inside-a-neuron&quot; aria-label=&quot;Anchor link for: inside-a-neuron&quot;&gt;Inside a neuron&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Here&#x27;s the neuron formula I promised.&lt;&#x2F;p&gt;
&lt;p&gt;A neuron holds a vector $w$ (its &lt;em&gt;weights&lt;&#x2F;em&gt;) and a number $b$ (its &lt;em&gt;bias&lt;&#x2F;em&gt;),
and training tunes both. Given an incoming vector $x$, it does two things:&lt;&#x2F;p&gt;
&lt;p&gt;$$\begin{aligned} \text{linear step:} \quad &amp;amp; s = \operatorname{dot}(w, x) + b \\ \text{nonlinear step:} \quad &amp;amp; \text{output} = \max(0, s) \end{aligned}$$&lt;&#x2F;p&gt;
&lt;p&gt;The output is called the neuron&#x27;s &lt;em&gt;activation&lt;&#x2F;em&gt;. With this design it&#x27;s
never negative, and when it&#x27;s above zero, people say the neuron is active
on that input. The cutoff has a name you&#x27;ll meet everywhere in the
literature: &lt;em&gt;ReLU&lt;&#x2F;em&gt;, for rectified linear unit &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-6&quot;&gt;6&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;. It isn&#x27;t the only
cutoff in use; many modern models prefer a smoothed relative called GELU
&lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-6&quot;&gt;6&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;. Nothing here depends on which one a model uses, because the pattern
is always the same: a linear step, then a simple nonlinear one. A full
layer is just many neurons doing this to the same $x$ at once; stack the
weight vectors as rows of a matrix, and all the dot products happen in
one multiplication.&lt;&#x2F;p&gt;
&lt;p&gt;Now look where $x$ enters: one place, inside $\operatorname{dot}(w, x)$. Everything the
neuron will ever learn from $x$ comes through that single dot product, and
the cutoff afterward can only reshape what the dot product already
measured. So the sentence from the opening, &quot;the neuron&#x27;s number became
large on Korean text,&quot; means exactly this and nothing else: on those
inputs, $\operatorname{dot}(w, x) + b$ is large.&lt;&#x2F;p&gt;

&lt;figure class=&quot;drawing wide&quot; style=&quot;--dw: 840px;&quot;&gt;
  &lt;div class=&quot;drawing-card&quot;&gt;
    &lt;img class=&quot;drawing-light&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;one-reading-light.svg?h=8fe4eed6cd5cdeaeb02c&quot;
         alt=&quot;the neuron drawn as a machine: the incoming vector x flows into one glowing box reading dot(w, x), the only place x enters, then a small plus-b step, then a graph of the ReLU cutoff with the smoother GELU curve beside it, and one orange number leaves: the activation&quot; width=&quot;840&quot; height=&quot;234&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
    &lt;img class=&quot;drawing-dark&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;one-reading-dark.svg?h=c65c132f8c7446186cc0&quot;
         alt=&quot;the neuron drawn as a machine: the incoming vector x flows into one glowing box reading dot(w, x), the only place x enters, then a small plus-b step, then a graph of the ReLU cutoff with the smoother GELU curve beside it, and one orange number leaves: the activation&quot; width=&quot;840&quot; height=&quot;234&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
  &lt;&#x2F;div&gt;
  &lt;figcaption&gt;&lt;span class=&quot;fig-label&quot;&gt;Figure 10.&lt;&#x2F;span&gt; everything the neuron learns from x passes through one dot product; the cutoff only reshapes what it measured&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;And here&#x27;s where the two halves of this article meet. Our storage scheme
read quantities back with dot products. The network reads its own vectors
with dot products, because that&#x27;s the only reading a neuron performs.
Whatever a model stores in $x$, the next layer can use only what a dot
product can recover. Storage along directions isn&#x27;t a modeling
convenience somebody chose; the architecture forces it. That&#x27;s why people
study meaning in neural networks as directions &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-7&quot;&gt;7&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;, and it&#x27;s why this
series does too.&lt;&#x2F;p&gt;
&lt;p&gt;A network is layers of these units, and its overall output is one
function built from all of them.&lt;&#x2F;p&gt;
&lt;p&gt;Which means there are two spaces in this story, and they shouldn&#x27;t be
confused. Since functions are vectors, the whole network is a single
point in a space of functions, and training moves that point. The storage
problem lives in the other space, the small one inside: the $\mathbb{R}^{n}$ that the
intermediate vectors, the &lt;em&gt;activations&lt;&#x2F;em&gt;, pass through on their way to the
output.&lt;&#x2F;p&gt;

&lt;figure class=&quot;drawing wide&quot; style=&quot;--dw: 912px;&quot;&gt;
  &lt;div class=&quot;drawing-card&quot;&gt;
    &lt;img class=&quot;drawing-light&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;two-spaces-light.svg?h=e13f6953f19e306a92e8&quot;
         alt=&quot;a large ellipse labeled the space of functions holds a dashed training path ending at one solid point, the whole network; a zoom cone opens from that point into a panel showing the small space inside, with axes and one orange activation vector x&quot; width=&quot;912&quot; height=&quot;359&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
    &lt;img class=&quot;drawing-dark&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;two-spaces-dark.svg?h=776360c5d0fbac9895ca&quot;
         alt=&quot;a large ellipse labeled the space of functions holds a dashed training path ending at one solid point, the whole network; a zoom cone opens from that point into a panel showing the small space inside, with axes and one orange activation vector x&quot; width=&quot;912&quot; height=&quot;359&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
  &lt;&#x2F;div&gt;
  &lt;figcaption&gt;&lt;span class=&quot;fig-label&quot;&gt;Figure 11.&lt;&#x2F;span&gt; the whole network is a single point in a space of functions; the storage problem lives in the small space inside it&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;h2 id=&quot;dimension-and-capacity&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#dimension-and-capacity&quot; aria-label=&quot;Anchor link for: dimension-and-capacity&quot;&gt;Dimension and capacity&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Now I can show you the exact spot where a true theorem turns into a false
belief.&lt;&#x2F;p&gt;
&lt;p&gt;The theorem: in $n$ dimensions, at most $n$ nonzero vectors can be mutually
orthogonal. Grant Sanderson (3Blue1Brown) gives its status exactly: &quot;to a
mathematician, actually, this is the definition of dimension&quot; &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-6&quot;&gt;6&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The belief: a space holds only as many ideas as it has dimensions. A
300-dimensional word-embedding space (a space where each word is stored
as a vector) holds 300 word-features, a 4096-dimensional model space
holds 4096 concepts, and that&#x27;s the end of it.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s the strange part: nobody actually states the belief. No textbook
prints it, and no theorem proves it. It just forms, quietly, because it
feels like a restatement of things that are true. Orthogonal directions
stop at $n$. Perfect storage stops at $n$ quantities. So capacity must be $n$.
I carried that belief for years without once looking at it directly.&lt;&#x2F;p&gt;
&lt;p&gt;So let&#x27;s look at it directly. Put the theorem and the belief side by
side, word for word:&lt;&#x2F;p&gt;

&lt;figure class=&quot;drawing&quot; style=&quot;--dw: 546px;&quot;&gt;
  &lt;div class=&quot;drawing-card&quot;&gt;
    &lt;img class=&quot;drawing-light&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;theorem-vs-belief-light.svg?h=c85003622b887aae7790&quot;
         alt=&quot;two cards: the theorem card reads storage with zero interference stops at n; the belief card is identical but the words with zero interference carry a strike through them, with an arrow between the cards reading two words quietly deleted&quot; width=&quot;546&quot; height=&quot;296&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
    &lt;img class=&quot;drawing-dark&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;theorem-vs-belief-dark.svg?h=81d7ed4a1f8f72b36115&quot;
         alt=&quot;two cards: the theorem card reads storage with zero interference stops at n; the belief card is identical but the words with zero interference carry a strike through them, with an arrow between the cards reading two words quietly deleted&quot; width=&quot;546&quot; height=&quot;296&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
  &lt;&#x2F;div&gt;
  &lt;figcaption&gt;&lt;span class=&quot;fig-label&quot;&gt;Figure 12.&lt;&#x2F;span&gt; the belief is the theorem minus two words, and nobody noticed the deletion&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;Same sentence. Two words deleted. Nobody performed the deletion on
purpose; it happened silently, somewhere between the course and the
memory of the course. And the deleted words are not decoration. They
are a condition. Our storage scheme told you exactly what stands behind
them: every reading returns $k$ plus $c \cdot \operatorname{dot}(u, v)$, and &quot;zero interference&quot;
is the demand that the extra term be exactly zero, every time. The
belief keeps the conclusion and forgets the condition. It silently
assumes that a reading is worthless unless it&#x27;s exact.&lt;&#x2F;p&gt;
&lt;p&gt;Mathematics offered us exactness. Somewhere we decided meaning requires
it. But nobody ever asked the question the deleted words were guarding:
how exact does a reading actually need to be?&lt;&#x2F;p&gt;
&lt;p&gt;What if the answer is not &quot;perfectly&quot;?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;almost-orthogonal&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#almost-orthogonal&quot; aria-label=&quot;Anchor link for: almost-orthogonal&quot;&gt;Almost orthogonal&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;So allow a small leak. Instead of demanding $\operatorname{dot}(u, v) = 0$ for every
stored pair, demand only that it stays small: no bigger in size than
some tolerance $\varepsilon$, say 0.05. The reading formula says exactly what this
costs. Here it is again:&lt;&#x2F;p&gt;
&lt;p&gt;$$\operatorname{dot}(u, x) = k + c\cdot \operatorname{dot}(u, v)$$&lt;&#x2F;p&gt;
&lt;p&gt;The overlap $\operatorname{dot}(u, v)$ can now be as large as $\varepsilon$, so a reading can be off
by at most $c \cdot \varepsilon$: the stored amount times the tolerance. Keep $\varepsilon$ small and
every reading stays nearly exact. In angle terms, $\varepsilon = 0.05$ keeps every
pair of directions within about $3^\circ$ of perpendicular.&lt;&#x2F;p&gt;
&lt;p&gt;What does the tolerance gain? In the plane, you can check by hand. Two
directions at $90^\circ$ satisfy the rule easily; their dot product is exactly
zero. Now try a third. It must stay within $3^\circ$ of perpendicular to both. But
the first two are perpendicular to each other, so any direction nearly
perpendicular to the first is nearly parallel to the second. There&#x27;s no
room at all. Try it below; the third arrow has nowhere legal to point.&lt;&#x2F;p&gt;

&lt;div class=&quot;widget widget-third&quot; data-widget=&quot;third-direction&quot;&gt;
  &lt;div class=&quot;w-frame&quot;&gt;
    &lt;span class=&quot;w-tag&quot;&gt;Interactive&lt;&#x2F;span&gt;
    &lt;div class=&quot;w-stage w-stage-third&quot;&gt;
      &lt;svg viewBox=&quot;0 0 440 440&quot; class=&quot;grabbable&quot; tabindex=&quot;0&quot;
           aria-label=&quot;the circle of directions with two green bands and a draggable third arrow; drag it, or press the arrow keys, to rotate it&quot;&gt;&lt;&#x2F;svg&gt;
    &lt;&#x2F;div&gt;
  &lt;&#x2F;div&gt;
  &lt;div class=&quot;w-caption&quot;&gt;
    &lt;p class=&quot;w-cap&quot;&gt;&lt;span class=&quot;fig-label&quot;&gt;Figure 13.&lt;&#x2F;span&gt;
Point the third arrow anywhere. Try to satisfy both rules. The rule, with
tolerance $\varepsilon = 0.05$: stay within $3^\circ$ of perpendicular to
&lt;b&gt;both&lt;&#x2F;b&gt; fixed directions. Each arc shows the arrow&#x27;s live angle to one
direction, green where that rule is satisfied. The two directions are
perpendicular to each other, so anything nearly perpendicular to the first
is nearly parallel to the second: the green bands can never meet.&lt;&#x2F;p&gt;
  &lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;
&lt;script src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;widgets.js?h=186ab988df8e56b4745e&quot; defer&gt;&lt;&#x2F;script&gt;

&lt;figure class=&quot;drawing&quot; style=&quot;--dw: 598px;&quot;&gt;
  &lt;div class=&quot;drawing-card&quot;&gt;
    &lt;img class=&quot;drawing-light&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;third-direction-light.svg?h=9a831cbc5358d4712071&quot;
         alt=&quot;the plane with the two perpendicular directions, a narrow green band around each one&amp;#x27;s perpendicular, and a third arrow drawn in the gap with a red cross&quot; width=&quot;598&quot; height=&quot;443&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
    &lt;img class=&quot;drawing-dark&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;third-direction-dark.svg?h=bc815c34eecabec543d5&quot;
         alt=&quot;the plane with the two perpendicular directions, a narrow green band around each one&amp;#x27;s perpendicular, and a third arrow drawn in the gap with a red cross&quot; width=&quot;598&quot; height=&quot;443&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
  &lt;&#x2F;div&gt;
  &lt;figcaption&gt;&lt;span class=&quot;fig-label&quot;&gt;Figure 14.&lt;&#x2F;span&gt; to be almost perpendicular to both, the third arrow needs the two bands to meet. They don&#x27;t.&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;Run the same argument in three dimensions, and you get three directions,
exactly what zero tolerance already gave. At this point, the sensible
conclusion is that almost-orthogonal is a technicality: it doesn&#x27;t
change how many directions fit. That conclusion is wrong, and it&#x27;s wrong
because two and three dimensions are the wrong place to check it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ten-thousand-dimensions&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#ten-thousand-dimensions&quot; aria-label=&quot;Anchor link for: ten-thousand-dimensions&quot;&gt;Ten thousand dimensions&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;We can&#x27;t see $\mathbb{R}^{10000}$. But we can measure it, and the measurement fits in
nine lines of code. Here&#x27;s the plan, before any code.&lt;&#x2F;p&gt;
&lt;p&gt;Pick two directions at random. Record how far from perpendicular they
land. Repeat twenty thousand times, so that no single lucky pair can
mislead us. Then run the whole experiment in three different dimensions:
$n = 3$, a space we can picture; $n = 100$, far beyond anything we can
picture; and $n = 10{,}000$, the scale of real models.&lt;&#x2F;p&gt;
&lt;p&gt;One question first: what number should we record for each pair? The dot
product, and here&#x27;s why it&#x27;s exactly the right one. Both directions are
unit vectors, so $\operatorname{length}(u) = \operatorname{length}(v) = 1$, and the geometric formula
from earlier loses both of its lengths:&lt;&#x2F;p&gt;
&lt;p&gt;$$\operatorname{dot}(u, v) = \operatorname{length}(u) \cdot \operatorname{length}(v) \cdot \cos\theta = 1 \cdot 1 \cdot \cos\theta = \cos\theta$$&lt;&#x2F;p&gt;
&lt;p&gt;For unit vectors, the dot product IS the cosine of the angle. No lengths
remain in it. So every measurement reads directly as geometry: 0 means
exactly perpendicular, $\pm 1$ means parallel, 0.5 means $60^\circ$. One number per
pair, and each number is an angle, written as its cosine.&lt;&#x2F;p&gt;

&lt;figure class=&quot;drawing wide&quot; style=&quot;--dw: 768px;&quot;&gt;
  &lt;div class=&quot;drawing-card&quot;&gt;
    &lt;img class=&quot;drawing-light&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;dot-is-angle-light.svg?h=726a6069d1394ad4e132&quot;
         alt=&quot;a unit circle with u fixed horizontal and three copies of v at 0, 60, and 90 degrees, labeled dot = 1, dot = 0.5, and dot = 0&quot; width=&quot;768&quot; height=&quot;280&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
    &lt;img class=&quot;drawing-dark&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;dot-is-angle-dark.svg?h=ca67903798a805fb3157&quot;
         alt=&quot;a unit circle with u fixed horizontal and three copies of v at 0, 60, and 90 degrees, labeled dot = 1, dot = 0.5, and dot = 0&quot; width=&quot;768&quot; height=&quot;280&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
  &lt;&#x2F;div&gt;
  &lt;figcaption&gt;&lt;span class=&quot;fig-label&quot;&gt;Figure 15.&lt;&#x2F;span&gt; for unit vectors nothing but the angle survives in the dot product&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;Now the code. Every line states its purpose in its comment.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span&gt; numpy&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; np&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;rng&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;random&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;default_rng&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;seed&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;     # fixed seed, so you get my exact numbers&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;for&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; in&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 100&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 10_000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;]:&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;              # a space we can see, a middle one, real scale&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;    u&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; rng&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;normal&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-punctuation&quot;&gt;=(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;20_000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    # 20,000 random vectors...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt; 6&lt;&#x2F;span&gt;&lt;span&gt;    u&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; &#x2F;=&lt;&#x2F;span&gt;&lt;span&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;linalg&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;norm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;u&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; axis&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; keepdims&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt;True&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;   # ...scaled to length 1: directions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt; 7&lt;&#x2F;span&gt;&lt;span&gt;    v&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; rng&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;normal&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt;size&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-punctuation&quot;&gt;=(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;20_000&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    # 20,000 more, to form the pairs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt; 8&lt;&#x2F;span&gt;&lt;span&gt;    v&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; &#x2F;=&lt;&#x2F;span&gt;&lt;span&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;linalg&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;norm&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; axis&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable&quot;&gt; keepdims&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt;True&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt; 9&lt;&#x2F;span&gt;&lt;span&gt;    dots&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;einsum&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string&quot;&gt;ij,ij-&amp;gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; u&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;  # dot(u, v) of each pair, row by row&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;giallo-ln&quot;&gt;10&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;    print&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;n&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; round&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;dots&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;std&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(),&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt; round&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;np&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;percentile&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support&quot;&gt;abs&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;dots&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 95&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;),&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Three details deserve a sentence each. Scaling a random normal vector to
length 1 is the standard way to draw a uniformly random direction: the
normal distribution has no preferred direction, so after the scaling,
every direction is equally likely. And the two printed numbers are two
summaries of each batch of 20,000 measurements: the typical size of the
dot products (their standard deviation), and the size that 95% of them
stay inside. One note on signs: a dot product can be negative, when the
two directions lean opposite ways, so the second summary measures size
only and ignores the sign.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s the output, with the columns labeled, plus one extra column that
I&#x27;ll explain in a moment:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;$n$&lt;&#x2F;th&gt;&lt;th&gt;typical size of $\operatorname{dot}(u, v)$&lt;&#x2F;th&gt;&lt;th&gt;95% of pairs stay inside&lt;&#x2F;th&gt;&lt;th&gt;$1&#x2F;\sqrt{n}$&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;0.5799&lt;&#x2F;td&gt;&lt;td&gt;$\pm 0.9524$&lt;&#x2F;td&gt;&lt;td&gt;0.5774&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;100&lt;&#x2F;td&gt;&lt;td&gt;0.0999&lt;&#x2F;td&gt;&lt;td&gt;$\pm 0.1946$&lt;&#x2F;td&gt;&lt;td&gt;0.1000&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;10,000&lt;&#x2F;td&gt;&lt;td&gt;0.0100&lt;&#x2F;td&gt;&lt;td&gt;$\pm 0.0195$&lt;&#x2F;td&gt;&lt;td&gt;0.0100&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Now read the table one row at a time. Every dot product here is a
cosine, so each one converts to an angle, and I&#x27;ll do each conversion
for you.&lt;&#x2F;p&gt;
&lt;p&gt;Start with $\mathbb{R}^{3}$. The typical dot product is 0.58. Which angle has cosine
0.58? About $55^\circ$. So in three dimensions, that typical size is the
cosine of $55^\circ$. Perpendicular would be $90^\circ$. The miss is $35^\circ$, a wide
miss. The third column agrees: 95% of pairs stay
inside $\pm 0.95$, and since a dot product can never pass $\pm 1$, that&#x27;s nearly
the entire possible range. In plain words: in 3D, a random pair can
land almost anywhere, and perpendicular is a special event.&lt;&#x2F;p&gt;
&lt;p&gt;Now $\mathbb{R}^{100}$. The typical dot product is 0.10, and the angle with cosine
0.10 is about $84^\circ$. The typical miss has shrunk from $35^\circ$ to $6^\circ$.&lt;&#x2F;p&gt;
&lt;p&gt;Now $\mathbb{R}^{10000}$. The typical dot product is 0.01, which is the angle $89.4^\circ$.
And the third column says 95% of all pairs keep their dot product
inside $\pm 0.0195$, which converts to the angle range $88.9^\circ$ to $91.1^\circ$.
Within about a degree of perpendicular, for 19 pairs out of every 20.&lt;&#x2F;p&gt;
&lt;p&gt;Say it plainly. Choose two directions at random in ten thousand
dimensions, and they&#x27;re almost certainly almost perpendicular. Nobody
arranged that. It&#x27;s the default state of high-dimensional space.&lt;&#x2F;p&gt;
&lt;p&gt;One column remains: the last one, which the program didn&#x27;t print. I
computed $1&#x2F;\sqrt{n}$ for each row myself: $1&#x2F;\sqrt{3} = 0.5774$, $1&#x2F;\sqrt{100} = 0.1000$,
$1&#x2F;\sqrt{10{,}000} = 0.0100$. Compare it to the second column, row by row. They
match to about three decimal places, in every dimension. That&#x27;s not a
coincidence; it&#x27;s a law. The typical size of $\operatorname{dot}(u, v)$ for random unit
vectors is $1&#x2F;\sqrt{n}$ &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-11&quot;&gt;11&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;, and your own twenty thousand samples measured it
before I ever named it.&lt;&#x2F;p&gt;
&lt;p&gt;Remember that number. It returns twice before the end.&lt;&#x2F;p&gt;
&lt;p&gt;The next page lets you watch all of this happen, live.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;try-it&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#try-it&quot; aria-label=&quot;Anchor link for: try-it&quot;&gt;Try it&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;

&lt;div class=&quot;widget&quot; data-widget=&quot;dimension-slider&quot;&gt;
  &lt;div class=&quot;w-frame&quot;&gt;
    &lt;span class=&quot;w-tag&quot;&gt;Interactive&lt;&#x2F;span&gt;

  &lt;div class=&quot;w-panel w-gate&quot;&gt;
    &lt;p class=&quot;w-title-sm&quot;&gt;Two predictions first&lt;&#x2F;p&gt;
    &lt;p class=&quot;w-note&quot;&gt;The controls unlock after you commit. The point of this
page is to compare what you expect with what happens.&lt;&#x2F;p&gt;

    &lt;p class=&quot;w-q&quot;&gt;1. As $n$ grows from 2 to 10,000, the
      histogram of $\operatorname{dot}(u, v)$ for two random unit vectors
      will:&lt;&#x2F;p&gt;
    &lt;div class=&quot;w-choices&quot;&gt;
    &lt;label class=&quot;w-choice&quot;&gt;&lt;input type=&quot;radio&quot; name=&quot;cs-q1&quot; value=&quot;a&quot;&gt; stay spread across [−1, 1]&lt;&#x2F;label&gt;
    &lt;label class=&quot;w-choice&quot;&gt;&lt;input type=&quot;radio&quot; name=&quot;cs-q1&quot; value=&quot;b&quot;&gt; split into two groups near −1 and +1&lt;&#x2F;label&gt;
    &lt;label class=&quot;w-choice&quot;&gt;&lt;input type=&quot;radio&quot; name=&quot;cs-q1&quot; value=&quot;c&quot;&gt; become a narrow spike at 0&lt;&#x2F;label&gt;
    &lt;label class=&quot;w-choice&quot;&gt;&lt;input type=&quot;radio&quot; name=&quot;cs-q1&quot; value=&quot;d&quot;&gt; flatten out evenly&lt;&#x2F;label&gt;
    &lt;&#x2F;div&gt;

    &lt;p class=&quot;w-q&quot;&gt;2. How many directions fit in
      $\mathbb{R}^{10{,}000}$ if every pair must keep $\operatorname{dot}(u, v)$ inside $\pm 0.05$?&lt;&#x2F;p&gt;
    &lt;p class=&quot;w-actions-left&quot;&gt;&lt;input type=&quot;number&quot; class=&quot;w-q2&quot; min=&quot;1&quot; value=&quot;10000&quot; aria-label=&quot;your guess&quot;&gt;
    &lt;button type=&quot;button&quot; class=&quot;w-lockbtn&quot;&gt;Lock in my predictions&lt;&#x2F;button&gt;&lt;&#x2F;p&gt;
    &lt;p class=&quot;w-warn&quot;&gt;Both predictions, please. They are the point.&lt;&#x2F;p&gt;
  &lt;&#x2F;div&gt;
  &lt;p class=&quot;w-locknote&quot; style=&quot;display: none&quot;&gt;&lt;&#x2F;p&gt;

  &lt;div class=&quot;w-panel w-chartpanel&quot; style=&quot;display: none&quot;&gt;
    &lt;p class=&quot;w-title-sm&quot;&gt;The experiment&lt;&#x2F;p&gt;
    &lt;div class=&quot;w-ctl&quot;&gt;
      &lt;span class=&quot;w-ctl-label&quot;&gt;dimension $n$&lt;&#x2F;span&gt;
      &lt;span class=&quot;w-sliderwrap&quot;&gt;&lt;input type=&quot;range&quot; class=&quot;w-nslider&quot; min=&quot;0&quot; max=&quot;1000&quot; value=&quot;463&quot;
             aria-label=&quot;dimension n&quot;&gt;&lt;&#x2F;span&gt;
      &lt;b class=&quot;w-nval&quot;&gt;100&lt;&#x2F;b&gt;
      &lt;label class=&quot;w-zoomlab&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;w-zoom&quot;&gt; magnify the center&lt;&#x2F;label&gt;
    &lt;&#x2F;div&gt;
    &lt;div class=&quot;w-chart&quot;&gt;&lt;canvas&gt;&lt;&#x2F;canvas&gt;&lt;&#x2F;div&gt;
    &lt;p class=&quot;w-statline&quot;&gt;typical size measured
      &lt;b class=&quot;w-stdval&quot;&gt;–&lt;&#x2F;b&gt;, predicted by the law $1&#x2F;\sqrt{n}$
      &lt;b class=&quot;w-theoryval&quot;&gt;–&lt;&#x2F;b&gt;; largest $\operatorname{dot}(u, v)$ in the sample
      &lt;b class=&quot;w-maxval&quot;&gt;–&lt;&#x2F;b&gt;&lt;&#x2F;p&gt;
  &lt;&#x2F;div&gt;

  &lt;div class=&quot;w-panel w-cappanel&quot; style=&quot;display: none&quot;&gt;
    &lt;p class=&quot;w-title-sm&quot;&gt;How many directions fit?&lt;&#x2F;p&gt;
    &lt;div class=&quot;w-ctl&quot;&gt;
      &lt;span class=&quot;w-ctl-label&quot;&gt;tolerance $\varepsilon$&lt;&#x2F;span&gt;
      &lt;span class=&quot;w-sliderwrap&quot;&gt;&lt;input type=&quot;range&quot; class=&quot;w-epsslider&quot; min=&quot;10&quot; max=&quot;300&quot; value=&quot;50&quot;
             aria-label=&quot;tolerance epsilon&quot;&gt;
      &lt;span class=&quot;w-track&quot;&gt;&lt;span class=&quot;w-tick&quot;&gt;$1&#x2F;\sqrt{n}$&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
      &lt;b class=&quot;w-epsval&quot;&gt;0.05&lt;&#x2F;b&gt;
      &lt;span class=&quot;w-ctl-note&quot;&gt;angle within &lt;span class=&quot;w-angval&quot;&gt;2.9°&lt;&#x2F;span&gt; of 90°&lt;&#x2F;span&gt;
    &lt;&#x2F;div&gt;
    &lt;p class=&quot;w-capline&quot;&gt;&lt;&#x2F;p&gt;
    &lt;p class=&quot;w-actions-left&quot;&gt;&lt;button type=&quot;button&quot; class=&quot;w-quiet w-revealbtn&quot;&gt;Compare with my predictions&lt;&#x2F;button&gt;&lt;&#x2F;p&gt;
    &lt;div class=&quot;w-reveal&quot;&gt;&lt;&#x2F;div&gt;
  &lt;&#x2F;div&gt;

  &lt;&#x2F;div&gt;
  &lt;div class=&quot;w-caption&quot;&gt;
    &lt;p class=&quot;w-cap&quot;&gt;&lt;span class=&quot;fig-label&quot;&gt;Figure 16.&lt;&#x2F;span&gt;
The Dimension Slider. Pick two directions at random in $n$-dimensional
space. How close to perpendicular are they? And how many directions fit if
every pair must stay almost perpendicular? Predict first; then move the
sliders.&lt;&#x2F;p&gt;
    &lt;p class=&quot;w-fine&quot;&gt;Both statements the counter makes are proved bounds,
not exact counts: a ceiling that holds below the threshold, a floor that
holds above it. The chapter proves each in a few lines. This page draws
live, unseeded samples from the exact distribution of
$\operatorname{dot}(u, v)$ for uniform random unit vectors (identical, by
rotational symmetry, to sampling pairs of vectors); every number quoted in
the chapter comes from the seeded, reproducible scripts in the series
repository.&lt;&#x2F;p&gt;
    &lt;noscript&gt;&lt;p class=&quot;w-fine&quot;&gt;This experiment needs JavaScript to run. The
chapter&#x27;s tables and figures carry the same numbers.&lt;&#x2F;p&gt;&lt;&#x2F;noscript&gt;
  &lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;
&lt;script src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;widgets.js?h=186ab988df8e56b4745e&quot; defer&gt;&lt;&#x2F;script&gt;
&lt;p&gt;The page asks you for two guesses before it opens, and the guesses are
the whole point, so answer honestly. First, as $n$ grows from 2 to 10,000,
what happens to the histogram of $\operatorname{dot}(u, v)$ for random pairs? And second,
how many directions fit in $\mathbb{R}^{10000}$ if every pair has to keep its dot
product inside $\pm 0.05$? Ten thousand? A million? More?&lt;&#x2F;p&gt;
&lt;p&gt;Then drag $n$ and watch. The histogram narrows onto a red curve, which is
the exact distribution, with width $1&#x2F;\sqrt{n}$ at every $n$. The largest dot product in
the sample shrinks along with it. And the capacity counter changes its
behavior at one sharp threshold. The rest of the article proves what the
page shows.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;checking-the-famous-demo&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#checking-the-famous-demo&quot; aria-label=&quot;Anchor link for: checking-the-famous-demo&quot;&gt;Checking the famous demo&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;For years I repeated a claim you&#x27;ve probably met too: &quot;the number of
almost-orthogonal directions grows exponentially with dimension; this
follows from the Johnson–Lindenstrauss lemma.&quot; Versions of that sentence
appear in the 3Blue1Brown video &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-6&quot;&gt;6&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt; and in Anthropic&#x27;s Toy Models paper
&lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-1&quot;&gt;1&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;, and I absorbed it from them like everyone else. While preparing this
series, I finally checked. Two problems appeared, one small and one
large.&lt;&#x2F;p&gt;
&lt;p&gt;The small one is a naming error. The Johnson–Lindenstrauss lemma is about
preserving distances: a fixed set of points can be projected into
surprisingly few dimensions while approximately keeping every pairwise
distance &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-12&quot;&gt;12&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;. It&#x27;s a beautiful fact, but it answers a different
question. It never counts how many directions fit, and counting is
exactly what we need. The counting question belongs to a different
field, the study of sphere packings and spherical codes &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-13&quot;&gt;13&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;. Mostly the
mislabeling is harmless.&lt;&#x2F;p&gt;
&lt;p&gt;The large problem is the numbers. The video demonstrates the exponential
claim with an experiment: 10,000 vectors in $\mathbb{R}^{100}$, adjusted step by step
until, as the narration puts it, all pairwise angles sit between 89 and
91 degrees &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-6&quot;&gt;6&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Before any theorem, hold those two numbers apart and look at them. The
space has exactly 100 independent directions; that is what dimension
means. The demo asks it to hold 10,000 directions, every pair nearly
perpendicular. That&#x27;s one hundred arrows for every direction the space
actually has.&lt;&#x2F;p&gt;

&lt;figure class=&quot;drawing wide&quot; style=&quot;--dw: 862px;&quot;&gt;
  &lt;div class=&quot;drawing-card&quot;&gt;
    &lt;img class=&quot;drawing-light&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;crowd-light.svg?h=18a81879212f96ad146b&quot;
         alt=&quot;a small square room labeled ℝ¹⁰⁰: 100 independent directions, a dense cloud of tiny arrows standing for the 10,000 requested directions, and a funnel between them with the badge 100 arrows per direction&quot; width=&quot;862&quot; height=&quot;339&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
    &lt;img class=&quot;drawing-dark&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;crowd-dark.svg?h=d7bc52c8ac334d5ab1bb&quot;
         alt=&quot;a small square room labeled ℝ¹⁰⁰: 100 independent directions, a dense cloud of tiny arrows standing for the 10,000 requested directions, and a funnel between them with the badge 100 arrows per direction&quot; width=&quot;862&quot; height=&quot;339&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
  &lt;&#x2F;div&gt;
  &lt;figcaption&gt;&lt;span class=&quot;fig-label&quot;&gt;Figure 17.&lt;&#x2F;span&gt; the demo&#x27;s request, drawn to scale in count if not in dimension&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;I wanted to reproduce it, and a theorem from 1974 stopped me. The
theorem is called the Welch bound &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-14&quot;&gt;14&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;, and it&#x27;s about exactly the kind
of attempt the video made. Here is that attempt, described slowly.&lt;&#x2F;p&gt;
&lt;p&gt;You have a space with $n$ dimensions. You place $m$ unit vectors in it, in
any arrangement you want: random, careful, computed by a machine. Your
aim is that every pair be as close to perpendicular as possible.&lt;&#x2F;p&gt;
&lt;p&gt;Whatever your arrangement, examine all its pairs and find the two
vectors that lean together the most: the pair furthest from
perpendicular. Call it the most crowded pair. That one pair is the
honest measure of the whole arrangement, because every other pair is
at least as good.&lt;&#x2F;p&gt;
&lt;p&gt;One more step before the theorem, so that every word of it can land.
Fix the direction of good and bad. What you want, for every pair, is a
dot product near 0, because 0 means perpendicular. The bigger a pair&#x27;s
dot product, the more the two vectors lean together, and the worse that
pair is for you. So improving an arrangement means exactly one thing:
pushing dot products down, toward 0. Keep that direction in mind; the
theorem is about how far down the pushing can go.&lt;&#x2F;p&gt;
&lt;p&gt;Welch proved that the pushing has a limit. In every arrangement of $m$
unit vectors in $n$ dimensions, the most crowded pair&#x27;s dot product is
at least&lt;&#x2F;p&gt;
&lt;p&gt;$$\sqrt{\dfrac{m - n}{n\cdot(m - 1)}}$$&lt;&#x2F;p&gt;
&lt;p&gt;where $m$ is how many vectors you placed and $n$ is the dimension.&lt;&#x2F;p&gt;
&lt;p&gt;What does that mean? Something you can picture directly. A space with
$n$ dimensions has room for exactly $n$ fully independent
directions, and no more. Now place $m$ vectors, with $m$ bigger than
$n$. They can&#x27;t all be independent. Some of them must lean toward
others, simply because there aren&#x27;t enough separate directions for
everyone.&lt;&#x2F;p&gt;
&lt;p&gt;Welch measured that forced leaning. His formula takes your two
numbers, $m$ and $n$, and produces one number. Suppose, for a moment, that
it produces 0.1. What does a dot product of 0.1 look like? These are
unit vectors, so every dot product is the cosine of the pair&#x27;s angle,
and $0.1 = \cos 84^\circ$. So the promise, in geometric words: in every
arrangement of your $m$ vectors, at least one pair sits at $84^\circ$ or
closer.&lt;&#x2F;p&gt;
&lt;p&gt;Watch it across arrangements. A careless one might have its most crowded
pair at a dot product of 0.3, which is the angle $73^\circ$: two vectors
leaning hard toward each other. A careful one improves that to 0.15,
which is $81^\circ$. The best ones approach 0.1, which is $84^\circ$. But no
arrangement, ever, pushes its most crowded pair past $84^\circ$, into the
last six degrees before perpendicular. That&#x27;s the theorem. You can
move the most crowded pair to a different spot. You can&#x27;t remove it,
and you can&#x27;t push its angle closer to perpendicular than the formula
allows.&lt;&#x2F;p&gt;
&lt;p&gt;The formula itself looks opaque, so check what it says at its edges.
Set $m = n$, exactly as many vectors as directions: the numerator $m - n$
is 0, so the promised overlap is 0, and perfect orthogonality is
allowed. That&#x27;s exactly what we proved with the $n$ perfect slots. Now
place vectors past $n$: each extra vector makes the numerator grow, so
the promised overlap rises. Crowding is not a side effect in this
formula; it&#x27;s the formula&#x27;s whole content. Finally, push $m$ toward
infinity: $(m - n)&#x2F;(n \cdot (m - 1))$ approaches $1&#x2F;n$, so the promised overlap
climbs toward $1&#x2F;\sqrt{n}$ and never passes it. Remember that; it returns in
the next section. Read this way, the formula says three plain things:
perfection is possible up to $n$, every vector beyond $n$ crowds all the
rest, and the crowding approaches a fixed level, $1&#x2F;\sqrt{n}$.&lt;&#x2F;p&gt;
&lt;p&gt;Now, why does any of this matter for the demo? Stay with the supposed
number 0.1, which is the angle $84^\circ$, and write the two sides as two
plain sentences.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The theorem says: in any arrangement whatsoever, some two vectors sit
at 84° or less.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;The demo says: in my arrangement, every two vectors sit at 89° or
more.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Hold both sentences at once. The same arrangement can&#x27;t satisfy both,
because the two vectors the theorem points at would have to be below
$84^\circ$ and above $89^\circ$ at the same time. So if the formula really produces
about 0.1 for the demo&#x27;s $m$ and $n$, then the demo describes an
arrangement that cannot exist, and we know it without placing a single
vector. Everything now depends on one number: what the formula
actually produces for $m = 10{,}000$ and $n = 100$. Let&#x27;s compute it, one
step at a time:&lt;&#x2F;p&gt;
&lt;p&gt;$$\begin{aligned} m - n &amp;amp;= 10{,}000 - 100 = 9{,}900 \\ n\cdot(m - 1) &amp;amp;= 100 \cdot 9{,}999 = 999{,}900 \\ \text{promised overlap} &amp;amp;= \sqrt{9{,}900 &#x2F; 999{,}900} = \sqrt{0.0099} = 0.0995 \end{aligned}$$&lt;&#x2F;p&gt;
&lt;p&gt;The real number is 0.0995, almost exactly the 0.1 we rehearsed with.
So the collision is real. The theorem&#x27;s sentence: some two vectors sit
at $84.3^\circ$ or less. The demo&#x27;s sentence: every two vectors sit at $89^\circ$ or
more. One of these sentences is a theorem, so the other one is false.
In every possible placement of ten thousand vectors in $\mathbb{R}^{100}$, some pair
stays at least $5.7^\circ$ away from perpendicular. No amount of adjustment
can change that.&lt;&#x2F;p&gt;

&lt;figure class=&quot;drawing wide&quot; style=&quot;--dw: 817px;&quot;&gt;
  &lt;div class=&quot;drawing-card&quot;&gt;
    &lt;img class=&quot;drawing-light&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;welch-axis-light.svg?h=dff6371fa6e2bbd7a67f&quot;
         alt=&quot;a horizontal axis of a pair&amp;#x27;s dot product with two brackets: the demo&amp;#x27;s promise, every pair between 0 and 0.0175, and Welch&amp;#x27;s promise, at least one pair from 0.0995 up, with an empty gap between the brackets&quot; width=&quot;817&quot; height=&quot;243&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
    &lt;img class=&quot;drawing-dark&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;welch-axis-dark.svg?h=a161513a824b8a2fb42a&quot;
         alt=&quot;a horizontal axis of a pair&amp;#x27;s dot product with two brackets: the demo&amp;#x27;s promise, every pair between 0 and 0.0175, and Welch&amp;#x27;s promise, at least one pair from 0.0995 up, with an empty gap between the brackets&quot; width=&quot;817&quot; height=&quot;243&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
  &lt;&#x2F;div&gt;
  &lt;figcaption&gt;&lt;span class=&quot;fig-label&quot;&gt;Figure 18.&lt;&#x2F;span&gt; both promises can&#x27;t hold, and one of them is a theorem&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;A short argument turns &quot;can&#x27;t be perfect&quot; into &quot;almost nothing fits.&quot;
It uses three pieces of linear algebra, and each one can be seen, not
just written: a table, its rank, and its trace.&lt;&#x2F;p&gt;
&lt;p&gt;The table first. Take any $N$ almost-orthogonal unit vectors and write
the $N$-by-$N$ table of all their dot products: the &lt;em&gt;Gram matrix&lt;&#x2F;em&gt;, whose
entry in row $i$, column $j$ is $\operatorname{dot}(u_i, u_j)$ &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-4&quot;&gt;4&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;. The diagonal is all 1s,
since $\operatorname{dot}(u, u) = 1$. Every other entry is at most $\varepsilon$ in size, tiny. Now
set that table next to the $N$-by-$N$ &lt;em&gt;identity matrix&lt;&#x2F;em&gt;, the table with 1s
on the diagonal and exact 0s everywhere else. The two are nearly the
same picture.&lt;&#x2F;p&gt;

&lt;figure class=&quot;drawing wide&quot; style=&quot;--dw: 744px;&quot;&gt;
  &lt;div class=&quot;drawing-card&quot;&gt;
    &lt;img class=&quot;drawing-light&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;gram-table-light.svg?h=30229ffda7d3814932c1&quot;
         alt=&quot;two N-by-N grids side by side: the identity with a bright diagonal of 1s and clean cells elsewhere, and the Gram matrix with the same diagonal but every other cell faintly shaded and labeled at most ε&quot; width=&quot;744&quot; height=&quot;360&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
    &lt;img class=&quot;drawing-dark&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;gram-table-dark.svg?h=480004d0155dfae3d076&quot;
         alt=&quot;two N-by-N grids side by side: the identity with a bright diagonal of 1s and clean cells elsewhere, and the Gram matrix with the same diagonal but every other cell faintly shaded and labeled at most ε&quot; width=&quot;744&quot; height=&quot;360&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
  &lt;&#x2F;div&gt;
  &lt;figcaption&gt;&lt;span class=&quot;fig-label&quot;&gt;Figure 19.&lt;&#x2F;span&gt; an almost-orthogonal family&#x27;s table is almost the identity&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;Rank next. The rank of a table is how many of its rows carry genuinely
new information. A tiny example: in the table with rows (1, 0, 1),
(0, 1, 1), (1, 1, 2), the third row is the first plus the second. It
brings nothing new, so the rank is 2, not 3. The identity is the
opposite extreme: every row is entirely its own, so the $N$-by-$N$ identity
has the maximum possible rank, $N$. And a table that is nearly the
identity is nearly full rank.&lt;&#x2F;p&gt;
&lt;p&gt;Now the ceiling. Our table wasn&#x27;t given to us; it was built from the
vectors: $G = V^{\mathsf T} V$, where the columns of $V$ are the vectors themselves.
And $V$ has only $n = 100$ rows, one per dimension. A product of two tables
can&#x27;t contain more independence than either factor, so $\operatorname{rank}(G) \le 100$.&lt;&#x2F;p&gt;

&lt;figure class=&quot;drawing wide&quot; style=&quot;--dw: 724px;&quot;&gt;
  &lt;div class=&quot;drawing-card&quot;&gt;
    &lt;img class=&quot;drawing-light&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;gram-factorization-light.svg?h=bc9a55f872c5a99e329b&quot;
         alt=&quot;G equals V-transpose times V drawn as a multiplication table: V-transpose tall on the left with its rows as the vectors, V flat on top with its columns as the vectors, and one highlighted row and column meeting inside G at a single orange cell labeled dot(u i, u j), with a note that the thin side is only n = 100&quot; width=&quot;724&quot; height=&quot;470&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
    &lt;img class=&quot;drawing-dark&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;gram-factorization-dark.svg?h=de4172037c9a453e5e6c&quot;
         alt=&quot;G equals V-transpose times V drawn as a multiplication table: V-transpose tall on the left with its rows as the vectors, V flat on top with its columns as the vectors, and one highlighted row and column meeting inside G at a single orange cell labeled dot(u i, u j), with a note that the thin side is only n = 100&quot; width=&quot;724&quot; height=&quot;470&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
  &lt;&#x2F;div&gt;
  &lt;figcaption&gt;&lt;span class=&quot;fig-label&quot;&gt;Figure 20.&lt;&#x2F;span&gt; a ten-thousand-row table built from hundred-row material. Its rank can&#x27;t pass 100.&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;So two facts now stand against each other. The table&#x27;s shape says:
nearly the identity, so rank near $N = 10{,}000$. The table&#x27;s origin says:
rank at most 100. Both can hold only if $N$ isn&#x27;t actually large. That&#x27;s
the whole proof. What&#x27;s left is to measure how large $N$ can be, and the
measuring tool is the trace.&lt;&#x2F;p&gt;
&lt;p&gt;The trace of a table means: walk down the diagonal and add the entries.
Ours is all 1s, so $\operatorname{trace}(G) = N$. No computation, just counting. One
more fact, which you may take on faith today or check at home: for any
Gram matrix,&lt;&#x2F;p&gt;
&lt;p&gt;$$\operatorname{rank}(G) \ge \dfrac{\operatorname{trace}(G)^2}{\operatorname{trace}(G\cdot G)}$$&lt;&#x2F;p&gt;
&lt;p&gt;(for readers who know eigenvalues: $G$&#x27;s are never negative, and this is
Cauchy–Schwarz applied to them), and $\operatorname{trace}(G \cdot G)$ equals the sum of every
entry of $G$ squared. Count that by hand too: $N$ ones on the diagonal, and
at most $N \cdot (N-1)$ other entries no bigger than $\varepsilon$. So $\operatorname{trace}(G \cdot G) \le N + N \cdot (N-1) \cdot \varepsilon^2$. Chain everything:&lt;&#x2F;p&gt;
&lt;p&gt;$$100 \ge \operatorname{rank}(G) \ge \dfrac{N^2}{N + N\cdot(N-1)\cdot\varepsilon^2}$$&lt;&#x2F;p&gt;
&lt;p&gt;and solve for $N$:&lt;&#x2F;p&gt;
&lt;p&gt;$$N \le \dfrac{n\cdot(1 - \varepsilon^2)}{1 - n\cdot\varepsilon^2}, \quad \text{valid whenever } \varepsilon &amp;lt; 1&#x2F;\sqrt{n}$$&lt;&#x2F;p&gt;
&lt;p&gt;Use the video&#x27;s own numbers, $n = 100$ and $\varepsilon = \cos 89^\circ \approx 0.0175$: the
bound says $N \le 103$. (The general fact behind it, that a nearly-identity
matrix must have high rank, is a theorem of Alon &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-19&quot;&gt;19&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;.)&lt;&#x2F;p&gt;
&lt;p&gt;A hundred dimensions hold at most 103 directions at $89^\circ$–$91^\circ$ tolerance.
The famous demo promised ten thousand. The truth is about a hundred
times smaller.&lt;&#x2F;p&gt;
&lt;p&gt;And this story has an ending. About a year after the video, Sanderson
posted a correction &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-17&quot;&gt;17&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;. The demo&#x27;s code had an error: not every pair
actually reached the $89^\circ$–$91^\circ$ range. Some pairs sat near $0^\circ$ or $180^\circ$,
hidden at the far edges of the histogram, and the cost function never
punished them. A viewer, Nick Yoder, traced the cause and measured the
truth: with a repaired loss, ten thousand vectors in $\mathbb{R}^{100}$ reach about
$76.5^\circ$ at best, nowhere near $89^\circ$ &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-18&quot;&gt;18&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;. Better still, the failed
optimization had a structure. It had built roughly one hundred groups
of one hundred nearly identical vectors &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-18&quot;&gt;18&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;: about one hundred truly
distinct directions, each copied about a hundred times. The optimizer
knew no theorems, and it found the same ceiling of about a hundred
that the table predicted.&lt;&#x2F;p&gt;
&lt;p&gt;I want to be fair to the video, which I admire, and which is how many
readers met this question in the first place. Its point stands, and
Sanderson said so himself in the correction: the number of
almost-orthogonal directions really does grow exponentially with
dimension &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-17&quot;&gt;17&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;. The demo just sits on the wrong side of a threshold
that nobody names. So let&#x27;s name it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-threshold-at-1-sqrtn&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#the-threshold-at-1-sqrtn&quot; aria-label=&quot;Anchor link for: the-threshold-at-1-sqrtn&quot;&gt;The threshold at 1&#x2F;√n&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;You&#x27;ve now met $1&#x2F;\sqrt{n}$ twice. It was the typical dot product of random
pairs, measured in your own table three sections ago. And it was the
condition on the counting bound, whose formula divides by $1 - n \cdot \varepsilon^2$ and
is therefore valid only below $\varepsilon = 1&#x2F;\sqrt{n}$. Twice is not a coincidence.
It&#x27;s one fact, and it&#x27;s the central fact of this article: $1&#x2F;\sqrt{n}$ is a
border, with a different law on each side. Here&#x27;s the whole territory
on one map, and then a walk through it.&lt;&#x2F;p&gt;

&lt;figure class=&quot;drawing wide&quot; style=&quot;--dw: 923px;&quot;&gt;
  &lt;div class=&quot;drawing-card&quot;&gt;
    &lt;img class=&quot;drawing-light&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;threshold-map-light.svg?h=664191ced34e0a9252ed&quot;
         alt=&quot;one wide panel with tolerance ε on the horizontal axis and directions that fit on a logarithmic vertical axis: a dashed border at 1&amp;#x2F;√n, a flat curve at height n on the left, a steeply rising curve on the right, and two marked points, the famous demo and the slider&amp;#x27;s question&quot; width=&quot;923&quot; height=&quot;432&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
    &lt;img class=&quot;drawing-dark&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;threshold-map-dark.svg?h=8296c63303a3e9fe8d2a&quot;
         alt=&quot;one wide panel with tolerance ε on the horizontal axis and directions that fit on a logarithmic vertical axis: a dashed border at 1&amp;#x2F;√n, a flat curve at height n on the left, a steeply rising curve on the right, and two marked points, the famous demo and the slider&amp;#x27;s question&quot; width=&quot;923&quot; height=&quot;432&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
  &lt;&#x2F;div&gt;
  &lt;figcaption&gt;&lt;span class=&quot;fig-label&quot;&gt;Figure 21.&lt;&#x2F;span&gt; one number, one border, two laws&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;Now the walk, in one concrete space: $n = 10{,}000$, where the border sits
at $1&#x2F;\sqrt{10{,}000} = 0.01$. Keep that number&#x27;s physical meaning in view. Pick
two directions in this space at random, with no design at all, and
their dot product is typically about 0.01. The space produces that much
overlap on its own. It&#x27;s the noise level of the space itself.&lt;&#x2F;p&gt;
&lt;p&gt;Start on the map&#x27;s left side, where the tolerance is below the border.
Ask for $\varepsilon = 0.005$, half the noise. Look at what that demand really
says: every pair of stored directions must overlap less than two random
directions typically do. Randomness itself fails your standard, so no
direction comes free, and every new one must be placed against all the
previous ones with care. The counting bound measures how far care can
go: $N \le 13{,}333$. Exact orthogonality already gave you 10,000 slots. You
allowed leaks, and you gained about three thousand more. Barely
anything.&lt;&#x2F;p&gt;
&lt;p&gt;Now move to the map&#x27;s right side. Ask for $\varepsilon = 0.05$, five times the
noise. The counting bound can no longer speak here: its formula divides
by $1 - n \cdot \varepsilon^2 = 1 - 25$, a negative number, so past the border its
derivation fails and it says nothing at all. What replaces it is an
argument you can hold in one picture.&lt;&#x2F;p&gt;
&lt;p&gt;Every direction is a point on the sphere: the set of all unit vectors
in $\mathbb{R}^{10000}$. When you place a direction, what does it actually forbid?
Only the directions too close to it, the ones whose overlap with it
would pass $\varepsilon$. On the sphere, those form two small caps: one around the
placed direction, and one around its exact opposite, where the overlap
is large and negative. And here&#x27;s the number that decides everything:
in high dimensions, the two caps together cover almost nothing, at most
$e^{-n\varepsilon^2&#x2F;2}$ of the surface. (The textbook bound is $e^{-n\varepsilon^2&#x2F;2}$ for one
cap &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-11&quot;&gt;11&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;; at our numbers the true cap is more than ten times smaller
than that, so the pair fits under the single bound with room to spare.)
That smallness is the fact your own table measured: nearly all of the sphere sits almost perpendicular to any one
direction. With our numbers that&#x27;s $e^{-12.5}$, about 3.7
millionths.&lt;&#x2F;p&gt;
&lt;p&gt;So placing directions becomes plain accounting:&lt;&#x2F;p&gt;
&lt;p&gt;$$\begin{aligned} \text{the whole surface:} \quad &amp;amp; 1 \\ \text{forbidden by each placed direction:} \quad &amp;amp; \text{about } 3.7 \text{ millionths} \\ \text{directions placed before the surface is used:} \quad &amp;amp; 1 &#x2F; (3.7 \text{ millionths}) \approx 270{,}000 \end{aligned}$$&lt;&#x2F;p&gt;
&lt;p&gt;You can keep placing directions until the caps cover the sphere, and
that takes about $e^{12.5}$, roughly 270,000 placements. And this is a
guarantee, not an estimate of the maximum; the truth is larger
still. It&#x27;s also, at last, the exact answer to the slider&#x27;s second
question.&lt;&#x2F;p&gt;

&lt;figure class=&quot;drawing wide&quot; style=&quot;--dw: 737px;&quot;&gt;
  &lt;div class=&quot;drawing-card&quot;&gt;
    &lt;img class=&quot;drawing-light&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;patch-budget-light.svg?h=e4d72f609c03c03c626f&quot;
         alt=&quot;a large circle for the sphere of directions in ℝ¹⁰⁰⁰⁰ with one placed arrow, a zoom bubble magnifying the small forbidden patch at the arrow&amp;#x27;s tip, and an accounting strip reading 1 ÷ 0.0000037 ≈ 270,000&quot; width=&quot;737&quot; height=&quot;431&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
    &lt;img class=&quot;drawing-dark&quot;
         src=&quot;https:&#x2F;&#x2F;circuit.khalilli.ai&#x2F;crowded-space&#x2F;ch01&#x2F;drawings&#x2F;patch-budget-dark.svg?h=8b803b46bef161632349&quot;
         alt=&quot;a large circle for the sphere of directions in ℝ¹⁰⁰⁰⁰ with one placed arrow, a zoom bubble magnifying the small forbidden patch at the arrow&amp;#x27;s tip, and an accounting strip reading 1 ÷ 0.0000037 ≈ 270,000&quot; width=&quot;737&quot; height=&quot;431&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;
  &lt;&#x2F;div&gt;
  &lt;figcaption&gt;&lt;span class=&quot;fig-label&quot;&gt;Figure 22.&lt;&#x2F;span&gt; each placed direction forbids almost nothing, so enormously many directions fit&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;Why is the growth exponential? Because the caps&#x27; share, $e^{-n\varepsilon^2&#x2F;2}$,
carries $n \cdot \varepsilon^2$ inside the exponent. Raise the tolerance a little, or the
dimension a little, and the share doesn&#x27;t shrink a little; it shrinks
by a factor. Every small increase of the tolerance multiplies the
capacity.&lt;&#x2F;p&gt;
&lt;p&gt;One more appearance of the number, and the picture is complete. In the
demo section, Welch&#x27;s promised overlap climbed toward $1&#x2F;\sqrt{n}$ as $m$ grew,
and never passed it. Read that again, now knowing what $1&#x2F;\sqrt{n}$ is: once
there are many vectors, every arrangement, designed by anyone, contains
a pair overlapping by about $1&#x2F;\sqrt{n}$. But a typical random pair already
sits at $1&#x2F;\sqrt{n}$ with no design at all. The cleverest possible placement
barely beats random choice.&lt;&#x2F;p&gt;
&lt;p&gt;So one number holds three jobs at once:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;$1&#x2F;\sqrt{n}$ is the overlap randomness produces on its own.&lt;&#x2F;li&gt;
&lt;li&gt;$1&#x2F;\sqrt{n}$ is where the counting bound stops being valid.&lt;&#x2F;li&gt;
&lt;li&gt;$1&#x2F;\sqrt{n}$ is the level that the best possible design approaches.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;That&#x27;s the whole section in three lines. And the summary needs no
numbers at all. Demand less interference than randomness produces on
its own, and you gain nothing. Accept interference at the random level
or above, and the space opens exponentially wide.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;at-the-scale-of-real-models&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#at-the-scale-of-real-models&quot; aria-label=&quot;Anchor link for: at-the-scale-of-real-models&quot;&gt;At the scale of real models&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Modern language models are transformers &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-15&quot;&gt;15&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;. Each token of the input
carries its own vector through the network, and layer after layer,
neurons read that vector with dot products and write their results back
into it. That carried vector is the &lt;em&gt;residual stream&lt;&#x2F;em&gt; &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-15&quot;&gt;15&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;, and in a
Llama model of the common 7-billion-parameter size, it&#x27;s a list of 4096
numbers: one vector in $\mathbb{R}^{4096}$. The few thousand numbers from this
article&#x27;s first paragraph are exactly this list.&lt;&#x2F;p&gt;
&lt;p&gt;So the practical question is how many almost-orthogonal directions fit in
4096 dimensions, and the answer depends on the tolerance more than on
anything else. At tolerance 0.05, the guaranteed count is about 167,
small
because 0.05 is only about three times this space&#x27;s noise level,
$1&#x2F;\sqrt{4096} \approx 0.016$. At 0.10, it&#x27;s about 800 million. Doubling the tolerance multiplied
the guarantee five million times, because the tolerance sits inside an
exponent. And randomness alone already delivers: a million random
directions fit with every pair between about $83^\circ$ and $97^\circ$, no design
needed.&lt;&#x2F;p&gt;
&lt;p&gt;A million meanings in four thousand dimensions. The capacity for the
storage problem really exists.&lt;&#x2F;p&gt;
&lt;p&gt;But the geometry can&#x27;t decide everything by itself, because interference
is only paid when it happens. Two overlapping directions collide only
when both hold a nonzero quantity at the same moment, and the opening
neuron&#x27;s four meanings almost never share an input; Korean text and HTTP
requests rarely arrive together. So the true cost of sharing depends on
how often stored things are active at the same time. That property of the
world is called sparsity, and it&#x27;s the whole subject of Part 2.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-i-can-prove-and-what-i-can-t-yet&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-i-can-prove-and-what-i-can-t-yet&quot; aria-label=&quot;Anchor link for: what-i-can-prove-and-what-i-can-t-yet&quot;&gt;What I can prove, and what I can&#x27;t yet&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Here&#x27;s where this leaves us. I can prove that below $1&#x2F;\sqrt{n}$, interference
tolerance gains almost nothing, and capacity stays near $n$. I can prove
that above $1&#x2F;\sqrt{n}$, capacity grows exponentially, that random directions
achieve it, and that the Welch bound keeps every arrangement&#x27;s
most crowded pair near $1&#x2F;\sqrt{n}$. So the capacity for millions of almost-orthogonal directions
inside a few thousand dimensions provably exists.&lt;&#x2F;p&gt;
&lt;p&gt;What I can&#x27;t tell you yet: whether training actually stores meanings
along such directions, what geometry it picks if it does, and what the
interference costs in practice. Those are Parts 2, 3, and 4.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;predict-then-run&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#predict-then-run&quot; aria-label=&quot;Anchor link for: predict-then-run&quot;&gt;Predict, then run&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Three small predictions before you go. Write each answer down before
checking; the prediction is where the learning happens.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The measurement code used $n$ up to 10,000. Using the law you
measured, predict the typical size of $\operatorname{dot}(u, v)$ for $n = 1{,}000{,}000$.
Then change one line of the code and run it.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;In $\mathbb{R}^{4096}$, the guaranteed capacity was about 167 at tolerance 0.05
and about 800 million at 0.10. Before computing: the guarantee is
$e^{n\varepsilon^2&#x2F;2}$, so by what factor does it grow when $\varepsilon$ moves from 0.05 to
0.10? Compute the exponent difference and check your guess.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;The counting bound $N \le n \cdot (1 - \varepsilon^2)&#x2F;(1 - n \cdot \varepsilon^2)$ decided the demo&#x27;s
fate. Use it once yourself: in $\mathbb{R}^{100}$ with $\varepsilon = 0.05$, at most how many
directions fit? First predict: closer to 100 or to 1,000? Then
compute.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;About the sources. The Background &amp;amp; Motivation section of Toy Models of
Superposition &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-1&quot;&gt;1&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt; and the whole of Olah&#x27;s note on composition and
superposition &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-7&quot;&gt;7&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt; are now fully readable; every idea in them (features as
directions, interference, almost-orthogonality) is one you&#x27;ve just used.
The 3Blue1Brown chapter &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-6&quot;&gt;6&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;, together with its correction &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-17&quot;&gt;17&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt; and the
follow-up it inspired &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-18&quot;&gt;18&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;, will read differently now too. The
Demonstrating Superposition section of Toy Models belongs to Part 2, so
save it.&lt;&#x2F;p&gt;
&lt;p&gt;If you want more, in rough order of need: Strang&#x27;s orthogonality chapter
or the MIT OCW 18.06 lectures, if $\mathbb{R}^{n}$ feels shaky &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-4&quot;&gt;4&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;; Axler&#x27;s
inner-product chapter, for the inner product family done properly &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-5&quot;&gt;5&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;;
Abbott&#x27;s Flatland, an 1884 novel about reasoning across dimensions, one
evening&#x27;s read &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-16&quot;&gt;16&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;; Cybenko, Hornik, and the Kolmogorov–Arnold paper, if you wonder what
stacks of these simple units can represent in principle, a question
this article never needed &lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-8&quot;&gt;8&lt;&#x2F;a&gt;, &lt;a href=&quot;#ref-9&quot;&gt;9&lt;&#x2F;a&gt;, &lt;a href=&quot;#ref-10&quot;&gt;10&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;; Vershynin&#x27;s Chapter 3 and the
Dasgupta–Gupta proof of the JL lemma, for the probability machinery
&lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-11&quot;&gt;11&lt;&#x2F;a&gt;, &lt;a href=&quot;#ref-12&quot;&gt;12&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;; Conway, Hardin and Sloane, for the packing literature itself
&lt;span class=&quot;cite&quot;&gt;[&lt;a href=&quot;#ref-13&quot;&gt;13&lt;&#x2F;a&gt;]&lt;&#x2F;span&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The capacity exists. Part 2 asks whether trained networks actually use
it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#references&quot; aria-label=&quot;Anchor link for: references&quot;&gt;References&lt;&#x2F;a&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;span class=&quot;ref-num&quot; id=&quot;ref-1&quot;&gt;[1]&lt;&#x2F;span&gt; Elhage et al., &lt;em&gt;Toy Models of Superposition&lt;&#x2F;em&gt;, Transformer Circuits
Thread, 2022. &lt;a class=&quot;ref-link&quot; href=&quot;https:&#x2F;&#x2F;transformer-circuits.pub&#x2F;2022&#x2F;toy_model&#x2F;index.html&quot;&gt;https:&#x2F;&#x2F;transformer-circuits.pub&#x2F;2022&#x2F;toy_model&#x2F;index.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;ref-num&quot; id=&quot;ref-2&quot;&gt;[2]&lt;&#x2F;span&gt; Bricken et al., &lt;em&gt;Towards Monosemanticity: Decomposing Language Models
With Dictionary Learning&lt;&#x2F;em&gt;, Transformer Circuits Thread, 2023.
&lt;a class=&quot;ref-link&quot; href=&quot;https:&#x2F;&#x2F;transformer-circuits.pub&#x2F;2023&#x2F;monosemantic-features&#x2F;index.html&quot;&gt;https:&#x2F;&#x2F;transformer-circuits.pub&#x2F;2023&#x2F;monosemantic-features&#x2F;index.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;ref-num&quot; id=&quot;ref-3&quot;&gt;[3]&lt;&#x2F;span&gt; Olah et al., &lt;em&gt;Zoom In: An Introduction to Circuits&lt;&#x2F;em&gt;, Distill, 2020.
&lt;a class=&quot;ref-link&quot; href=&quot;https:&#x2F;&#x2F;distill.pub&#x2F;2020&#x2F;circuits&#x2F;zoom-in&#x2F;&quot;&gt;https:&#x2F;&#x2F;distill.pub&#x2F;2020&#x2F;circuits&#x2F;zoom-in&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;ref-num&quot; id=&quot;ref-4&quot;&gt;[4]&lt;&#x2F;span&gt; Strang, &lt;em&gt;Introduction to Linear Algebra&lt;&#x2F;em&gt;, 5th ed.,
Wellesley-Cambridge Press, 2016. (Orthogonality: Ch. 4.)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;ref-num&quot; id=&quot;ref-5&quot;&gt;[5]&lt;&#x2F;span&gt; Axler, &lt;em&gt;Linear Algebra Done Right&lt;&#x2F;em&gt;, 3rd ed., Springer, 2015. (Inner
product spaces: Ch. 6.)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;ref-num&quot; id=&quot;ref-6&quot;&gt;[6]&lt;&#x2F;span&gt; Sanderson (3Blue1Brown), &lt;em&gt;How might LLMs store facts&lt;&#x2F;em&gt; (Deep Learning,
Chapter 7), 2024. &lt;a class=&quot;ref-link&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=9-Jl0dxWQs8&quot;&gt;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=9-Jl0dxWQs8&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;ref-num&quot; id=&quot;ref-7&quot;&gt;[7]&lt;&#x2F;span&gt; Olah, &lt;em&gt;Distributed Representations: Composition &amp;amp; Superposition&lt;&#x2F;em&gt;,
Transformer Circuits Thread, 2023.
&lt;a class=&quot;ref-link&quot; href=&quot;https:&#x2F;&#x2F;transformer-circuits.pub&#x2F;2023&#x2F;superposition-composition&#x2F;index.html&quot;&gt;https:&#x2F;&#x2F;transformer-circuits.pub&#x2F;2023&#x2F;superposition-composition&#x2F;index.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;ref-num&quot; id=&quot;ref-8&quot;&gt;[8]&lt;&#x2F;span&gt; Cybenko, &lt;em&gt;Approximation by superpositions of a sigmoidal function&lt;&#x2F;em&gt;,
Mathematics of Control, Signals and Systems, 1989.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;ref-num&quot; id=&quot;ref-9&quot;&gt;[9]&lt;&#x2F;span&gt; Hornik, Stinchcombe &amp;amp; White, &lt;em&gt;Multilayer feedforward networks are
universal approximators&lt;&#x2F;em&gt;, Neural Networks, 1989. (For ReLU and every
other non-polynomial activation: Leshno, Lin, Pinkus &amp;amp; Schocken,
&lt;em&gt;Multilayer feedforward networks with a nonpolynomial activation
function can approximate any function&lt;&#x2F;em&gt;, Neural Networks 6(6), 1993.)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;ref-num&quot; id=&quot;ref-10&quot;&gt;[10]&lt;&#x2F;span&gt; Liu et al., &lt;em&gt;KAN: Kolmogorov–Arnold Networks&lt;&#x2F;em&gt;, 2024.
&lt;a class=&quot;ref-link&quot; href=&quot;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;2404.19756&quot;&gt;https:&#x2F;&#x2F;arxiv.org&#x2F;abs&#x2F;2404.19756&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;ref-num&quot; id=&quot;ref-11&quot;&gt;[11]&lt;&#x2F;span&gt; Vershynin, &lt;em&gt;High-Dimensional Probability&lt;&#x2F;em&gt;, Cambridge University
Press, 2018, Ch. 3.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;ref-num&quot; id=&quot;ref-12&quot;&gt;[12]&lt;&#x2F;span&gt; Dasgupta &amp;amp; Gupta, &lt;em&gt;An elementary proof of a theorem of Johnson and
Lindenstrauss&lt;&#x2F;em&gt;, Random Structures &amp;amp; Algorithms, 2003.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;ref-num&quot; id=&quot;ref-13&quot;&gt;[13]&lt;&#x2F;span&gt; Conway, Hardin &amp;amp; Sloane, &lt;em&gt;Packing Lines, Planes, etc.: Packings in
Grassmannian Spaces&lt;&#x2F;em&gt;, Experimental Mathematics, 1996.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;ref-num&quot; id=&quot;ref-14&quot;&gt;[14]&lt;&#x2F;span&gt; Welch, &lt;em&gt;Lower bounds on the maximum cross correlation of signals&lt;&#x2F;em&gt;,
IEEE Transactions on Information Theory, 1974.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;ref-num&quot; id=&quot;ref-15&quot;&gt;[15]&lt;&#x2F;span&gt; Elhage et al., &lt;em&gt;A Mathematical Framework for Transformer Circuits&lt;&#x2F;em&gt;,
Transformer Circuits Thread, 2021.
&lt;a class=&quot;ref-link&quot; href=&quot;https:&#x2F;&#x2F;transformer-circuits.pub&#x2F;2021&#x2F;framework&#x2F;index.html&quot;&gt;https:&#x2F;&#x2F;transformer-circuits.pub&#x2F;2021&#x2F;framework&#x2F;index.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;ref-num&quot; id=&quot;ref-16&quot;&gt;[16]&lt;&#x2F;span&gt; Abbott, &lt;em&gt;Flatland: A Romance of Many Dimensions&lt;&#x2F;em&gt;, 1884.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;ref-num&quot; id=&quot;ref-17&quot;&gt;[17]&lt;&#x2F;span&gt; Sanderson (3Blue1Brown), pinned correction comment on [6], 2025.
&lt;a class=&quot;ref-link&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=9-Jl0dxWQs8&quot;&gt;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=9-Jl0dxWQs8&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;ref-num&quot; id=&quot;ref-18&quot;&gt;[18]&lt;&#x2F;span&gt; Yoder, &lt;em&gt;Beyond Orthogonality: How Language Models Pack Billions of
Concepts into 12,000 Dimensions&lt;&#x2F;em&gt;, 2025.
&lt;a class=&quot;ref-link&quot; href=&quot;https:&#x2F;&#x2F;nickyoder.com&#x2F;johnson-lindenstrauss&#x2F;&quot;&gt;https:&#x2F;&#x2F;nickyoder.com&#x2F;johnson-lindenstrauss&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;span class=&quot;ref-num&quot; id=&quot;ref-19&quot;&gt;[19]&lt;&#x2F;span&gt; Alon, &lt;em&gt;Perturbed Identity Matrices Have High Rank: Proof and
Applications&lt;&#x2F;em&gt;, Combinatorics, Probability and Computing, 2009.&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
