GCC Code Coverage Report


Directory: ./
File: Characterisation/include/Characterisation/FrameRandomisation.hpp
Date: 2022-10-15 05:10:18
Exec Total Coverage
Lines: 0 2 0.0%
Functions: 0 2 0.0%
Branches: 0 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 "Characterisation/Cycles.hpp"
18 #include "Circuit/Circuit.hpp"
19
20 namespace tket {
21
22 // Friend class for testing some private methods in FrameRandomisation
23 class FrameRandomisationTester;
24
25 // FrameRandomisation provides methods for applying a circuit noise shaping
26 // method 'Cycles' i.e. sub-circuits of a given circuit are found such that:
27 // • every gate Op has a type in some allowed set of OpTypes (cycle_types_)
28 // • the minimum number of cycles is found where each allowed Op is in a cycle
29 // New gates are wired into the EdgeType::Quantum boundary of each cycle (adding
30 // a Frame) such that:
31 // • Each OpType for vertices in the "in" boundary of each cycle is uniformly
32 // sampled from some allowed set of 1-qubit OpTypes (frame_types_)
33 // • OpTypes for vertices in the "out" boundary and are determined from "in"
34 // frame & cycle gates such that the overall circuit unitary is unchanged (up
35 // to global phase)
36 class FrameRandomisation {
37 public:
38 FrameRandomisation() {}
39 virtual ~FrameRandomisation() {}
40 // _frame_cycle_conjugates keys are OpTypes from _cycle_types
41 // _frame_cycle_conjugate values are maps between OpTypeVector, where all
42 // OpType are from _frame_types
43 FrameRandomisation(
44 const OpTypeSet& _cycle_types, const OpTypeSet& _frame_types,
45 std::map<OpType, std::map<OpTypeVector, OpTypeVector>>
46 _frame_cycle_conjugates)
47 : cycle_types_(_cycle_types),
48 frame_types_(_frame_types),
49 frame_cycle_conjugates_(_frame_cycle_conjugates) {}
50 // Returns samples instances of frame randomisation for circ
51 virtual std::vector<Circuit> sample_randomisation_circuits(
52 const Circuit& circ, unsigned samples);
53 // Returns every combination of frame for every cycle in circ
54 std::vector<Circuit> get_all_circuits(const Circuit& circ);
55
56 std::string to_string() const;
57
58 protected:
59 OpTypeSet cycle_types_;
60 OpTypeSet frame_types_;
61 std::map<OpType, std::map<OpTypeVector, OpTypeVector>>
62 frame_cycle_conjugates_;
63 Circuit circuit_;
64
65 // Each Cycle in cycles has corresponding addresses of frame vertices in circ
66 // The OpType of each frame vertex is reassigned given all_frame_ops
67 std::vector<Circuit> label_frames(
68 const std::vector<std::vector<OpTypeVector>>& all_frame_ops,
69 const std::vector<Cycle>& cycles);
70
71 // Labels frame_vertices with in_frame & out_frame OpType
72 void assign_vertices(
73 const OpTypeVector& in_frame, const OpTypeVector& out_frame,
74 const std::vector<std::pair<Vertex, Vertex>>& frame_vertices);
75
76 // Finds cycles of cycle_types_ Op in circ using CycleFinder class
77 std::vector<Cycle> get_cycles(const Circuit& circ) const;
78
79 // Uniformly samples size OpType from frame_types_
80 OpTypeVector sample_frame(const unsigned& size) const;
81
82 // Returns every permutation of OpType in frame_types_ up to largest
83 // frame_sizes value
84 std::vector<std::vector<OpTypeVector>> get_all_samples(
85 const unsigned& samples, const std::vector<unsigned>& frame_sizes) const;
86
87 private:
88 // Returns new OpTypeVector "out_frame"
89 // Sets "out_frame" equal to "in_frame"
90 // given OpType in "out_frame", sequentially finds action of OpType in cycle
91 // on "out_frame" OpType using frame_cycle_conjugates_ Unitarity of circuit
92 // preserved up to global phase
93 virtual std::pair<OpTypeVector, std::vector<Vertex>> get_out_frame(
94 const OpTypeVector& in_frame, const Cycle& cycle);
95
96 friend class FrameRandomisationTester;
97 };
98
99 // Instance of FrameRandomisation where cycle_types_ are "hard" Clifford gates
100 // frame_types_ are Pauli gates
101 class PauliFrameRandomisation : public FrameRandomisation {
102 public:
103 PauliFrameRandomisation() {
104 cycle_types_ = {OpType::H, OpType::CX, OpType::S};
105 frame_types_ = {OpType::X, OpType::Y, OpType::Z, OpType::noop};
106 }
107
108 protected:
109 // QubitPauliTensor class used to find "out_frame"
110 std::pair<OpTypeVector, std::vector<Vertex>> get_out_frame(
111 const OpTypeVector& in_frame, const Cycle& cycle);
112 };
113
114 // Instance of FrameRandomisation where cycle gates can be modified
115 class UniversalFrameRandomisation : public FrameRandomisation {
116 public:
117 UniversalFrameRandomisation() {
118 cycle_types_ = {OpType::H, OpType::CX, OpType::Rz};
119 frame_types_ = {OpType::X, OpType::Y, OpType::Z, OpType::noop};
120 }
121 virtual ~UniversalFrameRandomisation() {}
122
123 protected:
124 // QubitPauliTensor class used to find "out_frame"
125 std::pair<OpTypeVector, std::vector<Vertex>> get_out_frame(
126 const OpTypeVector& in_frame, const Cycle& cycle);
127 };
128
129 // Special Instance of PauliFrameRandomisation
130 // circ must be one cycle
131 // cycle + "out_frame" appended to circ cycle_repeats number of times
132 // one "in_frame" is sampled and each individual "out_frame" for each repeat
133 // determined
134 class PowerCycle : public PauliFrameRandomisation {
135 public:
136 PowerCycle() {
137 cycle_types_ = {OpType::Z, OpType::X, OpType::Y, OpType::S,
138 OpType::Sdg, OpType::V, OpType::Vdg, OpType::H,
139 OpType::CX, OpType::CY, OpType::CZ, OpType::noop};
140 frame_types_ = {OpType::X, OpType::Y, OpType::Z, OpType::noop};
141 }
142 std::vector<Circuit> sample_cycles(
143 const Circuit& circ, unsigned cycle_repeats, unsigned samples);
144 };
145
146 // Friend class of FrameRandomisation for testing some private methods
147 class FrameRandomisationTester {
148 private:
149 FrameRandomisation* fr;
150
151 public:
152 explicit FrameRandomisationTester(FrameRandomisation* _fr) : fr(_fr) {}
153
154 std::vector<Cycle> get_cycles(const Circuit& circ);
155
156 OpTypeVector get_out_frame(
157 const OpTypeVector& in_frame, const Cycle& cycle_ops);
158
159 std::vector<std::vector<OpTypeVector>> get_all_samples(
160 const unsigned& samples, const std::vector<unsigned>& frame_sizes);
161 };
162
163 } // namespace tket
164