Skip to content

Instantly share code, notes, and snippets.

@Hulupeep
Created July 10, 2026 02:05
Show Gist options
  • Select an option

  • Save Hulupeep/3853a35a3d871973fe8ea8756b77545b to your computer and use it in GitHub Desktop.

Select an option

Save Hulupeep/3853a35a3d871973fe8ea8756b77545b to your computer and use it in GitHub Desktop.
CCF Sinkhorn-Knopp presentation cost: iteration count vs matrix density, gauge/presentation not causal trust, real Rust benchmarks 5/10/20/50 iters, Prov6 posture

CCF 2026: Sinkhorn-Knopp Presentation Cost Tracks Matrix Density, Not a Fixed Iteration Count

Sinkhorn-Knopp doubly-stochastic normalization at a fixed iteration count wastes compute on dense matrices and under-serves sparse ones, measured directly.

Introduction

Sinkhorn-Knopp (SK) is the standard way to push a matrix of positive numbers toward doubly stochastic: alternately normalize every row, then every column, and repeat. It shows up across manifold-constrained hyper-connections (mHC, arXiv:2512.24880) and other neural-network mixing schemes as a fixed 20-iteration budget. This gist measures what that fixed budget actually buys, at 5/10/20/50 iterations, on two synthetic matrix regimes chosen to sit on either side of the density phase transition He (arXiv:2507.09711) identifies for Sinkhorn-Knopp convergence. In CCF, SK-style normalization is used only as a gauge/presentation step, never as the causal trust-transfer update itself, which is a separate quotient-affine contraction (QAC) step. This run stays entirely inside the presentation-layer question.

What CCF does about it

CCF's runtime-certified trust transfer (Prov6, US 64/092,485) separates the causal update from any normalization or gauge-fixing step that sits near it in a pipeline ([0099]-[0101]). This run supports that separation with a direct measurement: the cost of a gauge step like SK is not a fixed, portable number, which is exactly why a certificate must not be conflated with the presentation step next to it.

Implementation

See crates/research/sk-presentation-cost/ (branch research/nightly/2026-07-10-sk-presentation-cost). Zero external dependencies: a hand-rolled xorshift64* PRNG makes every matrix and benchmark reproducible from a seed. Key design decision: sinkhorn_knopp(matrix, iters) records the doubly-stochasticity residual after every pass, so one run yields the whole convergence curve instead of a single endpoint measurement.

What this means in plain English

Take a table of positive numbers and reshape it so every row and every column adds up to the same total, a balanced version of whatever the numbers represent. The standard trick: divide each row by its total, then each column by its total, repeat. How many repeats is enough varies with how lopsided the table was to start. An even table balances almost immediately, and extra repeats past that point do nothing. A lopsided table, where one number per row dominates, needs far more repeats, and even a lot of extra effort leaves it measurably less balanced than the easy table ever was. Getting the repeat count wrong doesn't break anything else, but it does mean wasted computation on one side and a falsely tidy-looking number on the other.

In a real room

Dara runs the night shift on an assembly line with six coordination robots. Each reports a weight for how much it should factor its neighbors' recent actions into its own next move. Balancing those weights gives Dara's dashboard a clean read on who is actually coordinating with whom. On a normal night the six robots hand off evenly, and the balancing settles almost instantly. The fixed pass count the plant has used for months is already more than needed. Then a sensor on robot 4 misreports, and robot 4 starts weighting one neighbor almost completely while ignoring the rest. The same fixed pass count that was overkill on a normal night falls far short now: the dashboard shows "mostly balanced" when the real pattern is badly skewed, and nobody notices until a supervisor checks the raw weights hours later. A smarter balancing algorithm alone would not have caught this. Checking the actual imbalance each night, instead of trusting one fixed pass count to have handled every night's data the same way, would have.

Comparisons

Approach Iteration count Regime-aware? Source
mHC (parent method) Fixed 20 No arXiv:2512.24880
mHC-lite 0 (exact BvN construction) Not applicable, replaces SK entirely arXiv:2601.05732
go-mHC 0 (direct orthostochastic parameterization) Not applicable arXiv:2604.02309
This run Measured at 5/10/20/50, both regimes Yes, measures the gap directly this crate

Benchmarks

cargo run --release -p sk-presentation-cost --bin sk-bench, n=64, 200 repeats per cell:

regime iters ns/full-run residual
dense 5 73,994 5.231e-13
dense 10 146,873 6.661e-16
dense 20 295,038 5.551e-16
dense 50 740,767 5.551e-16
sparse 5 75,326 3.426e-1
sparse 10 148,595 1.112e-1
sparse 20 296,155 3.600e-2
sparse 50 736,930 1.617e-2

Cost scales linearly with iteration count in both regimes. Quality does not. At the mHC anchor of 20 iterations, dense is already 10 iterations past its own plateau, while sparse is still two orders of magnitude worse than dense achieves at iteration 5. Full table across n in {32, 64, 128} is in the crate's RESULTS.txt.

Failure modes

This measures presentation quality, not trust. A balanced matrix says nothing about whether the underlying weights should be trusted. The dense/sparse split is a simplified proxy for He's density statistic, not a computation of it. Benchmarks ran on one development machine, not a dedicated bench server, so treat the nanosecond figures as indicative, not certified. The residual figures are exact and reproducible from the seed.

Get started

License & contact

BSL 1.1, converting to Apache 2.0 in 2032. Contact via floutlabs.com.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment