-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfig_composition.py
More file actions
87 lines (73 loc) · 3.32 KB
/
Copy pathfig_composition.py
File metadata and controls
87 lines (73 loc) · 3.32 KB
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
"""Opening result figure: the same crossover at two noise compositions, N = 3 (Fig 2).
Panel (a): pure dephasing, crossover 0.488. Panel (b): equal stacking of all
three channels, crossover 0.035 - a factor of 14 lower on a 10x finer axis.
"""
from GHZ_CKA import *
import figstyle
from figstyle import COLORS
import numpy as np
import matplotlib.pyplot as plt
N = 3
def rates_dephasing(g):
return (ghz_key_rate(N, "phase", g), pairwise_key_rate(N, "phase", g))
def rates_stacked(g):
q, c = ghz_circuit_split(N, phase=True, gamma_phase=g,
amplitude=True, gamma_amplitude=g,
depolarize=True, gamma_depolarize=g)
qx, qz_list = qbers(q, c)
r_ghz = max(0.0, 1 - h(qx) - max(h(z) for z in qz_list))
q, c = bell_circuit_split(phase=True, gamma_phase=g,
amplitude=True, gamma_amplitude=g,
depolarize=True, gamma_depolarize=g)
qx, qz_list = qbers(q, c)
r_pair = max(0.0, 1 - h(qx) - h(qz_list[0])) / (N - 1)
return r_ghz, r_pair
def bisect(gap, lo=1e-9, hi=0.9, tol=1e-9):
if gap(lo) < 0 or gap(hi) > 0:
return None
while hi - lo > tol:
mid = (lo + hi) / 2.0
if gap(mid) > 0:
lo = mid
else:
hi = mid
return (lo + hi) / 2.0
g_deph = bisect(lambda g: rates_dephasing(g)[0] - rates_dephasing(g)[1])
g_stack = bisect(lambda g: rates_stacked(g)[0] - rates_stacked(g)[1], hi=0.6)
print(f"dephasing crossover: {g_deph:.5f}")
print(f"stacked crossover: {g_stack:.5f} ({g_deph / g_stack:.1f}x lower)")
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(9.5, 3.8), sharey=True)
gammas = np.linspace(0.0, 0.6, 121)
ghz = [rates_dephasing(g)[0] for g in gammas]
pw = [rates_dephasing(g)[1] for g in gammas]
ax1.plot(gammas, ghz, color=COLORS["ghz"], label="GHZ conference")
ax1.plot(gammas, pw, linestyle="--", color=COLORS["pairwise"],
label="Pairwise BB84 / $(N-1)$")
ax1.axvline(g_deph, color=COLORS["accent"], linestyle=":", linewidth=1.4)
ax1.annotate(f"$\\gamma^* = {g_deph:.3f}$", xy=(g_deph, 0.45),
xytext=(0.22, 0.62), fontsize=11,
arrowprops=dict(arrowstyle="->", color=COLORS["accent"], lw=1.1))
ax1.set_xlabel("Noise strength $\\gamma$")
ax1.set_ylabel("Key rate (bits per network use)")
ax1.set_title("(a) Pure dephasing", loc="left")
ax1.set_xlim(0, 0.6)
ax1.set_ylim(0, 1.05)
ax1.legend(loc="upper right")
gammas_s = np.linspace(0.0, 0.06, 121)
ghz_s = [rates_stacked(g)[0] for g in gammas_s]
pw_s = [rates_stacked(g)[1] for g in gammas_s]
ax2.plot(gammas_s, ghz_s, color=COLORS["ghz"])
ax2.plot(gammas_s, pw_s, linestyle="--", color=COLORS["pairwise"])
ax2.axvline(g_stack, color=COLORS["accent"], linestyle=":", linewidth=1.4)
ax2.annotate(f"$\\gamma^* = {g_stack:.3f}$", xy=(g_stack, 0.45),
xytext=(0.041, 0.62), fontsize=11,
arrowprops=dict(arrowstyle="->", color=COLORS["accent"], lw=1.1))
ax2.set_xlabel("Noise strength per channel $\\gamma$")
ax2.set_title("(b) Equal stacking of all three channels", loc="left")
ax2.set_xlim(0, 0.06)
ax2.text(0.5, -0.30, "note the axis scale: the crossover is 14$\\times$ lower than in (a)",
transform=ax2.transAxes, ha="center", fontsize=9.5,
style="italic", color="0.35")
fig.tight_layout()
fig.savefig("composition.png")
print("saved composition.png")