Skip to content

Commit

Permalink
✨ Add XX-plus-YY and XX-minus-YY gate support to ZX library (#482)
Browse files Browse the repository at this point in the history
## Description

This PR adds the last remaining unsupported gates to the ZX library.
In the process, it also introduces a new convenience function for
integer division of parameter expressions that simplifies some code. In
conjunction with #549, this also fixes #486.

Fixes #343 

## Checklist:

<!---
This checklist serves as a reminder of a couple of things that ensure
your pull request will be merged swiftly.
-->

- [x] The pull request only contains commits that are related to it.
- [x] I have added appropriate tests and documentation.
- [x] I have made sure that all CI jobs on GitHub pass.
- [x] The pull request introduces no new warnings and follows the
project's style guidelines.

---------

Signed-off-by: burgholzer <burgholzer@me.com>
Co-authored-by: Tom Peham <pehamtom@gmx.at>
  • Loading branch information
burgholzer and pehamTom authored Feb 12, 2024
1 parent af9d20a commit 5f2041d
Show file tree
Hide file tree
Showing 4 changed files with 335 additions and 73 deletions.
20 changes: 20 additions & 0 deletions include/mqt-core/operations/Expression.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ class Term {
coeff /= rhs;
return *this;
}
Term& operator/=(const std::int64_t rhs) {
coeff /= static_cast<T>(rhs);
return *this;
}
[[nodiscard]] bool
totalAssignment(const VariableAssignment& assignment) const {
return assignment.find(getVar()) != assignment.end();
Expand Down Expand Up @@ -291,6 +295,16 @@ class Expression {
return *this;
}

Expression<T, U>& operator/=(int64_t rhs) {
if (rhs == 0) {
throw std::runtime_error("Trying to divide expression by 0!");
}
std::for_each(terms.begin(), terms.end(),
[&](auto& term) { term /= T{static_cast<double>(rhs)}; });
constant = U{double{constant} / static_cast<double>(rhs)};
return *this;
}

[[nodiscard]] Expression<T, U> operator-() const {
Expression<T, U> e;
e.terms.reserve(terms.size());
Expand Down Expand Up @@ -451,6 +465,12 @@ inline Expression<T, U> operator/(Expression<T, U> lhs, const U& rhs) {
return lhs;
}

template <typename T, typename U>
inline Expression<T, U> operator/(Expression<T, U> lhs, int64_t rhs) {
lhs /= rhs;
return lhs;
}

template <typename T, typename U>
inline Expression<T, U> operator*(const T& lhs, Expression<T, U> rhs) {
return rhs * lhs;
Expand Down
39 changes: 33 additions & 6 deletions include/mqt-core/zx/FunctionalityConstruction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "zx/ZXDiagram.hpp"

#include <cstddef>
#include <optional>

namespace zx {
class FunctionalityConstruction {
Expand All @@ -28,21 +29,47 @@ class FunctionalityConstruction {
std::vector<Vertex>& qubits,
const PiExpression& phase = PiExpression(),
EdgeType type = EdgeType::Simple);
static void
addRz(ZXDiagram& diag, const PiExpression& phase, Qubit target,
std::vector<Vertex>& qubits,
const std::optional<double>& unconvertedPhase = std::nullopt);
static void addRx(ZXDiagram& diag, const PiExpression& phase, Qubit target,
std::vector<Vertex>& qubits);
static void
addRy(ZXDiagram& diag, const PiExpression& phase, Qubit target,
std::vector<Vertex>& qubits,
const std::optional<double>& unconvertedPhase = std::nullopt);
static void addCnot(ZXDiagram& diag, Qubit ctrl, Qubit target,
std::vector<Vertex>& qubits,
EdgeType type = EdgeType::Simple);
static void addCphase(ZXDiagram& diag, const PiExpression& phase, Qubit ctrl,
Qubit target, std::vector<Vertex>& qubits);
static void addSwap(ZXDiagram& diag, Qubit target, Qubit target2,
std::vector<Vertex>& qubits);
static void addRzz(ZXDiagram& diag, const PiExpression& phase, Qubit target,
Qubit target2, std::vector<Vertex>& qubits);
static void addRxx(ZXDiagram& diag, const PiExpression& phase, Qubit target,
Qubit target2, std::vector<Vertex>& qubits);
static void addRzx(ZXDiagram& diag, const PiExpression& phase, Qubit target,
Qubit target2, std::vector<Vertex>& qubits);
static void
addRzz(ZXDiagram& diag, const PiExpression& phase, Qubit target,
Qubit target2, std::vector<Vertex>& qubits,
const std::optional<double>& unconvertedPhase = std::nullopt);
static void
addRxx(ZXDiagram& diag, const PiExpression& phase, Qubit target,
Qubit target2, std::vector<Vertex>& qubits,
const std::optional<double>& unconvertedPhase = std::nullopt);
static void
addRzx(ZXDiagram& diag, const PiExpression& phase, Qubit target,
Qubit target2, std::vector<Vertex>& qubits,
const std::optional<double>& unconvertedPhase = std::nullopt);
static void addDcx(ZXDiagram& diag, Qubit qubit1, Qubit qubit2,
std::vector<Vertex>& qubits);
static void
addXXplusYY(ZXDiagram& diag, const PiExpression& theta,
const PiExpression& beta, Qubit qubit0, Qubit qubit1,
std::vector<Vertex>& qubits,
const std::optional<double>& unconvertedBeta = std::nullopt);
static void
addXXminusYY(ZXDiagram& diag, const PiExpression& theta,
const PiExpression& beta, Qubit qubit0, Qubit qubit1,
std::vector<Vertex>& qubits,
const std::optional<double>& unconvertedBeta = std::nullopt);
static void addCcx(ZXDiagram& diag, Qubit ctrl0, Qubit ctrl1, Qubit target,
std::vector<Vertex>& qubits);
static op_it parseOp(ZXDiagram& diag, op_it it, op_it end,
Expand Down
Loading

0 comments on commit 5f2041d

Please sign in to comment.