From cb41504566a529fcc91bb3f773ff0180cbde3de8 Mon Sep 17 00:00:00 2001 From: WrathfulSpatula Date: Thu, 14 Nov 2024 14:40:24 -0500 Subject: [PATCH] Fix classical shadows --- rcs/fc_elided_time.py | 26 ++++++++++-------------- rcs/rcs_nn_elided.py | 26 +++++++++++++----------- rcs/rcs_nn_elided_time.py | 30 +++++++++++++--------------- rcs/sycamore_2019_elided.py | 34 +++++++++++++++----------------- rcs/sycamore_2019_elided_time.py | 34 +++++++++++++++----------------- 5 files changed, 70 insertions(+), 80 deletions(-) diff --git a/rcs/fc_elided_time.py b/rcs/fc_elided_time.py index 14cb9d3..122c1d3 100644 --- a/rcs/fc_elided_time.py +++ b/rcs/fc_elided_time.py @@ -16,27 +16,21 @@ from scipy.stats import binom -# sin(math.pi / 4) / 2 -epsilon = 0.353553390593273762 - - def ct_pair_prob(sim, q1, q2): - r = [0] * 4 - - r[0] = sim.prob(q1) - r[1] = sim.prob(q2) - r[2] = r[0] - r[3] = q2 - if r[0] < r[1]: - r[3] = q1 - r[2] = r[1] + p1 = sim.prob(q1) + p2 = sim.prob(q2) + p1Hi = p1 > p2 + pHi = p1 if p1Hi else p2 + pLo = p2 if p1Hi else p1 + cState = abs(pHi - 0.5) > abs(pLo - 0.5) + t = q1 if p1Hi == cState else q2 - return r + return cState, t def cz_shadow(sim, q1, q2): - prob1, prob2, prob_max, t = ct_pair_prob(sim, q1, q2) - if prob_max > (0.5 + epsilon): + cState, t = ct_pair_prob(sim, q1, q2) + if cState: sim.z(t) diff --git a/rcs/rcs_nn_elided.py b/rcs/rcs_nn_elided.py index 066d350..7e29ca0 100644 --- a/rcs/rcs_nn_elided.py +++ b/rcs/rcs_nn_elided.py @@ -31,23 +31,25 @@ def factor_width(width): def ct_pair_prob(sim, q1, q2): - r = [0] * 4 + p1 = sim.prob(q1) + p2 = sim.prob(q2) + p1Hi = p1 > p2 + pHi = p1 if p1Hi else p2 + pLo = p2 if p1Hi else p1 + cState = abs(pHi - 0.5) > abs(pLo - 0.5) + t = q1 if p1Hi == cState else q2 - r[0] = sim.prob(q1) - r[1] = sim.prob(q2) - r[2] = r[0] - r[3] = q2 - if r[0] < r[1]: - r[3] = q1 - r[2] = r[1] - - return r + return cState, t def cz_shadow(sim, q1, q2, anti = False): - prob1, prob2, prob_max, t = ct_pair_prob(sim, q1, q2) - if ((not anti) and (prob_max > (0.5 + epsilon))) or (anti and (prob_max < (0.5 - epsilon))): + if (anti): + sim.x(q1) + cState, t = ct_pair_prob(sim, q1, q2) + if cState: sim.z(t) + if (anti): + sim.x(q1) def cx_shadow(sim, c, t, anti = False): diff --git a/rcs/rcs_nn_elided_time.py b/rcs/rcs_nn_elided_time.py index 0cf2228..bb20cb7 100644 --- a/rcs/rcs_nn_elided_time.py +++ b/rcs/rcs_nn_elided_time.py @@ -15,10 +15,6 @@ from pyqrack import QrackSimulator, Pauli -# sin(math.pi / 4) / 2 -epsilon = 0.353553390593273762 - - def factor_width(width): row_len = math.floor(math.sqrt(width)) while (((width // row_len) * row_len) != width): @@ -31,23 +27,25 @@ def factor_width(width): def ct_pair_prob(sim, q1, q2): - r = [0] * 4 - - r[0] = sim.prob(q1) - r[1] = sim.prob(q2) - r[2] = r[0] - r[3] = q2 - if r[0] < r[1]: - r[3] = q1 - r[2] = r[1] + p1 = sim.prob(q1) + p2 = sim.prob(q2) + p1Hi = p1 > p2 + pHi = p1 if p1Hi else p2 + pLo = p2 if p1Hi else p1 + cState = abs(pHi - 0.5) > abs(pLo - 0.5) + t = q1 if p1Hi == cState else q2 - return r + return cState, t def cz_shadow(sim, q1, q2, anti = False): - prob1, prob2, prob_max, t = ct_pair_prob(sim, q1, q2) - if ((not anti) and (prob_max > (0.5 + epsilon))) or (anti and (prob_max < (0.5 - epsilon))): + if (anti): + sim.x(q1) + cState, t = ct_pair_prob(sim, q1, q2) + if cState: sim.z(t) + if (anti): + sim.x(q1) def cx_shadow(sim, c, t, anti = False): diff --git a/rcs/sycamore_2019_elided.py b/rcs/sycamore_2019_elided.py index db8dd09..e4a05e2 100644 --- a/rcs/sycamore_2019_elided.py +++ b/rcs/sycamore_2019_elided.py @@ -13,10 +13,6 @@ from pyqrack import QrackSimulator, Pauli -# sin(math.pi / 4) / 2 -epsilon = 0.353553390593273762 - - def factor_width(width): col_len = math.floor(math.sqrt(width)) while (((width // col_len) * col_len) != width): @@ -29,23 +25,25 @@ def factor_width(width): def ct_pair_prob(sim, q1, q2): - r = [0] * 4 - - r[0] = sim.prob(q1) - r[1] = sim.prob(q2) - r[2] = r[0] - r[3] = q2 - if r[0] < r[1]: - r[3] = q1 - r[2] = r[1] + p1 = sim.prob(q1) + p2 = sim.prob(q2) + p1Hi = p1 > p2 + pHi = p1 if p1Hi else p2 + pLo = p2 if p1Hi else p1 + cState = abs(pHi - 0.5) > abs(pLo - 0.5) + t = q1 if p1Hi == cState else q2 - return r + return cState, t def cz_shadow(sim, q1, q2, anti = False): - prob1, prob2, prob_max, t = ct_pair_prob(sim, q1, q2) - if ((not anti) and (prob_max > (0.5 + epsilon))) or (anti and (prob_max < (0.5 - epsilon))): + if (anti): + sim.x(q1) + cState, t = ct_pair_prob(sim, q1, q2) + if cState: sim.z(t) + if (anti): + sim.x(q1) def cx_shadow(sim, c, t, anti = False): @@ -146,8 +144,8 @@ def bench_qrack(width, depth): if ((b1 < patch_bound) and (b2 >= patch_bound)) or ((b2 < patch_bound) and (b1 >= patch_bound)): # This is our version of ("semi-classical") gate "elision": - prob1, prob2, prob_max, t = ct_pair_prob(patch_sim, b1, b2) - if prob_max > (0.5 + epsilon): + cState, t = ct_pair_prob(patch_sim, b1, b2) + if cState: # FSim controlled phase patch_sim.u(t, 0, 0, -math.pi / 6) diff --git a/rcs/sycamore_2019_elided_time.py b/rcs/sycamore_2019_elided_time.py index 90a9b1a..2400cc0 100644 --- a/rcs/sycamore_2019_elided_time.py +++ b/rcs/sycamore_2019_elided_time.py @@ -13,10 +13,6 @@ from pyqrack import QrackSimulator, Pauli -# sin(math.pi / 4) / 2 -epsilon = 0.353553390593273762 - - def factor_width(width): col_len = math.floor(math.sqrt(width)) while (((width // col_len) * col_len) != width): @@ -29,23 +25,25 @@ def factor_width(width): def ct_pair_prob(sim, q1, q2): - r = [0] * 4 - - r[0] = sim.prob(q1) - r[1] = sim.prob(q2) - r[2] = r[0] - r[3] = q2 - if r[0] < r[1]: - r[3] = q1 - r[2] = r[1] + p1 = sim.prob(q1) + p2 = sim.prob(q2) + p1Hi = p1 > p2 + pHi = p1 if p1Hi else p2 + pLo = p2 if p1Hi else p1 + cState = abs(pHi - 0.5) > abs(pLo - 0.5) + t = q1 if p1Hi == cState else q2 - return r + return cState, t def cz_shadow(sim, q1, q2, anti = False): - prob1, prob2, prob_max, t = ct_pair_prob(sim, q1, q2) - if ((not anti) and (prob_max > (0.5 + epsilon))) or (anti and (prob_max < (0.5 - epsilon))): + if (anti): + sim.x(q1) + cState, t = ct_pair_prob(sim, q1, q2) + if cState: sim.z(t) + if (anti): + sim.x(q1) def cx_shadow(sim, c, t, anti = False): @@ -141,8 +139,8 @@ def bench_qrack(width, depth): if ((b1 < patch_bound) and (b2 >= patch_bound)) or ((b2 < patch_bound) and (b1 >= patch_bound)): # This is our version of ("semi-classical") gate "elision": - prob1, prob2, prob_max, t = ct_pair_prob(patch_sim, b1, b2) - if prob_max > (0.5 + epsilon): + cState, t = ct_pair_prob(patch_sim, b1, b2) + if cState: # FSim controlled phase patch_sim.u(t, 0, 0, -math.pi / 6)