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 "GateNodesBuffer.hpp" | |||
16 | ||||
17 | #include <stdexcept> | |||
18 | #include <tkassert/Assert.hpp> | |||
19 | ||||
20 | namespace tket { | |||
21 | namespace tket_sim { | |||
22 | namespace internal { | |||
23 | ||||
24 | struct GateNodesBuffer::Impl { | |||
25 | Eigen::MatrixXcd& matrix; | |||
26 | const double abs_epsilon; | |||
27 | const unsigned number_of_qubits; | |||
28 | double global_phase; | |||
29 | ||||
30 | 5871 | Impl(Eigen::MatrixXcd& matr, double abs_eps) | ||
31 | 5871 | : matrix(matr), | ||
32 | 5871 | abs_epsilon(abs_eps), | ||
33 | 5871 | number_of_qubits(get_number_of_qubits(matr.rows())), | ||
34 | 5871 | global_phase(0.0) { | ||
35 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 5871 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 5871 times.
|
5871 | if (matr.cols() == 0) { |
36 | ✗ | throw std::invalid_argument("Matrix has zero cols"); | ||
37 | } | |||
38 | 5871 | } | ||
39 | ||||
40 | void push(const GateNode&); | |||
41 | ||||
42 | 5952 | void add_global_phase(double ph) { global_phase += ph; } | ||
43 | ||||
44 | void flush(); | |||
45 | }; | |||
46 | ||||
47 | 191037 | void GateNodesBuffer::Impl::push(const GateNode& node) { | ||
48 | // Later, we might add fancy optimisation here: | |||
49 | // storing the gate for later use, looking for other compatible gates | |||
50 | // acting on the same qubits to merge with this, etc. etc. | |||
51 | 191037 | node.apply_full_unitary(matrix, number_of_qubits); | ||
52 | 191037 | } | ||
53 | ||||
54 | 5868 | void GateNodesBuffer::Impl::flush() { | ||
55 |
2/2✓ Branch 0 taken 967 times.
✓ Branch 1 taken 4901 times.
|
2/2✓ Decision 'true' taken 967 times.
✓ Decision 'false' taken 4901 times.
|
5868 | if (global_phase != 0.0) { |
56 | 967 | const auto factor = std::polar(1.0, PI * global_phase); | ||
57 |
1/2✓ Branch 1 taken 967 times.
✗ Branch 2 not taken.
|
967 | matrix *= factor; | |
58 | 967 | global_phase = 0.0; | ||
59 | } | |||
60 | 5868 | } | ||
61 | ||||
62 | 5871 | GateNodesBuffer::GateNodesBuffer(Eigen::MatrixXcd& matrix, double abs_epsilon) | ||
63 | 5871 | : pimpl(std::make_unique<Impl>(matrix, abs_epsilon)) {} | ||
64 | ||||
65 | 5871 | GateNodesBuffer::~GateNodesBuffer() {} | ||
66 | ||||
67 | 191037 | void GateNodesBuffer::push(const GateNode& node) { pimpl->push(node); } | ||
68 | ||||
69 | 5952 | void GateNodesBuffer::add_global_phase(double ph) { | ||
70 | 5952 | pimpl->add_global_phase(ph); | ||
71 | 5952 | } | ||
72 | ||||
73 | 5868 | void GateNodesBuffer::flush() { pimpl->flush(); } | ||
74 | ||||
75 | } // namespace internal | |||
76 | } // namespace tket_sim | |||
77 | } // namespace tket | |||
78 |