Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
190 commits
Select commit Hold shift + click to select a range
26abfcd
create permutation file
inctechs Nov 25, 2024
2b74027
add function to create steane state prep circuit
inctechs Nov 26, 2024
010df06
add function preparing Steane code CSS object
inctechs Nov 27, 2024
714e8f7
Correct wrong stabilizer generators
inctechs Nov 28, 2024
af56986
add option to check for logical 0
inctechs Jan 28, 2025
a8b5e47
add set up for Simulation circuit
inctechs Jan 28, 2025
112c777
disable print statement removement
inctechs Jan 28, 2025
15ef182
Merge remote-tracking branch 'origin/main' into ft-stateprep-qubit-perm
inctechs Jan 28, 2025
4d49bef
Merge remote-tracking branch 'origin/main' into ft-stateprep-qubit-perm
inctechs Feb 7, 2025
e832caf
Merge remote-tracking branch 'origin/main' into ft-stateprep-qubit-perm
inctechs Feb 10, 2025
28de0e3
add utility function to get automorphism subgroup from generators
inctechs Feb 10, 2025
0bed263
add function to evaluate fault set overlap based on permutations
inctechs Feb 20, 2025
3e249b8
mandatory format changes (return -> Return)
inctechs Feb 20, 2025
2cb6521
Merge remote-tracking branch 'origin/main' into ft-stateprep-qubit-perm
inctechs Feb 20, 2025
27569f1
Merge remote-tracking branch 'origin/main' into ft-stateprep-qubit-perm
inctechs Mar 3, 2025
1d64f19
🎨 pre-commit fixes
pre-commit-ci[bot] Mar 3, 2025
acbabdb
guide heuristic gauss based on penalty columns/ CNOTs
inctechs Mar 3, 2025
1359027
move overlap search out and turn it into a standalone function
inctechs Mar 3, 2025
3d7529a
update heuristic SPC function to allow guiding information
inctechs Mar 3, 2025
9bac3af
🎨 pre-commit fixes
pre-commit-ci[bot] Mar 3, 2025
a15c6e1
add method to permute qubits of StatePreparationCircuit
inctechs Mar 5, 2025
3beda63
Ignore missing library stubs sympy.
pehamTom Mar 5, 2025
2481cbb
add method that checks overlap of fault sets to SPC class
inctechs Mar 5, 2025
79c60e3
add function to check mutual disjunctness
inctechs Mar 7, 2025
924b1d2
add automorphism as optional property to CSSCode class
inctechs Mar 7, 2025
277d946
Merge branch 'main' into ft-stateprep-qubit-perm
pehamTom Mar 14, 2025
92143b3
Simulation steane ftsp (#383)
pehamTom Mar 14, 2025
1e97ab1
Allow steane-type FTSP with only two circuits.
pehamTom Mar 14, 2025
c18c07e
Synthesis of state prep circuits in standard form.
pehamTom Mar 14, 2025
ef66114
Checks in simulation dependent on state.
pehamTom Mar 15, 2025
a09f00f
Merge branch 'ft-stateprep-qubit-perm' into standard-form-commutations
pehamTom Mar 15, 2025
52d2095
remove debug prints
inctechs Mar 17, 2025
288132c
Merge branch 'ft-stateprep-qubit-perm' of https://github.com/cda-tum/…
inctechs Mar 17, 2025
1d6e0dd
set up eval directory structure
inctechs Mar 18, 2025
705876b
add z_observable flag for z errors
inctechs Mar 18, 2025
fff679e
🎨 pre-commit fixes
pre-commit-ci[bot] Mar 18, 2025
a04dd7c
missing comma
inctechs Mar 18, 2025
ae7a1dd
Merge remote-tracking branch 'refs/remotes/origin/ft-stateprep-qubit-…
inctechs Mar 18, 2025
31cc107
Revert "add z_observable flag for z errors"
inctechs Mar 18, 2025
e08521d
Canonical form circuits for Steane-type FTSP.
pehamTom Mar 18, 2025
d9f72f4
add binomial error calulation for SteaneNDFTStatePrepSimulator
inctechs Mar 19, 2025
03bba84
prepare simulation
inctechs Mar 19, 2025
48e484d
update cc_4_8_8 circuits
inctechs Mar 19, 2025
1094955
change cc_6_6_6 from qasm3 to qasm2
inctechs Mar 19, 2025
a5e4877
Bugged implementation.
pehamTom Mar 19, 2025
e05ba10
add new headers for binomial errors in csv
inctechs Mar 19, 2025
a8ae963
remove falsly tracked files
inctechs Mar 19, 2025
0450ed5
Second attempt.
pehamTom Mar 19, 2025
f97238b
Fix bug in Steane Type measurement regarding measurement order.
pehamTom Mar 19, 2025
c27efc5
Merge remote-tracking branch 'origin/ft-stateprep-qubit-perm' into ft…
pehamTom Mar 19, 2025
7d61efc
Random CNOT Permutation.
pehamTom Mar 20, 2025
5de6e3c
add circuits for cc_488 of distance 7
inctechs Mar 21, 2025
c57903a
update sim file to include distance 7 cc488
inctechs Mar 21, 2025
65679e9
Merge branch 'ft-stateprep-qubit-perm' of https://github.com/cda-tum/…
inctechs Mar 21, 2025
9c6587f
correct crucial typo
inctechs Mar 24, 2025
e0aa0be
Speed up LUT creation.
pehamTom Mar 24, 2025
eda6704
Merge remote-tracking branch 'origin/ft-stateprep-qubit-perm' into ft…
pehamTom Mar 24, 2025
52f6b09
Remove old function.
pehamTom Mar 24, 2025
b4e07ec
Remove another old function.
pehamTom Mar 24, 2025
5e7f906
Merge branch 'ft-stateprep-qubit-perm' into standard-form-commutations
pehamTom Mar 24, 2025
b6ec765
Fix index error in permutation generation.
pehamTom Mar 25, 2025
fef08e7
Steane-type check for Z errors.
pehamTom Mar 25, 2025
6540dc2
Remove pheno noise.
pehamTom Mar 25, 2025
663c7a4
Merge branch 'ft-stateprep-qubit-perm' into standard-form-commutations
pehamTom Mar 25, 2025
5c70209
Noise on ancilla.
pehamTom Mar 26, 2025
78e8594
Eval scripts for canonical Steane State Prep.
pehamTom Mar 26, 2025
1ac2a39
edit heuristic_gauss
inctechs Mar 26, 2025
d8cb475
add function to find next error
inctechs Mar 26, 2025
e34ae29
change check mutual disjunctness function
inctechs Mar 26, 2025
0d86484
change distance based fault set calculation
inctechs Mar 26, 2025
9471f0d
change build funciton for cnot circuit
inctechs Mar 26, 2025
017a640
Merge remote-tracking branch 'origin/ft-stateprep-qubit-perm' into ft…
inctechs Mar 26, 2025
90357d6
reference based heuristic changed to reference fault sets and speed ups
inctechs Mar 28, 2025
06ed523
define default for faulst set overlap check
inctechs Mar 28, 2025
77b4155
Fix canonical permutation.
pehamTom Mar 31, 2025
4a4688d
Merge remote-tracking branch 'origin/ft-stateprep-qubit-perm' into ft…
pehamTom Mar 31, 2025
33970ba
Removed old variable.
pehamTom Apr 1, 2025
945449a
Improve memory usage.
pehamTom Apr 2, 2025
4f1dba3
Remove unnecessary stabilizer measurements in simulation.
pehamTom Apr 3, 2025
599d0af
Indent
pehamTom Apr 7, 2025
925ea2e
Merge branch 'standard-form-commutations' into ft-stateprep-qubit-perm
pehamTom Apr 7, 2025
f18def0
🎨 pre-commit fixes
pre-commit-ci[bot] Apr 7, 2025
ff4ac1d
update octagon distance 7 simulation circuits
inctechs Apr 7, 2025
f67bdb4
add scripts for distance 7 and private mac simulation
inctechs Apr 7, 2025
3a4f838
new circuit folder structure and add hexagonal d7 circuits
inctechs Apr 8, 2025
210ed96
correct simulation script and expand it to include hexagonal d7 circuits
inctechs Apr 8, 2025
d2901f4
change C3 and C4 of hexd7 code to be reproduceable
inctechs Apr 8, 2025
18b6805
heuristic indep of SPC (only code) add 2 error check
inctechs Apr 8, 2025
c817945
clean up StatePreparationCircuit Class add variables to heuristic
inctechs Apr 8, 2025
461ea1b
add variable descriptions
inctechs Apr 8, 2025
e3bb849
add fs overlap check to circuit and add Z logical to equivalence check
inctechs Apr 8, 2025
a8be98c
improve CNOT count of C4 for the distance 7 octagon code
inctechs Apr 8, 2025
168fb96
remove unwanted csv files and change propabilities
inctechs Apr 11, 2025
7d18b2f
add functionality to start z error sim
inctechs Apr 11, 2025
a1ceeb7
remove print statements when constructing heuristic circuit
inctechs Apr 11, 2025
6e95f6c
Fix bug in simulator circuit construction.
pehamTom Apr 14, 2025
588316a
Merge remote-tracking branch 'origin/main' into ft-stateprep-qubit-perm
pehamTom May 13, 2025
6d28a6b
reinstate gaussian elimination, copy advanced logic
inctechs May 27, 2025
f07d5f4
clean up unused files and functions
inctechs May 27, 2025
95b3ffa
set up GaussianElimination Class
inctechs May 28, 2025
cd8ab5e
Merge remote-tracking branch 'origin' into ft-stateprep-qubit-perm
inctechs Jun 23, 2025
9c12af1
refactor heuristic elimination
inctechs Jun 23, 2025
8d04cdf
add test file for gaussian elimination and first test
inctechs Jun 24, 2025
5841154
🎨 pre-commit fixes
pre-commit-ci[bot] Jun 24, 2025
cf67d3d
remove Sympy from synthesis utils
inctechs Jun 24, 2025
73c97bd
Merge remote-tracking branch 'origin' into ft-stateprep-qubit-perm
inctechs Jun 24, 2025
0d97505
Merge branch 'ft-stateprep-qubit-perm' of https://github.com/cda-tum/…
inctechs Jun 24, 2025
ca943c4
solving mypy issues with sympy
inctechs Jun 25, 2025
ecfaa36
solve issue with qsample and pytest
inctechs Jun 25, 2025
de0580a
add integration test for basic elimination
inctechs Jun 26, 2025
89022a9
fix typo
inctechs Jun 26, 2025
3ea4ccb
add more tests
inctechs Jun 26, 2025
93d78a7
add docstrings and typehints
inctechs Jun 26, 2025
fbab28e
fix first mypy issues
inctechs Jun 26, 2025
ab0172f
add to API functions for both reference based and regular SP
inctechs Jun 27, 2025
f2c06e1
🎨 pre-commit fixes
pre-commit-ci[bot] Jun 27, 2025
0b84a10
Merge remote-tracking branch 'origin' into ft-stateprep-qubit-perm
inctechs Jun 27, 2025
cc68d86
Merge branch 'ft-stateprep-qubit-perm' of https://github.com/cda-tum/…
inctechs Jun 27, 2025
8e2a37e
solve more mypy issues
inctechs Jun 27, 2025
3262db8
fix final mypy issues in synthesis utils
inctechs Jun 27, 2025
c01e2a1
remove old legacy function after refactoring
inctechs Jun 30, 2025
5427d4c
change name of penalty columns to penalty cnots
inctechs Jun 30, 2025
31d37c7
change name from penalty cols to penalty cnots on state_prep.py
inctechs Jun 30, 2025
0c9a4b6
remove mypy issues in synthesis_utils.py
inctechs Jun 30, 2025
bd463a9
remove legacy entry points to legacy function
inctechs Jun 30, 2025
8c0e481
remove legacy function form encoding.py and swap it with class structure
inctechs Jun 30, 2025
321d687
add pytest.ini to git ignore to keep locally neotest working
inctechs Jun 30, 2025
d7a5206
add required positional argument 'code' to GaussianElimination
inctechs Jun 30, 2025
5d84f7a
Some minor refactoring.
pehamTom Jul 4, 2025
e05bf34
Removed unused method.
pehamTom Jul 24, 2025
6f63f96
Merge branch 'main' into ft-stateprep-qubit-perm
pehamTom Jul 28, 2025
70f5316
Add ideal qubits to noise model.
pehamTom Jul 28, 2025
fec9f2b
Added method to get unmeasured qubits of stim circuit.
pehamTom Jul 28, 2025
0764a88
Start refactoring noisy simulation.
pehamTom Jul 28, 2025
7734528
remove linter flag T201 for avoiding print removal
inctechs Jul 28, 2025
597e51e
remove automorphism functionality from CSSCode class
inctechs Jul 28, 2025
c2efbd9
remove sympy dependency from pyproject.toml
inctechs Jul 28, 2025
31a9c8d
delete stateprep docs (previously removed on the master)
inctechs Jul 28, 2025
971c6ff
Refactor Simulation functionality.
pehamTom Jul 29, 2025
c15ddc7
Merge branch 'ft-stateprep-qubit-perm' of https://github.com/cda-tum/…
inctechs Jul 29, 2025
3478a68
remove commented out code
inctechs Jul 29, 2025
8cf2622
rename EliminationCNOTSynthesizer and API functions
inctechs Jul 29, 2025
693867f
improve docstring of EliminationCNOTSynthesizer class
inctechs Jul 30, 2025
d699a12
rename _handle_stagnation to _reset_if_stuck
inctechs Jul 30, 2025
2966b4c
update docstring of _is_reduced() method
inctechs Jul 30, 2025
95de5b1
fix logical error in validate_inputs() method
inctechs Jul 30, 2025
f219dd2
fix type cast
inctechs Jul 30, 2025
3ec3bf7
remove _modify_matrix_structure() method
inctechs Jul 30, 2025
9e5d02a
separate greedy initialisation from fault set guided init
inctechs Jul 30, 2025
41a6a23
Merge branch 'main' into ft-stateprep-qubit-perm
inctechs Aug 13, 2025
6a9ed32
Merge branch 'main' into ft-stateprep-qubit-perm
inctechs Aug 13, 2025
0f1ad6f
🎨 pre-commit fixes
pre-commit-ci[bot] Aug 13, 2025
0b4696a
clean up repository and add personal playground directory
inctechs Aug 14, 2025
1b6df83
correct false initialization of fault set arrays
inctechs Aug 20, 2025
902d76c
TEMPORARILY remove standard form features to pass CI
inctechs Aug 20, 2025
c95e30f
fix double initialisation due to wrong order
inctechs Aug 20, 2025
871655e
temp add unused code instance to pass test
inctechs Aug 20, 2025
690dde1
adapt fault set handling to new PureFaultSet class structure
inctechs Aug 20, 2025
82edb70
adapt method to new indexing of fault sets
inctechs Aug 20, 2025
e9b1a1a
Merge branch 'main' into ft-stateprep-qubit-perm
inctechs Aug 20, 2025
ea8382f
Delete ecc_qiskit_wrapper.py
inctechs Aug 20, 2025
f2714cf
fix mypy issues
inctechs Aug 20, 2025
0f92bb8
add .qasm postfix to all circuit files to pass license hook
inctechs Aug 20, 2025
0fa238d
allow pickle despite security warnings
inctechs Aug 20, 2025
6ec2d45
temporarily allow testing of private methods
inctechs Aug 20, 2025
35679d9
Merge branch 'ft-stateprep-qubit-perm' of https://github.com/cda-tum/…
inctechs Aug 20, 2025
5d1ca34
fix error using variable prior to initialization
inctechs Aug 21, 2025
873d805
remove commented out code
inctechs Aug 21, 2025
59743f6
fix edge case of wrong error type parsed
inctechs Aug 21, 2025
6fefe7a
fix bug that propagation matrix does not get updated
inctechs Sep 12, 2025
81ff592
add plus state simulation capability
inctechs Sep 12, 2025
6520ef2
Merge remote-tracking branch 'origin/main' into ft-stateprep-qubit-perm
inctechs Sep 16, 2025
d677437
prepare simulations
inctechs Sep 17, 2025
c1fafa2
change probabilities
inctechs Sep 17, 2025
74a524f
add simulation results for 20,2,6 and rot surface code d5
inctechs Oct 8, 2025
983903b
Merge remote-tracking branch 'origin' into ft-stateprep-qubit-perm
inctechs Oct 8, 2025
cfe031a
change simulation propability
inctechs Oct 8, 2025
df89fbf
Merge branch 'main' of https://github.com/munich-quantum-toolkit/qecc…
inctechs Oct 27, 2025
c1d78ae
add (repaired) stim circuit and check matrices of QECCs
inctechs Oct 28, 2025
8d6746c
prepare simulation files for flag at origin sims
inctechs Oct 28, 2025
bf08cc3
update mac bash script for 0.001 sims
inctechs Oct 28, 2025
ea8ac5e
add 0.001 results for square octagon distance 7 code
inctechs Oct 28, 2025
139cb75
Merge remote-tracking branch 'origin/main' into ft-stateprep-qubit-perm
inctechs Nov 23, 2025
d001d50
rename circuit and check matrix files for consitency
inctechs Nov 23, 2025
3013bff
update fao simulation scripts to do remap of qubits
inctechs Nov 23, 2025
5020d48
fix CSV files (comma was missing)
inctechs Jan 15, 2026
654ad36
Merge branch 'main' of https://github.com/munich-quantum-toolkit/qecc…
inctechs Feb 15, 2026
e652cc3
🎨 pre-commit fixes
pre-commit-ci[bot] Feb 15, 2026
789ff50
add draft for SteaneFTSP docs
inctechs Feb 20, 2026
674ff96
WIP: save work, add current tests
inctechs Mar 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
207 changes: 207 additions & 0 deletions docs/SteaneFTSP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
---
file_format: mystnb
kernelspec:
name: python3
mystnb:
number_source_lines: true
---

```{code-cell} ipython3
:tags: [remove-cell]
%config InlineBackend.figure_formats = ['svg']
```

# Steane-type Fault-Tolerant State Preparation

This module provides automated synthesis for **Steane-type Fault-Tolerant State Preparation (FTSP)** circuits. This approach is particularly well-suited for quantum computing architectures that support a high degree of gate-level parallelism, such as trapped-ion and neutral atom quantum computers.

Unlike other methods that rely on measuring stabilizers directly on the data qubits (flag-based or standard syndrome extraction), Steane-type preparation works by initializing separate logical ancilla states and interacting them with the data state via transversal CNOT gates to detect errors.

## The Challenge: Error Cancellation

The core principle of Steane-type error detection is to copy errors from a data block to an ancilla block using transversal CNOTs and then measure the ancilla to detect the error.

However, if we consider more than just one error to occur under circuit level noise models, so errors can also happen on the ancilla qubits, then this approach can lead to a critical issue: **Error Cancellation**.
For example, if the data state and the ancilla state are prepared using the _exact same_ circuit structure, they suffer from identical propagated errors at identical locations error locations.

When two identical errors meet at a transversal CNOT gate, they can cancel each other out on the target (ancilla) while remaining on the control (data). For example, if an X-error occurs on the $i$-th qubit of both the data and ancilla, the transversal CNOT interaction may result in no detectable syndrome on the ancilla. Consequently, the error on the data block goes undetected, breaking fault tolerance.

### Solution: Structurally Distinct Circuits

To ensure fault tolerance, we must break this symmetry. We need to prepare logical states using circuits that are **logically equivalent** (they prepare the same quantum state) but **structurally distinct** regarding error propagation.
In other words, we want to synthesize circuits in which errors propagate differently, so that no matter where an error occurs, we still get a detectable syndrome on the ancilla.

#### Example: The Steane Code ($d=3$)

To see all of the above in action, let's consider the Steane code, which is a $[[7,1,3]]$ CSS code.
Since the code distance is $d=3$, it can correct up to $t=1$ error. Therefore, we only focus on single errors in the circuit and how they propagate.
We can find a state preparation circuit for the logical $|0\rangle_L$ state using the QECC synthesis tools. This will be our reference circuit, and we can analyze its fault set to understand how errors propagate through it.

```{code-cell} ipython3
from mqt.qecc import CSSCode

steane_code = CSSCode.from_code_name("Steane")
print(steane_code.stabs_as_pauli_strings())
```

```{code-cell} ipython3
from mqt.qecc.circuit_synthesis.state_prep import heuristic_prep_circuit

steane_circ = heuristic_prep_circuit(steane_code)
steane_circ.circ.draw('mpl')
```

Errors propagate this circuit in a specific way, which we can analyze by extracting the fault set.
The fault set lists propagated errors which are the result of a errors within the circuit.
For example, a single X-error on $q_1$ just before the last CNOT gate will propagate to a weight two error on qubits $q_1$ and $q_5$.
Looking at the fault set of the circuit above, we can see this error listed here.

```{code-cell} ipython3
steane_circ.compute_fault_sets()
steane_circ.x_fault_sets[0].faults
```

Note that the fault set is reduced and ignores stabilizer-equivalent errors. Meaning that the propagated error on $q_0$ and $q_4$ is not listed, since it is equivalent to the error on $q_1$ and $q_5$ up to multiplication by the first stabilizer generator $XXIIXXI$.

The bottom line is that the fault set above characterizes the error propagation of the given circuit. So if we were to synthesize a second circuit for the same logical state, that has a different fault set, we can be sure that no errors $E$ of weight up to $\text{wt}(E)=1$ can cancel each other out.

For this, QECC provides a function called `heuristic_reference_prep_circuit` which takes a reference circuit and its fault set as input and tries to find a new circuit that avoids the same faults.

```{code-cell} ipython3
from mqt.qecc.circuit_synthesis.state_prep import heuristic_reference_prep_circuit

steane_circ_alt = heuristic_reference_prep_circuit(steane_code, ref_x_fs=steane_circ.x_fault_sets[0].faults)
steane_circ_alt.circ.draw('mpl')

```

```{code-cell} ipython3
steane_circ_alt.compute_fault_sets()
steane_circ_alt.x_fault_sets[0].faults
```

The two fault sets are distinct also under multiplication by stabilizers. One can verify this by multiplying each of the propagated errors with the $X$ stabilizer generators of the Steane Code and ensuring that errors are not equivalent.

## The 4-Circuit Protocol (Distance $\ge 5$)

For higher-distance codes ($d \geq 5$), simply avoiding identical errors is not enough. We must ensure that the verification process itself does not introduce high-weight errors that go undetected.

This module implements a constant-overhead protocol that uses **four specific circuits** to guarantee strict fault tolerance. This protocol is general and works even for codes without symmetries, such as the $[[17,1,5]]$ color code.

### The Protocol Structure

The protocol requires synthesizing four unique circuits ($C_1, C_2, C_3, C_4$) that interact in a specific sequence:

1. **$C_1$ (Data Candidate):** The initial state we wish to prepare.
2. **$C_2$ (X-Verifier):** An ancilla used to detect X-errors on $C_1$.
- _Constraint:_ Must have a distinct X-fault set from $C_1$.
3. **$C_3$ (Z-Verifier):** An ancilla used to detect Z-errors on $C_1$.
- _Constraint:_ Must have a distinct Z-fault set from _both_ $C_1$ and $C_2$ (since Z-errors can propagate backward from ancilla to data).
4. **$C_4$ (Verifier of the Verifier):** An ancilla used to detect X-errors on $C_3$.
- _Constraint:_ Ensures that the Z-verification step ($C_3$) did not introduce undetectable X-errors. It must be distinct from the relevant faults of the previous chains.

### Utility: Automated 4-Circuit Synthesis Wrapper

While you can call the synthesis API manually for each step, you can use the following custom helper function in your workflow to automatically generate the full suite of 4 mutually distinct circuits based on the protocol rules.

However, note that for codes with higher distance, the search space for circuits grows significantly, and hence the synthesis process might get stuck sometimes.
Therefore, this utility function is not guaranteed to always find a solution and might be more of a starting point for your own custom synthesis workflow.

```{code-cell} ipython3
import numpy as np
from mqt.qecc.circuit_synthesis import heuristic_prep_circuit
from mqt.qecc.circuit_synthesis.synthesis_utils import check_mutually_disjointness_spcs, get_fs_based_on_d

def synthesize_four_ft_circuits(c1_circuit):
"""
Synthesizes the four distinct state preparation circuits required
for Steane-type Fault-Tolerant State Preparation.

Args:
c1_circuit: The reference state preparation circuit (C1).

Returns:
List of 4 circuits [C1, C2, C3, C4] satisfying t-distinctness constraints.
"""
# ---------------------------------------------------------
# Step 1: Analyze Reference Circuit (C1)
# ---------------------------------------------------------
c1_x_faults, c1_z_faults = get_fs_based_on_d(c1_circuit)

# ---------------------------------------------------------
# Step 2: Synthesize X-Verifier (C2)
# Constraint: X-faults must be distinct from C1.
# ---------------------------------------------------------
c2_circuit = heuristic_reference_prep_circuit(c1_circuit.code, ref_x_fs=c1_x_faults)
#BUG: Distance is not properly initialized
c2_circuit.code.distance = c1_circuit.code.distance
c2_x_faults, c2_z_faults = get_fs_based_on_d(c2_circuit)

# ---------------------------------------------------------
# Step 3: Synthesize Z-Verifier (C3)
# Constraint: Z-faults must be distinct from BOTH C1 and C2.
# ---------------------------------------------------------
# Combine Z-faults from C1 and C2 to avoid them simultaneously
if c1_z_faults.size and c2_z_faults.size:
combined_z_faults = np.unique(np.vstack((c1_z_faults, c2_z_faults), dtype=np.int8), axis=0)
elif c1_z_faults.size:
combined_z_faults = c1_z_faults
elif c2_z_faults.size:
combined_z_faults = c2_z_faults
else:
# If no Z-faults exist that require distinctness, fallback to reusing circuits
return [c1_circuit, c2_circuit, c1_circuit, c2_circuit]

c3_circuit = heuristic_reference_prep_circuit(c1_circuit.code, ref_z_fs=combined_z_faults, guide_by_x=False)
#BUG: Distance is not properly initialized
c3_circuit.code.distance = c1_circuit.code.distance
c3_x_faults, c3_z_faults = get_fs_based_on_d(c3_circuit)

# ---------------------------------------------------------
# Step 4: Synthesize Final Verifier (C4)
# Constraint: X-faults distinct from C3, Z-faults distinct from C1 & C2.
# ---------------------------------------------------------
c4_circuit = heuristic_reference_prep_circuit(
c1_circuit.code,
ref_x_fs=c3_x_faults,
ref_z_fs=combined_z_faults,
guide_by_x=False
)

return [c1_circuit, c2_circuit, c3_circuit, c4_circuit]
```

### Automated Synthesis with the $[[17,1,5]]$ Color Code

The $[[17,1,5]]$ color code is a perfect candidate for this approach because it lacks the symmetries required by older manual construction methods. The QECC toolkit uses a "Fault-Set Guided Synthesis" algorithm to find these circuits automatically by backtracking whenever a constraint is violated.

```{code-cell} ipython3
from mqt.qecc.codes import SquareOctagonColorCode

soc = SquareOctagonColorCode(5)
c1 = heuristic_prep_circuit(soc)
#BUG: Distance is not properly initialized
c1.code.distance = soc.distance
c1.code.x_distance = soc.distance
c1.code.z_distance = soc.distance
c1c2c3c4 = synthesize_four_ft_circuits(c1)

```

## Simulation and Verification

Once the four circuits are generated, they form a complete fault-tolerant gadget. The expected behavior is that the logical error rate should scale with $O(p^{\lceil d/2 \rceil})$, and the circuit should satisfy strict fault tolerance (no error of weight $t \le (d-1)/2$ leads to a logical failure).

```{code-cell} ipython3
from mqt.qecc.circuit_synthesis.simulation import SteaneNDFTStatePrepSimulator
simulation = SteaneNDFTStatePrepSimulator(
circ1=c1c2c3c4[0].circ.to_qiskit_circuit(),
circ2=c1c2c3c4[1].circ.to_qiskit_circuit(),
circ3=c1c2c3c4[2].circ.to_qiskit_circuit(),
circ4=c1c2c3c4[3].circ.to_qiskit_circuit(),
code=soc
)
ps = [0.007,0.006,0.005, 0.004, 0.003, 0.002, 0.001]
# simulation.plot_state_prep(ps, min_errors=10, p_idle_factor=0.01)

```
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ self
installation
LightsOutDecoder
StatePrep
SteaneFTSP
CatStates
CodeSwitching
Encoders
Expand Down
82 changes: 82 additions & 0 deletions scripts/ft_stateprep/canonical_steane/estimate_canonical.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Copyright (c) 2023 - 2026 Chair for Design Automation, TUM
# All rights reserved.
#
# SPDX-License-Identifier: MIT
#
# Licensed under the MIT License

"""Estimate logical error rate for CSS state preparation circuits for a given code and physical error rate."""

from __future__ import annotations

import argparse

from mqt.qecc import CSSCode
from mqt.qecc.circuit_synthesis import SteaneNDFTStatePrepSimulator, heuristic_prep_circuit
from mqt.qecc.circuit_synthesis.state_prep import canonical_steane_type_prep_circuits, random_steane_type_prep_circuits
from mqt.qecc.codes import HexagonalColorCode, SquareOctagonColorCode

codes = {"golay": CSSCode.from_code_name("golay"), "hex": HexagonalColorCode(7), "sqoct": SquareOctagonColorCode(7)}


def main() -> None:
"""Run the logical error rate estimation for a given code and physical error rate."""
parser = argparse.ArgumentParser(description="Estimate logical error rate for CSS state preparation circuits")
parser.add_argument(
"code",
type=str,
help="Code for which to estimate logical error rate. Available codes: " + ", ".join(codes),
)
parser.add_argument("-p", "--p_error", type=float, help="Physical error rate")
parser.add_argument("-n", "--n_errors", type=int, default=500, help="Number of errors to sample")
parser.add_argument(
"--perm",
type=str,
default="canonical",
help="Permutation for state preparation. Can be 'canonical' or 'random'",
)
parser.add_argument(
"-e", "--error_type", type=str, default="X", help="Type of error to use for simulation. Can be 'X' or 'Z'."
)

args = parser.parse_args()
code_name = args.code
if code_name in codes:
code = codes[code_name]
else:
raise ValueError("Code " + code_name + " not available. Available codes: " + ", ".join(codes))

if args.perm == "canonical":
qc1, qc2, qc3, qc4 = canonical_steane_type_prep_circuits(code)
perm = "canonical"
elif args.perm == "random":
qc1, qc2, qc3, qc4, perm = random_steane_type_prep_circuits(code)
else:
raise ValueError("Permutation " + args.perm + " not available. Available permutations: 'canonical, random'")

sim = SteaneNDFTStatePrepSimulator(
qc1, qc2, code, qc3, qc4, check_circuit=heuristic_prep_circuit(code, zero_state=False).circ
)
sim.set_p(args.p_error, args.p_error * 0.01)

if args.error_type == "X":
p_l, r_a, num_logical_errors, total_shots, p_l_error, r_a_error = sim.logical_error_rate(
min_errors=args.n_errors
)
elif args.error_type == "Z":
p_l, r_a, num_logical_errors, total_shots, p_l_error, r_a_error = sim.secondary_logical_error_rate(
min_errors=args.n_errors
)
else:
msg = "Error type should be either X or Z."
raise ValueError(msg)

print(
";".join([
str(x) for x in [args.p_error, p_l, r_a, num_logical_errors, total_shots, p_l_error, r_a_error, perm]
Comment thread Fixed
Comment thread Fixed
Comment thread Fixed
Comment thread Fixed
Comment thread Fixed
Comment thread Fixed
])
)


if __name__ == "__main__":
main()
21 changes: 21 additions & 0 deletions scripts/ft_stateprep/canonical_steane/run_parallel.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash
# Copyright (c) 2023 - 2026 Chair for Design Automation, TUM
# All rights reserved.
#
# SPDX-License-Identifier: MIT
#
# Licensed under the MIT License

declare -a p=("0.001" "0.0015" "0.002" "0.0025" "0.003" "0.0035" "0.004" "0.0045" "0.005" "0.0055" "0.006" "0.0065" "0.007" "0.0075" "0.008" "0.0085" "0.009" "0.0095" "0.01")

echo "p;p_l;r_a;num_logical_errors;total_shots;p_l_error;r_a_error" > "$1.csv"

run_and_write() {
local res=$(python estimate_canonical.py ${@:2:$#-2} "-p" "${@: -1}")
local line="${@: -1};${res}"
(flock -e 200 echo $line >> "$1.csv") 200>lock
}

export -f run_and_write

parallel --load 16 --link run_and_write $@ ::: ${p[@]}
4 changes: 2 additions & 2 deletions scripts/ft_stateprep/eval/estimate_logical_error_rate.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

from mqt.qecc import CSSCode
from mqt.qecc.circuit_synthesis import (
NoisyNDFTStatePrepSimulator,
VerificationNDFTStatePrepSimulator,
gate_optimal_prep_circuit,
gate_optimal_verification_circuit,
heuristic_prep_circuit,
Expand Down Expand Up @@ -98,7 +98,7 @@ def main() -> None:
# load circuit from file
qc = QuantumCircuit.from_qasm_file(prefix / code_name / circ_file)

sim = NoisyNDFTStatePrepSimulator(
sim = VerificationNDFTStatePrepSimulator(
qc,
code=code,
p=args.p_error,
Expand Down
6 changes: 4 additions & 2 deletions scripts/ft_stateprep/eval/run_d7.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from qiskit import QuantumCircuit

from mqt.qecc.circuit_synthesis import (
NoisyNDFTStatePrepSimulator,
VerificationNDFTStatePrepSimulator,
)
from mqt.qecc.codes import SquareOctagonColorCode

Expand All @@ -38,7 +38,9 @@ def main() -> None:
lut_path = (Path(__file__) / "../luts/decoder_488_7.pickle").resolve()
with lut_path.open("rb") as f:
lut = pickle.load(f) # noqa: S301
sim = NoisyNDFTStatePrepSimulator(qc, code, decoder=lut, p=args.p_error, p_idle=args.p_idle_factor * args.p_error)
sim = VerificationNDFTStatePrepSimulator(
qc, code, decoder=lut, p=args.p_error, p_idle=args.p_idle_factor * args.p_error
)
res = sim.logical_error_rate(min_errors=args.n_errors)
print(",".join([str(x) for x in [args.p_error, *res]]))

Expand Down
18 changes: 18 additions & 0 deletions scripts/ft_stateprep/eval_circ_mod/check_matrix/eve_20_2_6.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
XIIIIIIIIXIXXIXXXXII
IXIIIIIIIXIIXXIIXXXX
IIXIIIIIIIXXIXXIXXXI
IIIXIIIIIIXIXXXXIXIX
IIIIXIIIIXXIXIIIXXXX
IIIIIXIIIXIXIIXXXXIX
IIIIIIXIIIXXIXIXXXXI
IIIIIIIXIXIXIIIIIIXI
IIIIIIIIXIXIXXXXXIIX
ZIIIIIIIIZIZZIZZZZII
IZIIIIIIIZIIZZIIZZZZ
IIZIIIIIIIZZIZZIZZZI
IIIZIIIIIIZIZZZZIZIZ
IIIIZIIIIZZIZIIIZZZZ
IIIIIZIIIZIZIIZZZZIZ
IIIIIIZIIIZZIZIZZZZI
IIIIIIIZIZIZIIIIIIZI
IIIIIIIIZIZIZZZZZIIZ
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
ZZZZIIIIIIIIIIIII
IZIZIIZZIIIIIIIII
IIIIZIIIZIIIZZIII
IIIIZZIIZZIIIIIII
IIZZIZZIIZZIIIZZI
IIIIIIZZIIZZIIIII
IIIIIIIIZZIIIZZII
IIIIIIIIIIZZIIIZZ
XXXXIIIIIIIIIIIII
IXIXIIXXIIIIIIIII
IIIIXIIIXIIIXXIII
IIIIXXIIXXIIIIIII
IIXXIXXIIXXIIIXXI
IIIIIIXXIIXXIIIII
IIIIIIIIXXIIIXXII
IIIIIIIIIIXXIIIXX
Loading
Loading