diff --git a/python/quantum-pecos/src/pecos/qeclib/steane/decoders/lookup.py b/python/quantum-pecos/src/pecos/qeclib/steane/decoders/lookup.py index 9d386dc6..5cb10e9e 100644 --- a/python/quantum-pecos/src/pecos/qeclib/steane/decoders/lookup.py +++ b/python/quantum-pecos/src/pecos/qeclib/steane/decoders/lookup.py @@ -27,7 +27,7 @@ def __init__( syndromes: CReg, raw_syn: CReg, pf: Bit, - flag: Bit, + flag: CReg, flags: CReg, scratch: CReg, ): @@ -96,7 +96,7 @@ def __init__( syndromes: CReg, raw_syn: CReg, pf: Bit, - flag: Bit, + flag: CReg, flags: CReg, scratch: CReg, pf_bit_copy: Bit | None = None, diff --git a/python/quantum-pecos/src/pecos/qeclib/steane/steane_class.py b/python/quantum-pecos/src/pecos/qeclib/steane/steane_class.py index 826b36b2..4fce47f2 100644 --- a/python/quantum-pecos/src/pecos/qeclib/steane/steane_class.py +++ b/python/quantum-pecos/src/pecos/qeclib/steane/steane_class.py @@ -15,6 +15,7 @@ from warnings import warn from pecos.qeclib.steane.decoders.lookup import ( + FlagLookupQASMActiveCorrectionX, FlagLookupQASMActiveCorrectionZ, ) from pecos.qeclib.steane.gates_sq import paulis, sqrt_paulis @@ -496,6 +497,160 @@ def qec(self, flag: Bit | None = None): block.extend(If(self.flags != 0).Then(flag.set(1))) return block + def qec_steane( + self, + aux: Steane, + reject_x: Bit | None = None, + reject_z: Bit | None = None, + flag_x: Bit | None = None, + flag_z: Bit | None = None, + rus_limit: int | None = None, + ) -> Block: + """Run a Steane-type error-correction cycle of this code.""" + return Block( + self.qec_steane_x( + aux, + reject=reject_x, + flag=flag_x, + rus_limit=rus_limit, + ), + self.qec_steane_z( + aux, + reject=reject_z, + flag=flag_z, + rus_limit=rus_limit, + ), + ) + + def qec_steane_x( + self, + aux: Steane, + reject: Bit | None = None, + flag: Bit | None = None, + rus_limit: int | None = None, + ) -> Block: + """Run a Steane-type error-correction cycle for X errors.""" + warn("Using experimental feature: qec_steane_x", stacklevel=2) + block = Block( + aux.px(reject=reject, rus_limit=rus_limit), + self.cx(aux), + aux.mz(), + self.syn_z.set(aux.syn_meas), + self.last_raw_syn_z.set(0), + self.pf_x.set(0), + FlagLookupQASMActiveCorrectionZ( + self.d, + self.syn_z, + self.syn_z, + self.last_raw_syn_z, + self.pf_x, + self.syn_z, + self.syn_z, + self.scratch, + ), + ) + if flag is not None: + block.extend(If(self.syn_z != 0).Then(flag.set(1))) + return block + + def qec_steane_z( + self, + aux: Steane, + reject: Bit | None = None, + flag: Bit | None = None, + rus_limit: int | None = None, + ) -> Block: + """Run a Steane-type error-correction cycle for Z errors.""" + warn("Using experimental feature: qec_steane_z", stacklevel=2) + block = Block( + aux.pz(reject=reject, rus_limit=rus_limit), + aux.cx(self), + aux.mx(), + self.syn_x.set(aux.syn_meas), + self.last_raw_syn_x.set(0), + self.pf_z.set(0), + FlagLookupQASMActiveCorrectionX( + self.d, + self.syn_x, + self.syn_x, + self.last_raw_syn_x, + self.pf_z, + self.syn_x, + self.syn_x, + self.scratch, + ), + ) + if flag is not None: + block.extend(If(self.syn_x != 0).Then(flag.set(1))) + return block + + def qec_tel( + self, + aux: Steane, + reject_x: Bit | None = None, + reject_z: Bit | None = None, + flag_x: Bit | None = None, + flag_z: Bit | None = None, + rus_limit: int | None = None, + ) -> Block: + """Run a teleportation-based error correction cycle.""" + return Block( + self.qec_tel_x(aux, reject_x, flag_x, rus_limit), + self.qec_tel_z(aux, reject_z, flag_z, rus_limit), + ) + + def qec_tel_x( + self, + aux: Steane, + reject: Bit | None = None, + flag: Bit | None = None, + rus_limit: int | None = None, + ) -> Block: + """Run a teleportation-based error correction cycle for X errors.""" + warn("Using experimental feature: qec_tel_x", stacklevel=2) + block = Block( + # teleport + aux.px(reject=reject, rus_limit=rus_limit), + aux.cx(self), + self.mz(), + If(self.log == 1).Then(aux.x()), + Permute(self.d, aux.d), + # update syndromes and pauli frame + self.last_raw_syn_x.set(0), + self.last_raw_syn_z.set(0), + self.syn_z.set(self.syn_meas), + self.pf_x.set(0), + ) + if flag is not None: + block.extend(If(self.syn_meas != 0).Then(flag.set(1))) + return block + + def qec_tel_z( + self, + aux: Steane, + reject: Bit | None = None, + flag: Bit | None = None, + rus_limit: int | None = None, + ) -> Block: + """Run a teleportation-based error correction cycle for Z errors.""" + warn("Using experimental feature: qec_tel_z", stacklevel=2) + block = Block( + # teleport + aux.pz(reject=reject, rus_limit=rus_limit), + self.cx(aux), + self.mx(), + If(self.log == 1).Then(aux.z()), + Permute(self.d, aux.d), + # update syndromes and pauli frame + self.last_raw_syn_x.set(0), + self.last_raw_syn_z.set(0), + self.syn_x.set(self.syn_meas), + self.pf_z.set(0), + ) + if flag is not None: + block.extend(If(self.syn_meas != 0).Then(flag.set(1))) + return block + def permute(self, other: Steane): """Permute this code block (including both quantum and classical registers) with another.""" block = Block(