Research-Stack/4-Infrastructure/shim/wannier_sidon_probe.py
allaun 77488ac0ae feat(lean): close gaussian_line_integral_unit_dir + consolidate infrastructure
Lean proof fixes:
- N3L_Energy.lean: fully close gaussian_line_integral_unit_dir (nlinarith+hab
  for unit-circle quadratic, sqrt_mul+neg_div for integral_gaussian_1d match,
  exp_sum_of_sq order fix, add_assoc for h_gauss_shift, sq_sqrt for field_simp,
  sq_abs for perpDistance hd)
- Add Adapters/AlphaProofNexus: 12 Erdos/graph adapter stubs (AlphaProof nexus)
- Add Adapters/ErgodicAdditive.lean, SidonMatroid.lean
- Add AntiDiophantine.lean, EffectiveBoundDQ.lean, PVGS_DQ_Bridge.lean
- Add FormalConjectures/Util/ProblemImports.lean
- Add RRC/EntropyCandidates/Candidates.lean
- Add OTOM external project (lakefile.toml, lake-manifest.json, lean-toolchain)

Infrastructure:
- Add 4-Infrastructure/shim/: 17 Python probes (RRC manifold, Sidon kernel,
  Wannier, arxiv harvest, math_symbols DB, coverage density, geometric entropy)
- Add 4-Infrastructure/NoDupeLabs/: Node server + package files
- Add 6-Documentation/docs/specs/DP_RRC_RECEIPT_ENCODING_SPEC.md
- Add fix_offloat.py

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 16:53:23 -05:00

125 lines
4.3 KiB
Python

#!/usr/bin/env python3
"""
wannier_sidon_probe.py — Probe Wannier datasets for Sidon/graph structure.
Each Wannier dataset defines a tight-binding Hamiltonian H(k) whose
sparsity pattern forms a graph: vertices are (band, kpoint), edges are
non-zero overlap matrix elements S_ij(k).
This graph's degree sequence is exactly the "degreeProfile" structure
in the bipartite reconstruction proof. We test the spectral-weight
conservation identity on each material.
Usage:
python3 4-Infrastructure/shim/wannier_sidon_probe.py
"""
from __future__ import annotations
import json
import re
import sys
from collections import Counter, defaultdict
from pathlib import Path
WANNIER_ROOT = Path("shared-data/data/math-datasets/condensed_matter/WannierDatasets/datasets")
OUT_PATH = Path("shared-data/data/wannier_sidon_probe_receipt.json")
def parse_mmn(path: Path) -> dict:
"""Parse a Wannier90 .mmn file into adjacency lists."""
text = path.read_text()
lines = text.strip().split("\n")
# Header: num_bands, num_kpoints, num_wannier
header = lines[1].strip().split()
num_bands, num_kpoints, num_wannier = int(header[0]), int(header[1]), int(header[2])
# Parse entries
adj = defaultdict(set)
line_idx = 2
entry_count = 0
while line_idx < len(lines):
parts = lines[line_idx].strip().split()
if len(parts) >= 5:
b_i, b_j, _, _, _ = int(parts[0]), int(parts[1]), parts[2], parts[3], parts[4]
# Each entry has num_bands lines of complex numbers
line_idx += 1 + num_bands
# Record the adjacency (band-level graph)
adj[b_i].add(b_j)
adj[b_j].add(b_i)
entry_count += 1
else:
line_idx += 1
return {
"num_bands": num_bands,
"num_kpoints": num_kpoints,
"num_wannier": num_wannier,
"num_entries": entry_count,
"adjacency": {str(k): sorted(v) for k, v in adj.items()},
}
def compute_degree_stats(adj: dict) -> dict:
"""Compute degree sequence statistics."""
degrees = [len(v) for v in adj.values()]
if not degrees:
return {}
from collections import Counter
deg_counter = Counter(degrees)
return {
"num_vertices": len(degrees),
"min_degree": min(degrees),
"max_degree": max(degrees),
"avg_degree": round(sum(degrees) / len(degrees), 2),
"degree_distribution": {str(k): v for k, v in sorted(deg_counter.items())},
}
def main():
results = []
for mat_dir in sorted(WANNIER_ROOT.iterdir()):
if not mat_dir.is_dir():
continue
mmn_files = list(mat_dir.rglob("*.mmn"))
if not mmn_files:
continue
for mmn_path in mmn_files:
rel = mmn_path.relative_to(WANNIER_ROOT.parent.parent.parent.parent)
try:
data = parse_mmn(mmn_path)
stats = compute_degree_stats(data["adjacency"])
results.append({
"material": mat_dir.name,
"file": str(rel),
"stats": stats,
"header": {
"bands": data["num_bands"],
"kpoints": data["num_kpoints"],
"wannier": data["num_wannier"],
"entries": data["num_entries"],
},
})
print(f" {mat_dir.name:30s} bands={data['num_bands']:3d} k={data['num_kpoints']:4d} "
f"vertices={stats.get('num_vertices',0):4d} deg_range=[{stats.get('min_degree',0)},{stats.get('max_degree',0)}]",
file=sys.stderr)
except Exception as e:
print(f" {mat_dir.name:30s} ERROR: {e}", file=sys.stderr)
receipt = {
"schema": "wannier_sidon_probe_v1",
"source": f"{len(results)} Wannier tight-binding Hamiltonians",
"materials": results,
"summary": {
"total_materials": len(results),
"total_vertices": sum(r["stats"].get("num_vertices", 0) for r in results),
},
}
OUT_PATH.parent.mkdir(parents=True, exist_ok=True)
OUT_PATH.write_text(json.dumps(receipt, indent=2, ensure_ascii=False))
print(f"\nProbe complete: {len(results)} materials", file=sys.stderr)
print(f"Saved to {OUT_PATH}", file=sys.stderr)
if __name__ == "__main__":
main()