GCC Code Coverage Report


Directory: ./
File: Converters/include/Converters/PhasePoly.hpp
Date: 2022-10-15 05:10:18
Exec Total Coverage
Lines: 9 14 64.3%
Functions: 3 6 50.0%
Branches: 6 10 60.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 #include "Circuit/Boxes.hpp"
17 #include "Circuit/CircUtils.hpp"
18 #include "Circuit/Circuit.hpp"
19 #include "Utils/HelperFunctions.hpp"
20 #include "Utils/Json.hpp"
21 #include "Utils/MatrixAnalysis.hpp"
22 namespace tket {
23
24 /**
25 * PhasePolynomial is just a sequence of parities: that is, terms of the form
26 * \f$ e^{\alpha \bigotimes Z} \f$, where Z is a Pauli Z. This is capable of
27 * representing a restricted set of circuits made up of CNOTs and Rzs:
28 * specifically, circuits where the output qubits have the same state as the
29 * inputs, modulo (local) phases. The vectors are always assumed to be the same
30 * size as the qubit count. */
31 typedef std::map<std::vector<bool>, Expr> PhasePolynomial;
32 typedef std::pair<std::vector<bool>, Expr> phase_term_t;
33
34 /* arXiv:1712.01859 : heuristic for synthesis of phase polynomial into
35 a CNOT-dihedral circuit (ie CNOT + Rz). Architecture-blind. */
36 Circuit gray_synth(
37 unsigned n_qubits, const std::list<phase_term_t> &parities,
38 const MatrixXb &linear_transformation);
39
40 /**
41 * A PhasePolyBox is capable of representing arbitrary Circuits made up of CNOT
42 * and RZ, as a PhasePolynomial plus a boolean matrix representing an additional
43 * linear transformation.
44 */
45 class PhasePolyBox : public Box {
46 public:
47 explicit PhasePolyBox(const Circuit &circ);
48 explicit PhasePolyBox(
49 unsigned n_qubits, const boost::bimap<Qubit, unsigned> &qubit_indices,
50 const PhasePolynomial &phase_polynomial,
51 const MatrixXb &linear_transformation);
52
53 PhasePolyBox() : Box(OpType::PhasePolyBox) {}
54
55 /**
56 * Copy constructor
57 */
58 PhasePolyBox(const PhasePolyBox &other);
59
60 ~PhasePolyBox() override {}
61
62 Op_ptr symbol_substitution(
63 const SymEngine::map_basic_basic &sub_map) const override;
64
65 SymSet free_symbols() const override;
66
67 9 bool is_equal(const Op &op_other) const override {
68
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 const PhasePolyBox &other = dynamic_cast<const PhasePolyBox &>(op_other);
69 return (
70 18 this->n_qubits_ == other.n_qubits_ &&
71
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
9 this->phase_polynomial_ == other.phase_polynomial_ &&
72
3/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 1 times.
26 this->linear_transformation_ == other.linear_transformation_ &&
73
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
17 this->qubit_indices_ == other.qubit_indices_);
74 }
75
76 const PhasePolynomial &get_phase_polynomial() const {
77 return phase_polynomial_;
78 }
79 const MatrixXb &get_linear_transformation() const {
80 return linear_transformation_;
81 }
82 1 const boost::bimap<Qubit, unsigned> &get_qubit_indices() const {
83 1 return qubit_indices_;
84 }
85
86 98 unsigned get_n_qubits() const { return n_qubits_; }
87
88 static Op_ptr from_json(const nlohmann::json &j);
89
90 static nlohmann::json to_json(const Op_ptr &op);
91
92 protected:
93 // automatically uses GraySynth
94 // (https://arxiv.org/pdf/1712.01859.pdf)
95 // other circuit generation methods (for architectures) to come!
96 void generate_circuit() const override;
97
98 private:
99 unsigned n_qubits_;
100 boost::bimap<Qubit, unsigned> qubit_indices_;
101 PhasePolynomial phase_polynomial_;
102 MatrixXb linear_transformation_;
103 };
104
105 /**
106 * this class realises the conversion all sub circuits of a given circuits which
107 * contains only CX+Rz to a PhasePolyBox. The circuit should contain only
108 * CX, Rz, H, measure, reset, collape, barrier.
109 */
110 class CircToPhasePolyConversion {
111 public:
112 /**
113 * converts all sub circuits of a given circuits which contains only
114 * CX+Rz to a PhasePolyBox.
115 * @throw not implemented for unsupported gates
116 * @param circ circuit to be converted
117 * @param min_size value for the minimal number of CX in each box, groups with
118 * less than min_size CX gates are not converted to a PhasePolyBox, default
119 * value is 0
120 */
121 explicit CircToPhasePolyConversion(
122 const Circuit &circ, unsigned min_size = 0);
123 void convert();
124 Circuit get_circuit() const;
125
126 private:
127 enum class QubitType { pre, in, post };
128 void add_phase_poly_box();
129 unsigned nq_;
130 unsigned nb_;
131 unsigned min_size_;
132 unsigned box_size_;
133 std::map<Qubit, unsigned> qubit_indices_;
134 std::map<Bit, unsigned> bit_indices_;
135 std::vector<QubitType> qubit_types_;
136 qubit_vector_t all_qu_;
137 Circuit input_circ_;
138 Circuit box_circ_;
139 Circuit post_circ_;
140 Circuit circ_;
141 Circuit empty_circ_;
142 };
143
144 } // namespace tket
145