Skip to content

Commit

Permalink
init commit
Browse files Browse the repository at this point in the history
  • Loading branch information
multiphaseCFD committed Oct 18, 2024
1 parent a36c0fc commit 34c5e28
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 1 deletion.
3 changes: 3 additions & 0 deletions .github/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@

### Improvements

* Add joint check for the N-controlled wires support in `lightning.qubit`.
[(#949)](https://github.com/PennyLaneAI/pennylane-lightning/pull/949)

* Optimize `GlobalPhase` and `C(GlobalPhase)` gate implementation for `lightning.gpu`.
[(#946)](https://github.com/PennyLaneAI/pennylane-lightning/pull/946)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,11 @@ class StateVectorLQubit : public StateVectorBase<PrecisionT, Derived> {
const std::vector<std::size_t> &wires,
bool inverse = false,
const std::vector<PrecisionT> &params = {}) {
// Add disjoint check.
PL_ABORT_IF_NOT(
areVecsDisjoint<std::size_t>(controlled_wires, wires),
"`controlled_wires` and `target wires` must be disjoint.");

PL_ABORT_IF_NOT(controlled_wires.size() == controlled_values.size(),
"`controlled_wires` must have the same size as "
"`controlled_values`.");
Expand Down Expand Up @@ -420,6 +425,11 @@ class StateVectorLQubit : public StateVectorBase<PrecisionT, Derived> {
const std::vector<std::size_t> &wires, bool inverse,
const std::vector<PrecisionT> &params,
const std::vector<ComplexT, Alloc> &matrix) {
// Add disjoint check.
PL_ABORT_IF_NOT(
areVecsDisjoint<std::size_t>(controlled_wires, wires),
"`controlled_wires` and `target wires` must be disjoint.");

PL_ABORT_IF_NOT(controlled_wires.size() == controlled_values.size(),
"`controlled_wires` must have the same size as "
"`controlled_values`.");
Expand Down Expand Up @@ -569,6 +579,10 @@ class StateVectorLQubit : public StateVectorBase<PrecisionT, Derived> {
const std::vector<bool> &controlled_values,
const std::vector<std::size_t> &wires,
bool inverse = false) {
// Add disjoint check.
PL_ABORT_IF_NOT(
areVecsDisjoint<std::size_t>(controlled_wires, wires),
"`controlled_wires` and `target wires` must be disjoint.");
applyControlledMatrix(matrix.data(), controlled_wires,
controlled_values, wires, inverse);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,14 @@ TEMPLATE_TEST_CASE("StateVectorLQubitManaged::applyOperation non-param "
<< "controls = {" << control << "} "
<< ", wires = {" << wire << "} - "
<< PrecisionToName<PrecisionT>::value) {
if (control == wire) {
REQUIRE_THROWS_AS(
sv0.applyOperation("PauliX", std::vector<std::size_t>{control},
std::vector<bool>{true},
std::vector<std::size_t>{wire}),
LightningException);
}

if (control != wire) {
auto st0 = createRandomStateVectorData<PrecisionT>(re, num_qubits);
sv0.updateData(st0);
Expand All @@ -687,7 +695,7 @@ TEMPLATE_TEST_CASE("StateVectorLQubitManaged::applyOperation non-param "
approx(sv1.getDataVector()).margin(margin));
}

if (control != 0 && wire != 0) {
if (control != 0 && wire != 0 && control != wire) {
sv0.applyOperation("Toffoli", {0, control, wire});
sv1.applyOperation("PauliX", std::vector<std::size_t>{0, control},
std::vector<bool>{true, true},
Expand Down Expand Up @@ -760,6 +768,15 @@ TEMPLATE_TEST_CASE("StateVectorLQubitManaged::applyOperation non-param "
REQUIRE(sv0.getDataVector() ==
approx(sv1.getDataVector()).margin(margin));
}

if (control == wire) {
const auto matrix = getHadamard<std::complex, PrecisionT>();
REQUIRE_THROWS_AS(sv0.applyControlledMatrix(
matrix, std::vector<std::size_t>{control},
std::vector<bool>{true},
std::vector<std::size_t>{wire}),
LightningException);
}
}
DYNAMIC_SECTION("N-controlled S - "
<< "controls = {" << control << "} "
Expand Down
14 changes: 14 additions & 0 deletions pennylane_lightning/core/src/utils/Util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -574,4 +574,18 @@ std::vector<T1> cast_vector(const std::vector<T0> &vec) {
return result;
}

/**
* @brief Check if two vectors are disjoint.
* @tparam T Data type.
* @param v1 First vector.
* @param v2 Second vector.
*
* @return bool True if the vectors are disjoint, false otherwise.
*/
template <typename T = std::size_t>
bool areVecsDisjoint(const std::vector<T> &v1, const std::vector<T> &v2) {
std::set<std::size_t> s0(v1.begin(), v1.end());
s0.insert(v2.begin(), v2.end());
return s0.size() == v1.size() + v2.size();
}
} // namespace Pennylane::Util
16 changes: 16 additions & 0 deletions pennylane_lightning/core/src/utils/tests/Test_Util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,3 +217,19 @@ TEMPLATE_TEST_CASE("Util::kronProd", "[Util][LinearAlgebra]", float, double) {
CHECK(vec == expected);
}
}

TEST_CASE("Util::areVecsDisjoint", "[Util][LinearAlgebra]") {
SECTION("Test for disjoint vectors") {
std::vector<std::size_t> vec0{0, 1, 2};
std::vector<std::size_t> vec1{3, 4, 5};

REQUIRE(areVecsDisjoint(vec0, vec1) == true);
}

SECTION("Test for joint vectors") {
std::vector<std::size_t> vec0{0, 1, 2};
std::vector<std::size_t> vec1{2, 4, 5};

REQUIRE(areVecsDisjoint(vec0, vec1) == false);
}
}

0 comments on commit 34c5e28

Please sign in to comment.