mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-07-31 03:05:21 +00:00
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>
125 lines
4.3 KiB
Python
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()
|