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 |