Skip to content

Commit

Permalink
Fix incorrect controlled ConjugationBox handling (#1118)
Browse files Browse the repository at this point in the history
* Fix incorrect controlled ConjugationBox handling

* Add changelog entry

* Bump tket version

* run clang format

* bump tket version
  • Loading branch information
yao-cqc authored Nov 9, 2023
1 parent 57e64bd commit e5e0c3b
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 3 deletions.
2 changes: 1 addition & 1 deletion pytket/conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def package(self):
cmake.install()

def requirements(self):
self.requires("tket/1.2.66@tket/stable")
self.requires("tket/1.2.67@tket/stable")
self.requires("tklog/0.3.3@tket/stable")
self.requires("tkrng/0.3.3@tket/stable")
self.requires("tkassert/0.3.4@tket/stable")
Expand Down
1 change: 1 addition & 0 deletions pytket/docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Fixes:
of the bits in the expression in the resulting ``cmd.args``
* Fix incorrect serialisation of ``PauliExpPairBox`` when the Pauli strings are of
length 2.
* Fix incorrect controlled ``ConjugationBox`` handling.

1.21.0 (October 2023)
---------------------
Expand Down
2 changes: 1 addition & 1 deletion tket/conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

class TketConan(ConanFile):
name = "tket"
version = "1.2.66"
version = "1.2.67"
package_type = "library"
license = "Apache 2"
homepage = "https://github.com/CQCL/tket"
Expand Down
8 changes: 7 additions & 1 deletion tket/src/Circuit/CircUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,10 @@ static Circuit controlled_conjugation_box(
all_args[n_controls + i] = Qubit(n_controls + args[i].index()[0]);
target_args[i] = Qubit(n_controls + args[i].index()[0]);
}
Circuit circ(n_controls + n_targets);
Circuit circ;
for (const Qubit &q : all_args) {
circ.add_qubit(q);
}
circ.add_op(compute, target_args);
QControlBox controlled_action(action, n_controls);
circ.add_box(controlled_action, all_args);
Expand Down Expand Up @@ -801,6 +804,9 @@ static Eigen::Matrix2cd get_target_op_matrix(const Op_ptr &op) {

// A gate block containing Cn* gates that can be merged as a single CnU gate
// a block can also contain a single Barrier, which will be left in place
// TODO: conjugation boxs are accepted as well; however they don't fit the
// semantics. control_qubits and target_qubit don't mean anything for a
// conjugation box.
struct CnGateBlock {
enum class MergeMode { append, prepend };
CnGateBlock(const Command &command) {
Expand Down
26 changes: 26 additions & 0 deletions tket/test/src/Circuit/test_Boxes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,18 @@ SCENARIO("QControlBox", "[boxes]") {
d.add_op<unsigned>(OpType::CX, {2, 1});
REQUIRE(*c == d);
}
WHEN("Wrapped in a CircBox") {
Circuit inner_circ(4);
inner_circ.add_op<unsigned>(cj_op, {1, 3});
Op_ptr circbox_op = std::make_shared<CircBox>(inner_circ);
QControlBox qbox(circbox_op);
std::shared_ptr<Circuit> c = qbox.to_circuit();
Circuit d(5);
d.add_op<unsigned>(OpType::CX, {4, 2});
d.add_op<unsigned>(OpType::CZ, {0, 2});
d.add_op<unsigned>(OpType::CX, {4, 2});
REQUIRE(*c == d);
}
WHEN("Nested") {
Circuit compute_outer(3);
compute_outer.add_op<unsigned>(OpType::CX, {2, 1});
Expand Down Expand Up @@ -929,6 +941,20 @@ SCENARIO("QControlBox", "[boxes]") {
std::shared_ptr<Circuit> c = qbox.to_circuit();
REQUIRE(c->count_gates(OpType::CX) == 4);
}
GIVEN("controlled PauliExpBox") {
// https://github.com/CQCL/tket/issues/1109
PauliExpBox pbox(
SymPauliTensor({Pauli::I, Pauli::Z, Pauli::I, Pauli::I}, 0.7));
Op_ptr op = std::make_shared<PauliExpBox>(pbox);
QControlBox qbox(op);
std::shared_ptr<Circuit> c = qbox.to_circuit();
// construct the expected circuit
Circuit correct_inner(4);
correct_inner.add_op<unsigned>(OpType::Rz, 0.7, {1});
QControlBox correct_qbox(std::make_shared<CircBox>(correct_inner));
std::shared_ptr<Circuit> d = correct_qbox.to_circuit();
REQUIRE(*c == *d);
}
}

SCENARIO("Unitary3qBox", "[boxes]") {
Expand Down

0 comments on commit e5e0c3b

Please sign in to comment.