Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
45 changes: 30 additions & 15 deletions scripts/scaling_fit.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ def quantile_ci(arr):
def write_csv(path, form, params, cis, qof_label, qof_value, failed):
os.makedirs(os.path.dirname(os.path.abspath(path)) or ".", exist_ok=True)
with open(path, "w", newline="") as f:
w = csv.writer(f)
w = csv.writer(f, lineterminator="\n")
w.writerow(["parameter", "value", "ci_lo", "ci_hi"])
for name in params:
lo, hi = cis.get(name, (float("nan"), float("nan")))
Expand All @@ -316,7 +316,7 @@ def write_csv(path, form, params, cis, qof_label, qof_value, failed):
w.writerow(["failed_resamples", failed, "", ""])


def make_plot(path, form, data, params, degree):
def make_plot(path, form, data, params, degree, ylabel):
os.makedirs(os.path.dirname(os.path.abspath(path)) or ".", exist_ok=True)
L = data["L"]
if form == "data-collapse":
Expand All @@ -330,10 +330,11 @@ def make_plot(path, form, data, params, degree):
sel = L == Lval
order = np.argsort(x[sel])
ax.plot(x[sel][order], yy[sel][order], "o-", label=f"L={Lval:g}")
ax.set_xlabel("L^(1/nu) (param - h_c)")
ax.set_ylabel("obs * L^(gamma_over_nu)")
ax.set_xlabel("L^(1/nu) (param - h_c)", fontsize=12)
ax.set_ylabel("obs * L^(gamma_over_nu)", fontsize=12)
ax.tick_params(axis="both", labelsize=12)
ax.set_title("data collapse")
ax.legend(fontsize=7)
ax.legend(fontsize=10)
else:
y, err = data["obs"], data["err"]
if form == "power-law":
Expand All @@ -345,19 +346,32 @@ def make_plot(path, form, data, params, degree):
names = [f"c{k}" for k in range(degree + 1)]
model = full @ np.asarray([params[n] for n in names])
resid = (y - model) / err
fig, (ax0, ax1) = plt.subplots(1, 2, figsize=(9, 4))
if form == "power-law":
fig, ax0 = plt.subplots(figsize=(5.5, 4.5))
ax1 = None
else:
fig, (ax0, ax1) = plt.subplots(1, 2, figsize=(9, 4))
order = np.argsort(L)
ax0.errorbar(L[order], y[order], yerr=err[order], fmt="o", label="data")
ax0.plot(L[order], model[order], "-", label="fit")
ax0.set_xlabel("L")
ax0.set_ylabel("obs")
if form == "power-law":
ticks = np.unique(L[order])
ax0.set_xscale("log", base=2)
ax0.set_yscale("log")
ax0.set_xticks(ticks)
ax0.set_xticklabels([f"{value:g}" for value in ticks])
ax0.set_xlabel("L", fontsize=12)
ax0.set_ylabel(ylabel, fontsize=12)
ax0.tick_params(axis="both", labelsize=12)
ax0.set_title(form)
ax0.legend(fontsize=8)
ax1.axhline(0.0, color="k", lw=0.8)
ax1.plot(L[order], resid[order], "o")
ax1.set_xlabel("L")
ax1.set_ylabel("(obs - model) / err")
ax1.set_title("normalized residuals")
ax0.legend(fontsize=10)
if ax1 is not None:
ax1.axhline(0.0, color="k", lw=0.8)
ax1.plot(L[order], resid[order], "o")
ax1.set_xlabel("L", fontsize=12)
ax1.set_ylabel("(obs - model) / err", fontsize=12)
ax1.tick_params(axis="both", labelsize=12)
ax1.set_title("normalized residuals")
fig.tight_layout()
fig.savefig(path, dpi=120)
plt.close(fig)
Expand Down Expand Up @@ -386,6 +400,7 @@ def build_parser():
p.add_argument("--size-col", default="L")
p.add_argument("--obs-col", default="obs")
p.add_argument("--err-col", default="err")
p.add_argument("--ylabel", default="obs", help="y-axis label for diagnostic plots")
p.add_argument(
"--param-col", default=None, help="parameter column (required for data-collapse)"
)
Expand Down Expand Up @@ -426,7 +441,7 @@ def main(argv=None):
qof_label = "collapse_residual" if args.form == "data-collapse" else "chi2_per_dof"

