Spaces:
Sleeping
Sleeping
| import numpy as np | |
| import torch | |
| from ideal_poly_volume_toolkit.geometry import ( | |
| delaunay_triangulation_indices, | |
| triangle_volume_from_points_torch, | |
| ideal_poly_volume_via_delaunay | |
| ) | |
| def random_complex_points(K, rng): | |
| """Generate K random complex points""" | |
| r = 0.5 + 1.0 * rng.random(K) | |
| theta = 2 * np.pi * rng.random(K) | |
| return r * np.exp(1j * theta) | |
| def build_Z_free(real_parts: torch.Tensor, imag_parts: torch.Tensor) -> torch.Tensor: | |
| """Build complex array from real and imaginary parts""" | |
| Z = torch.empty(real_parts.numel() + 2, dtype=torch.complex128, device=real_parts.device) | |
| Z[0] = 0 + 0j # Fixed at origin | |
| Z[1] = 1 + 0j # Fixed at 1 | |
| Z[2:] = torch.complex(real_parts, imag_parts) | |
| return Z | |
| def torch_sum_volume(Z_t: torch.Tensor, idx, series_terms: int) -> torch.Tensor: | |
| total = torch.zeros((), dtype=torch.float64, device=Z_t.device) | |
| for (i, j, k) in idx: | |
| total = total + triangle_volume_from_points_torch( | |
| Z_t[i], Z_t[j], Z_t[k], series_terms=series_terms | |
| ) | |
| return total | |
| def run_optimization_trial(seed, max_iters=100, K=5): | |
| """Run one optimization trial with given seed""" | |
| rng = np.random.default_rng(seed) | |
| # Initialize with random complex points | |
| z_init = random_complex_points(K, rng) | |
| real_parts = torch.tensor(z_init.real, dtype=torch.float64, requires_grad=True) | |
| imag_parts = torch.tensor(z_init.imag, dtype=torch.float64, requires_grad=True) | |
| # Use LBFGS optimizer | |
| opt = torch.optim.LBFGS([real_parts, imag_parts], lr=1.0, max_iter=20, line_search_fn='strong_wolfe') | |
| prev_triangulation = None | |
| triangulation_changes = 0 | |
| for it in range(1, max_iters + 1): | |
| # Rebuild Delaunay triangulation | |
| with torch.no_grad(): | |
| Z_np = build_Z_free(real_parts, imag_parts).detach().cpu().numpy() | |
| idx = delaunay_triangulation_indices(Z_np) | |
| if prev_triangulation is not None: | |
| if idx.shape != prev_triangulation.shape or not np.array_equal(idx, prev_triangulation): | |
| triangulation_changes += 1 | |
| prev_triangulation = idx.copy() | |
| # Closure for LBFGS | |
| def closure(): | |
| opt.zero_grad(set_to_none=True) | |
| Z_t = build_Z_free(real_parts, imag_parts) | |
| total = torch_sum_volume(Z_t, idx, 96) | |
| loss = -total | |
| loss.backward() | |
| torch.nn.utils.clip_grad_norm_([real_parts, imag_parts], max_norm=10.0) | |
| return loss | |
| opt.step(closure) | |
| # Final evaluation | |
| with torch.no_grad(): | |
| Zf = build_Z_free(real_parts, imag_parts).detach().cpu().numpy() | |
| vol_fast = torch_sum_volume(build_Z_free(real_parts, imag_parts), idx, 96).item() | |
| vol_exact = ideal_poly_volume_via_delaunay(Zf, mode='eval_only', dps=250) | |
| return { | |
| 'seed': seed, | |
| 'volume_fast': vol_fast, | |
| 'volume_exact': vol_exact, | |
| 'final_config': Zf.copy(), | |
| 'num_triangles': len(idx), | |
| 'triangulation_changes': triangulation_changes | |
| } | |
| # Run multiple trials | |
| print("Running multiple optimization trials with 5 free points...") | |
| print("Expected volumes:") | |
| print(" Regular tetrahedron: ~1.0149") | |
| print(" Regular cube: ~5.0747") | |
| print("\n") | |
| num_trials = 10 | |
| results = [] | |
| for seed in range(num_trials): | |
| print(f"Trial {seed+1}/{num_trials} (seed={seed})...", end='', flush=True) | |
| result = run_optimization_trial(seed) | |
| results.append(result) | |
| print(f" Volume: {result['volume_exact']:.6f}") | |
| # Analyze results | |
| volumes = [r['volume_exact'] for r in results] | |
| print(f"\n=== Summary of {num_trials} trials ===") | |
| print(f"Minimum volume: {min(volumes):.6f}") | |
| print(f"Maximum volume: {max(volumes):.6f}") | |
| print(f"Average volume: {np.mean(volumes):.6f}") | |
| print(f"Std deviation: {np.std(volumes):.6f}") | |
| # Count how many exceed the cube | |
| cube_volume = 5.0747 | |
| num_exceed_cube = sum(1 for v in volumes if v > cube_volume) | |
| print(f"\nTrials exceeding cube volume ({cube_volume:.4f}): {num_exceed_cube}/{num_trials}") | |
| # Group by similar volumes | |
| print("\nVolume distribution:") | |
| volume_groups = {} | |
| for r in results: | |
| v = r['volume_exact'] | |
| found = False | |
| for group_v in volume_groups: | |
| if abs(v - group_v) < 0.01: # Group within 0.01 | |
| volume_groups[group_v].append(r) | |
| found = True | |
| break | |
| if not found: | |
| volume_groups[v] = [r] | |
| for v in sorted(volume_groups.keys(), reverse=True): | |
| group = volume_groups[v] | |
| print(f" Volume ~{v:.4f}: {len(group)} trial(s) (seeds: {[r['seed'] for r in group]})") | |
| # Check if any special values appear | |
| phi = (1 + np.sqrt(5)) / 2 | |
| print(f"\nChecking for special values (φ = {phi:.6f}):") | |
| for v in sorted(volume_groups.keys(), reverse=True): | |
| ratio = v / 1.0149 # Ratio to tetrahedron | |
| print(f" {v:.4f} = {ratio:.4f} × tetrahedron") | |
| # Save the best configuration | |
| best = max(results, key=lambda r: r['volume_exact']) | |
| print(f"\nBest configuration found:") | |
| print(f" Seed: {best['seed']}") | |
| print(f" Volume: {best['volume_exact']:.6f}") | |
| print(f" Points:") | |
| for i, z in enumerate(best['final_config']): | |
| print(f" z[{i}] = {z.real:.4f} + {z.imag:.4f}i") |