GCC Code Coverage Report


Directory: ./
File: Gate/GateUnitaryMatrixFixedMatrices.cpp
Date: 2022-10-15 05:10:18
Exec Total Coverage
Lines: 78 78 100.0%
Functions: 33 33 100.0%
Branches: 118 234 50.4%
Decisions: 2 2 100.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 #include "GateUnitaryMatrixImplementations.hpp"
16 #include "GateUnitaryMatrixUtils.hpp"
17 #include "Utils/Constants.hpp"
18
19 namespace tket {
20 namespace internal {
21
22 namespace {
23
24 struct FixedData {
25 Eigen::Matrix2cd X;
26 Eigen::Matrix2cd Y;
27 Eigen::Matrix2cd Z;
28 Eigen::Matrix2cd S;
29 Eigen::Matrix2cd Sdg;
30 Eigen::Matrix2cd T;
31 Eigen::Matrix2cd Tdg;
32 Eigen::Matrix2cd V;
33 Eigen::Matrix2cd Vdg;
34 Eigen::Matrix2cd H;
35 Eigen::Matrix2cd SX;
36 Eigen::Matrix2cd SXdg;
37 Eigen::Matrix4cd CSX;
38 Eigen::Matrix4cd CSXdg;
39 Eigen::Matrix4cd CX;
40 Eigen::Matrix4cd CY;
41 Eigen::Matrix4cd CZ;
42 Eigen::Matrix4cd CH;
43 Eigen::Matrix4cd CV;
44 Eigen::Matrix4cd CVdg;
45 Matrix8cd CCX;
46 Eigen::Matrix4cd SWAP;
47 Matrix8cd CSWAP;
48 Matrix8cd BRIDGE;
49 Eigen::Matrix2cd noop;
50 Eigen::Matrix4cd ECR;
51 Eigen::Matrix4cd ZZMax;
52 Eigen::Matrix4cd Sycamore;
53 Eigen::Matrix4cd ISWAPMax;
54 std::array<unsigned, 8> bridge_columns;
55 std::array<unsigned, 8> cswap_columns;
56
57 1 FixedData() {
58
4/8
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
1 X << 0, 1, 1, 0;
59
4/8
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
1 Y << 0, -i_, i_, 0;
60
4/8
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
1 Z << 1, 0, 0, -1;
61
62
4/8
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
1 S << 1, 0, 0, i_;
63
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 Sdg = S.adjoint();
64
65
4/8
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
1 T << 1, 0, 0, std::polar(1.0, 0.25 * PI);
66
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 Tdg = T.adjoint();
67
68
4/8
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
1 V << 1, -i_, -i_, 1;
69
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 V *= std::sqrt(0.5);
70
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 Vdg = V.adjoint();
71
72
4/8
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
1 H << 1, 1, 1, -1;
73
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 H *= std::sqrt(0.5);
74
75 1 const Complex one_plus_i = i_ + 1.0;
76 1 const Complex one_minus_i = -i_ + 1.0;
77
4/8
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
1 SX << one_plus_i, one_minus_i, one_minus_i, one_plus_i;
78
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 SX *= 0.5;
79
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 SXdg = SX.adjoint();
80
81
16/32
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✓ Branch 26 taken 1 times.
✗ Branch 27 not taken.
✓ Branch 30 taken 1 times.
✗ Branch 31 not taken.
✓ Branch 34 taken 1 times.
✗ Branch 35 not taken.
✓ Branch 38 taken 1 times.
✗ Branch 39 not taken.
✓ Branch 42 taken 1 times.
✗ Branch 43 not taken.
✓ Branch 46 taken 1 times.
✗ Branch 47 not taken.
✓ Branch 50 taken 1 times.
✗ Branch 51 not taken.
✓ Branch 54 taken 1 times.
✗ Branch 55 not taken.
✓ Branch 58 taken 1 times.
✗ Branch 59 not taken.
✓ Branch 62 taken 1 times.
✗ Branch 63 not taken.
1 SWAP << 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1;
82
83 1 bridge_columns = {0, 1, 2, 3, 5, 4, 7, 6};
84 1 cswap_columns = {0, 1, 2, 3, 4, 6, 5, 7};
85
86
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 BRIDGE = Matrix8cd::Zero();
87
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 CSWAP = BRIDGE;
88
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
2/2
✓ Decision 'true' taken 8 times.
✓ Decision 'false' taken 1 times.
9 for (unsigned ii = 0; ii < 8; ++ii) {
89
1/2
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
8 BRIDGE(ii, bridge_columns[ii]) = 1.0;
90
1/2
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
8 CSWAP(ii, cswap_columns[ii]) = 1.0;
91 }
92
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 noop = Eigen::Matrix2cd::Identity();
93
94
16/32
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✓ Branch 28 taken 1 times.
✗ Branch 29 not taken.
✓ Branch 32 taken 1 times.
✗ Branch 33 not taken.
✓ Branch 36 taken 1 times.
✗ Branch 37 not taken.
✓ Branch 40 taken 1 times.
✗ Branch 41 not taken.
✓ Branch 44 taken 1 times.
✗ Branch 45 not taken.
✓ Branch 48 taken 1 times.
✗ Branch 49 not taken.
✓ Branch 52 taken 1 times.
✗ Branch 53 not taken.
✓ Branch 56 taken 1 times.
✗ Branch 57 not taken.
✓ Branch 60 taken 1 times.
✗ Branch 61 not taken.
1 ECR << 0, 0, 1, i_, 0, 0, i_, 1, 1, -i_, 0, 0, -i_, 1, 0, 0;
95
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 ECR *= std::sqrt(0.5);
96
97
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 CX = GateUnitaryMatrixUtils::get_controlled_gate_unitary(X);
98
99 CCX =
100
3/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
1 GateUnitaryMatrixUtils::get_multi_controlled_gate_dense_unitary(CX, 3);
101
102
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 CY = GateUnitaryMatrixUtils::get_controlled_gate_unitary(Y);
103
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 CZ = GateUnitaryMatrixUtils::get_controlled_gate_unitary(Z);
104
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 CH = GateUnitaryMatrixUtils::get_controlled_gate_unitary(H);
105
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 CV = GateUnitaryMatrixUtils::get_controlled_gate_unitary(V);
106
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 CVdg = GateUnitaryMatrixUtils::get_controlled_gate_unitary(Vdg);
107
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 CSX = GateUnitaryMatrixUtils::get_controlled_gate_unitary(SX);
108
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 CSXdg = GateUnitaryMatrixUtils::get_controlled_gate_unitary(SXdg);
109
110 // Accuracy notes: std::sqrt is guaranteed by IEEE 754
111 // but std::sin, std::cos are not (although C++ is not guaranteed
112 // to follow IEEE 754 anyway), so where there is a choice
113 // (e.g., cos(pi/4) vs. sqrt(2), cos(pi/6) vs. sqrt(3), etc.),
114 // std::sqrt might be very slightly more accurate,
115 // but it's not worth worrying about.
116 // However, note that cos(pi/2), sin(pi), etc. need NOT be exact
117 // so we should prefer exact values if it's easy to do.
118
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ZZMax = GateUnitaryMatrixImplementations::ZZPhase(0.5);
119
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 Sycamore = GateUnitaryMatrixImplementations::FSim(0.5, 1.0 / 6.0);
120
121 // Equals ISWAP(1) in theory, but ensure the exact result!
122
16/32
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✓ Branch 29 taken 1 times.
✗ Branch 30 not taken.
✓ Branch 33 taken 1 times.
✗ Branch 34 not taken.
✓ Branch 36 taken 1 times.
✗ Branch 37 not taken.
✓ Branch 40 taken 1 times.
✗ Branch 41 not taken.
✓ Branch 44 taken 1 times.
✗ Branch 45 not taken.
✓ Branch 48 taken 1 times.
✗ Branch 49 not taken.
✓ Branch 52 taken 1 times.
✗ Branch 53 not taken.
✓ Branch 56 taken 1 times.
✗ Branch 57 not taken.
✓ Branch 60 taken 1 times.
✗ Branch 61 not taken.
1 ISWAPMax << 1, 0, 0, 0, 0, 0, i_, 0, 0, i_, 0, 0, 0, 0, 0, 1;
123 1 }
124 }; // struct FixedData
125
126 102831 const FixedData& get_fixed_data() {
127 // Remember "Static Initialization Order Fiasco"
128
4/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 102830 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
102831 static const FixedData data;
129 102831 return data;
130 }
131
132 } // unnamed namespace
133
134 #ifdef GATE_FUNCTION_1Q
135 #error "Macro already defined!"
136 #endif
137 #define GATE_FUNCTION_1Q(funcname) \
138 const Eigen::Matrix2cd& GateUnitaryMatrixImplementations::funcname() { \
139 return get_fixed_data().funcname; \
140 }
141 1393 GATE_FUNCTION_1Q(X)
142 520 GATE_FUNCTION_1Q(Y)
143 1196 GATE_FUNCTION_1Q(Z)
144 703 GATE_FUNCTION_1Q(S)
145 342 GATE_FUNCTION_1Q(Sdg)
146 888 GATE_FUNCTION_1Q(T)
147 646 GATE_FUNCTION_1Q(Tdg)
148 1095 GATE_FUNCTION_1Q(V)
149 809 GATE_FUNCTION_1Q(Vdg)
150 19927 GATE_FUNCTION_1Q(H)
151 106 GATE_FUNCTION_1Q(SX)
152 19 GATE_FUNCTION_1Q(SXdg)
153 13 GATE_FUNCTION_1Q(noop)
154 #undef GATE_FUNCTION_1Q
155
156 #ifdef GATE_FUNCTION_2Q
157 #error "Macro already defined!"
158 #endif
159 #define GATE_FUNCTION_2Q(funcname) \
160 const Eigen::Matrix4cd& GateUnitaryMatrixImplementations::funcname() { \
161 return get_fixed_data().funcname; \
162 }
163 49 GATE_FUNCTION_2Q(SWAP)
164 20 GATE_FUNCTION_2Q(ECR)
165 74444 GATE_FUNCTION_2Q(CX)
166 24 GATE_FUNCTION_2Q(CY)
167 384 GATE_FUNCTION_2Q(CZ)
168 22 GATE_FUNCTION_2Q(CH)
169 18 GATE_FUNCTION_2Q(CV)
170 16 GATE_FUNCTION_2Q(CVdg)
171 18 GATE_FUNCTION_2Q(CSX)
172 16 GATE_FUNCTION_2Q(CSXdg)
173 98 GATE_FUNCTION_2Q(ZZMax)
174 15 GATE_FUNCTION_2Q(Sycamore)
175 15 GATE_FUNCTION_2Q(ISWAPMax)
176 #undef GATE_FUNCTION_2Q
177
178 #ifdef GATE_FUNCTION_XQ
179 #error "Macro already defined!"
180 #endif
181 #define GATE_FUNCTION_3Q(funcname) \
182 const Matrix8cd& GateUnitaryMatrixImplementations::funcname() { \
183 return get_fixed_data().funcname; \
184 }
185 14 GATE_FUNCTION_3Q(BRIDGE)
186 9 GATE_FUNCTION_3Q(CCX)
187 10 GATE_FUNCTION_3Q(CSWAP)
188 #undef GATE_FUNCTION_3Q
189
190 const std::array<unsigned, 8>&
191 1 GateUnitaryMatrixImplementations::get_bridge_columns() {
192 1 return get_fixed_data().bridge_columns;
193 }
194
195 const std::array<unsigned, 8>&
196 1 GateUnitaryMatrixImplementations::get_cswap_columns() {
197 1 return get_fixed_data().cswap_columns;
198 }
199
200 } // namespace internal
201 } // namespace tket
202