diff options
| author | YurenHao0426 <Blackhao0426@gmail.com> | 2026-08-01 21:37:55 -0500 |
|---|---|---|
| committer | YurenHao0426 <Blackhao0426@gmail.com> | 2026-08-01 21:37:55 -0500 |
| commit | 22acd2899958def0d103f11da49c2c4a499be773 (patch) | |
| tree | 892b422c1e04cd9854420eda0c965e21df81c8db /worldalign/match_battery.py | |
| parent | ef104fe4f07713bf11f266d2954b7446f176f8ae (diff) | |
The missing term was unary: omit-size solved at its ceiling in 1.4s
Adversarial review of the artifacts found three of my numbers to be
artifacts of my own code. All three reproduced here before acceptance:
- anchor_bound presented probe rows in the same index order on both
sides, so exact twins had their tie broken onto the diagonal. 0.997 ->
0.920 on omit-size. Fixed by scrambling the T-side presentation.
- The truth is not a strict local minimum: 51 transpositions have
exactly zero energy delta. fast_pair_descent only looked stationary
because its break test treats zero as no-improvement.
- scipy's FAQ takes no n_init, so it was swallowed into unknown_options
and 'FAQ x30 restarts' computed bit-identically to plain FAQ. Replaced
with a real restart loop over P0='randomized'.
The blind ceiling for omit-size is 0.836, not 1.0: the text field has 51
exact transposition automorphisms, so T[s,s] is bitwise identical to T
and no objective f(V, P T P^T) can separate an orbit at any order. Every
synthetic accuracy was being divided by the wrong denominator.
The fifteen failed solvers share one property -- all purely quadratic or
purely spectral, none with a node-level term. Eight moments of each
node's own field row, blended with the quadratic term through
Frank-Wolfe, reach 0.837 with an energy gap of exactly zero. The term
must stay in the loop: as a seed for pure-quadratic descent it scores
0.21, pinned through the iterations it scores 0.84 -- which is also why
amplification plateaued, being itself pure-quadratic.
Co-Authored-By: Claude <noreply@anthropic.com>
Diffstat (limited to 'worldalign/match_battery.py')
| -rw-r--r-- | worldalign/match_battery.py | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/worldalign/match_battery.py b/worldalign/match_battery.py index 9035e62..63a4bf1 100644 --- a/worldalign/match_battery.py +++ b/worldalign/match_battery.py @@ -142,11 +142,19 @@ def solve_faq_multi(visual, shuffled, **_): """FAQ from many random doubly stochastic starts, best by its own objective.""" from scipy.optimize import quadratic_assignment - result = quadratic_assignment( - visual, shuffled, method="faq", - options={"maximize": True, "n_init": 30, "rng": 0}, - ) - return result.col_ind + # scipy's FAQ takes no `n_init`; passing one is silently swallowed into + # unknown_options, which is why an earlier version of this function + # returned bit-identical results to plain FAQ. Restart explicitly. + best, best_value = None, -np.inf + for seed in range(15): + result = quadratic_assignment( + visual, shuffled, method="faq", + options={"maximize": True, "rng": seed, "P0": "randomized"}, + ) + value = float((visual * shuffled[np.ix_(result.col_ind, result.col_ind)]).sum()) + if value > best_value: + best, best_value = result.col_ind, value + return best def solve_2opt(visual, shuffled, **_): |
