Spaces:
Sleeping
Sleeping
File size: 3,937 Bytes
f9b644c 3bf2012 f9b644c 3bf2012 f9b644c 3bf2012 f9b644c 3bf2012 f9b644c 3bf2012 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 |
#!/usr/bin/env python3
"""
Test a few 7-vertex variations to see if there are multiple maxima.
"""
import numpy as np
import torch
from ideal_poly_volume_toolkit.geometry import (
delaunay_triangulation_indices,
triangle_volume_from_points_torch,
)
def evaluate_config(Z):
"""Evaluate volume and structure of a configuration."""
Z_np = np.array(Z, dtype=np.complex128)
try:
idx = delaunay_triangulation_indices(Z_np)
# Check vertices used
vertices_used = set()
for (i, j, k) in idx:
vertices_used.update([i, j, k])
if len(vertices_used) < 7:
return None, None
# Compute volume
Z_torch = torch.tensor(Z_np, dtype=torch.complex128)
total = 0
for (i, j, k) in idx:
vol = triangle_volume_from_points_torch(Z_torch[i], Z_torch[j], Z_torch[k], series_terms=96)
total += vol.item()
# Compute degrees
degrees = [0] * 7
edges = set()
for (a, b, c) in idx:
edges.add(tuple(sorted([a, b])))
edges.add(tuple(sorted([b, c])))
edges.add(tuple(sorted([a, c])))
for edge in edges:
degrees[edge[0]] += 1
degrees[edge[1]] += 1
return total, tuple(sorted(degrees))
except:
return None, None
# Test several hand-crafted configurations
configs = []
# Config 1: Previous optimum
Z1 = [complex(0, 0), complex(1, 0),
complex(-0.9959, 0.1942), complex(-0.4018, -0.9331),
complex(0.8441, -1.2772), complex(0.3669, -0.5609)]
configs.append(("Previous optimum", Z1))
# Config 2: Regular hexagon + center
angles = np.linspace(0, 2*np.pi, 7)[:-1]
Z2 = [complex(0, 0), complex(1, 0)]
for a in angles[2:]:
Z2.append(complex(np.cos(a), np.sin(a)))
configs.append(("Hexagon + center", Z2))
# Config 3: Two triangles
Z3 = [complex(0, 0), complex(1, 0),
complex(0.5, 0.5), complex(-1, 0), complex(0, -1),
complex(-0.5, -0.5)]
configs.append(("Two triangles", Z3))
# Config 4: Star pattern
Z4 = [complex(0, 0), complex(1, 0)]
for r, a in [(2, 0.5), (2, 2.5), (0.5, 4), (0.5, 5.5), (1.5, 1.0)]:
Z4.append(complex(r*np.cos(a), r*np.sin(a)))
configs.append(("Star pattern", Z4))
print("Testing different 7-vertex configurations...")
print("="*50)
results = []
for name, Z in configs:
vol, sig = evaluate_config(Z)
if vol is not None:
results.append((vol, sig, name))
print(f"\n{name}:")
print(f" Volume: {vol:.6f}")
print(f" Degree signature: {sig}")
print(f" Ratio to octahedron: {vol/5.333:.3f}")
# Group by signature
print("\n" + "="*50)
print("Grouping by degree signature:")
sig_groups = {}
for vol, sig, name in results:
if sig not in sig_groups:
sig_groups[sig] = []
sig_groups[sig].append((vol, name))
for sig, items in sig_groups.items():
print(f"\nSignature {sig}:")
for vol, name in sorted(items, reverse=True):
print(f" {name}: {vol:.6f}")
# Now try a few random perturbations of the best config
print("\n" + "="*50)
print("Testing small perturbations of the optimum...")
best_Z = Z1
best_vol = results[0][0]
for i in range(5):
# Perturb slightly
Z_perturbed = best_Z[:2] # Keep first 2 fixed (0 and 1)
for z in best_Z[2:]:
noise = 0.1 * (np.random.randn() + 1j*np.random.randn())
Z_perturbed.append(z + noise)
vol, sig = evaluate_config(Z_perturbed)
if vol is not None:
print(f"\nPerturbation {i+1}: volume={vol:.6f}, signature={sig}")
if vol > best_vol * 0.99: # Within 1% of optimum
print(" -> Near optimal!")
print("\n" + "="*50)
print("CONCLUSION:")
unique_sigs = len(sig_groups)
if unique_sigs == 1:
print("All good configurations have the same degree signature!")
else:
print(f"Found {unique_sigs} different degree signatures.") |