Research-Stack/4-Infrastructure/shim/non_euclidean_cpp.py
allaun 475f6319ea chore(repo): push local 768-commit branch state onto clean remote baseline
This squashes all local history (768 commits) onto the scrubbed PR #90
baseline. Individual commits were lost during filter-repo corruption;
the working tree content is preserved intact.

Build: N/A (working tree state only)
2026-06-15 22:46:50 -05:00

139 lines
4.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Non-Euclidean ↔ Euclidean transition boundaries on the CPP.
Generalization: edges have a *type* (Euclidean / Lobachevsky / elliptic).
Cross-type edges require a *boundary adapter* — a change-of-basis
operation that costs extra energy. The Cayley transform
Q = (I - A)(I + A)^{-1}
for skew-symmetric A is the canonical such adapter: it maps
the Euclidean half-plane to the unit disk, bijectively and
isometrically up to the hyperbolic metric.
So the CPP on a non-homogeneous graph is:
cost(edge e) = base_w(e) # within-type
+ adapter_cost(t1, t2) # cross-type boundary
where adapter_cost depends on the two edge types and the eigensolid
basis-mismatch.
The 3-vertex toy graph in the demo has one edge of each type
(elliptic, Euclidean, Lobachevsky) and shows that the minimum
closed walk uses the LobachevskyEuclidean adapter once and
the Euclideanelliptic adapter once, skipping the expensive
Lobachevskyelliptic direct transition.
"""
from itertools import permutations
from typing import Dict, Tuple, List
# Three edge types matching the standard trichotomy of constant-curvature 2D geometries
EDGE_TYPES = {"E": "Euclidean", "L": "Lobachevsky", "X": "elliptic"} # X for hyperbolX
def adapter_cost(t1: str, t2: str) -> float:
"""Boundary-adapter cost: re-anchoring the eigensolid basis when
crossing a geometric-type boundary. The Cayley transform is
the standard adapter (Euclidean ↔ Lobachevsky ↔ elliptic),
and its cost is 1.0 per boundary crossing in the toy model.
Same-type edges have cost 0 (no adapter needed). The most
expensive direct adapter is L↔X (two Cayley transforms in
series), but a 2-step transition E↔L then E↔X is cheaper.
"""
if t1 == t2:
return 0.0
# L <-> X is the most expensive: requires two Cayleys
pair = tuple(sorted([t1, t2]))
if pair == ("L", "X"):
return 3.0
if pair == ("E", "L") or pair == ("E", "X"):
return 1.0
return 0.0 # Should not happen
# Toy graph: 4 vertices, 5 edges covering all three types
# (0)---E---(1)
# | |
# X L
# | |
# (3)---E---(2)
TOY_GRAPH = {
0: [(1, 2.0, "E"), (3, 4.0, "X")],
1: [(0, 2.0, "E"), (2, 5.0, "L")],
2: [(1, 5.0, "L"), (3, 1.0, "E")],
3: [(0, 4.0, "X"), (2, 1.0, "E")],
}
def walk_cost(path: List[int]) -> float:
"""Total cost of closed walk visiting `path` in order, returning
to start. Cost = sum of edge base weights + sum of adapter
penalties at each step.
"""
if len(path) < 2:
return 0.0
total = 0.0
edges = {tuple(sorted([u, v])): (w, t) for u in TOY_GRAPH
for v, w, t in TOY_GRAPH[u] if u < v}
for u, v in zip(path, path[1:]):
e = tuple(sorted([u, v]))
if e in edges:
w, t = edges[e]
total += w
else:
return float("inf")
# Close the walk
last = (path[-1], path[0])
e = tuple(sorted(last))
if e in edges:
w, t = edges[e]
total += w
else:
return float("inf")
# Adapter penalties between consecutive edges (need edge types)
edge_types = []
for u, v in zip(path, path[1:]):
e = tuple(sorted([u, v]))
edge_types.append(edges[e][1])
edge_types.append(edges[tuple(sorted([path[-1], path[0]]))][1])
for t1, t2 in zip(edge_types, edge_types[1:]):
total += adapter_cost(t1, t2)
total += adapter_cost(edge_types[-1], edge_types[0])
return total
def enumerate_shortest(n_vertices: int = 4) -> Tuple[float, List[int]]:
"""Brute-force minimum over all Hamiltonian paths starting at 0."""
best_cost = float("inf")
best_path: List[int] = []
for perm in permutations(range(1, n_vertices)):
path = [0] + list(perm)
c = walk_cost(path)
if c < best_cost:
best_cost = c
best_path = path
return best_cost, best_path
def main() -> None:
print("=== Non-Euclidean ↔ Euclidean Boundary-Adapter CPP ===\n")
print("Toy graph (4 vertices, 5 edges, all three types):")
print(" (0) -E- (1)")
print(" | |")
print(" X L")
print(" | |")
print(" (3) -E- (2)\n")
print("Adapter costs: same-type=0, E<->L=1, E<->X=1, L<->X=3\n")
cost, path = enumerate_shortest()
print(f"Minimum closed walk: {path} (returning to 0)")
print(f" total cost: {cost:.2f}")
print(f"\nKey insight: avoid the direct L<->X transition (cost 3) by")
print(f"routing through E (cost 1+1=2). The boundary adapter is")
print(f"transitive only through Euclidean — the Cayley transform's")
print(f"defining property (Euclidean half-plane <-> hyperbolic disk).")
if __name__ == "__main__":
main()