Skip to article frontmatterSkip to article content

N-balls in high dimensions

Phytomech Industries

The Real Problem

The problem isn’t that we lack ideas or eloquence - it’s that our thoughts are fragmented across platforms and protocols. I can write extensively about software development in conversations with AI, but translating that into long-form content feels like an insurmountable task.

So I want to do something to help with this. Solve your own problem and you’ll end up solving a problem a lot of people face, because...

nobody’s that special.

So great, I’m looking to create Yet Another AI Writing Tool and I’m dressing it up like “oh I’m just trying to stick MyST markdown in the preview of whtwnd and also enable it across my fork.” Yeah that’s just the pretense to cramming another AI assistant down everyone’s throats. I feel like there’s a better way to interface with your assistant than just through chat. It should be listening to what you write and doing tasks in the background that can help with your project and interests and goals. A full assistant, but through your journal.

So this isn’t about creating another AI writing tool to automate college essay slop generation. It’s about building a system that helps organize our scattered knowledge into coherent structures, whether that’s a tweet, a blog post, or a book. The goal is to help people maintain consistency, identify patterns in their thinking, and build on their ideas without losing the human element. Because the truth is, most of us are more capable than we realize - we just need help organizing our thoughts into something meaningful.

Today’s Mathematical Journey

I’ve been thinking a lot about high-dimensional spaces lately. It’s one of those topics that keeps coming up in different contexts - from machine learning to quantum mechanics. The weird thing about high dimensions is how they completely break our 3D intuition. Let me walk through a proof that blew my mind when I first saw it.

The N-Ball Properties

Let’s prove two fascinating properties of high-dimensional spaces:

  1. Points cluster near the surface of the N-ball
  2. Any two points are approximately 2\sqrt{2} units apart

Radial Distance Distribution

What does the phrase “points cluster near the surface” really mean?
Let R[0,1]R\in[0,1] be the distance from the origin to a point picked uniformly at random inside the nn–dimensional unit ball B1nB^n_1.
The probability that RR falls in (r,r+dr)(r, r+dr) equals the fraction of the ball’s volume occupied by the thin spherical shell at that radius. In symbols,

fn(r)dr  =  vol of shell thickness drvol(B1n)  =  Sn1(r)drVn(1),f_n(r)\,dr\;=\;\frac{\text{vol of shell thickness }dr}{\text{vol}(B^n_1)} \;=\;\frac{S_{n-1}(r)\,dr}{V_n(1)},

where Sn1(r)S_{n-1}(r) is the surface area of the (n1)(n{-}1)-sphere of radius rr and Vn(1)V_n(1) is the volume of the unit nn-ball. Because Vn(r)=Vn(1)rnV_n(r)=V_n(1)\,r^{n}, differentiating with respect to rr shows that Sn1(r)=ddrVn(r)=nVn(1)rn1S_{n-1}(r)=\tfrac{d}{dr}V_n(r)=n\,V_n(1)\,r^{n-1}. Plugging this into the fraction above immediately gives the probability-density function

fn(r)  =  nrn1,0r1.f_n(r)\;=\;n\,r^{n-1},\qquad 0\le r\le 1.

Meaning of fn(r)f_n(r)


Why fn(r)=nrn1f_n(r)=n\,r^{n-1}

(thin shell volume)  =  [surface area at radius r]dr  =  Snrn1dr,\text{(thin shell volume)} \;=\; \bigl[\text{surface area at radius }r\bigr]\,dr \;=\; S_n\,r^{\,n-1}\,dr,

where SnS_n is the surface area of the unit (n1)(n-1)-sphere.

Because the point is chosen uniformly, its probability of landing in that shell is

Snrn1drVn,\frac{S_n\,r^{\,n-1}\,dr}{V_n},

with VnV_n the total volume of the unit nn-ball.

The ratio Sn/VnS_n/V_n equals nn for the unit ball, so

fn(r)dr=nrn1drfn(r)=nrn1,  0r1.f_n(r)\,dr = n\,r^{\,n-1}\,dr \quad\Longrightarrow\quad f_n(r)=n\,r^{\,n-1}, \; 0\le r\le1.

The factor rn1r^{n-1} captures how the “room to place points” grows with radius, while the leading nn ensures the PDF integrates to 1.

Because V(r)=Vnrn for an n-ball, dVdr=Sn(r)=ddr ⁣(Vnrn)=nVnrn1; evaluating at r=1 gives Sn=nVn, so SnVn=n.\text{Because }V(r)=V_n r^{n}\text{ for an $n$-ball, } \frac{dV}{dr}=S_n(r)=\frac{d}{dr}\!\bigl(V_n r^{n}\bigr)=nV_n r^{\,n-1};\ \text{evaluating at }r=1\text{ gives }S_n=nV_n,\ \text{so } \dfrac{S_n}{V_n}=n.

