Created
July 13, 2022 23:59
-
-
Save Strilanc/9a4560d5be902cfcd466fab6304913a2 to your computer and use it in GitHub Desktop.
Code to convert a stim.Circuit into an equivalent stim.Tableau and a stim.Tableau into an equivalent stim.Circuit. The circuit decomposition isn't efficient but it's simple to write.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from typing import List | |
import stim | |
def circuit_to_tableau(circuit: stim.Circuit) -> stim.Tableau: | |
s = stim.TableauSimulator() | |
s.do_circuit(circuit) | |
return s.current_inverse_tableau() ** -1 | |
def tableau_to_circuit(tableau: stim.Tableau) -> stim.Circuit: | |
remaining = tableau.inverse() | |
recorded_circuit = stim.Circuit() | |
def do(gate: str, targets: List[int]): | |
recorded_circuit.append(gate, targets) | |
remaining.append(stim.Tableau.from_named_gate(gate), targets) | |
n = len(remaining) | |
for col in range(n): | |
# Find a cell with an anti-commuting pair of Paulis. | |
for pivot_row in range(col, n): | |
px = remaining.x_output_pauli(col, pivot_row) | |
pz = remaining.z_output_pauli(col, pivot_row) | |
if px and pz and px != pz: | |
break | |
else: | |
raise NotImplementedError("Failed to find a pivot cell") | |
# Move the pivot to the diagonal. | |
if pivot_row != col: | |
do("SWAP", [pivot_row, col]) | |
# Transform the pivot to X->X, Z->Z. | |
px = remaining.x_output_pauli(col, col) | |
if px == 3: | |
do("H", [col]) | |
elif px == 2: | |
do("H_XY", [col]) | |
pz = remaining.z_output_pauli(col, col) | |
if pz == 2: | |
do("H_YZ", [col]) | |
# Use the pivot to remove all other terms in the X observable. | |
for row in range(col + 1, n): | |
px = remaining.x_output_pauli(col, row) | |
if px: | |
do("C" + "_XYZ"[px], [col, row]) | |
# Use the pivot to remove all other terms in the Z observable. | |
for row in range(col + 1, n): | |
pz = remaining.z_output_pauli(col, row) | |
if pz: | |
do("XC" + "_XYZ"[pz], [col, row]) | |
# Fix pauli signs. | |
if remaining.z_output(col).sign == -1: | |
do("X", [col]) | |
if remaining.x_output(col).sign == -1: | |
do("Z", [col]) | |
# The column is now solved. | |
# By some sort of symmetry this also solves the row. | |
return recorded_circuit |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment