File size: 2,388 Bytes
2facf1f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""
Construct functions that might achieve low C1 using analytical insights.

Key insight: C1 = max(f*f) / (integral(f))^2
For f supported on N discrete points with spacing dx = 0.5/N,
the autoconvolution f*f has 2N-1 points.

If we think of f as a discrete signal, C1 is related to the
peak-to-average ratio of the autocorrelation of f.

Approach: Use functions related to low-autocorrelation sequences.
"""
import numpy as np

def compute_c1(f_values, dx):
    f = np.maximum(f_values, 0.0)
    autoconv = np.convolve(f, f, mode='full') * dx
    integral_sq = (np.sum(f) * dx) ** 2
    if integral_sq < 1e-20:
        return 1e10
    return float(np.max(autoconv) / integral_sq)

N = 1000
dx = 0.5 / N

# Try various analytical constructions

# 1. Constant function
f = np.ones(N)
print(f"Constant: C1 = {compute_c1(f, dx):.10f}")

# 2. Linear ramp
f = np.linspace(0.1, 1.0, N)
print(f"Linear ramp: C1 = {compute_c1(f, dx):.10f}")

# 3. Square root
f = np.sqrt(np.linspace(0.01, 1.0, N))
print(f"Sqrt: C1 = {compute_c1(f, dx):.10f}")

# 4. Exponential decay
for tau in [0.5, 1.0, 2.0, 3.0]:
    f = np.exp(-np.linspace(0, tau, N))
    print(f"Exp decay tau={tau}: C1 = {compute_c1(f, dx):.10f}")

# 5. Power law
for p in [0.5, 1.0, 1.5, 2.0]:
    x = np.linspace(0.01, 1.0, N)
    f = x**p
    print(f"Power x^{p}: C1 = {compute_c1(f, dx):.10f}")

# 6. Inverse power (decreasing)
for p in [0.3, 0.5, 1.0]:
    x = np.linspace(0.01, 1.0, N)
    f = x**(-p)
    print(f"x^(-{p}): C1 = {compute_c1(f, dx):.10f}")

# 7. Two-level step functions
for h in np.arange(0.1, 1.0, 0.1):
    for split in np.arange(0.1, 0.9, 0.1):
        f = np.ones(N)
        s = int(N * split)
        f[:s] = h
        c1 = compute_c1(f, dx)
        if c1 < 1.6:
            print(f"Step h={h:.1f} split={split:.1f}: C1 = {c1:.10f}")

# 8. Gaussian
for sigma in [0.1, 0.2, 0.3, 0.5, 1.0]:
    x = np.linspace(-1, 1, N)
    f = np.exp(-x**2 / (2*sigma**2))
    print(f"Gaussian sigma={sigma}: C1 = {compute_c1(f, dx):.10f}")

# 9. B-spline / hat function
x = np.linspace(0, 1, N)
f = np.minimum(2*x, 2*(1-x))
print(f"Hat: C1 = {compute_c1(f, dx):.10f}")

# 10. Raised cosine
x = np.linspace(0, np.pi, N)
f = (1 + np.cos(x)) / 2
print(f"Raised cosine: C1 = {compute_c1(f, dx):.10f}")

# 11. Epanechnikov
x = np.linspace(-1, 1, N)
f = np.maximum(1 - x**2, 0)
print(f"Epanechnikov: C1 = {compute_c1(f, dx):.10f}")