99 */
1010
1111#include " Helpers.h"
12+ #include " ir/Definitions.hpp"
1213#include " mlir/Dialect/MQTOpt/IR/MQTOptDialect.h"
1314#include " mlir/Dialect/MQTOpt/Transforms/Passes.h"
1415
3233namespace mqt ::ir::opt {
3334
3435/* *
35- * @brief This pattern attempts to cancel consecutive self-inverse operations.
36+ * @brief This pattern attempts to collect as many operations as possible into a
37+ * 4x4 unitary matrix and then decompose it into rotation and given basis
38+ * gates.
3639 */
3740struct GateDecompositionPattern final
3841 : mlir::OpInterfaceRewritePattern<UnitaryInterface> {
@@ -70,7 +73,13 @@ struct GateDecompositionPattern final
7073 */
7174 std::vector<Gate> gates;
7275
76+ /* *
77+ * Global phase adjustment required for the sequence.
78+ */
7379 fp globalPhase{};
80+ /* *
81+ * @return true if the global phase adjustment is not zero.
82+ */
7483 [[nodiscard]] bool hasGlobalPhase () const {
7584 return std::abs (globalPhase) > DEFAULT_ATOL ;
7685 }
@@ -106,7 +115,14 @@ struct GateDecompositionPattern final
106115 return unitaryMatrix;
107116 }
108117 };
118+ /* *
119+ * Helper type to show that a gate sequence is supposed to only contain
120+ * single-qubit gates.
121+ */
109122 using OneQubitGateSequence = QubitGateSequence;
123+ /* *
124+ * Helper type to show that the gate sequence may contain two-qubit gates.
125+ */
110126 using TwoQubitGateSequence = QubitGateSequence;
111127
112128 /* *
@@ -1518,7 +1534,15 @@ struct GateDecompositionPattern final
15181534 }
15191535 };
15201536
1537+ /* *
1538+ * Factor by which two matrices are considered to be the same when simplifying
1539+ * during a decomposition.
1540+ */
15211541 static constexpr auto DEFAULT_FIDELITY = 1.0 - 1e-15 ;
1542+ /* *
1543+ * Largest number that will be assumed as zero for the euler decompositions
1544+ * and the global phase.
1545+ */
15221546 static constexpr auto DEFAULT_ATOL = 1e-12 ;
15231547
15241548 /* *
@@ -1922,7 +1946,7 @@ struct GateDecompositionPattern final
19221946 * necessary to construct an equivalent to the canonical gate.
19231947 */
19241948 [[nodiscard]] std::array<qfp, 4 >
1925- traces (TwoQubitWeylDecomposition target) const {
1949+ traces (const TwoQubitWeylDecomposition& target) const {
19261950 return {
19271951 static_cast <fp>(4 .) *
19281952 qfp (std::cos (target.a ) * std::cos (target.b ) * std::cos (target.c ),
@@ -1938,10 +1962,13 @@ struct GateDecompositionPattern final
19381962 };
19391963 }
19401964
1941- static OneQubitGateSequence generateCircuit (EulerBasis targetBasis,
1942- const matrix2x2& unitaryMatrix,
1943- bool simplify,
1944- std::optional<fp> atol) {
1965+ /* *
1966+ * Perform single-qubit decomposition of a 2x2 unitary matrix based on a
1967+ * given euler basis.
1968+ */
1969+ [[nodiscard]] static OneQubitGateSequence
1970+ generateCircuit (EulerBasis targetBasis, const matrix2x2& unitaryMatrix,
1971+ bool simplify, std::optional<fp> atol) {
19451972 auto [theta, phi, lambda, phase] =
19461973 anglesFromUnitary (unitaryMatrix, targetBasis);
19471974
@@ -1964,12 +1991,16 @@ struct GateDecompositionPattern final
19641991 }
19651992 }
19661993
1967- static OneQubitGateSequence unitaryToGateSequenceInner (
1968- matrix2x2 unitaryMat,
1994+ /* *
1995+ * Decompose a single-qubit unitary matrix into a single-qubit gate
1996+ * sequence. Multiple euler bases may be specified and the one with the
1997+ * least complexity will be chosen.
1998+ */
1999+ [[nodiscard]] static OneQubitGateSequence unitaryToGateSequenceInner (
2000+ const matrix2x2& unitaryMat,
19692001 const llvm::SmallVector<EulerBasis>& targetBasisList, QubitId /* qubit*/ ,
19702002 const std::vector<std::unordered_map<std::string, fp>>&
1971- /* error_map*/ , // TODO: remove error_map+qubit for platform
1972- // independence
2003+ /* error_map*/ , // per qubit a mapping of operation name to error value
19732004 bool simplify, std::optional<fp> atol) {
19742005 auto calculateError = [](const OneQubitGateSequence& sequence) -> fp {
19752006 return static_cast <fp>(sequence.complexity ());
0 commit comments