“Know how to solve every problem that has been solved.” “What I cannot create, I do not understand.” — Richard Feynman

Project: Symbolic Regression in the Browser

Projects

What you need to know first 10 concepts, 6 layers

The requisite-knowledge inventory for this page, bottom-up: the primitives at the base, combined upward until you reach what this page assumes. Skim the layers you already own; start wherever the ground gets unfamiliar.

  1. base
  2. L1
  3. L2
  4. L3
  5. L4
  6. L5
  7. you are here

2 of these are concepts without a dedicated page yet — the grey chips. Following the linked ones first makes the rest land.

Hand the machine 25 points sampled from a hidden function and ask for the function back — not a fit, the formula. The engine below does it the bluntest way possible: it tries every formula, shortest first, and keeps the best one. That brute-force core is the inner loop of AI Feynman (Udrescu & Tegmark, 2020); everything clever in that paper is a way of making this loop's job smaller. The engine is written in Knot, compiled through C to a 42 KB WebAssembly module by the same pipeline as the in-browser SCF, and races about 4.4 million candidate formulas when you press run.

Knot sourcegenerated C42 KB WebAssembly4.4 million formulas raced in your browser

Pick a mystery or hit run — the engine sees 25 (x, y) points and nothing else.

How the search works

A formula is a string in reverse Polish notation over a ten-symbol alphabet: the leaves and , four binary operators, and four unary ones. Enumerating "every formula" means counting through symbol sequences at each length and discarding the ones that don't parse — a sequence is a valid program exactly when its stack depth never goes negative and ends at one. At that's 1,111,110 sequences per mystery, of which 20,090 survive the stack check. Each survivor is evaluated on the 25 data points and scored.

# the entire search, structurally (see the Knot tab above for the real thing)
for L in 1..6:                      # length = description length: short first
    for every sequence in {x, 1, +, -, *, /, sin, exp, sqrt, neg}^L:
        if not valid_rpn(seq): continue          # stack must end at depth 1
        c = sum(y*f)/sum(f*f)                    # best prefactor, closed form
        err = rms(y - c*f)
        if err < best: crown_champion(seq, c, err)

Trying lengths in order is not just tidy bookkeeping — it is the prior. A formula found at length 4 is preferred over an equally-fitting one at length 6 because the enumeration got there first: candidate number in the count costs about bits of description length, so "search short-to-long" and "prefer simple explanations" are the same act. The Pareto table under each finished race makes this concrete: at every length there is a best-effort formula, and the champion is wherever error collapses to machine zero.

One free constant, fitted in closed form

The alphabet has no constants except 1, which would make targets like unreachable. The fix costs one line: score each candidate as with the multiplicative prefactor chosen by least squares, . The structure is searched discretely; the scale is fitted continuously. Watch Mystery B: the engine finds the shape at length 4 and the fit hands it for free.

# least-squares multiplicative prefactor: y ~ c * f
syf = 0.0
sff = 0.0
for p to NPTS {
    f = eval_rpn(L, xs[p])
    syf = syf + ys[p] * f
    sff = sff + f * f
}
cbest = syf / sff
sse = syy[0] - cbest * syf     # = sum(y^2) - c * sum(y f), expanded square

The champion races are worth replaying. On the engine climbs through , then , then — a genuine surprise — with a fitted prefactor, which on the sampled interval is a better one-term compromise between the linear and quadratic pieces than either alone. And on it lands on the equivalent form — same function, different tree, one token cheaper than negating the square.

What AI Feynman adds on top

This page is the paper's inner loop, isolated. The full method wraps it in machinery whose only purpose is to shrink before the enumeration starts: dimensional analysis removes variables outright (a nullspace computation over the units matrix), a neural network trained on the data is interrogated for symmetries and separability — if never changes, search in instead — and a sequential statistical test kills bad candidates after a handful of points instead of all of them. Each trick buys another variable or another token of headroom, and the same dumb loop underneath then succeeds where it previously drowned. The symmetry-discovery step is built and running: a neural net that finds the symmetry, watching this exact engine fail on a two-variable mystery and then win after the network hands it a substitution.

The engine itself is a 250-line Knot program (the ① tab above) — flat arrays, loops, and the ten-way opcode dispatch, the same idiom as the playground's symbolic-differentiation preset. The numeric output protocol is a small trick of necessity: Knot prints numbers only, so the browser component keys on labeled show lines and decodes the RPN back to the formulas you see.

There is also an opposite strategy: skip the search entirely, fit one continuous function family whose parameter space contains the familiar formulas, and identify the answer by where the fit lands. That engine — Meijer G-functions, digamma gradients, same compiler, same 42-kilobyte-class wasm — runs at Formula Discovery Without Search.

Try First

Each prompt asks a checkable question about the working code or math above — predict an output, derive a sign, state an invariant, find a bug. Commit to an answer before clicking "reveal." That commitment is the whole point: if your answer matched, you understand the piece you were looking at; if it didn't, that's the part worth re-reading.

predict
The stats line reports exactly 1,111,110 sequences searched for every mystery. Where does that number come from?
why does this work
On Mystery A (), the length-4 champion is with rms error 0.197 — beating from length 3. Why is a power between 1 and 2 the best four-token story?
what if
Could any length-4 formula fit Mystery C () exactly, with the prefactor's help? Answer before checking the Pareto table.

Reproduce it

scripts/build_sr_wasm.sh rebuilds everything: symbolic_regression.knot → knotkit C backend → emscripten. The native binary runs all four searches in 0.11 s; the wasm build is the same program with a different final compiler flag. Nothing on this page is precomputed — the numbers, champions, and Pareto tables come out of the search running on your machine.