That single formula encapsulates the "surface concentration’’ effect: for large nn the density is negligible until rr is very close to 1. Indeed, E[R]=nn+11\mathbb E[R]=\tfrac{n}{n+1}\to 1 and Var(R)=1(n+1)(n+2)0\operatorname{Var}(R)=\tfrac{1}{(n+1)(n+2)}\to 0, so almost every point lies within an O ⁣(1/n)O\!\bigl(1/\sqrt n\bigr) shell of the boundary.


Distance Between Two Random Points Concentrates at 2\sqrt2

Goal For independent, uniformly-random points
X,YSn1RnX,Y\in S^{\,n-1}\subset\mathbb R^{n} show

XY  P  2\lVert X-Y\rVert \;\xrightarrow{P}\; \sqrt2

as nn\to\infty.

Rewrite the distance via a dot product

Because X=Y=1\lVert X\rVert=\lVert Y\rVert=1,

XY2=2(1X ⁣ ⁣Y).\lVert X-Y\rVert^{2}=2\bigl(1-X\!\cdot\!Y\bigr).

Thus it suffices to prove X ⁣ ⁣Y  P  0X\!\cdot\!Y\;\xrightarrow{P}\;0.

Model the sphere points with Gaussians

Represent each uniform point as a normalised Gaussian vector:

X=ZZ,Y=WW,X=\frac{Z}{\lVert Z\rVert},\qquad Y=\frac{W}{\lVert W\rVert},

where Zi,WiiidN(0,1)Z_i,\,W_i\stackrel{\text{iid}}{\sim}\mathcal N(0,1) and ZWZ\perp W.

Then

X ⁣ ⁣Y=i=1nZiWiZW.X\!\cdot\!Y=\frac{\sum_{i=1}^n Z_i W_i}{\lVert Z\rVert\,\lVert W\rVert}.

Asymptotics of the numerator and denominators

Combine with (10):

X ⁣ ⁣Y=1nN(0,1)(1+o(1))  P  0.X\!\cdot\!Y=\frac{1}{\sqrt n}\,\mathcal N(0,1)\bigl(1+o(1)\bigr) \;\xrightarrow{P}\;0.

Distance convergence

Insert X ⁣ ⁣Y0X\!\cdot\!Y\to 0 into (8):

XY2  P  2,henceXY  P  2,\lVert X-Y\rVert^{2}\;\xrightarrow{P}\;2, \qquad \text{hence}\qquad \lVert X-Y\rVert\;\xrightarrow{P}\;\sqrt2,

which establishes the claim in (7).



From Geometry to Robots

All right, brain back in applied mode. The same tooling that renders those crisp equations is powering my day-to-day robotics stack, so the next section pivots from hollow nn-balls back to slow and boring coding.

What I’m Actually Working On

I’m knee deep in robotics! I spent a good hour or so working on getting maniskill hooked up to lerobot. Didn’t end up connecting it to my robot and move the configuration over into the newly cloned repo because it’s saturday night and I’ve just been crunching on my website and typesetting projects.

The Big Picture

I already live in the power-user endgame—VS Code, GitHub Pages, and an AI co-pilot wired straight into my editor. Spinning up a static site or a LaTeX\LaTeX-heavy blog post is possible today; the real pain is in the dozen tiny steps that sit between inspiration and a shareable link. Those paper-cuts don’t just slow me down—they keep everyone else from even trying.

So the goal isn’t to invent new powers, it’s to compress the ones we have into a single, low-friction loop that anyone who can type Markdown can ride.

  1. Capture → Journal extension. Works right inside whatever editor you love. Jot an idea, tag it, and it’s instantly part of the knowledge graph—no copy-pasting, no context switching.
  2. Refine → whtwnd editor. One click promotes a note into a full-blown article lab. Live code blocks, LaTeX\LaTeX rendering, and a design system that makes even dense proofs look readable.
  3. Publish → Zero-touch deploy. The build spins up locally, ships through a DO jump-box, and lands in GitHub Pages (or your own server) without you touching a terminal. Good-looking, citation-ready pages, every time.

If we can make that cycle feel as effortless as pressing ⌘-S, then the subject matter—robotics tutorials, category-theory deep dives, garden-variety blog posts—becomes almost incidental. And when the tooling handles my edge-case chaos, chances are it will feel like magic for everyone else.

Okay one bad thing

Now I feel like I have to make every damn post all sparkly and sexy and cool like I give a single solitary fuck. Yeah that’s a definite reason to work hard to get whtwnd up and running. You can have posts that aren’t visible to the public, though I don’t know if that means people can’t go see if they’re on your PDS lol.

So I am going to use the designs for the base but I think I’m going to modify both the bottom part of the camera post but also the top. Try to get them pointing at the same basic work area for a nice degree of separation and difference in POV. I’m going to turn them like 30 degrees inward even though that might not be enough. It will create more overlapping field of vision in the cameras than having them both stare straight down.

They just seem like a collision obstacle right now, so I’m going to kick them out by extending the STL file somehow. I wish people shared the actual parametric models instead of just the STL meshes. Oh well. I can probably reinvent the part I need just looking at it, which I’ve already started doing.


Multiple posts in a day, or one big ass journal entry?

I don’t know! Certainly seems like I’m doing on big post-a-day, but they can be themed of course. Posts can and definitely should be longer thought out and revisited.

I’ve got the framework for writing my book on robotics now. I need to do that.

My daily journal has already grown to be too unwieldy after focusing on it for a day! I guess I finally have something to say.

It’s sort of blowing my mind that I’m technically going to be publishing my book as I write it but that’s sort of the whole point of having my own journal/book site.

Okay I commented out that part of my myst.yml.

version: 1
project:
  id: 91143d4d-0120-4764-9c1d-b16de83a4b9c
  title: Welcome
  authors:
    - name: Thomas Wood
      website: https://odellus.github.io/
      id: thomas
      orcid: 0009-0001-6099-2115
      github: odellus
      affiliations:
        - name: Phytomech Industries
          url: https://phytomech.com
  github: https://github.com/odellus/odellus.github.io
  plugins:
    - type: executable
      path: src/blogpost.py
    - src/socialpost.mjs
  toc:
    - file: index.md
    - file: about.md
    - file: projects.md
    # - file: books.md
    #   children:
    #     - title: Scientific Computing with Python
    #       children:
    #         - pattern: books/Scientific-Computing-with-Python/**{.ipynb,.md}
    - file: journal.md
      children:
        - title: '2025'
          children:
            - title: June
              children:
                - pattern: journal/2025/Jun/**{.ipynb,.md}

  thumbnail: _static/social-banner.jpg
site:
  template: book-theme
  options:
    folders: true
    logo_text: Thomas Wood
    favicon: _static/profile-color-circle-small.png
    style: _static/custom.css
  domains:
    - odellus.github.io
  nav:
    - title: About
      url: /about
    - title: Projects
      url: /projects
    # - title: Books
    #   url: /books
    - title: Journal
      url: /journal

unlike with journal posts, I don’t want to necessarily share this automatically.

I can also add the drafts in journal/drafts to this. I did but I don’t know when I’ll ever use it.

Kinda feel like I’m on big brother but whatever. I mean I’m a poster on deer.social ffs. I’m already living in the bright eye of the panopticon.

In other words I decided to start publishing my scientific computing with python book live. Fuck it. I’m still not entirely sure what the final structure will be but the very first thing was going to be here’s numpy.

I guess I do need to introduce more practical stuff in there and not just punt and say "here’s dir() and help() you’re welcome. Yeah what am I talking about this is terrible. Oh well. Somewhere to start.

23:11

Okay what’s up?

What did I accomplish this weekend?

I’ve been meaning to put the book together for fucking years now. Now I have my own website that’s not just a place to keep notes on what I’ve done but a place to publish it, I mean no joke I can just make a book out of jupyter notebooks and markdown files and host it at odellus.github.io like a crazy person.

I’m going to be revisiting each chapter in succession as I build up the subject material and yeah honestly I definitely need to motivate the reader with some worked examples showing the power of numpy to solve real world problems in science and engineering.

I think we really should start by building up towards the methods in maniskill and lerobot. Screw the nonsense. We picked the simulation framework and the learning/hardware framework because we’re going to teach people about applied mathematics and that means simulations and optimization.

That’s what we do. That’s our whole business, and business is good.

I don’t know every last little thing about how maniskill works right now, I’m not going to lie. But I know Emo Todorov and took some classes from him and I studied scientific and numerical computing under J. Nathan Kutz, who has written several books about the subject. That’s my background. Heavy on SVD. Heavy on ode45 and all of that jazz.

I might not get right into Partial Differential Equations, but yeah we’re going to have to go pretty deep into math to talk about what lerobot and maniskill do.