Skip to content

fix: remove gauge bias in random_vector() — complex Gaussian sampling - #1

Open
PFmix wants to merge 1 commit into
masterfrom
fix/random-vector-gauge-bias
Open

fix: remove gauge bias in random_vector() — complex Gaussian sampling#1
PFmix wants to merge 1 commit into
masterfrom
fix/random-vector-gauge-bias

Conversation

@PFmix

@PFmix PFmix commented Aug 27, 2026

Copy link
Copy Markdown

Problem

random_vector() in set_relationship had two compounding biases:

  1. Real-only samplingnp.array([2*random()-1 for _ in range(4)], dtype='complex')
    draws only from the real axis; the imaginary degrees of freedom are never explored.
  2. abs() clampvec[0] = abs(vec[0]) forces the first component non-negative,
    biasing fallback vectors toward |00⟩ for +ZZ targets.

Together these introduce a gauge anomaly: all-open (s_ij = +1 everywhere) scores
systematically higher in S^tomo than gauge-equivalent all-walled (s_ij = −1) and
unfrustrated Mattis configurations. On a 120-qubit square lattice at STEPS=2, the gap
reaches ~0.075 (~20% relative inflation for all-open).

Root cause

random_vector() is called as a fallback in make_vec when the projected vector
orthogonalises to zero. For the initial |+>^N state, this fallback is structurally
guaranteed for −ZZ edges (analytically: |P_{-ZZ} @ vecs[1]|² = 0 exactly) but never
triggered for +ZZ edges. The sign-asymmetric fallback frequency, combined with the
biased sampling, inflates +ZZ scores relative to −ZZ.

Fix

Replace the two biased lines with a single complex Gaussian draw:

# before
vec = np.array([2 * random() - 1 for _ in range(4)], dtype='complex')
vec[0] = abs(vec[0])

# after
vec = np.random.randn(4) + 1j * np.random.randn(4)

This uniformly covers the full complex unit sphere (after normalize), making the
fallback unbiased with respect to gauge sign. The random import from random is
no longer needed inside random_vector after this change.

Testing

Sweep over N=120 (10×12 square lattice), K=3, STEPS=13, N=6 builds per config:


│ STEPSoriginal gapfixed gap% closed │

│ 10.03380.03312 %      │

│ 20.07500.051032 %     │

│ 30.06660.037044 %SVG maze and max-frustrated configurations are unaffected (deltas within σ0.006),
as expected for mixed/symmetric sign distributions where the fallback asymmetry averages
out across edges.

A residual gap (~56% of original) remains due to a structural property of eigh on the
initial tensor-product statethe second null-space eigenvector always falls back forZZ but not for +ZZ regardless of sampling distribution. This is documented separately.

It is also a residual issue I did not manage to solve.

Real-uniform sampling (2*random()-1) restricted fallback vectors to the
real axis, and abs(vec[0]) forced the first component non-negative (|00>
bias for +ZZ targets). Together these cause all-open (s_ij=+1) to score
~0.075 higher in S^tomo than gauge-equivalent all-walled and unfrustrated
configurations on a 120-qubit square lattice at STEPS=2 (~20% inflation).

Replace with a complex Gaussian draw (randn + 1j*randn), which samples
uniformly from the full complex unit sphere after normalization. Closes
~25-44% of the gauge gap depending on STEPS; SVG maze and max-frustrated
configs are unaffected (mixed-sign distributions where the asymmetry
averages out across edges).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@PFmix
PFmix requested a review from quantumjim August 27, 2026 09:10
@PFmix PFmix added the bug Something isn't working label Aug 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant