GCC Code Coverage Report


Directory: ./
File: Circuit/include/Circuit/Boxes.hpp
Date: 2022-10-15 05:10:18
Exec Total Coverage
Lines: 42 101 41.6%
Functions: 29 73 39.7%
Branches: 13 34 38.2%
Decisions: 1 4 25.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 <boost/uuid/uuid.hpp>
18 #include <boost/uuid/uuid_generators.hpp>
19 #include <boost/uuid/uuid_io.hpp>
20 #include <memory>
21
22 #include "OpType/OpTypeInfo.hpp"
23 #include "Ops/Op.hpp"
24 #include "Utils/BiMapHeaders.hpp"
25 #include "Utils/EigenConfig.hpp"
26 #include "Utils/Json.hpp"
27 #include "Utils/MatrixAnalysis.hpp"
28 #include "Utils/UnitID.hpp"
29
30 namespace tket {
31
32 class Circuit;
33
34 /**
35 * Abstract class for an operation from which a circuit can be extracted
36 */
37 class Box : public Op {
38 public:
39 2492 explicit Box(const OpType &type, const op_signature_t &signature = {})
40
2/4
✓ Branch 2 taken 2492 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2492 times.
✗ Branch 7 not taken.
2492 : Op(type), signature_(signature), circ_(), id_(idgen()) {
41
2/6
✓ Branch 1 taken 2492 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2492 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
1/2
✓ Decision 'true' taken 2492 times.
✗ Decision 'false' not taken.
2492 if (!is_box_type(type)) throw BadOpType(type);
42 2492 }
43
44 414 Box(const Box &other)
45 : Op(other.get_type()),
46 414 signature_(other.signature_),
47 414 circ_(other.circ_),
48
2/4
✓ Branch 2 taken 414 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 414 times.
✗ Branch 6 not taken.
828 id_(other.id_) {}
49
50 /** Number of Quantum inputs */
51 unsigned n_qubits() const override;
52
53 /** Number of Boolean inputs */
54 unsigned n_boolean() const;
55
56 /** Number of Classical inputs */
57 unsigned n_classical() const;
58
59 op_signature_t get_signature() const override;
60
61 nlohmann::json serialize() const override;
62
63 static Op_ptr deserialize(const nlohmann::json &j);
64
65 /** Circuit represented by box */
66 std::shared_ptr<Circuit> to_circuit() const {
67
0/2
✗ Decision 'true' not taken.
✗ Decision 'false' not taken.
if (circ_ == nullptr) generate_circuit();
68 return circ_;
69 };
70
71 /** Unique identifier (preserved on copy) */
72 boost::uuids::uuid get_id() const { return id_; }
73
74 template <typename BoxT>
75 friend Op_ptr set_box_id(BoxT &b, boost::uuids::uuid newid);
76
77 protected:
78 2492 static boost::uuids::uuid idgen() {
79 static boost::uuids::random_generator gen = {};
80
81 2492 return gen();
82 }
83 op_signature_t signature_;
84 mutable std::shared_ptr<Circuit> circ_;
85 boost::uuids::uuid id_;
86
87 virtual void generate_circuit() const = 0;
88 };
89
90 // json for base Box attributes
91 nlohmann::json core_box_json(const Box &box);
92
93 /**
94 * @brief Set explicit ID on a box
95 *
96 * This is used for deserialization.
97 *
98 * @param b box
99 * @param[in] newid new ID
100 *
101 * @tparam BoxT concrete box type
102 *
103 * @return box with desired ID
104 */
105 template <typename BoxT>
106 23 Op_ptr set_box_id(BoxT &b, boost::uuids::uuid newid) {
107 23 b.id_ = newid;
108 23 return std::make_shared<BoxT>(b);
109 }
110
111 /**
112 * Operation defined as a circuit.
113 */
114 class CircBox : public Box {
115 public:
116 /**
117 * Construct from a given circuit. The circuit must be simple.
118 */
119 explicit CircBox(const Circuit &circ);
120
121 /**
122 * Construct from the empty circuit
123 */
124 CircBox();
125
126 /**
127 * Copy constructor
128 */
129 CircBox(const CircBox &other);
130
131 ~CircBox() override {}
132
133 bool is_clifford() const override;
134
135 Op_ptr symbol_substitution(
136 const SymEngine::map_basic_basic &sub_map) const override;
137
138 SymSet free_symbols() const override;
139
140 /**
141 * Equality check between two CircBox instances
142 */
143 3 bool is_equal(const Op &op_other) const override {
144
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 const CircBox &other = dynamic_cast<const CircBox &>(op_other);
145 3 return id_ == other.get_id();
146 }
147
148 Op_ptr dagger() const override;
149
150 Op_ptr transpose() const override;
151
152 static Op_ptr from_json(const nlohmann::json &j);
153
154 static nlohmann::json to_json(const Op_ptr &op);
155
156 protected:
157 void generate_circuit() const override {} // Already set by constructor
158 };
159
160 /**
161 * One-qubit operation defined as a unitary matrix
162 */
163 class Unitary1qBox : public Box {
164 public:
165 /**
166 * Construct from a given 2x2 unitary matrix
167 *
168 * @param m unitary matrix
169 */
170 explicit Unitary1qBox(const Eigen::Matrix2cd &m);
171
172 /**
173 * Construct from the identity matrix
174 */
175 Unitary1qBox();
176
177 /**
178 * Copy constructor
179 */
180 Unitary1qBox(const Unitary1qBox &other);
181
182 ~Unitary1qBox() override {}
183
184 Op_ptr symbol_substitution(
185 const SymEngine::map_basic_basic &) const override {
186 return Op_ptr();
187 }
188
189 SymSet free_symbols() const override { return {}; }
190
191 /**
192 * Equality check between two Unitary1qBox instances
193 */
194 3 bool is_equal(const Op &op_other) const override {
195
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 const Unitary1qBox &other = dynamic_cast<const Unitary1qBox &>(op_other);
196 3 return id_ == other.get_id();
197 }
198
199 /** Get the unitary matrix correspnding to this operation */
200 Eigen::Matrix2cd get_matrix() const { return m_; }
201
202 Eigen::MatrixXcd get_unitary() const override { return m_; }
203
204 Op_ptr dagger() const override;
205
206 Op_ptr transpose() const override;
207
208 bool is_clifford() const override;
209
210 static Op_ptr from_json(const nlohmann::json &j);
211
212 static nlohmann::json to_json(const Op_ptr &op);
213
214 protected:
215 void generate_circuit() const override;
216
217 private:
218 const Eigen::Matrix2cd m_;
219 };
220
221 /**
222 * Two-qubit operation defined as a unitary matrix (ILO-BE)
223 */
224 class Unitary2qBox : public Box {
225 public:
226 /**
227 * Construct from a given 4x4 unitary matrix
228 *
229 * @param m unitary matrix
230 * @param basis basis order convention for matrix
231 */
232 explicit Unitary2qBox(
233 const Eigen::Matrix4cd &m, BasisOrder basis = BasisOrder::ilo);
234
235 /**
236 * Construct from the identity matrix
237 */
238 Unitary2qBox();
239
240 /**
241 * Copy constructor
242 */
243 Unitary2qBox(const Unitary2qBox &other);
244
245 ~Unitary2qBox() override {}
246
247 Op_ptr symbol_substitution(
248 const SymEngine::map_basic_basic &) const override {
249 return Op_ptr();
250 }
251
252 SymSet free_symbols() const override { return {}; }
253
254 /**
255 * Equality check between two Unitary2qBox instances
256 */
257 6 bool is_equal(const Op &op_other) const override {
258
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 const Unitary2qBox &other = dynamic_cast<const Unitary2qBox &>(op_other);
259 6 return id_ == other.get_id();
260 }
261
262 /** Get the unitary matrix correspnding to this operation */
263 Eigen::Matrix4cd get_matrix() const { return m_; }
264
265 2 Eigen::MatrixXcd get_unitary() const override { return m_; }
266
267 Op_ptr dagger() const override;
268
269 Op_ptr transpose() const override;
270
271 static Op_ptr from_json(const nlohmann::json &j);
272
273 static nlohmann::json to_json(const Op_ptr &op);
274
275 protected:
276 void generate_circuit() const override;
277
278 private:
279 const Eigen::Matrix4cd m_;
280 };
281
282 /**
283 * Three-qubit operation defined as a unitary matrix (ILO-BE)
284 */
285 class Unitary3qBox : public Box {
286 public:
287 /**
288 * Construct from a given 8x8 unitary matrix
289 *
290 * @param m unitary matrix
291 * @param basis basis order convention for matrix
292 */
293 explicit Unitary3qBox(const Matrix8cd &m, BasisOrder basis = BasisOrder::ilo);
294
295 /**
296 * Construct from the identity matrix
297 */
298 Unitary3qBox();
299
300 /**
301 * Copy constructor
302 */
303 Unitary3qBox(const Unitary3qBox &other);
304
305 ~Unitary3qBox() override {}
306
307 Op_ptr symbol_substitution(
308 const SymEngine::map_basic_basic &) const override {
309 return Op_ptr();
310 }
311
312 SymSet free_symbols() const override { return {}; }
313
314 /**
315 * Equality check between two Unitary3qBox instances
316 */
317 3 bool is_equal(const Op &op_other) const override {
318
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 const Unitary3qBox &other = dynamic_cast<const Unitary3qBox &>(op_other);
319 3 return id_ == other.get_id();
320 }
321
322 /** Get the unitary matrix correspnding to this operation */
323 Matrix8cd get_matrix() const { return m_; }
324
325 Eigen::MatrixXcd get_unitary() const override { return m_; }
326
327 Op_ptr dagger() const override;
328
329 Op_ptr transpose() const override;
330
331 static Op_ptr from_json(const nlohmann::json &j);
332
333 static nlohmann::json to_json(const Op_ptr &op);
334
335 protected:
336 void generate_circuit() const override;
337
338 private:
339 const Matrix8cd m_;
340 };
341
342 /**
343 * Two-qubit operation defined in terms of a hermitian matrix and a phase.
344 *
345 * The unitary corresponding to the matrix A and phase t is exp(i*t*A).
346 * Matrix A is stored in ILO-BE form.
347 */
348 class ExpBox : public Box {
349 public:
350 /**
351 * Construct from a given 4x4 hermitian matrix and optional phase.
352 *
353 * @param A hermitian matrix
354 * @param t phase to apply
355 * @param basis basis order convention for matrix
356 */
357 ExpBox(
358 const Eigen::Matrix4cd &A, double t = 1.,
359 BasisOrder basis = BasisOrder::ilo);
360
361 /**
362 * Construct from the zero matrix (resulting in the identity)
363 */
364 ExpBox();
365
366 /**
367 * Copy constructor
368 */
369 ExpBox(const ExpBox &other);
370
371 ~ExpBox() override {}
372
373 Op_ptr symbol_substitution(
374 const SymEngine::map_basic_basic &) const override {
375 return Op_ptr();
376 }
377
378 SymSet free_symbols() const override { return {}; }
379
380 /**
381 * Equality check between two ExpBox instances
382 */
383 3 bool is_equal(const Op &op_other) const override {
384
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 const ExpBox &other = dynamic_cast<const ExpBox &>(op_other);
385 3 return id_ == other.get_id();
386 }
387
388 /** Get the hermitian matrix and phase parameter */
389 std::pair<Eigen::Matrix4cd, double> get_matrix_and_phase() const {
390 return std::make_pair(A_, t_);
391 }
392
393 Op_ptr dagger() const override;
394
395 Op_ptr transpose() const override;
396
397 static Op_ptr from_json(const nlohmann::json &j);
398
399 static nlohmann::json to_json(const Op_ptr &op);
400
401 protected:
402 void generate_circuit() const override;
403
404 private:
405 const Eigen::Matrix4cd A_;
406 double t_;
407 };
408
409 /**
410 * Operation defined as the exponential of a tensor of Pauli operators
411 */
412 class PauliExpBox : public Box {
413 public:
414 /**
415 * The operation implements the unitary operator
416 * \f$ e^{-\frac12 i \pi t \sigma_0 \otimes \sigma_1 \otimes \cdots} \f$
417 * where \f$ \sigma_i \in \{I,X,Y,Z\} \f$ are the Pauli operators.
418 */
419 PauliExpBox(const std::vector<Pauli> &paulis, const Expr &t);
420
421 /**
422 * Construct from the empty vector
423 */
424 PauliExpBox();
425
426 /**
427 * Copy constructor
428 */
429 PauliExpBox(const PauliExpBox &other);
430
431 ~PauliExpBox() override {}
432
433 bool is_clifford() const override;
434
435 SymSet free_symbols() const override;
436
437 /**
438 * Equality check between two PauliExpBox instances
439 */
440 3 bool is_equal(const Op &op_other) const override {
441
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 const PauliExpBox &other = dynamic_cast<const PauliExpBox &>(op_other);
442 3 return id_ == other.get_id();
443 }
444
445 /** Get the Pauli string */
446 std::vector<Pauli> get_paulis() const { return paulis_; }
447
448 /** Get the phase parameter */
449 Expr get_phase() const { return t_; }
450
451 Op_ptr dagger() const override;
452
453 Op_ptr transpose() const override;
454
455 Op_ptr symbol_substitution(
456 const SymEngine::map_basic_basic &sub_map) const override;
457
458 static Op_ptr from_json(const nlohmann::json &j);
459
460 static nlohmann::json to_json(const Op_ptr &op);
461
462 protected:
463 void generate_circuit() const override;
464
465 private:
466 std::vector<Pauli> paulis_;
467 Expr t_;
468 };
469
470 class CompositeGateDef;
471 typedef std::shared_ptr<CompositeGateDef> composite_def_ptr_t;
472
473 // CompositeGateDef
474 JSON_DECL(composite_def_ptr_t)
475
476 class CompositeGateDef : public std::enable_shared_from_this<CompositeGateDef> {
477 public:
478 CompositeGateDef(
479 const std::string &name, const Circuit &def,
480 const std::vector<Sym> &args);
481
482 static composite_def_ptr_t define_gate(
483 const std::string &name, const Circuit &def,
484 const std::vector<Sym> &args);
485
486 Circuit instance(const std::vector<Expr> &params) const;
487
488 13 std::string get_name() const { return name_; }
489 2 std::vector<Sym> get_args() const { return args_; }
490 8 std::shared_ptr<Circuit> get_def() const { return def_; }
491 16 unsigned n_args() const { return args_.size(); }
492 op_signature_t signature() const;
493
494 bool operator==(const CompositeGateDef &other) const;
495
496 private:
497 std::string name_;
498 std::shared_ptr<Circuit> def_;
499 std::vector<Sym> args_;
500
501 CompositeGateDef() {}
502 };
503
504 class CustomGate : public Box {
505 public:
506 CustomGate(const composite_def_ptr_t &gate, const std::vector<Expr> &params);
507 CustomGate(const CustomGate &other);
508
509 SymSet free_symbols() const override;
510
511 composite_def_ptr_t get_gate() const { return gate_; }
512 std::vector<Expr> get_params() const override { return params_; }
513 std::string get_name(bool latex = false) const override;
514
515 Op_ptr symbol_substitution(
516 const SymEngine::map_basic_basic &sub_map) const override;
517
518 /**
519 * Equality check between two CustomGate instances.
520 * This does more than simply checking id_.
521 */
522 bool is_equal(const Op &op_other) const override;
523
524 static Op_ptr from_json(const nlohmann::json &j);
525
526 static nlohmann::json to_json(const Op_ptr &op);
527
528 bool is_clifford() const override;
529
530 protected:
531 void generate_circuit() const override;
532 CustomGate() : Box(OpType::CustomGate), gate_(), params_() {}
533
534 private:
535 composite_def_ptr_t gate_;
536 const std::vector<Expr> params_;
537 };
538
539 /**
540 * Wraps another quantum op, adding control qubits
541 */
542 class QControlBox : public Box {
543 public:
544 /**
545 * Construct from a given op and number of controls
546 *
547 * @param op op to control
548 * @param n_controls number of qubit controls to add
549 */
550 explicit QControlBox(const Op_ptr &op, unsigned n_controls = 1);
551
552 /**
553 * Copy constructor
554 */
555 QControlBox(const QControlBox &other);
556
557 ~QControlBox() override {}
558
559 Op_ptr symbol_substitution(
560 const SymEngine::map_basic_basic &sub_map) const override;
561
562 SymSet free_symbols() const override;
563
564 /**
565 * Equality check between two QControlBox instances
566 */
567 3 bool is_equal(const Op &op_other) const override {
568
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 const QControlBox &other = dynamic_cast<const QControlBox &>(op_other);
569 3 return id_ == other.get_id();
570 }
571
572 std::string get_command_str(const unit_vector_t &args) const override;
573
574 Op_ptr dagger() const override;
575
576 Op_ptr transpose() const override;
577
578 Op_ptr get_op() const { return op_; }
579 unsigned get_n_controls() const { return n_controls_; }
580
581 static Op_ptr from_json(const nlohmann::json &j);
582
583 static nlohmann::json to_json(const Op_ptr &op);
584
585 protected:
586 void generate_circuit() const override;
587 QControlBox()
588 : Box(OpType::QControlBox), op_(), n_controls_(0), n_inner_qubits_(0) {}
589
590 private:
591 const Op_ptr op_;
592 const unsigned n_controls_;
593 unsigned n_inner_qubits_;
594 };
595
596 class ProjectorAssertionBox : public Box {
597 public:
598 /**
599 * Construct from a given 2x2, 4x4 or 8x8 projector matrix
600 *
601 * @param m projector matrix
602 * @param basis basis order convention for matrix
603 */
604 explicit ProjectorAssertionBox(
605 const Eigen::MatrixXcd &m, BasisOrder basis = BasisOrder::ilo);
606
607 /**
608 * Copy constructor
609 */
610 ProjectorAssertionBox(const ProjectorAssertionBox &other);
611
612 ~ProjectorAssertionBox() override {}
613
614 Op_ptr symbol_substitution(
615 const SymEngine::map_basic_basic &) const override {
616 return Op_ptr();
617 }
618
619 SymSet free_symbols() const override { return {}; }
620
621 /**
622 * Equality check between two ProjectorAssertionBox instances
623 */
624 bool is_equal(const Op &op_other) const override {
625 const ProjectorAssertionBox &other =
626 dynamic_cast<const ProjectorAssertionBox &>(op_other);
627 return id_ == other.get_id();
628 }
629
630 /** Get the unitary matrix correspnding to this operation */
631 8 Eigen::MatrixXcd get_matrix() const { return m_; }
632 8 std::vector<bool> get_expected_readouts() const { return expected_readouts_; }
633
634 Op_ptr dagger() const override;
635
636 Op_ptr transpose() const override;
637
638 op_signature_t get_signature() const override;
639
640 static Op_ptr from_json(const nlohmann::json &j);
641
642 static nlohmann::json to_json(const Op_ptr &op);
643
644 protected:
645 void generate_circuit() const override;
646
647 private:
648 const Eigen::MatrixXcd m_;
649 // expected readouts the debug bits
650 // false -> 0
651 // true -> 1
652 mutable std::vector<bool> expected_readouts_;
653 };
654
655 class StabiliserAssertionBox : public Box {
656 public:
657 /**
658 * Construct from a set of stabiliser Pauli strings
659 *
660 * @param paulis a set of stabiliser Pauli strings
661 */
662 explicit StabiliserAssertionBox(const PauliStabiliserList &paulis);
663
664 /**
665 * Copy constructor
666 */
667 StabiliserAssertionBox(const StabiliserAssertionBox &other);
668
669 ~StabiliserAssertionBox() override {}
670 Op_ptr symbol_substitution(
671 const SymEngine::map_basic_basic &) const override {
672 return Op_ptr();
673 }
674
675 SymSet free_symbols() const override { return {}; }
676
677 /**
678 * Equality check between two StabiliserAssertionBox instances
679 */
680 bool is_equal(const Op &op_other) const override {
681 const StabiliserAssertionBox &other =
682 dynamic_cast<const StabiliserAssertionBox &>(op_other);
683 return id_ == other.get_id();
684 }
685
686 /** Get the pauli stabilisers */
687 PauliStabiliserList get_stabilisers() const { return paulis_; }
688 5 std::vector<bool> get_expected_readouts() const { return expected_readouts_; }
689
690 Op_ptr dagger() const override;
691
692 Op_ptr transpose() const override;
693
694 static Op_ptr from_json(const nlohmann::json &j);
695
696 static nlohmann::json to_json(const Op_ptr &op);
697
698 op_signature_t get_signature() const override;
699
700 protected:
701 void generate_circuit() const override;
702
703 private:
704 const PauliStabiliserList paulis_;
705 // expected readouts the debug bits
706 // false -> 0
707 // true -> 1
708 mutable std::vector<bool> expected_readouts_;
709 };
710
711 class ToffoliBox : public Box {
712 public:
713 /**
714 * A cycle is a vector of basis states such that the first
715 * is mapped to the second, the second to the third, etc,
716 * with the final mapped to the first. The ordering is unique but the
717 * vector can be rotated without effecting the meaning.
718 */
719 typedef std::vector<std::vector<bool>> cycle_permutation_t;
720 /**
721 * Construct from a map between input and output basis states.
722 * Every basis state changed by the permutation should
723 * be in the provided map.A invalid_argument error is thrown
724 * if this is not true.
725 * Any basis state not in a permutation cycle will be assumed to
726 * take the identity.
727 * If each basis state is not the same size will throw an
728 * invalid_argument error.
729 *
730 * @param _n_qubits number of qubits permuted
731 * @param _permutation map between basis states
732 */
733 ToffoliBox(
734 unsigned _n_qubits,
735 std::map<std::vector<bool>, std::vector<bool>> _permutation);
736
737 /**
738 * Construct from a cycle of basis states.
739 * Any basis state not in a permutation cycle will be assumed to
740 * take the identity.
741 * The first element in the cycle is mapped to the second, second
742 * to third and so on. The final element is mapped to the first.
743 * If each basis state is not the same size will throw an
744 * invalid_argument error.
745 *
746 * @param _n_qubits number of qubits permuted
747 * @param _cycles basis states being peruted
748 */
749 ToffoliBox(unsigned _n_qubits, const std::set<cycle_permutation_t> &_cycles);
750
751 /**
752 * Copy constructor
753 */
754 ToffoliBox(const ToffoliBox &other);
755
756 Op_ptr symbol_substitution(
757 const SymEngine::map_basic_basic &) const override {
758 return Op_ptr();
759 }
760
761 /** Get the number of qubits */
762 unsigned get_n_qubits() const { return n_qubits_; }
763
764 /** Get cycles of basis states for ToffoliBox */
765 std::set<std::vector<std::vector<bool>>> get_cycles() const {
766 return cycles_;
767 }
768
769 SymSet free_symbols() const override { return {}; }
770
771 op_signature_t get_signature() const override;
772
773 static Op_ptr from_json(const nlohmann::json &j);
774
775 static nlohmann::json to_json(const Op_ptr &op);
776
777 protected:
778 void generate_circuit() const override;
779
780 private:
781 struct transposition_t {
782 std::vector<bool> first;
783 std::vector<bool> middle;
784 std::vector<bool> last;
785 };
786
787 typedef std::vector<transposition_t> cycle_transposition_t;
788
789 typedef std::vector<std::pair<std::vector<bool>, unsigned>> gray_code_t;
790
791 std::vector<transposition_t> cycle_to_transposition(
792 cycle_permutation_t cycle) const;
793
794 std::vector<cycle_transposition_t> get_transpositions() const;
795
796 Circuit get_bitstring_circuit(
797 const std::vector<bool> &bitstring, const unsigned &target) const;
798
799 gray_code_t transposition_to_gray_code(
800 const ToffoliBox::transposition_t &transposition) const;
801
802 cycle_transposition_t merge_cycles(
803 std::vector<ToffoliBox::cycle_transposition_t> &cycle_transpositions)
804 const;
805
806 unsigned n_qubits_;
807 std::set<cycle_permutation_t> cycles_;
808 };
809
810 } // namespace tket
811