-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ Partial equivalence checking (#375)
## Description Added a flag `checkPartialEquivalence` in order to decide whether to check for total equivalence or for partial equivalence. Two circuits are partially equivalent if, for each possible initial input state, they have the same probability for each measurement outcome. Therefore the state of not measured qubits (= garbage qubits), or phases are ignored. The Construction Checker and the Simulation Checker implement this by reducing the contribution of garbage qubits in the matrix/vector representation of the circuit. Additionally, all weights in the DD representation are set to their magnitude, such that different phases don't influence the result. The Alternating Checker implements it by checking that the resulting matrix representation is equal to a diagonal matrix, modulo garbage qubits (instead of checking that it is equal to the identity matrix). For more information, there is documentation in the file `PartialEquivalence.ipynb`. An additional feature are the automatically generated benchmarks for partial equivalence. The function `generatePartiallyEquivalentCircuits` generates pairs of circuits which are partially equivalent, following the method described in the paper [Partial Equivalence Checking of Quantum Circuits](https://arxiv.org/abs/2208.07564) in Section VI. B. Fixes issue #155 ## Checklist: <!--- This checklist serves as a reminder of a couple of things that ensure your pull request will be merged swiftly. --> - [x] The pull request only contains commits that are related to it. - [x] I have added appropriate tests and documentation. - [x] I have made sure that all CI jobs on GitHub pass. - [x] The pull request introduces no new warnings and follows the project's style guidelines. --------- Signed-off-by: burgholzer <burgholzer@me.com> Co-authored-by: burgholzer <burgholzer@me.com>
- Loading branch information
1 parent
a46794a
commit 4b5f383
Showing
33 changed files
with
10,941 additions
and
44 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 |
---|---|---|
@@ -1,4 +1,4 @@ | ||
[submodule "extern/mqt-core"] | ||
path = extern/mqt-core | ||
path = extern/mqt-core | ||
url = https://github.com/cda-tum/mqt-core.git | ||
branch = main |
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,192 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"id": "77a131e6", | ||
"metadata": {}, | ||
"source": [ | ||
"# Partial Equivalence Checking\n", | ||
"\n", | ||
"## Partial Equivalence vs. Total Equivalence\n", | ||
"\n", | ||
"Different definitions of quantum circuit equivalence have been proposed, with the most commonly used being total equivalence. \n", | ||
"Two circuits are considered totally equivalent when their matrix representations are exactly the same. \n", | ||
"However, it is often sufficient to consider observational equivalence, because the only way to extract information from a quantum circuit is through measurement. \n", | ||
"Therefore, partial equivalence has been defined, which is a weaker equality than total equivalence. \n", | ||
"Two circuits are considered partially equivalent if, for each possible input state, they have the same probabilities for each measurement outcome. \n", | ||
"In particular, partial equivalence doesn't consider qubits that are not measured or different phase angles for each measurement.\n", | ||
"\n", | ||
"This definition is especially useful for circuits that do not measure all of their qubits at the end, or where some qubits are initialized to a certain value at the beginning. \n", | ||
"We refer to the qubits that are initialized to a certain value at the beginning of the computation as *ancillary* qubits. \n", | ||
"Without loss of generality, we assume that these qubits are initially set to $|0\\rangle$. \n", | ||
"Any other initial state can be reached from the $|0\\rangle$ state by applying the appropriate gates. \n", | ||
"The remaining qubits are the qubits that hold the input state, and they are referred to as *data* qubits.\n", | ||
"\n", | ||
"Similarly, we differentiate between *measured* and *garbage* qubits. \n", | ||
"In order to read the output at the end of a circuit, a measurement is performed on some qubits, but not necessarily all of them. \n", | ||
"These qubits are the *measured* qubits. All qubits that are not measured are called the *garbage* qubits. \n", | ||
"Their final state doesn't influence the output we obtain from the computation. \n", | ||
"\n", | ||
"For a circuit $C$ we denote $P(t | \\psi, C)$ as the probability that the quantum circuit $C$ collapses to state $|t\\rangle$ upon a measurement on the measured qubits, \n", | ||
"given that the data qubits have the initial state $|\\psi\\rangle$. \n", | ||
"Two circuits $C_1$ and $C_2$ are considered partially equivalent if, for each initial state $|\\psi\\rangle$ of the data qubits and each final state $|t\\rangle$ of the measured qubits, \n", | ||
"it holds that $P(t|\\psi, C_1) = P(t|\\psi, C_2)$.\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "b9be796e", | ||
"metadata": {}, | ||
"source": [ | ||
"\n", | ||
"## Checking Partial Equivalence of Quantum Circuits\n", | ||
"\n", | ||
"Partial equivalence checking is a bit more costly than regular equivalence checking. \n", | ||
"It is necessary to reduce the contribution of garbage qubits and normalize the phase of each measurement outcome. \n", | ||
"Therefore, it is not enabled by default in QCEC. \n", | ||
"It can be activated using an option in the configuration parameters. \n", | ||
"If the option `check_partial_equivalence` is set to `True`, the equivalence checker will return `equivalent` not only for totally equivalent circuits, \n", | ||
"but also for partially equivalent circuits. The result will be `not_equivalent` if and only if the circuits are not partially equivalent. \n", | ||
"On the other hand, if the option `check_partial_equivalence` is set to `False`, then the equivalence checker considers total equivalence modulo ancillary qubits. \n", | ||
"This means that the garbage qubits are considered as if they were measured qubits, while ancillary qubits are set to zero, as in the partial equivalence check. \n", | ||
"The equivalence checker will return `equivalent` for totally equivalent circuits or `equivalent_up_to_global_phase` for circuits which differ only in their global phase \n", | ||
"and `not_equivalent` for other circuits.\n", | ||
"\n", | ||
"The following is a summary of the behaviour of each type of equivalence checker when the `check_partial_equivalence` option is set to `True`.\n", | ||
"\n", | ||
"1. **Construction Equivalence Checker:** The construction checker supports partial equivalence checking by using decision diagrams to calculate the normalized phases of the possible outputs and then summing up the contribution of garbage qubits, in order to consider only the measurement probabilities of measured qubits. \n", | ||
"Then it compares the reduced decision diagrams of the two circuits. \n", | ||
"\n", | ||
"1. **Alternating Equivalence Checker:** The alternating checker can only be used for circuits where at least one of the two does not contain ancillary qubits. \n", | ||
"It computes the composition of one circuit with the inverse of the other and verifies that the result resembles the identity. \n", | ||
"When checking for partial equivalence, it suffices to verify that the result resembles the identity modulo garbage qubits. \n", | ||
"\n", | ||
"1. **Simulation Equivalence Checker:** The simulation checker computes a representation of the state vector resulting from simulating the circuit with certain initial states. \n", | ||
"Partial equivalence is enabled by summing up the contributions of garbage qubits.\n", | ||
"\n", | ||
"1. **ZX-Calculus Equivalence Checker:** The ZX-calculus checker doesn't directly support partial equivalence, which is not a problem for the equivalence checking workflow, \n", | ||
"given that the ZX-calculus checker cannot demonstrate non-equivalence of circuits due to its incompleteness. \n", | ||
"Therefore it will simply output 'No Information' for circuits that are partially but not totally equivalent." | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "977071d9", | ||
"metadata": {}, | ||
"source": [ | ||
"## Using QCEC to Check for Partial Equivalence\n", | ||
"\n", | ||
"Consider the following quantum circuit with three qubits, which are all data qubits, but only one of them is measured." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "03b73b17", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"from qiskit import QuantumCircuit\n", | ||
"\n", | ||
"qc_lhs = QuantumCircuit(3, 1)\n", | ||
"qc_lhs.cswap(1, 0, 2)\n", | ||
"qc_lhs.h(0)\n", | ||
"qc_lhs.z(2)\n", | ||
"qc_lhs.cswap(1, 0, 2)\n", | ||
"qc_lhs.measure(0, 0)\n", | ||
"\n", | ||
"qc_lhs.draw(output=\"mpl\", style=\"iqp\")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "10fff8c7-f36c-422e-8deb-796cc7637e45", | ||
"metadata": {}, | ||
"source": [ | ||
"Aditionally, consider the following circuit, which only acts on two qubits." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "d167869e-e082-4a42-9eab-112931f5c697", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"qc_rhs = QuantumCircuit(3, 1)\n", | ||
"qc_rhs.x(1)\n", | ||
"qc_rhs.ch(1, 0)\n", | ||
"qc_rhs.measure(0, 0)\n", | ||
"qc_rhs.draw(output=\"mpl\", style=\"iqp\")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "3b85338e", | ||
"metadata": {}, | ||
"source": [ | ||
"Then, these circuits are not totally equivalent, as can be shown using QCEC. \n", | ||
"The library even emits a handy warning in this case that indicates that two circuits have been shown to be non-equivalent, but at least one of the circuits does not measure all its qubits (i.e., has garbage qubits) and partial equivalence checking support has not been enabled." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "36df44b7", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"from mqt.qcec import verify\n", | ||
"\n", | ||
"verify(qc_lhs, qc_rhs)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "8cae4862", | ||
"metadata": {}, | ||
"source": [ | ||
"However, both circuits are partially equivalent, because they have the same probability distribution of measured values for any given initial input state.\n", | ||
"This equality can be proven with QCEC by enabling the `check_partial_equivalence` option:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "da9fa188", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"verify(qc_lhs, qc_rhs, check_partial_equivalence=True)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "6af54b68", | ||
"metadata": {}, | ||
"source": [ | ||
"Source: The definitions and example for partial equivalence are described in the paper [Partial Equivalence Checking of Quantum Circuits](https://arxiv.org/abs/2208.07564) by Tian-Fu Chen, Jie-Hong R. Jiang and Min-Hsiu Hsieh." | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "Python 3 (ipykernel)", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"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 | ||
} |
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
Submodule mqt-core
updated
23 files
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
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
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
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
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
Oops, something went wrong.