Line | Branch | Decision | Exec | Source |
---|---|---|---|---|
1 | // Copyright 2019-2022 Cambridge Quantum Computing | |||
2 | // | |||
3 | // Licensed under the Apache License, Version 2.0 (the "License"); | |||
4 | // you may not use this file except in compliance with the License. | |||
5 | // You may obtain a copy of the License at | |||
6 | // | |||
7 | // http://www.apache.org/licenses/LICENSE-2.0 | |||
8 | // | |||
9 | // Unless required by applicable law or agreed to in writing, software | |||
10 | // distributed under the License is distributed on an "AS IS" BASIS, | |||
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
12 | // See the License for the specific language governing permissions and | |||
13 | // limitations under the License. | |||
14 | ||||
15 | #pragma once | |||
16 | ||||
17 | #include "OpType/OpType.hpp" | |||
18 | #include "Utils/MatrixAnalysis.hpp" | |||
19 | #include "Utils/PauliStrings.hpp" | |||
20 | ||||
21 | namespace tket { | |||
22 | ||||
23 | // Forward declare friend UnitaryTableau and Circuit for converters | |||
24 | class UnitaryTableau; | |||
25 | class Circuit; | |||
26 | ||||
27 | /** | |||
28 | * Boolean encoding of Pauli | |||
29 | * <x, z> = <false, false> ==> I | |||
30 | * <x, z> = <false, true> ==> Z | |||
31 | * <x, z> = <true, false> ==> X | |||
32 | * <x, z> = <true, true> ==> Y | |||
33 | */ | |||
34 | struct BoolPauli { | |||
35 | bool x; | |||
36 | bool z; | |||
37 | ||||
38 | /** | |||
39 | * Lexicographic ordering by <x, z> | |||
40 | */ | |||
41 | bool operator<(const BoolPauli &other) const; | |||
42 | ||||
43 | Pauli to_pauli() const; | |||
44 | ||||
45 | /** | |||
46 | * Look-up table for Pauli multiplication with boolean encoding | |||
47 | */ | |||
48 | static const std::map< | |||
49 | std::pair<BoolPauli, BoolPauli>, std::pair<BoolPauli, Complex>> | |||
50 | mult_lut; | |||
51 | }; | |||
52 | ||||
53 | class SymplecticTableau { | |||
54 | /** | |||
55 | * Class to represent a tableau of Paulis via the symplectic (binary) | |||
56 | * decomposition. Specifically, each element in the tableau represents a Pauli | |||
57 | * by a pair of binary values: | |||
58 | * - (x, z) <==> X^x Z^z ignoring phase | |||
59 | * - (0, 0) <==> I | |||
60 | * - (0, 1) <==> Z | |||
61 | * - (1, 0) <==> X | |||
62 | * - (1, 1) <==> Y | |||
63 | * Each row also maintains a phase value as a single boolean (-1)^p making the | |||
64 | * assumption that rows are intended to capture stabilizers of some system and | |||
65 | * thus have real coefficients. Pulling these together, each row represents a | |||
66 | * (phaseful) Pauli string. Qubits are indexed by unsigneds in a linear array. | |||
67 | * | |||
68 | * This class provides the data structure, mechanisms for row multiplication, | |||
69 | * gate application and validity checks. | |||
70 | * | |||
71 | * It is expected that all Pauli strings in a tableau should be linearly | |||
72 | * independent, so a validity check is provided. A utility for checking the | |||
73 | * mutual commutativity of terms is also provided. | |||
74 | * | |||
75 | * This serves as a base class for: | |||
76 | * - StabTableau where each row represents a stabilizer of a given state. | |||
77 | * - UnitaryTableau where there is both a Z row and an X row for each input | |||
78 | * describing the Pauli string formed when pushing a Z or X on the input | |||
79 | * through to the outputs. | |||
80 | * - IsometryTableau is a generalisation of StabTableau and UnitaryTableau | |||
81 | * that can represent Clifford isometries by a Z and X row per input and a | |||
82 | * spare row per free stabilizer. | |||
83 | */ | |||
84 | public: | |||
85 | /** | |||
86 | * Constructor to initialise the tableau into a given state. | |||
87 | * Includes checks for compatibility of sizes but will not force commutativity | |||
88 | * or linear independence. | |||
89 | */ | |||
90 | explicit SymplecticTableau( | |||
91 | const MatrixXb &xmat, const MatrixXb &zmat, const VectorXb &phase); | |||
92 | explicit SymplecticTableau(const PauliStabiliserList &rows); | |||
93 | ||||
94 | /** | |||
95 | * Other required constructors | |||
96 | */ | |||
97 |
2/4✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 11 times.
✗ Branch 6 not taken.
|
11 | SymplecticTableau(const SymplecticTableau &other) = default; | |
98 | SymplecticTableau(SymplecticTableau &&other) = default; | |||
99 | SymplecticTableau &operator=(const SymplecticTableau &other) = default; | |||
100 | 36 | SymplecticTableau &operator=(SymplecticTableau &&other) = default; | ||
101 | ||||
102 | /** | |||
103 | * Get the number of rows in the tableau | |||
104 | */ | |||
105 | unsigned get_n_rows() const; | |||
106 | /** | |||
107 | * Get the number of qubits in the tableau (number of binary columns is | |||
108 | * 2*n_qubits + 1) | |||
109 | */ | |||
110 | unsigned get_n_qubits() const; | |||
111 | ||||
112 | /** | |||
113 | * Read off a row as a Pauli string | |||
114 | */ | |||
115 | PauliStabiliser get_pauli(unsigned i) const; | |||
116 | ||||
117 | /** | |||
118 | * Format in output stream as a binary tableau | |||
119 | * Prints as "xmat zmat phase" | |||
120 | */ | |||
121 | friend std::ostream &operator<<( | |||
122 | std::ostream &os, const SymplecticTableau &tab); | |||
123 | ||||
124 | /** | |||
125 | * Equality operator checks all contents | |||
126 | */ | |||
127 | bool operator==(const SymplecticTableau &other) const; | |||
128 | ||||
129 | /** | |||
130 | * Row multiplication | |||
131 | * Multiplies rows ra and rw, stores the result in row rw | |||
132 | */ | |||
133 | void row_mult(unsigned ra, unsigned rw, Complex coeff = 1.); | |||
134 | ||||
135 | /** | |||
136 | * Applies an S/V/CX gate to the given qubit(s) | |||
137 | */ | |||
138 | void apply_S(unsigned qb); | |||
139 | void apply_V(unsigned qb); | |||
140 | void apply_CX(unsigned qc, unsigned qt); | |||
141 | void apply_gate(OpType type, const std::vector<unsigned> &qbs); | |||
142 | void apply_pauli_gadget(const PauliStabiliser &pauli, unsigned half_pis); | |||
143 | ||||
144 | /** | |||
145 | * Generates relation of anti-commutativity between rows | |||
146 | * Matrix element (i, j) is 0 if row i and row j commute, 1 if they | |||
147 | * anti-commute | |||
148 | */ | |||
149 | MatrixXb anticommuting_rows() const; | |||
150 | ||||
151 | /** | |||
152 | * Obtains rank of tableau matrix for determining linear independence of rows | |||
153 | */ | |||
154 | unsigned rank() const; | |||
155 | ||||
156 | private: | |||
157 | /** | |||
158 | * Number of rows | |||
159 | */ | |||
160 | unsigned n_rows_; | |||
161 | ||||
162 | /** | |||
163 | * Number of qubits in each row | |||
164 | */ | |||
165 | unsigned n_qubits_; | |||
166 | ||||
167 | /** | |||
168 | * Tableau contents | |||
169 | */ | |||
170 | MatrixXb xmat_; | |||
171 | MatrixXb zmat_; | |||
172 | VectorXb phase_; | |||
173 | ||||
174 | /** | |||
175 | * Complex conjugate of the state by conjugating rows | |||
176 | */ | |||
177 | SymplecticTableau conjugate() const; | |||
178 | ||||
179 | /** | |||
180 | * Helper methods for manipulating the tableau when applying gates | |||
181 | */ | |||
182 | void row_mult( | |||
183 | const MatrixXb::RowXpr &xa, const MatrixXb::RowXpr &za, const bool &pa, | |||
184 | const MatrixXb::RowXpr &xb, const MatrixXb::RowXpr &zb, const bool &pb, | |||
185 | Complex phase, MatrixXb::RowXpr &xw, MatrixXb::RowXpr &zw, bool &pw); | |||
186 | void col_mult( | |||
187 | const MatrixXb::ColXpr &a, const MatrixXb::ColXpr &b, bool flip, | |||
188 | MatrixXb::ColXpr &w, VectorXb &pw); | |||
189 | ||||
190 | friend class UnitaryTableau; | |||
191 | friend Circuit unitary_tableau_to_circuit(const UnitaryTableau &tab); | |||
192 | friend std::ostream &operator<<(std::ostream &os, const UnitaryTableau &tab); | |||
193 | ||||
194 | friend void to_json(nlohmann::json &j, const SymplecticTableau &tab); | |||
195 | friend void from_json(const nlohmann::json &j, SymplecticTableau &tab); | |||
196 | }; | |||
197 | ||||
198 | JSON_DECL(SymplecticTableau) | |||
199 | ||||
200 | std::ostream &operator<<(std::ostream &os, const SymplecticTableau &tab); | |||
201 | ||||
202 | } // namespace tket | |||
203 |