GCC Code Coverage Report


Directory: ./
File: Circuit/latex_drawing.cpp
Date: 2022-10-15 05:10:18
Warnings: 8 unchecked decisions!
Exec Total Coverage
Lines: 227 260 87.3%
Functions: 3 3 100.0%
Branches: 311 614 50.7%
Decisions: 66 98 67.3%

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 <limits>
16
17 #include "Boxes.hpp"
18 #include "Circuit.hpp"
19 #include "OpType/OpType.hpp"
20 namespace tket {
21
22 struct LineBufferInfo {
23 std::stringstream buffer;
24 unsigned depth;
25 bool is_quantum;
26 };
27
28 struct LatexContext {
29 std::map<UnitID, unsigned> line_ids;
30 std::vector<LineBufferInfo> lines;
31 };
32
33 41 void add_latex_for_command(LatexContext& context, const Command& command) {
34 41 std::map<UnitID, unsigned>& line_ids = context.line_ids;
35 41 std::vector<LineBufferInfo>& lines = context.lines;
36
1/2
✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
41 unit_vector_t args = command.get_args();
37 41 const Op_ptr op = command.get_op_ptr();
38
10/12
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 7 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 20 times.
✓ Branch 13 taken 4 times.
41 switch (op->get_type()) {
39 4 case OpType::CnRy:
40 case OpType::CnX:
41 case OpType::CnY:
42 case OpType::CnZ: {
43
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 int target_index = line_ids.at(args.back());
44 4 args.pop_back();
45
2/2
✓ Branch 4 taken 16 times.
✓ Branch 5 taken 4 times.
2/2
✓ Decision 'true' taken 16 times.
✓ Decision 'false' taken 4 times.
20 for (const UnitID& u : args) {
46
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 int control_index = line_ids.at(u);
47
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 lines.at(control_index).buffer
48
3/6
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 16 times.
✗ Branch 8 not taken.
16 << "\\ctrl{" << target_index - control_index << "} & ";
49
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 lines.at(control_index).depth++;
50 }
51
2/2
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 3 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 3 times.
4 if (op->get_type() == OpType::CnRy) {
52
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 lines.at(target_index).buffer
53 << "\\gate{\\text{"
54
3/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
2 << get_op_ptr(OpType::Ry, op->get_params())->get_name(true)
55
3/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
2 << "}} & ";
56
2/2
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 2 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 2 times.
3 } else if (op->get_type() == OpType::CnX) {
57
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 lines.at(target_index).buffer << "\\targ{} & ";
58
2/2
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 1 times.
2 } else if (op->get_type() == OpType::CnY) {
59
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 lines.at(target_index).buffer << "\\gate{\\text{"
60
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
2 << get_op_ptr(OpType::Y)->get_name(true)
61
3/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
2 << "}} & ";
62 } else {
63
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 lines.at(target_index).buffer << "\\control{} & ";
64 }
65
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 lines.at(target_index).depth++;
66 4 break;
67 }
68
1/1
✓ Decision 'true' taken 1 times.
1 case OpType::CCX: {
69
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 int control0_index = line_ids.at(args.at(0));
70
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 int control1_index = line_ids.at(args.at(1));
71
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 int target_index = line_ids.at(args.at(2));
72
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 lines.at(control0_index).buffer
73
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 << "\\ctrl{" << target_index - control0_index << "} & ";
74
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 lines.at(control0_index).depth++;
75
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 lines.at(control1_index).buffer
76
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 << "\\ctrl{" << target_index - control1_index << "} & ";
77
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 lines.at(control1_index).depth++;
78
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 lines.at(target_index).buffer << "\\targ{} & ";
79
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 lines.at(target_index).depth++;
80 1 break;
81 }
82
1/1
✓ Decision 'true' taken 1 times.
1 case OpType::CSWAP: {
83
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 int control_index = line_ids.at(args.at(0));
84
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 int target0_index = line_ids.at(args.at(1));
85
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 int target1_index = line_ids.at(args.at(2));
86
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 lines.at(control_index).buffer << "\\ctrl{"
87
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 << target0_index - control_index << "} & ";
88
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 lines.at(control_index).depth++;
89
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 lines.at(target0_index).buffer << "\\swap{"
90
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 << target1_index - target0_index << "} & ";
91
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 lines.at(target0_index).depth++;
92
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 lines.at(target1_index).buffer << "\\targX{} & ";
93
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 lines.at(target1_index).depth++;
94 1 break;
95 }
96 7 case OpType::CH:
97 case OpType::CRz:
98 case OpType::CRx:
99 case OpType::CRy:
100 case OpType::CU1:
101 case OpType::CU3:
102 case OpType::CY: {
103
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 std::stringstream gate_name;
104 7 switch (op->get_type()) {
105
1/1
✓ Decision 'true' taken 1 times.
1 case OpType::CH: {
106
3/6
✓ 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.
1 gate_name << get_op_ptr(OpType::H)->get_name(true);
107 1 break;
108 }
109
1/1
✓ Decision 'true' taken 1 times.
1 case OpType::CRz: {
110
4/8
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
1 gate_name << get_op_ptr(OpType::Rz, op->get_params())->get_name(true);
111 1 break;
112 }
113
1/1
✓ Decision 'true' taken 1 times.
1 case OpType::CRx: {
114
4/8
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
1 gate_name << get_op_ptr(OpType::Rx, op->get_params())->get_name(true);
115 1 break;
116 }
117
1/1
✓ Decision 'true' taken 1 times.
1 case OpType::CRy: {
118
4/8
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
1 gate_name << get_op_ptr(OpType::Ry, op->get_params())->get_name(true);
119 1 break;
120 }
121
1/1
✓ Decision 'true' taken 1 times.
1 case OpType::CU1: {
122
4/8
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
1 gate_name << get_op_ptr(OpType::U1, op->get_params())->get_name(true);
123 1 break;
124 }
125
1/1
✓ Decision 'true' taken 1 times.
1 case OpType::CU3: {
126
4/8
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
1 gate_name << get_op_ptr(OpType::U3, op->get_params())->get_name(true);
127 1 break;
128 }
129
1/1
✓ Decision 'true' taken 1 times.
1 case OpType::CY: {
130
3/6
✓ 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.
1 gate_name << get_op_ptr(OpType::Y)->get_name(true);
131 1 break;
132 }
133
0/1
✗ Decision 'true' not taken.
case OpType::CV: {
134 gate_name << get_op_ptr(OpType::V)->get_name(true);
135 break;
136 }
137
0/1
✗ Decision 'true' not taken.
case OpType::CVdg: {
138 gate_name << get_op_ptr(OpType::Vdg)->get_name(true);
139 break;
140 }
141
0/1
✗ Decision 'true' not taken.
case OpType::CSX: {
142 gate_name << get_op_ptr(OpType::SX)->get_name(true);
143 break;
144 }
145
0/1
✗ Decision 'true' not taken.
case OpType::CSXdg: {
146 gate_name << get_op_ptr(OpType::SXdg)->get_name(true);
147 break;
148 }
149
0/1
✗ Decision 'true' not taken.
7 default: {
150 }
151 }
152
2/4
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
7 int control_index = line_ids.at(args.at(0));
153
2/4
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
7 int target_index = line_ids.at(args.at(1));
154
2/4
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
7 lines.at(control_index).buffer << "\\ctrl{"
155
2/4
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
7 << target_index - control_index << "} & ";
156
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 lines.at(control_index).depth++;
157
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
14 lines.at(target_index).buffer << "\\gate{\\text{" << gate_name.str()
158
4/8
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 7 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 7 times.
✗ Branch 11 not taken.
7 << "}} & ";
159
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 lines.at(target_index).depth++;
160 7 break;
161 7 }
162
1/1
✓ Decision 'true' taken 1 times.
1 case OpType::CX: {
163
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 int control_index = line_ids.at(args.at(0));
164
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 int target_index = line_ids.at(args.at(1));
165
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 lines.at(control_index).buffer << "\\ctrl{"
166
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 << target_index - control_index << "} & ";
167
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 lines.at(control_index).depth++;
168
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 lines.at(target_index).buffer << "\\targ{} & ";
169
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 lines.at(target_index).depth++;
170 1 break;
171 }
172
1/1
✓ Decision 'true' taken 1 times.
1 case OpType::CZ: {
173
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 int control_index = line_ids.at(args.at(0));
174
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 int target_index = line_ids.at(args.at(1));
175
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 lines.at(control_index).buffer << "\\ctrl{"
176
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 << target_index - control_index << "} & ";
177
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 lines.at(control_index).depth++;
178
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 lines.at(target_index).buffer << "\\control{} & ";
179
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 lines.at(target_index).depth++;
180 1 break;
181 }
182
1/1
✓ Decision 'true' taken 1 times.
1 case OpType::Measure: {
183
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 int qb_index = line_ids.at(args.at(0));
184
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 int cb_index = line_ids.at(args.at(1));
185
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 lines.at(qb_index).buffer << "\\meter{} \\vcw{" << cb_index - qb_index
186
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 << "} & ";
187
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 lines.at(qb_index).depth++;
188
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 lines.at(cb_index).buffer << "\\cw & ";
189
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 lines.at(cb_index).depth++;
190 1 break;
191 }
192
0/1
✗ Decision 'true' not taken.
case OpType::Collapse: {
193 int qb_index = line_ids.at(args.at(0));
194 lines.at(qb_index).buffer << "\\meter{} & ";
195 lines.at(qb_index).depth++;
196 break;
197 }
198
1/1
✓ Decision 'true' taken 1 times.
1 case OpType::SWAP: {
199
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 int qb0_index = line_ids.at(args.at(0));
200
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 int qb1_index = line_ids.at(args.at(1));
201
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 lines.at(qb0_index).buffer << "\\swap{" << qb1_index - qb0_index
202
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 << "} & ";
203
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 lines.at(qb0_index).depth++;
204
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 lines.at(qb1_index).buffer << "\\targX{} & ";
205
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 lines.at(qb1_index).depth++;
206 1 break;
207 }
208
0/1
✗ Decision 'true' not taken.
case OpType::QControlBox: {
209 const QControlBox& box = static_cast<const QControlBox&>(*op);
210 unsigned n_controls = box.get_n_controls();
211 int max_index = 0;
212 unit_vector_t target_args;
213
0/2
✗ Decision 'true' not taken.
✗ Decision 'false' not taken.
for (unsigned i = n_controls; i < args.size(); ++i) {
214 target_args.push_back(args[i]);
215 int index = line_ids.at(args[i]);
216
0/2
✗ Decision 'true' not taken.
✗ Decision 'false' not taken.
if (index > max_index) max_index = index;
217 }
218 add_latex_for_command(context, Command(box.get_op(), target_args));
219
0/2
✗ Decision 'true' not taken.
✗ Decision 'false' not taken.
for (unsigned i = 0; i < n_controls; ++i) {
220 int index = line_ids.at(args[i]);
221 lines.at(index).buffer << "\\ctrl{" << max_index - index << "} & ";
222 lines.at(index).depth++;
223 }
224 break;
225 }
226
1/1
✓ Decision 'true' taken 20 times.
20 case OpType::Conditional: {
227 20 const Conditional& box = static_cast<const Conditional&>(*op);
228
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 unsigned n_controls = box.get_width();
229 20 int max_index = 0;
230 20 unit_vector_t target_args;
231
2/2
✓ Branch 1 taken 51 times.
✓ Branch 2 taken 20 times.
2/2
✓ Decision 'true' taken 51 times.
✓ Decision 'false' taken 20 times.
71 for (unsigned i = n_controls; i < args.size(); ++i) {
232
1/2
✓ Branch 2 taken 51 times.
✗ Branch 3 not taken.
51 target_args.push_back(args[i]);
233
1/2
✓ Branch 2 taken 51 times.
✗ Branch 3 not taken.
51 int index = line_ids.at(args[i]);
234
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 23 times.
2/2
✓ Decision 'true' taken 20 times.
✓ Decision 'false' taken 31 times.
51 if (index > max_index) max_index = index;
235 }
236
5/10
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 20 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 20 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 20 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 20 times.
✗ Branch 15 not taken.
20 add_latex_for_command(context, Command(box.get_op(), target_args));
237
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 20 times.
2/2
✓ Decision 'true' taken 4 times.
✓ Decision 'false' taken 20 times.
24 for (unsigned i = 0; i < n_controls; ++i) {
238
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 int index = line_ids.at(args[i]);
239
4/8
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
4 lines.at(index).buffer << "\\cwbend{" << max_index - index << "} & ";
240
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 lines.at(index).depth++;
241 }
242 20 break;
243 20 }
244
1/1
✓ Decision 'true' taken 4 times.
4 default: {
245 4 unsigned min_index = std::numeric_limits<unsigned>::max();
246 4 unsigned max_index = 0;
247
2/2
✓ Branch 5 taken 5 times.
✓ Branch 6 taken 4 times.
2/2
✓ Decision 'true' taken 5 times.
✓ Decision 'false' taken 4 times.
9 for (const UnitID& arg : args) {
248
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 unsigned index = line_ids.at(arg);
249
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
1/2
✓ Decision 'true' taken 5 times.
✗ Decision 'false' not taken.
5 if (index < min_index) min_index = index;
250
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3 times.
2/2
✓ Decision 'true' taken 4 times.
✓ Decision 'false' taken 1 times.
5 if (index > max_index) max_index = index;
251 }
252
3/6
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
4 lines.at(min_index).buffer << "\\gate[" << (max_index + 1 - min_index)
253
4/8
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 4 times.
✗ Branch 12 not taken.
4 << "]{\\text{" + op->get_name(true) + "}} & ";
254
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 lines.at(min_index).depth++;
255
2/2
✓ Branch 5 taken 5 times.
✓ Branch 6 taken 4 times.
2/2
✓ Decision 'true' taken 5 times.
✓ Decision 'false' taken 4 times.
9 for (const UnitID& arg : args) {
256
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 unsigned index = line_ids.at(arg);
257
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 4 times.
5 if (index != min_index) {
258
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 lines.at(index).buffer << "& ";
259
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 lines.at(index).depth++;
260 }
261 }
262 }
263 }
264 41 }
265
266 1 std::string Circuit::to_latex_str() const {
267 // Initial header
268
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 std::stringstream buffer;
269
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 buffer << "\\documentclass[tikz]{standalone}\n";
270
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 buffer << "\\usetikzlibrary{quantikz}\n";
271
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 buffer << "\\begin{document}\n";
272
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 buffer << "\\begin{quantikz}\n";
273
274 // Wire labels
275 1 LatexContext context;
276 1 std::map<UnitID, unsigned>& line_ids = context.line_ids;
277 1 std::vector<LineBufferInfo>& lines = context.lines;
278
3/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 7 taken 5 times.
✓ Branch 8 taken 1 times.
0/1
? Decision couldn't be analyzed.
6 for (const Qubit& qb : this->all_qubits()) {
279 5 unsigned n_lines = lines.size();
280
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 line_ids.insert({qb, n_lines});
281
1/2
✓ Branch 3 taken 5 times.
✗ Branch 4 not taken.
5 LineBufferInfo& line = *lines.emplace(lines.end());
282
4/8
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 5 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 5 times.
✗ Branch 11 not taken.
5 line.buffer << "\\lstick{" + qb.repr() + "} & ";
283 5 line.is_quantum = true;
284 1 }
285
3/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 7 taken 2 times.
✓ Branch 8 taken 1 times.
0/1
? Decision couldn't be analyzed.
3 for (const Bit& cb : this->all_bits()) {
286 2 unsigned n_lines = lines.size();
287
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 line_ids.insert({cb, n_lines});
288
1/2
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
2 LineBufferInfo& line = *lines.emplace(lines.end());
289
4/8
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
2 line.buffer << "\\lstick{" + cb.repr() + "} & ";
290 2 line.is_quantum = false;
291 1 }
292
293 // Commands
294
3/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 8 taken 21 times.
✓ Branch 9 taken 1 times.
0/1
? Decision couldn't be analyzed.
22 for (const Command& com : this->get_commands()) {
295 21 std::set<unsigned> used_lines;
296 21 unsigned min_index = std::numeric_limits<unsigned>::max();
297 21 unsigned max_index = 0;
298
3/4
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
✓ Branch 8 taken 57 times.
✓ Branch 9 taken 21 times.
0/1
? Decision couldn't be analyzed.
78 for (const UnitID& arg : com.get_args()) {
299
2/4
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 57 times.
✗ Branch 5 not taken.
57 used_lines.insert(line_ids.at(arg));
300 21 }
301
2/2
✓ Branch 5 taken 57 times.
✓ Branch 6 taken 21 times.
2/2
✓ Decision 'true' taken 57 times.
✓ Decision 'false' taken 21 times.
78 for (unsigned index : used_lines) {
302
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 36 times.
1/2
✓ Decision 'true' taken 57 times.
✗ Decision 'false' not taken.
57 if (index < min_index) min_index = index;
303
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 15 times.
2/2
✓ Decision 'true' taken 21 times.
✓ Decision 'false' taken 36 times.
57 if (index > max_index) max_index = index;
304 }
305
306 21 unsigned max_depth = 0;
307
2/2
✓ Branch 0 taken 75 times.
✓ Branch 1 taken 21 times.
2/2
✓ Decision 'true' taken 75 times.
✓ Decision 'false' taken 21 times.
96 for (unsigned index = min_index; index <= max_index; index++) {
308
4/6
✓ Branch 1 taken 75 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 19 times.
✓ Branch 4 taken 56 times.
✓ Branch 6 taken 19 times.
✗ Branch 7 not taken.
0/1
? Decision couldn't be analyzed.
75 if (lines.at(index).depth > max_depth) max_depth = lines.at(index).depth;
309 }
310
2/2
✓ Branch 4 taken 57 times.
✓ Branch 5 taken 21 times.
2/2
✓ Decision 'true' taken 57 times.
✓ Decision 'false' taken 21 times.
78 for (unsigned index : used_lines) {
311
3/4
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
✓ Branch 4 taken 57 times.
0/1
? Decision couldn't be analyzed.
68 for (unsigned d = lines.at(index).depth; d < max_depth; d++) {
312
3/4
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 6 times.
2/2
✓ Decision 'true' taken 5 times.
✓ Decision 'false' taken 6 times.
11 if (lines.at(index).is_quantum) {
313
2/4
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
5 lines.at(index).buffer << "\\qw & ";
314 } else {
315
2/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
6 lines.at(index).buffer << "\\cw & ";
316 }
317 }
318
1/2
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
57 lines.at(index).depth = max_depth;
319 }
320
321
1/2
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
21 add_latex_for_command(context, com);
322
323
2/2
✓ Branch 0 taken 75 times.
✓ Branch 1 taken 21 times.
2/2
✓ Decision 'true' taken 75 times.
✓ Decision 'false' taken 21 times.
96 for (unsigned index = min_index; index <= max_index; index++) {
324
3/4
✓ Branch 1 taken 75 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 24 times.
✓ Branch 4 taken 75 times.
0/1
? Decision couldn't be analyzed.
99 for (unsigned d = lines.at(index).depth; d <= max_depth; d++) {
325
3/4
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 23 times.
✓ Branch 4 taken 1 times.
2/2
✓ Decision 'true' taken 23 times.
✓ Decision 'false' taken 1 times.
24 if (lines.at(index).is_quantum) {
326
2/4
✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 23 times.
✗ Branch 5 not taken.
23 lines.at(index).buffer << "\\qw & ";
327 } else {
328
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 lines.at(index).buffer << "\\cw & ";
329 }
330 }
331
1/2
✓ Branch 1 taken 75 times.
✗ Branch 2 not taken.
75 lines.at(index).depth = max_depth + 1;
332 }
333 22 }
334
335 // Fill out ends
336 1 unsigned max_depth = 0;
337
2/2
✓ Branch 5 taken 7 times.
✓ Branch 6 taken 1 times.
2/2
✓ Decision 'true' taken 7 times.
✓ Decision 'false' taken 1 times.
8 for (const LineBufferInfo& l : lines) {
338
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
0/1
? Decision couldn't be analyzed.
7 if (l.depth > max_depth) max_depth = l.depth;
339 }
340
2/2
✓ Branch 5 taken 7 times.
✓ Branch 6 taken 1 times.
2/2
✓ Decision 'true' taken 7 times.
✓ Decision 'false' taken 1 times.
8 for (LineBufferInfo& l : lines) {
341
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 7 times.
2/2
✓ Decision 'true' taken 20 times.
✓ Decision 'false' taken 7 times.
27 for (unsigned d = l.depth; d < max_depth; d++) {
342
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 20 times.
20 if (l.is_quantum) {
343 l.buffer << "\\qw & ";
344 } else {
345
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 l.buffer << "\\cw & ";
346 }
347 }
348 }
349
2/2
✓ Branch 5 taken 7 times.
✓ Branch 6 taken 1 times.
2/2
✓ Decision 'true' taken 7 times.
✓ Decision 'false' taken 1 times.
8 for (LineBufferInfo& l : lines) {
350
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 2 times.
2/2
✓ Decision 'true' taken 5 times.
✓ Decision 'false' taken 2 times.
7 if (l.is_quantum) {
351
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 l.buffer << "\\qw \\\\";
352 } else {
353
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 l.buffer << "\\cw \\\\";
354 }
355 }
356
357 // Build up overall buffer
358
2/2
✓ Branch 4 taken 7 times.
✓ Branch 5 taken 1 times.
2/2
✓ Decision 'true' taken 7 times.
✓ Decision 'false' taken 1 times.
8 for (LineBufferInfo& l : lines) {
359
3/6
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 7 times.
✗ Branch 8 not taken.
7 buffer << l.buffer.str() << "\n";
360 }
361
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 buffer << "\\end{quantikz}\n";
362
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 buffer << "\\end{document}";
363
364
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 return buffer.str();
365 1 }
366
367 1 void Circuit::to_latex_file(const std::string& filename) const {
368
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 std::ofstream file(filename);
369
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 file << to_latex_str();
370 1 }
371
372 } // namespace tket
373