write_csv(args.out_csv, args.form, params, cis, qof_label, qof, failed)
make_plot(args.out_png, args.form, data, params, args.degree)
make_plot(args.out_png, args.form, data, params, args.degree, args.ylabel)

# Report: 2-3 lines, generic labels only.
lines = []
Expand Down
46 changes: 46 additions & 0 deletions tracks/qmc/solutions/薛定谔的套马杆/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
## Team

| | |
|---|---|
| **Team name** | 薛定谔的套马杆 |
| **Members** | Gui-Xin Liu, ShangTech University; Hao-Yu Lu, Hong Kong University |

## Challenge

| Row | |
|---|---|
| **Challenge** | Can finite-size QMC of the normalized two-dimensional long-range Ising model distinguish whether long-range universality ends at σ*=7/4 or σ*=2, beyond conclusions that depend on a single correction fit? |
| **Catalog issue** | `Addresses #86` — “Where does long-range universality end? Three adversarial tests of the σ*=7/4 vs 2 dispute,” released by Kun Chen, Institute of Theoretical Physics, Chinese Academy of Sciences. |
| **Track** | `tracks/qmc/` — the team selected Track A, whose prescribed core calculation is classical Monte Carlo. |

## Implementation

The reproducible implementation is in [`long_range_ising_fk/`](long_range_ising_fk/):

- Fukui–Todo/Poisson-event FK cluster Monte Carlo with wrapping observables;
- an independent factorized-Metropolis Clock implementation;
- locked power-law and marginal/log correction analyses;
- Slurm production jobs, tests, bilingual reports, and frozen raw-data escrow.

The frozen base production contains 96/96 successful cells. The large-size
cutoff snapshot contains 36 completed cells with central data through
$L=2048$, and the independent Clock production contains 16/16 completed
cells. The defensible conclusion is that the finite-size behavior is
reproduced, while thermodynamic discrimination between
$\sigma_*=7/4$ and $\sigma_*=2$ remains inconclusive.

## Run and inspect

From the repository root:

```bash
SOLUTION="tracks/qmc/solutions/薛定谔的套马杆/long_range_ising_fk"
julia --project="$SOLUTION" "$SOLUTION/test/runtests.jl"
sbatch "$SOLUTION/jobs/production_20260727.sbatch"
```

- [English report](long_range_ising_fk/reports/track_a_report_en.md)
- [中文报告](long_range_ising_fk/reports/track_a_report_zh.md)
- [Locked base analysis](long_range_ising_fk/locked_analysis.md)
- [Locked extension analysis](long_range_ising_fk/locked_extension_analysis.md)
- [Frozen-data manifest](long_range_ising_fk/data_manifest.md)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name = "LongRangeIsingFK"
uuid = "c80ff6ef-b2af-47d4-b6ed-afdcf70f70af"
version = "0.1.0"

[compat]
julia = "1.11"
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Clock Monte Carlo cross-check protocol

Locked before the 16-cell production array.

## Purpose and scope

This is an implementation-independent thermodynamic cross-check of the
Fukui-Todo/FK production sampler. It compares `Qm` and
`chi = L^2 <m^2>`. Clock local updates do not construct FK clusters and
therefore do not measure or validate `Rp`.

## Correctness gates

1. On a fixed `L=4` configuration, compare 200,000 one-spin proposals from
the clock sampler and an explicit factorized-Metropolis implementation.
Their acceptance probabilities must agree within six binomial standard
errors.
2. Require `sum_j J_ij = 4` to floating-point precision.
3. At `sigma=1.875`, run two seeds at `L=64,128` with 50,000 thermalization
and 300,000 measurement sweeps. Proceed only if both seeds are visibly
mixed and the combined `Qm` and `chi` agree with FK within three combined
standard errors. If block errors are unreliable, increase sampling rather
than weakening this gate.

## Production grid

