Jump to content

The Principia Machina/TPC-PY/diff cluster.py: Difference between revisions

From The Invariance Itself
TPC-PY source diff_cluster.py (0.3.0), SHA-256 00d67d36d74f491d; conformed TPS 0.3.0; PROPOSED, not declared (CO-8)
 
m 1 revision imported
 
(No difference)

Latest revision as of 04:32, 28 September 2026

"""diff_cluster 0.3.0: the cross-residence differential for tpc_cluster
0.3.0. Random rows, parameters and, in half the cases, a paired-SE table
(complete, or with one pair dropped, duplicated or negative); random
resolving_step inputs. Both residences run on the same inputs; 0
differences is the pass. Usage: python3 diff_cluster.py [seed] [cases]."""
import json, os, random, subprocess, sys, tempfile
here = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, here)
from tpc_cluster import run_case
seed = int(sys.argv[1]) if len(sys.argv) > 1 else 1
count = int(sys.argv[2]) if len(sys.argv) > 2 else 20000
random.seed(seed)
cases = []
for t in range(count):
    if random.random() < 0.2:
        n = random.randint(0, 8)
        ses = [random.choice([0.0, round(random.uniform(0, 3), 3), round(random.uniform(0, 1), 2)]) for _ in range(n)]
        paired = None
        if random.random() < 0.5:
            paired = [round(random.uniform(0, 2), 3) for _ in range(max(n - 1, 0))]
            if random.random() < 0.1 and paired:
                paired = paired[:-1]
        p = {"in_max": random.choice([2.5, 1.5, 1.0]), "cusp_max": random.choice([3.5, 4.0]), "z": random.choice([1.645, 1.0, 0.0, 2.0])}
        cases.append({"fn": "resolving", "spacing": random.choice([0.0, round(random.uniform(0, 5), 3), 1.0]), "ses": ses, "params": p, "paired": paired})
        continue
    nm = random.randint(0, 8)
    mode = random.random()
    rows = []
    for j in range(nm):
        for cfg in random.sample(["high", "med", "low", "default"], random.randint(1, 3)):
            if mode < 0.3: s = round(random.uniform(0, 10), 1)
            elif mode < 0.6: s = round(random.uniform(0, 100), 2)
            else: s = random.choice([10.0, 9.0, 8.0, 7.0, 6.0, 5.0])
            e = random.choice([0.0, 0.0, round(random.uniform(0, 5), 2), round(random.uniform(0, 1), 3)])
            rows.append(["m%d" % j, cfg, s, e])
    p = {"in_max": random.choice([2.5, 1.5, 1.0]), "cusp_max": random.choice([3.5, 4.0]),
         "z": random.choice([1.645, 1.0, 0.0, 2.0]), "spacing_floor": random.choice([0.0, 0.5, 0.1, 1.0])}
    case = {"fn": "cluster", "rows": rows, "params": p, "paired": None}
    if random.random() < 0.5:
        paired = []
        for i in range(len(rows)):
            for j in range(i + 1, len(rows)):
                sd = random.choice([0.0, round(random.uniform(0, 3), 3), round(random.uniform(0, 0.5), 3)])
                a, b = rows[i], rows[j]
                if random.random() < 0.5:
                    a, b = b, a
                paired.append([a[0], a[1], b[0], b[1], sd])
        r = random.random()
        if r < 0.05 and paired:
            paired.pop(random.randrange(len(paired)))
        elif r < 0.10 and paired:
            x = paired[random.randrange(len(paired))]
            paired.append([x[2], x[3], x[0], x[1], x[4]])
        elif r < 0.13 and paired:
            paired[random.randrange(len(paired))][4] = -0.5
        case["paired"] = paired
    cases.append(case)
CASES_PATH = os.environ.get("TPC_DIFF_CASES")  # named: kept, for crosspy.py
if not CASES_PATH:
    fd, CASES_PATH = tempfile.mkstemp(prefix="tpc_diff_", suffix=".json")  # outside the tree
    os.close(fd)
with open(CASES_PATH, "w", encoding="utf-8") as f:
    json.dump(cases, f)
py = [run_case(c) for c in cases]
php = json.loads(subprocess.run(["php", os.path.join(here, "diff_cluster.php"), CASES_PATH], capture_output=True, text=True, check=True).stdout)
if not os.environ.get("TPC_DIFF_CASES"):
    os.remove(CASES_PATH)
diffs = sum(1 for a, b in zip(py, php) if a != b)
print("seed", seed, "cases", len(cases), "differences", diffs, "errors", sum(1 for x in py if x.startswith("ERROR")),
      "paired", sum(1 for c in cases if c.get("paired") is not None), "resolving", sum(1 for c in cases if c["fn"] == "resolving"))
for a, b in zip(py, php):
    if a != b:
        print(a); print("---"); print(b); break