GCC Code Coverage Report


Directory: ./
File: Clifford/include/Clifford/SymplecticTableau.hpp
Date: 2022-10-15 05:10:18
Exec Total Coverage
Lines: 2 2 100.0%
Functions: 2 2 100.0%
Branches: 2 4 50.0%
Decisions: 0 0 -%

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