- `sigma = 1.875, 2.0`
- `L = 64, 128, 256, 512`
- two independent seeds per point, 16 cells total
- thermalization sweeps by size: `50k, 100k, 200k, 300k`
- measurement sweeps: `1,000,000` per cell
- 50 raw blocks per cell

The production analysis reports per-seed results, block errors, maximum
autocorrelation time, and standardized Clock-minus-FK differences. Failed
cells are rerun only with identical parameters and remain documented.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
run = "clock_production_20260729"
algorithm = "clock_factorized_metropolis"
primary_run = "track_a_20260727"
sigmas = [1.875, 2.0]
sizes = [64, 128, 256, 512]
seeds_per_point = 2
beta = [0.336985, 0.344439]
thermalization_sweeps = [50000, 100000, 200000, 300000]
measurement_sweeps = 1000000
blocks = 50
normalization = "sum_j J_ij = 4"
distance = "minimum-image square torus"
comparable_observables = ["Qm", "chi"]
excluded_observables = ["Rp"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"L": [64, 128, 256, 512, 1024, 2048, 4096],
"seed": [73001, 84002, 95003, 106004]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"run_id": "nn_large_20260730",
"purpose": "High-precision exact nearest-neighbor control for Qm, Rp, and eta",
"issue": "QuantumBFS/quantum.harness#86",
"base_commit": "26234d49bddd6005398d35361ff98b5efbba6b88",
"protocol": "strict NN J=1 at exact square-lattice beta_c; seven sizes; four independent seeds",
"source_sha256": "88521ce9d6e15e817e8e99837899317a4dc0e3e0a73951bdb45201edaff4b205"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"model": "nearest_neighbor_square_ising",
"hamiltonian": "H=-sum_<ij> s_i s_j",
"coupling_J": 1.0,
"geometry": "LxL square lattice",
"boundary": "periodic square torus",
"beta": 0.44068679350977147,
"algorithm": "exact nearest-neighbor Swendsen-Wang/FK",
"entrypoint": "tracks/qmc/solutions/薛定谔的套马杆/long_range_ising_fk/scripts/nn_large_point.jl",
"blocks": 50,
"thermalization_sweeps_by_size": {
"64": 5000,
"128": 5000,
"256": 5000,
"512": 4000,
"1024": 3000,
"2048": 2000,
"4096": 1000
},
"measurement_sweeps_by_size": {
"64": 200000,
"128": 200000,
"256": 150000,
"512": 100000,
"1024": 50000,
"2048": 20000,
"4096": 5000
},
"targets": {
"Qm": 0.856216,
"Rp": 0.0,
"eta": 0.25
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
issue = "QuantumBFS/quantum.harness#86"
track = "A"
algorithm = "Fukui-Todo Poisson-event FK"
sigmas = [1.75, 1.875, 2.0, 2.5]
critical_beta = [0.329136, 0.336985, 0.344439, 0.369446]
beta_offsets = [-0.002, 0.0, 0.002]
sizes = [64, 128, 256, 512]
seed_bases = [11001, 22002]
thermalization_sweeps = 10000
measurement_sweeps = 100000
blocks = 20
normalization_sum_j = 4.0
distance = "minimum-image Euclidean distance on square torus"
rp_definition = "<R2> - 2<R0>"
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
parent_run = "track_a_20260727"
run = "track_a_large_20260728"
issue = "QuantumBFS/quantum.harness#86"
algorithm = "Fukui-Todo Poisson-event FK"
critical_sigmas = [1.75, 1.875, 2.0, 2.5]
critical_sizes = [768, 1024, 1536, 2048]
critical_beta = [0.329136, 0.336985, 0.344439, 0.369446]
crossing_sigmas = [1.875, 2.0]
crossing_sizes = [1024, 2048]
crossing_offsets = [-0.0005, 0.0005]
seed_bases = [31001, 42002]
thermalization_sweeps = 5000
measurement_sweeps_L768 = 100000
measurement_sweeps_L1024 = 75000
measurement_sweeps_L1536 = 35000
measurement_sweeps_L2048 = 20000
memory_per_cell = "2G"
walltime_per_cell = "24:00:00"
raw_blocks = 20
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Frozen-data escrow manifest

**Freeze date:** 2026-07-31

**Generation-code revision:** [`26234d49bddd6005398d35361ff98b5efbba6b88`](https://github.com/Luka3519/quantum.harness/commit/26234d49bddd6005398d35361ff98b5efbba6b88)

**Integrity file:** [`data_manifest.sha256`](data_manifest.sha256)

**Integrity-file SHA-256:** `fd550c16724a23a6b2e2b767bc06da486ac470023570c2312d35fa4793905806`

The generation revision is the first committed snapshot of the code used for
the frozen runs. This submission only relocates that implementation into the
registered team directory and updates repository-relative job paths; it does
not alter the algorithms or frozen numerical values.

## Published datasets

| Dataset | Files | Bytes | SHA-256 tree digest |
|---|---:|---:|---|
| `track_a_20260727` | 489 | 158254 | `2b62aba4b833d677d62806f277bf409ed9740546fa026ee90bfed73393c2097b` |
| `track_a_large_20260728` | 212 | 60586 | `3d8be845faf51dd49b9a89e0081b2f799c55e99fe7c27f892811d8b3ac7778da` |
| `clock_production_20260729` | 82 | 47539 | `62adfbe29861a9b58fb919f1c141c449c2ab4710f9557356a3c3b68983648160` |
| `nn_large_20260730` | 115 | 224923 | `05d0f8b4ae576e185185a1495b40ad98d5aa2b18e06cab4935f7cc6780c96f48` |
| `nn_v3_20260730` | 48 | 111568 | `6ee4e59197eb759149f961d340df7708f485ed2d9d777570719d08a9cb56bdde` |
| `track_a_cutoff_analysis_20260730` | 4 | 18791 | `f6ea9fde0f546f9116da624f7c86209e366f499aaa2afd52e5908371e2b30dcb` |
| **Total** | **950** | **621661** | See the integrity-file hash above |

A dataset tree digest is the SHA-256 of its sorted
`<file-sha256><two spaces><relative-path>\n` records. The integrity file
contains all 950 records and uses paths relative to this solution directory.
From this directory, verify the escrow on a Unix-like system with:

```bash
sha256sum -c data_manifest.sha256
```

## Completeness and exclusions

- `track_a_20260727` contains exactly 96 successful `summary.csv`,
`blocks.csv`, and `metadata.txt` cell triplets, plus frozen analysis and
scheduler logs.
- `track_a_large_20260728` is an honest cutoff snapshot with 36 successful
cell triplets. It has 30 central-$\beta_c$ cells and six partial-crossing
cells; the registered large-size crossing grid is incomplete and is not
extrapolated.
- `clock_production_20260729` contains exactly 16 successful cell triplets
and the frozen FK comparison tables.
- `nn_large_20260730` is a complete seven-size nearest-neighbor control
dataset with 28 cells: four seeds at each of
\(L=64,128,256,512,1024,2048,4096\). Every cell contains `summary.csv`,
`blocks.csv`, `metadata.txt`, and a deterministically repaired
`manifest.json`. Slurm reports the cells as failed only because the
Python 2.7 wrapper raised a text/byte error after the numerical files had
already been written.
- `nn_v3_20260730` is an independently added higher-statistics
nearest-neighbor snapshot with 16 completed cell triplets: eight seeds at
each of \(L=64,128\). Its registered \(L=256\) cells are not present in the
published snapshot.
- `track_a_cutoff_analysis_20260730` contains the combined central data,
competing-model fits, distinguishable-size forecast, and cutoff report.
- Local smoke tests, timing probes, superseded interim analyses, and incomplete
pre-production runs are intentionally excluded from the public escrow.

Per-cell metadata records timestamps, host/runtime information, Slurm job and
array-cell identifiers, and validation values. Seeds, autocorrelation
estimates, convergence fields, and raw block observables are retained in the
corresponding summaries and block files.

The cell-level escrow and locked-analysis records were created locally before
the cutoff analysis. Their public packaging occurs in this submission; the
original timestamps and the immutable generation revision are retained so
that an independent adjudicator can audit the chronology.
Loading