Spaces:
Sleeping
Sleeping
File size: 6,131 Bytes
f9b644c d7d27f0 f9b644c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
import numpy as np
import json
from scipy.spatial import Delaunay
from ideal_poly_volume_toolkit.rivin_holonomy import Triangulation, generators_from_triangulation
def compute_holonomy_traces(vertices_complex, triangles):
"""
Compute holonomy generators and their traces for an ideal polyhedron.
Returns traces and checks if they're close to integers.
"""
# Convert complex vertices to 2D points for triangulation
vertices_2d = np.array([[z['real'], z['imag']] for z in vertices_complex if isinstance(z, dict)])
# Build adjacency structure from Delaunay triangulation
F = len(triangles) # number of triangles
adjacency = {}
edge_id_map = {}
edge_id = 0
# Build adjacency between triangles
for i, tri_i in enumerate(triangles):
for side_i in range(3):
v1_i, v2_i = tri_i[side_i], tri_i[(side_i + 1) % 3]
edge = tuple(sorted([v1_i, v2_i]))
# Find matching triangle
for j, tri_j in enumerate(triangles):
if i == j:
continue
for side_j in range(3):
v1_j, v2_j = tri_j[side_j], tri_j[(side_j + 1) % 3]
if set([v1_j, v2_j]) == set([v1_i, v2_i]):
# Found matching edge
if (i, side_i) not in adjacency:
if edge not in edge_id_map:
edge_id_map[edge] = edge_id
edge_id += 1
adjacency[(i, side_i)] = (j, side_j, edge_id_map[edge])
# Define order (counterclockwise) for each triangle
order = {t: [0, 1, 2] for t in range(F)}
# Define orientations for edges
orientation = {}
for edge, eid in edge_id_map.items():
# Find triangles containing this edge
for (t, s), (u, su, e) in adjacency.items():
if e == eid:
orientation[eid] = ((t, s), (u, su))
break
# Create triangulation object
T = Triangulation(F, adjacency, order, orientation)
# Zero shears (ideal polyhedra have no shearing)
Z = {eid: 0.0 for eid in range(edge_id)}
# Compute generators
gens = generators_from_triangulation(T, Z, root=0)
# Extract traces
traces = []
trace_analysis = []
print(f"\nHolonomy analysis for {F} triangles:")
print("-" * 70)
print(f"Number of generators: {len(gens)}")
print("\nTraces of holonomy generators:")
for i, (u, v, tokens, M) in enumerate(gens):
trace = M[0][0] + M[1][1]
traces.append(trace)
# Check proximity to integers
nearest_int = round(trace)
distance = abs(trace - nearest_int)
is_close = distance < 0.01
trace_analysis.append({
'generator': i,
'edge': (u, v),
'trace': trace,
'nearest_integer': nearest_int,
'distance': distance,
'possibly_integral': is_close
})
print(f" Generator {i} (edge {u}-{v}): trace = {trace:.6f}")
print(f" Nearest integer: {nearest_int}, distance: {distance:.6f}")
if is_close:
print(f" *** CLOSE TO INTEGER! ***")
return traces, trace_analysis
# Load optimal configurations
with open('optimal_configurations.json', 'r') as f:
data = json.load(f)
print("="*70)
print("ARITHMETICITY CHECK FOR MAXIMAL IDEAL POLYHEDRA")
print("="*70)
# Check the maximal 8-vertex configuration
print("\n1. MAXIMAL 8-VERTEX CONFIGURATION (volume = 6.488)")
print("-"*70)
config = data['discovered_configurations']['maximal_8vertex']
vertices = []
for k, v in config['vertices_complex'].items():
if isinstance(v, dict):
vertices.append(v)
triangles = config['delaunay_triangles']
traces1, analysis1 = compute_holonomy_traces(vertices, triangles)
# Check for arithmetic patterns
integral_count = sum(1 for a in analysis1 if a['possibly_integral'])
print(f"\nSummary: {integral_count}/{len(analysis1)} traces are close to integers")
# Check the golden ratio configuration
print("\n\n2. GOLDEN RATIO 8-VERTEX CONFIGURATION (volume = 6.002)")
print("-"*70)
config = data['discovered_configurations']['golden_ratio_8vertex']
vertices = []
for k, v in config['vertices_complex'].items():
if isinstance(v, dict):
vertices.append(v)
triangles = config['delaunay_triangles']
traces2, analysis2 = compute_holonomy_traces(vertices, triangles)
integral_count = sum(1 for a in analysis2 if a['possibly_integral'])
print(f"\nSummary: {integral_count}/{len(analysis2)} traces are close to integers")
# Check trace field generation
print("\n\n3. TRACE FIELD ANALYSIS")
print("-"*70)
def analyze_trace_field(traces):
"""Check if traces generate an algebraic number field close to integers."""
# Look for algebraic relations
products = []
sums = []
for i in range(len(traces)):
for j in range(i, len(traces)):
products.append(traces[i] * traces[j])
sums.append(traces[i] + traces[j])
all_values = traces + products + sums
integral_values = []
for val in all_values:
nearest = round(val)
if abs(val - nearest) < 0.01:
integral_values.append((val, nearest))
return integral_values
print("\nMaximal configuration trace field:")
integral_vals1 = analyze_trace_field(traces1)
print(f"Found {len(integral_vals1)} values close to integers in trace field")
print("\nGolden ratio configuration trace field:")
integral_vals2 = analyze_trace_field(traces2)
print(f"Found {len(integral_vals2)} values close to integers in trace field")
print("\n\nCONCLUSION:")
print("-"*70)
print("If many traces are close to integers, the polyhedron may be arithmetic.")
print("Arithmetic hyperbolic 3-manifolds have holonomies in PSL(2,O_K) where")
print("O_K is the ring of integers in a number field K.")
print("\nFor ideal polyhedra, arithmeticity would mean the configuration")
print("has deep number-theoretic significance!") |