<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://invarians.org/index.php?action=history&amp;feed=atom&amp;title=The_Principia_Machina%2FTPC-PY%2Fdiff_cluster.py</id>
	<title>The Principia Machina/TPC-PY/diff cluster.py - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://invarians.org/index.php?action=history&amp;feed=atom&amp;title=The_Principia_Machina%2FTPC-PY%2Fdiff_cluster.py"/>
	<link rel="alternate" type="text/html" href="https://invarians.org/index.php?title=The_Principia_Machina/TPC-PY/diff_cluster.py&amp;action=history"/>
	<updated>2026-10-21T13:40:07Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.46.2</generator>
	<entry>
		<id>https://invarians.org/index.php?title=The_Principia_Machina/TPC-PY/diff_cluster.py&amp;diff=4041&amp;oldid=prev</id>
		<title>BFP Rauch: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://invarians.org/index.php?title=The_Principia_Machina/TPC-PY/diff_cluster.py&amp;diff=4041&amp;oldid=prev"/>
		<updated>2026-09-28T04:32:52Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw-interface=&quot;&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 04:32, 28 September 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;4&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;!-- diff cache key pma_cutover_20261020t051351z-soft_:diff:1.41:old-4040:rev-4041 --&gt;
&lt;/table&gt;</summary>
		<author><name>BFP Rauch</name></author>
	</entry>
	<entry>
		<id>https://invarians.org/index.php?title=The_Principia_Machina/TPC-PY/diff_cluster.py&amp;diff=4040&amp;oldid=prev</id>
		<title>BFP Rauch: TPC-PY source diff_cluster.py (0.3.0), SHA-256 00d67d36d74f491d; conformed TPS 0.3.0; PROPOSED, not declared (CO-8)</title>
		<link rel="alternate" type="text/html" href="https://invarians.org/index.php?title=The_Principia_Machina/TPC-PY/diff_cluster.py&amp;diff=4040&amp;oldid=prev"/>
		<updated>2026-09-27T15:43:18Z</updated>

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