def path_pauli(self, crd_0, crd_1, err_type): """ Returns a minimum-length Pauli between two ancillas, given the type of error that joins the two. This function is awkward, because it works implicitly on the un-rotated surface code, first finding a "corner" (a place on the lattice for the path to turn 90 degrees), then producing two diagonal paths on the rotated lattice that go to and from this corner. """ err_type = err_type.upper() if self.boundary_conditions == 'open': pth_0 = [(x, crd_0[1]) for x in short_seq(crd_0[0], crd_1[0], None)] pth_1 = [(crd_1[0], y) for y in short_seq(crd_0[1], crd_1[1], None)] if self.boundary_conditions == 'rotated': mid_v = diag_intersection(crd_0, crd_1, self.layout.ancillas.values()) pth_0, pth_1 = diag_pth(crd_0, mid_v), diag_pth(mid_v, crd_1) elif self.boundary_conditions == 'closed': pth_0 = [(x, crd_0[1]) for x in short_seq(crd_0[0], crd_1[0], self.dx)] pth_1 = [(crd_1[0], y) for y in short_seq(crd_0[1], crd_1[1], self.dy)] #path on lattice, uses idxs p = [self.layout.map[crd] for crd in list(pth_0) + list(pth_1)] pl = sp.X(p) if err_type == 'X' else sp.Z(p) return pl
def xyx_check(): """ If BP works, than a chain consisting of X-Y-X errors will be corrected at d = 5. """ layout = sc.SCLayout(5) err = sp.X([15, 24, 33]) * sp.Z([24]) mdl = [0.9, 0.1 / 3, 0.1 / 3, 0.1 / 3]
def sprt_paulis(): """ Just taking a look at some Paulis to see if they're being reformatted correctly. """ sprt = range(5) paulis = [sp.X([0, 2, 4]) * sp.Y([1]), sp.Z([0, 1]) * sp.X([1, 3])] return [mw.pauli_to_tpls(pauli, sprt) for pauli in paulis]
def logicals(self): dx, dy = self.dx, self.dy if self.top == 'rough': x_pts = [self.map[(x, 1)] for x in range(0, 2 * dx, 2)] z_pts = [self.map[(0, y)] for y in range(1, 2 * dy + 1, 2)] elif self.top == 'smooth': x_pts = [self.map[(1, y)] for y in range(0, 2 * dy, 2)] z_pts = [self.map[(x, 0)] for x in range(1, 2 * dx + 1, 2)] else: raise ValueError("top type " "{} not allowed".format(self.top)) return [sp.X(x_pts), sp.Z(z_pts)]
def stabilisers(self): """ Sometimes it's convenient to have the stabilisers of a surface code, especially when doing a 2d example. """ stab_dict = {'X': {}, 'Z': {}} for key in stab_dict.keys(): for anc in self.ancillas[key]: d_set = [self.map[ad(anc, shft, self.l)] for shft in TC_SHIFTS] stab = sp.X(d_set) if key == "X" else sp.Z(d_set) stab_dict[key][self.map[anc]] = stab return stab_dict
def two_bit_bp(): """ Reproduce Figure 2a from Poulin/Chung 2008, using the BP from matched_weights.py. """ stabs = {2: sp.X([0, 1]), 3: sp.Z([0, 1])} err = sp.X([0]) mdl = [0.9, 0.1 / 3, 0.1 / 3, 0.1 / 3] g = mw.tanner_graph(stabs, err, mdl) b_list = [g.node[1]['prior']] # symmetry sez: identical on both qubits for _ in range(10): mw.propagate_beliefs(g, 1) b_list.append(mw.beliefs(g)[1]) return b_list
def logicals(self): x_1 = [self.map[(x, 1)] for x in _evens(self.l)] x_2 = [self.map[(1, y)] for y in _evens(self.l)] z_1 = [self.map[(x, 0)] for x in _odds(self.l)] z_2 = [self.map[(0, y)] for y in _odds(self.l)] return [sp.X(x_1), sp.X(x_2), sp.Z(z_1), sp.Z(z_2)]
# This big block of variables is meant to pre-compute a lot of the # stuff that goes into check_to_qubit for surface codes at import-time. g_14 = [{0}, {1}, {2}, {3}] g_24 = [{0, 1}, {1, 2}, {2, 3}] g_12 = [{0}, {1}] g_22 = [{0, 1}] _xxxx_com = list(sp.generated_group(g_14, g_24)) _zzzz_com = list(sp.generated_group(g_24, g_14)) _xx_com = list(sp.generated_group(g_12, g_22)) _zz_com = list(sp.generated_group(g_22, g_12)) _xxxx_acom = [sp.Z([0]) * p for p in sp.generated_group(g_14, g_24)] _zzzz_acom = [sp.X([0]) * p for p in sp.generated_group(g_24, g_14)] _xx_acom = [sp.Z([0]) * p for p in sp.generated_group(g_12, g_22)] _zz_acom = [sp.X([0]) * p for p in sp.generated_group(g_22, g_12)] def tpl_lst(pauli_lst, n_bits): return [str_sprt_to_tpl(p.str_sprt_pair(), range(n_bits)) for p in pauli_lst] _lpg_wrap = { ('XXXX', 0): tpl_lst(_xxxx_com, 4), ('XXXX', 1): tpl_lst(_xxxx_acom, 4), ('ZZZZ', 0): tpl_lst(_zzzz_com, 4), ('ZZZZ', 1): tpl_lst(_zzzz_acom, 4), ('XX', 0): tpl_lst(_xx_com, 2), ('XX', 1): tpl_lst(_xx_acom, 2),