File size: 3,979 Bytes
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
import numpy as np
from ideal_poly_volume_toolkit.geometry import ideal_poly_volume_via_delaunay

def compute_volume_statistics(n_samples, seed=42):
    """Compute volumes and return statistics"""
    np.random.seed(seed)
    volumes = []
    
    for i in range(n_samples):
        # Uniform point on sphere
        vec = np.random.randn(3)
        vec = vec / np.linalg.norm(vec)
        x, y, z = vec
        
        if z > 0.999:  # Skip north pole
            continue
        
        # Stereographic projection
        w = complex(x/(1-z), y/(1-z))
        
        if abs(w) < 0.01 or abs(w-1) < 0.01:
            continue
        
        vertices = np.array([0+0j, 1+0j, w])
        vol = ideal_poly_volume_via_delaunay(vertices, mode='fast', series_terms=96)
        volumes.append(vol)
    
    volumes = np.array(volumes)
    n = len(volumes)
    mean = np.mean(volumes)
    std = np.std(volumes, ddof=1)  # Sample standard deviation
    se_mean = std / np.sqrt(n)  # Standard error of mean
    se_std = std / np.sqrt(2 * (n - 1))  # Standard error of std dev
    
    return {
        'n': n,
        'mean': mean,
        'std': std,
        'se_mean': se_mean,
        'se_std': se_std,
        'volumes': volumes
    }

print("Statistical Precision Analysis for Random Ideal Tetrahedron Volumes")
print("="*70)

# Test with different sample sizes
sample_sizes = [1000, 5000, 10000, 25000, 50000]

results = {}
for n in sample_sizes:
    print(f"\nComputing {n} samples...")
    stats = compute_volume_statistics(n)
    results[n] = stats
    
    print(f"  Actual samples: {stats['n']}")
    print(f"  Mean: {stats['mean']:.6f} ± {stats['se_mean']:.6f}")
    print(f"  Std:  {stats['std']:.6f} ± {stats['se_std']:.6f}")
    print(f"  95% CI for mean: [{stats['mean'] - 1.96*stats['se_mean']:.6f}, "
          f"{stats['mean'] + 1.96*stats['se_mean']:.6f}]")
    
    # How many decimal places are reliable?
    mean_precision = -int(np.floor(np.log10(2 * stats['se_mean'])))
    std_precision = -int(np.floor(np.log10(2 * stats['se_std'])))
    print(f"  Reliable decimal places: mean={mean_precision}, std={std_precision}")

# Convergence analysis
print("\n" + "="*70)
print("Convergence Analysis:")
print("-"*70)

# Check how mean and std converge
means = [results[n]['mean'] for n in sample_sizes]
stds = [results[n]['std'] for n in sample_sizes]

print("\nMean convergence:")
for i, n in enumerate(sample_sizes):
    print(f"  n={n:6d}: {means[i]:.6f}")
    
print("\nStd convergence:")
for i, n in enumerate(sample_sizes):
    print(f"  n={n:6d}: {stds[i]:.6f}")

# Estimate how many samples needed for different precisions
print("\n" + "="*70)
print("Samples needed for different precision levels:")
print("-"*70)

# Use the largest sample to estimate true parameters
best_estimate = results[sample_sizes[-1]]
true_std = best_estimate['std']

# For mean
for decimals in [2, 3, 4, 5]:
    required_se = 0.5 * 10**(-decimals)
    required_n = int(np.ceil((true_std / required_se)**2))
    print(f"  {decimals} decimal places in mean: {required_n:,} samples")

# For standard deviation
print("\nFor standard deviation:")
for decimals in [2, 3, 4]:
    required_se = 0.5 * 10**(-decimals)
    required_n = int(np.ceil(2 * (true_std / (2 * required_se))**2))
    print(f"  {decimals} decimal places in std: {required_n:,} samples")

# Final recommendation
print("\n" + "="*70)
print("SUMMARY:")
print(f"  Standard deviation: ~{true_std:.4f}")
print(f"  This means the distribution is quite broad (CV = {true_std/best_estimate['mean']:.2f})")
print(f"\nFor 4 significant digits:")
print(f"  In mean: need ~{int(np.ceil((true_std / 0.00005)**2)):,} samples")
print(f"  In std: need ~{int(np.ceil(2 * (true_std / 0.0001)**2)):,} samples")
print(f"\nCurrent precision with {sample_sizes[-1]} samples:")
print(f"  Mean: {best_estimate['mean']:.4f}{best_estimate['se_mean']:.4f})")
print(f"  Std:  {best_estimate['std']:.4f}{best_estimate['se_std']:.4f})")