Skip to content

Commit 7536d27

Browse files
committed
Merge branch 'development' into feat/pauli
2 parents 5fb9335 + cc28567 commit 7536d27

File tree

1 file changed

+114
-23
lines changed

1 file changed

+114
-23
lines changed

python/quantum-pecos/src/pecos/qeclib/steane/steane_class.py

Lines changed: 114 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
from typing import TYPE_CHECKING
1515
from warnings import warn
1616

17+
from pecos.qeclib.steane.decoders.lookup import (
18+
FlagLookupQASMActiveCorrectionZ,
19+
)
1720
from pecos.qeclib.steane.gates_sq import paulis, sqrt_paulis
1821
from pecos.qeclib.steane.gates_sq.hadamards import H
1922
from pecos.qeclib.steane.gates_tq import transversal_tq
@@ -162,9 +165,7 @@ def prep_t_plus_state(
162165
d=self.d,
163166
a=self.a,
164167
out=self.scratch,
165-
reject=self.scratch[
166-
2
167-
], # the first two bits of self.scratch are used by "out"
168+
reject=self.scratch[2], # the first two bits are used by "out"
168169
flag_x=self.flag_x,
169170
flag_z=self.flag_z,
170171
flags=self.flags,
@@ -268,6 +269,7 @@ def tdg(self, aux: Steane, reject: Bit | None = None, rus_limit: int | None = No
268269
)
269270

270271
# Begin Experimental: ------------------------------------
272+
271273
def nonft_t_tel(self, aux: Steane):
272274
"""Warning:
273275
This is experimental.
@@ -283,7 +285,7 @@ def nonft_t_tel(self, aux: Steane):
283285
aux.cx(self),
284286
self.mz(self.t_meas),
285287
If(self.t_meas == 1).Then(aux.x(), aux.sz()),
286-
Permute(self.d, aux.d),
288+
self.permute(aux),
287289
)
288290

289291
def t_tel(
@@ -306,7 +308,7 @@ def t_tel(
306308
aux.cx(self),
307309
self.mz(self.t_meas),
308310
If(self.t_meas == 1).Then(aux.x(), aux.sz()), # SZ/S correction.
309-
Permute(self.d, aux.d),
311+
self.permute(aux),
310312
)
311313

312314
def nonft_tdg_tel(self, aux: Steane):
@@ -324,7 +326,7 @@ def nonft_tdg_tel(self, aux: Steane):
324326
aux.cx(self),
325327
self.mz(self.tdg_meas),
326328
If(self.tdg_meas == 1).Then(aux.x(), aux.szdg()),
327-
Permute(self.d, aux.d),
329+
self.permute(aux),
328330
)
329331

330332
def tdg_tel(
@@ -347,8 +349,84 @@ def tdg_tel(
347349
aux.cx(self),
348350
self.mz(self.tdg_meas),
349351
If(self.t_meas == 1).Then(aux.x(), aux.szdg()), # SZdg/Sdg correction.
350-
Permute(self.d, aux.d),
352+
self.permute(aux),
353+
)
354+
355+
def t_cor(
356+
self,
357+
aux: Steane,
358+
reject: Bit | None = None,
359+
flag: Bit | None = None,
360+
rus_limit: int | None = None,
361+
):
362+
"""T gate via teleportation using fault-tolerant initialization of the T|+> state.
363+
364+
Applies active corrections of errors diagnozed by the measurement for gate teleportation.
365+
"""
366+
warn("Using experimental feature: t_cor", stacklevel=2)
367+
block = Block(
368+
# gate teleportation without logical correction
369+
aux.prep_t_plus_state(reject=reject, rus_limit=rus_limit),
370+
self.cx(aux),
371+
aux.mz(self.t_meas),
372+
# active error correction
373+
self.syn_z.set(aux.syn_meas),
374+
self.last_raw_syn_z.set(0),
375+
self.pf_x.set(0),
376+
FlagLookupQASMActiveCorrectionZ(
377+
self.d,
378+
self.syn_z,
379+
self.syn_z,
380+
self.last_raw_syn_z,
381+
self.pf_x,
382+
self.syn_z,
383+
self.syn_z,
384+
self.scratch,
385+
),
386+
# logical correction
387+
If(self.t_meas == 1).Then(self.sz()),
351388
)
389+
if flag is not None:
390+
block.extend(If(self.syn_z != 0).Then(flag.set(1)))
391+
return block
392+
393+
def tdg_cor(
394+
self,
395+
aux: Steane,
396+
reject: Bit | None = None,
397+
flag: Bit | None = None,
398+
rus_limit: int | None = None,
399+
):
400+
"""Tdg gate via teleportation using fault-tolerant initialization of the Tdg|+> state.
401+
402+
Applies active corrections of errors diagnozed by the measurement for gate teleportation.
403+
"""
404+
warn("Using experimental feature: t_cor", stacklevel=2)
405+
block = Block(
406+
# gate teleportation without logical correction
407+
aux.prep_tdg_plus_state(reject=reject, rus_limit=rus_limit),
408+
self.cx(aux),
409+
aux.mz(self.tdg_meas),
410+
# active error correction
411+
self.syn_z.set(aux.syn_meas),
412+
self.last_raw_syn_z.set(0),
413+
self.pf_x.set(0),
414+
FlagLookupQASMActiveCorrectionZ(
415+
self.d,
416+
self.syn_z,
417+
self.syn_z,
418+
self.last_raw_syn_z,
419+
self.pf_x,
420+
self.syn_z,
421+
self.syn_z,
422+
self.scratch,
423+
),
424+
# logical correction
425+
If(self.tdg_meas == 1).Then(self.szdg()),
426+
)
427+
if flag is not None:
428+
block.extend(If(self.syn_z != 0).Then(flag.set(1)))
429+
return block
352430

353431
# End Experimental: ------------------------------------
354432

@@ -370,19 +448,17 @@ def cz(self, target: Steane):
370448

371449
def m(self, meas_basis: str, log: Bit | None = None):
372450
"""Destructively measure the logical qubit in some Pauli basis."""
373-
block = Block(
374-
MeasDecode(
375-
q=self.d,
376-
meas_basis=meas_basis,
377-
meas=self.raw_meas,
378-
log_raw=self.log_raw,
379-
log=self.log,
380-
syn_meas=self.syn_meas,
381-
pf_x=self.pf_x,
382-
pf_z=self.pf_z,
383-
last_raw_syn_x=self.last_raw_syn_x,
384-
last_raw_syn_z=self.last_raw_syn_z,
385-
),
451+
block = MeasDecode(
452+
q=self.d,
453+
meas_basis=meas_basis,
454+
meas=self.raw_meas,
455+
log_raw=self.log_raw,
456+
log=self.log,
457+
syn_meas=self.syn_meas,
458+
pf_x=self.pf_x,
459+
pf_z=self.pf_z,
460+
last_raw_syn_x=self.last_raw_syn_x,
461+
last_raw_syn_z=self.last_raw_syn_z,
386462
)
387463
if log is not None:
388464
block.extend(log.set(self.log))
@@ -400,7 +476,7 @@ def mz(self, log: Bit | None = None):
400476
"""Logical destructive measurement of the logical Z operator."""
401477
return self.m("Z", log=log)
402478

403-
def qec(self, flag_bit: Bit | None = None):
479+
def qec(self, flag: Bit | None = None):
404480
block = ParallelFlagQECActiveCorrection(
405481
q=self.d,
406482
a=self.a,
@@ -416,6 +492,21 @@ def qec(self, flag_bit: Bit | None = None):
416492
pf_z=self.pf_z,
417493
scratch=self.scratch,
418494
)
419-
if flag_bit is not None:
420-
block.extend(If(self.flags != 0).Then(flag_bit.set(1)))
495+
if flag is not None:
496+
block.extend(If(self.flags != 0).Then(flag.set(1)))
497+
return block
498+
499+
def permute(self, other: Steane):
500+
"""Permute this code block (including both quantum and classical registers) with another."""
501+
block = Block(
502+
Permute(self.d, other.d),
503+
Permute(self.a, other.a),
504+
)
505+
for var_a, var_b in zip(self.vars, other.vars):
506+
if isinstance(var_a, CReg):
507+
block.extend(
508+
var_a.set(var_a ^ var_b),
509+
var_b.set(var_b ^ var_a),
510+
var_a.set(var_a ^ var_b),
511+
)
421512
return block

0 commit comments

Comments
 (0)