-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added documentation for FT state prep.
- Loading branch information
Showing
5 changed files
with
311 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,280 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"id": "26db7b98-afc0-48d5-846b-e4fb1fe9e6f4", | ||
"metadata": {}, | ||
"source": [ | ||
"# Fault tolerant state preparation of Pauli eigenstates for CSS codes\n", | ||
"\n", | ||
"The QECC package contains functionality for synthesizing and simulating fault tolerant and non-fault tolerant state preparation circuits for Pauli eigenstates of CSS codes.\n", | ||
"Currently it supports synthesizing circuits for preparing the $|0\\rangle_L^k$ and $|+\\rangle_L^k$ states of arbitrary $[[n,k,d]]$ CSS codes.\n", | ||
"\n", | ||
"## Synthesizing non-FT state preparation circuits\n", | ||
"\n", | ||
"A non-fault tolerant preparation circuit can be generated directly from a CSS code. Let's consider the [Steane code](https://errorcorrectionzoo.org/c/steane) which is a $[[7, 1, 3]]$ color code." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "f556173a-1657-403f-8226-bdb565c9b8ee", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"from mqt.qecc import CSSCode\n", | ||
"\n", | ||
"steane_code = CSSCode.from_code_name(\"Steane\")\n", | ||
"print(steane_code.stabs_as_pauli_strings())" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "b8e3bf10-7253-40f6-9b5d-ad6b85df6876", | ||
"metadata": {}, | ||
"source": [ | ||
"A state preparation circuit for the logical $|0\\rangle_L$ of this code is a circuit that generates a state that is stabilized by all of the above Pauli operators and the logical $Z_L$ operator of the Steane code. \n", | ||
"\n", | ||
"The code is small enough that we can generate a CNOT-optimal state preparation circuit for it:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "35cc5bff-74cf-4ebc-be24-bc614b08a15f", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"from mqt.qecc.ft_stateprep import gate_optimal_prep_circuit\n", | ||
"\n", | ||
"non_ft_sp = gate_optimal_prep_circuit(steane_code, zero_state=True, max_timeout=2)\n", | ||
"\n", | ||
"non_ft_sp.circ.draw(output=\"mpl\", initial_state=True)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "a648f3c7-1002-423d-99b9-f4d15b0d4cc3", | ||
"metadata": {}, | ||
"source": [ | ||
"We see that the minimal number of CNOTs required to prepare the logical $|0\\rangle_L$ circuit of the Steane code is $7$.\n", | ||
"\n", | ||
"## Synthesizing FT state preparation circuits\n", | ||
"The circuit above is not fault-tolerant. For example, an $X$ error on qubit $q_1$ before the last CNOT propagates to a weight $2$ X error on $q_1$ and $q_2$. This is to be expected since we apply two-qubit gates between the qubits of a single logical qubit. \n", | ||
"\n", | ||
"A common method to turn a non-FT protocol into a fault tolerant one is through post-selection. We can try to detect whether an error was propagated through the circuit and restart the preparation in case of a detection event. A circuit performing such measurements is called a *verification circuit*. \n", | ||
"\n", | ||
"Verification circuits need to be carefully constructed such that only stabilizers of the code are measured and no more measurements are performed than necessary. Finding good verification circuits is NP-complete.\n", | ||
"\n", | ||
"QECC can automatically generate optimal verification circuits." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "edb629ed-50d2-4be0-9345-d938c316a9ac", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"from mqt.qecc.ft_stateprep import gate_optimal_verification_circuit\n", | ||
"\n", | ||
"ft_sp = gate_optimal_verification_circuit(non_ft_sp)\n", | ||
"\n", | ||
"ft_sp.draw(output=\"mpl\", initial_state=True)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "9fd98702-1505-4f7e-a5d9-8510d36ec78b", | ||
"metadata": {}, | ||
"source": [ | ||
"We have just automatically generated the known FT state preparation circuit for the Steane\n", | ||
"code: [^1]. We see that if an X error happens on qubit $q_1$ before the last CNOT causes the verification circuit to measure a $-1$. \n", | ||
"\n", | ||
"## Simulating state preparation circuits\n", | ||
"\n", | ||
"If we want to see the probability of a logical error happening after post-selecting, QECC provides simulation utilities that can quickly generate results. We can simulate the non-FT and FT circuits and compare the results.\n", | ||
"\n", | ||
"[^1]: https://www.nature.com/articles/srep19578" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "9ccb7239-c669-432e-b195-b8f0887c83a3", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"from mqt.qecc.ft_stateprep import NoisyNDFTStatePrepSimulator\n", | ||
"\n", | ||
"p = 0.05\n", | ||
"\n", | ||
"non_ft_simulator = NoisyNDFTStatePrepSimulator(non_ft_sp.circ, code=steane_code, zero_state=True, p=p)\n", | ||
"ft_simulator = NoisyNDFTStatePrepSimulator(ft_sp, code=steane_code, zero_state=True, p=p)\n", | ||
"\n", | ||
"\n", | ||
"pl_non_ft, ra_non_ft, _, _ = non_ft_simulator.logical_error_rate(min_errors=10)\n", | ||
"pl_ft, ra_ft, _, _ = ft_simulator.logical_error_rate(min_errors=10)\n", | ||
"\n", | ||
"print(f\"Logical error rate for non-FT state preparation: {pl_non_ft}\")\n", | ||
"print(f\"Logical error rate for FT state preparation: {pl_ft}\")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "56258f47-3a31-4b95-a374-9b4d0725551a", | ||
"metadata": {}, | ||
"source": [ | ||
"The error rates seem quite close to each other. To properly judge the fault tolerance of the circuits we want to look at how the logical error rate scales with the physical error rate." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "3514dc4d-9346-4a60-b685-45241068585c", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"ps = [0.1, 0.05, 0.01, 0.008, 0.006, 0.004, 0.002, 0.001]\n", | ||
"\n", | ||
"non_ft_simulator.plot_state_prep(ps, min_errors=50, name=\"non-FT\")\n", | ||
"ft_simulator.plot_state_prep(ps, min_errors=50, name=\"FT\")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "d0e7d899-aa16-4252-8186-485465483df6", | ||
"metadata": {}, | ||
"source": [ | ||
"Indeed we observe a quadratic scaling for the fault tolerant state preparation circuit while the logical error rate scales linearly for the non-fault tolerant state preparation.\n", | ||
"\n", | ||
"## Beyond distance 3\n", | ||
"\n", | ||
"Distance 3 circuits are particularly simple for fault tolerant state preparation because for the $|0\\rangle_L$ we can completely ignore Z errors. Due to error degeneracy any Z error is equivalent to a weight 1 or 0 error. \n", | ||
"\n", | ||
"Additionally one has to pay special attention to the order of measurements in the verification circuits when more than one independent error in the state preparation circuit is considered. \n", | ||
"\n", | ||
"Because both error types are considered, the verification circuit now measures both X- and Z-stabilizers. Unforunately a Z error in an X measurement can propagate to the data qubits and vice versa for Z measurements. Therefore, if we check for Z errors after we have checked for X errors the measurements might introduce more X errors on the data qubits. We can check those again but that would just turn the situation around; now Z errors can propagate to the data qubits.\n", | ||
"\n", | ||
"Detecting such *hook errors* can be achieved via flag-fault tolerant stabilizer measurements [^2]. Usually, information from such hook errors is used to augment an error correction scheme. But we can also use these flags as additional measurements on which we post-select. If one of the flags triggers, this indicates that a hook error happened and we reset.\n", | ||
"\n", | ||
"By default QECC automatically performs such additional measurements when necessary. Let's consider a larger code to illustrate the point. The [square-octagon color code](https://errorcorrectionzoo.org/c/488_color) is defined on the following lattice:\n", | ||
"\n", | ||
"<img src=\"images/488_color_code.svg\" alt=\"Square-Octagon color code\" width=\"50%\">\n", | ||
"\n", | ||
"The distance 5 code uses 17 qubits from this lattice, i.e., we have a $[[17, 1, 5]]$ CSS code. Given the size of the code, synthesizing an optimal state preparation circuit might take a long time. QECC also has a fast heuristic state preparation circuit synthesis.\n", | ||
"\n", | ||
"[^2]: https://arxiv.org/abs/1708.02246" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "e77aa2f2-4920-4e1c-a84f-8511053a07b5", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"from mqt.qecc.ft_stateprep import heuristic_prep_circuit\n", | ||
"\n", | ||
"cc = CSSCode.from_code_name(\"cc_4_8_8\")\n", | ||
"cc_non_ft_sp = heuristic_prep_circuit(cc, zero_state=True, optimize_depth=True)\n", | ||
"\n", | ||
"cc_non_ft_sp.circ.draw(output=\"mpl\", initial_state=True, scale=0.7)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "6f29ff66-836e-4d11-ab8e-860325bdd7a9", | ||
"metadata": {}, | ||
"source": [ | ||
"Even though optimal state preparation circuit synthesis seems out of range we can still synthesize good verification circuits in a short time if we give an initial guess on how many measurements we will need." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "6c43c729-d303-4d99-b519-aa87a9fb2342", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"cc_ft_sp = gate_optimal_verification_circuit(cc_non_ft_sp, max_timeout=2, max_ancillas=3)\n", | ||
"\n", | ||
"cc_ft_sp.draw(output=\"mpl\", initial_state=True, fold=-1, scale=0.2)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "2af33324-99db-48b0-aef8-4ef93546d3b1", | ||
"metadata": {}, | ||
"source": [ | ||
"We see that the overhead for the verification overshadows the state preparation by a large margin. But this verification circuit is still much smaller than the naive variant of post-selecting on the stabilizer generators of the code." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "b16d84d5-3b82-4f0c-8aef-3a35f54d547d", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"from mqt.qecc.ft_stateprep import naive_verification_circuit\n", | ||
"\n", | ||
"cc_ft_naive = naive_verification_circuit(cc_non_ft_sp)\n", | ||
"\n", | ||
"print(f\"CNOTs required for naive FT state preparation: {cc_ft_naive.num_nonlocal_gates()}\")\n", | ||
"print(f\"CNOTs required for optimized FT state preparation: {cc_ft_sp.num_nonlocal_gates()}\")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "7be705a4-7732-43d5-b4e2-c13619e99703", | ||
"metadata": {}, | ||
"source": [ | ||
"We expect that the distance 5 color code should be prepared with a better logical error rate than the Steane code. And this is indeed the case:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "c81d9f32-af86-4388-9915-6d5be01efce3", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"cc_simulator = NoisyNDFTStatePrepSimulator(cc_ft_sp, code=cc, zero_state=True, p=p)\n", | ||
"\n", | ||
"ps = [0.1, 0.05, 0.01, 0.008, 0.006, 0.004, 0.002, 0.001, 0.0008, 0.0006, 0.0004, 0.0003]\n", | ||
"\n", | ||
"ft_simulator.plot_state_prep(ps, min_errors=50, name=\"Distance 3\") # simulate Steane code as comparison\n", | ||
"cc_simulator.plot_state_prep(ps, min_errors=50, name=\"Distance 5\")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "1ca531fc-cd09-45b4-af6e-7c47518ac895", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "python11", | ||
"language": "python", | ||
"name": "python11" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 5 | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,3 +15,4 @@ Library | |
DecodingRunInformation | ||
SamplePauliError | ||
LightsOutDecoder | ||
StatePrep |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
Fault tolerant state preparation | ||
================================ | ||
|
||
QECC provides functionality to synthesize and simulate state preparation circuits for logical basis states for arbitrary :math:`[[n, k, d]]` quantum CSS codes. | ||
|
||
.. currentmodule:: mqt.qecc.ft_stateprep | ||
|
||
Non-fault tolerant state preparation circuits can be synthesized using :function:`depth_optimal_state_prep_circuit`, :function:`gate_optimal_prep_circuit` and :function:`heuristic_prep_circuit`. | ||
|
||
.. automethod:: depth_optimal_state_prep_circuit | ||
|
||
.. automethod:: gate_optimal_state_prep_circuit | ||
|
||
.. automethod:: heuristic_state_prep_circuit | ||
|
||
These methods return a :class:`StatePrepCircuit` from which the circuit can be obtained as a qiskit :code:`QuantumCircuit` object via the :code:`circ` member. The :class:`StatePrepCircuit` class contains methods for computing the state preparation circuit's fault set. :class:`StatePrepCircuit` are given as input to the verification circuit synthesis methods which add verification measurements to the circuit such that postselection on +1 measurement results of these circuit outputs a state with a logical error rate on the order of :math:`O(p^{\frac{n-1}{2}})`. | ||
|
||
Gate-optimal verification circuits can be generated using the :function:`gate_optimal_verification_circuit` method. This method uses the SMT solver `Z3 <https://github.com/Z3Prover/z3>`_ for iteratively searching for better verification circuits. The search is guided by a :code:`min_timeout` and :code:`max_timeout` parameter. Initially, the search is only allowed to continue for the minimal amount of time. This time budget is successively increased until a solution is found. At this point the maximum number of CNOTs is reduced until the synthesis takes :code:`max_timeout` time or if the SAT solver manages to prove that no smaller circuit exists. | ||
|
||
.. automethod:: gate_optimal_verification_circuit | ||
|
||
If the optimal synthesis takes too long, the :function:`heuristic_verification_circuit` method can be used. This method reduces the synthesis of state preparation circuits to a set cover problem. Quality of solution can be traded with performance via the :code:`max_covering_sets` parameter. The smaller this parameter is set the lower the number of sets from which a covering is obtained. | ||
|
||
.. automethod:: heuristic_verification_circuit | ||
|
||
State preparation circuits can be simulated using the :class:`NoisyNDFTStatePrepSimulator` class. | ||
|
||
.. autoclass:: NoisyNDFTStatePrepSimulator |