| 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 "MeasurementReduction.hpp" | |||
| 16 | ||||
| 17 | namespace tket { | |||
| 18 | ||||
| 19 | 6 | MeasurementSetup measurement_reduction( | ||
| 20 | const std::list<QubitPauliString>& strings, PauliPartitionStrat strat, | |||
| 21 | GraphColourMethod method, CXConfigType cx_config) { | |||
| 22 | 6 | std::set<Qubit> qubits; | ||
| 23 |
2/2✓ Branch 5 taken 40 times.
✓ Branch 6 taken 6 times.
|
2/2✓ Decision 'true' taken 40 times.
✓ Decision 'false' taken 6 times.
|
46 | for (const QubitPauliString& qpt : strings) { |
| 24 |
2/2✓ Branch 5 taken 112 times.
✓ Branch 6 taken 40 times.
|
2/2✓ Decision 'true' taken 112 times.
✓ Decision 'false' taken 40 times.
|
152 | for (const std::pair<const Qubit, Pauli>& qb_p : qpt.map) |
| 25 |
1/2✓ Branch 1 taken 112 times.
✗ Branch 2 not taken.
|
112 | qubits.insert(qb_p.first); | |
| 26 | } | |||
| 27 | ||||
| 28 | 6 | std::map<Qubit, unsigned> qb_location_map; | ||
| 29 | 6 | unsigned u = 0; | ||
| 30 |
2/2✓ Branch 4 taken 18 times.
✓ Branch 5 taken 6 times.
|
2/2✓ Decision 'true' taken 18 times.
✓ Decision 'false' taken 6 times.
|
24 | for (const Qubit& qb : qubits) { |
| 31 |
1/2✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
|
18 | qb_location_map[qb] = u; | |
| 32 | 18 | ++u; | ||
| 33 | } | |||
| 34 | ||||
| 35 | std::list<std::list<QubitPauliString>> all_terms = | |||
| 36 |
1/2✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
|
6 | term_sequence(strings, strat, method); | |
| 37 | 6 | MeasurementSetup ms; | ||
| 38 | 6 | unsigned i = 0; | ||
| 39 |
2/2✓ Branch 5 taken 20 times.
✓ Branch 6 taken 6 times.
|
2/2✓ Decision 'true' taken 20 times.
✓ Decision 'false' taken 6 times.
|
26 | for (const std::list<QubitPauliString>& terms : all_terms) { |
| 40 | 20 | std::list<std::pair<QubitPauliTensor, Expr>> gadgets; | ||
| 41 |
2/2✓ Branch 5 taken 40 times.
✓ Branch 6 taken 20 times.
|
2/2✓ Decision 'true' taken 40 times.
✓ Decision 'false' taken 20 times.
|
60 | for (const QubitPauliString& string : terms) { |
| 42 |
1/2✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
|
40 | QubitPauliTensor qps(string); | |
| 43 |
2/4✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 40 times.
✗ Branch 5 not taken.
|
40 | gadgets.push_back({qps, 1.}); | |
| 44 | 40 | } | ||
| 45 | ||||
| 46 |
1/2✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
|
20 | std::set<Qubit> mutable_qb_set(qubits); | |
| 47 |
2/4✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
|
20 | Circuit cliff_circ = mutual_diagonalise(gadgets, mutable_qb_set, cx_config); | |
| 48 | 20 | unsigned bit_count = 0; | ||
| 49 |
3/4✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 7 taken 62 times.
✓ Branch 8 taken 20 times.
|
0/1? Decision couldn't be analyzed.
|
82 | for (const Qubit& qb : cliff_circ.all_qubits()) { |
| 50 |
2/4✓ Branch 1 taken 62 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 62 times.
✗ Branch 5 not taken.
|
62 | cliff_circ.add_bit(Bit(bit_count)); | |
| 51 |
2/4✓ Branch 1 taken 62 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 62 times.
✗ Branch 5 not taken.
|
62 | cliff_circ.add_measure(qb, Bit(bit_count)); | |
| 52 | 62 | ++bit_count; | ||
| 53 | 20 | } | ||
| 54 |
1/2✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
|
20 | ms.add_measurement_circuit(cliff_circ); | |
| 55 | ||||
| 56 | std::list<std::pair<QubitPauliTensor, Expr>>::const_iterator gadgets_iter = | |||
| 57 | 20 | gadgets.begin(); | ||
| 58 |
2/2✓ Branch 5 taken 40 times.
✓ Branch 6 taken 20 times.
|
2/2✓ Decision 'true' taken 40 times.
✓ Decision 'false' taken 20 times.
|
60 | for (const QubitPauliString& string : terms) { |
| 59 | 40 | const std::pair<QubitPauliTensor, Expr>& new_gadget = *gadgets_iter; | ||
| 60 | 40 | std::vector<unsigned> bits; | ||
| 61 | 40 | for (const std::pair<const Qubit, Pauli>& qp_pair : | ||
| 62 |
2/2✓ Branch 5 taken 112 times.
✓ Branch 6 taken 40 times.
|
192 | new_gadget.first.string.map) { | |
| 63 |
2/2✓ Branch 0 taken 88 times.
✓ Branch 1 taken 24 times.
|
2/2✓ Decision 'true' taken 88 times.
✓ Decision 'false' taken 24 times.
|
112 | if (qp_pair.second == Pauli::Z) |
| 64 |
2/4✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 88 times.
✗ Branch 5 not taken.
|
88 | bits.push_back(qb_location_map.at(qp_pair.first)); | |
| 65 | } | |||
| 66 |
1/2✓ Branch 2 taken 40 times.
✗ Branch 3 not taken.
|
40 | bool invert = (std::abs(new_gadget.first.coeff + Complex(1)) < EPS); | |
| 67 |
2/4✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 40 times.
✗ Branch 5 not taken.
|
40 | ms.add_result_for_term(string, {i, bits, invert}); | |
| 68 | 40 | ++gadgets_iter; | ||
| 69 | 40 | } | ||
| 70 | 20 | ++i; | ||
| 71 | 20 | } | ||
| 72 | ||||
| 73 | 12 | return ms; | ||
| 74 | 6 | } | ||
| 75 | ||||
| 76 | } // namespace tket | |||
| 77 |