32 #ifndef CLASSES_GATES_H_ 33 #define CLASSES_GATES_H_ 68 H << 1 / std::sqrt(2.), 1 / std::sqrt(2.), 1 / std::sqrt(2.),
74 T << 1, 0, 0, std::exp(1_i *
pi / 4.0);
75 CNOT.block(2, 2, 2, 2) =
X;
82 SWAP.block(1, 1, 2, 2) =
X;
83 TOF.block(6, 6, 2, 2) =
X;
105 cmat Rn(
double theta,
const std::vector<double>& n)
const {
111 "qpp::Gates::Rn()",
"n is not a 3-dimensional vector!");
115 result = std::cos(theta / 2) *
Id2 -
116 1_i * std::sin(theta / 2) * (n[0] *
X + n[1] *
Y + n[2] *
Z);
132 return Rn(theta, {1, 0, 0});
146 return Rn(theta, {0, 1, 0});
160 return Rn(theta, {0, 0, 1});
182 cmat result = cmat::Zero(D, D);
183 for (
idx i = 0; i < D; ++i)
184 result(i, i) = std::pow(
omega(D), static_cast<double>(i));
203 cmat result = cmat::Zero(D * D, D * D);
206 #pragma omp parallel for collapse(2) 207 #endif // WITH_OPENMP_ 209 for (
idx j = 0; j < D; ++j)
210 for (
idx i = 0; i < D; ++i)
211 result(D * i + j, i + D * j) = 1;
237 #pragma omp parallel for collapse(2) 238 #endif // WITH_OPENMP_ 240 for (
idx j = 0; j < D; ++j)
241 for (
idx i = 0; i < D; ++i)
242 result(i, j) = 1 / std::sqrt(D) *
243 std::pow(
omega(D), static_cast<double>(i * j));
267 assert(
gcd(a, N) == 1);
272 if (N < 3 || a >= N) {
277 if (n < static_cast<idx>(std::ceil(std::log2(N)))) {
283 idx D =
static_cast<idx>(std::llround(std::pow(2, n)));
285 cmat result = cmat::Zero(D, D);
288 #pragma omp parallel for collapse(2) 289 #endif // WITH_OPENMP_ 291 for (
idx j = 0; j < N; ++j)
292 for (
idx i = 0; i < N; ++i)
293 if (static_cast<idx>(
modmul(j, a, N)) == i)
297 #pragma omp parallel for 298 #endif // WITH_OPENMP_ 300 for (
idx i = N; i < D; ++i)
323 return Fd(D).inverse() *
Zd(D) *
Fd(D);
335 template <
typename Derived = Eigen::MatrixXcd>
344 return Derived::Identity(D, D);
362 template <
typename Derived>
364 CTRL(
const Eigen::MatrixBase<Derived>& A,
const std::vector<idx>& ctrl,
365 const std::vector<idx>& target,
idx n,
idx d = 2)
const {
379 if (ctrl.size() == 0)
381 if (target.size() == 0)
393 std::vector<idx> ctrlgate = ctrl;
394 ctrlgate.insert(std::end(ctrlgate), std::begin(target),
396 std::sort(std::begin(ctrlgate), std::end(ctrlgate));
398 std::vector<idx> dims(n, d);
408 static_cast<Index
>(std::llround(std::pow(d, target.size()))))
425 idx n_gate = target.size();
426 idx n_ctrl = ctrl.size();
427 idx n_subsys_bar = n - ctrlgate.size();
428 idx D =
static_cast<idx>(std::llround(std::pow(d, n)));
429 idx DA =
static_cast<idx>(rA.rows());
431 static_cast<idx>(std::llround(std::pow(d, n_subsys_bar)));
434 std::vector<idx> subsys_bar =
complement(ctrlgate, n);
435 std::copy(std::begin(subsys_bar), std::end(subsys_bar),
436 std::begin(Csubsys_bar));
438 for (
idx k = 0; k < n; ++k) {
439 midx_row[k] = midx_col[k] = 0;
443 for (
idx k = 0; k < n_subsys_bar; ++k) {
448 for (
idx k = 0; k < n_gate; ++k) {
449 midxA_row[k] = midxA_col[k] = 0;
458 for (
idx i = 0; i < Dsubsys_bar; ++i) {
461 for (
idx k = 0; k < d; ++k) {
464 for (
idx a = 0; a < DA; ++a) {
471 for (
idx c = 0; c < n_ctrl; ++c)
472 midx_row[ctrl[c]] = midx_col[ctrl[c]] = k;
475 for (
idx c = 0; c < n_subsys_bar; ++c)
476 midx_row[Csubsys_bar[c]] = midx_col[Csubsys_bar[c]] =
480 for (
idx c = 0; c < n_gate; ++c)
481 midx_row[target[c]] = midxA_row[c];
484 for (
idx b = 0; b < DA; ++b) {
489 for (
idx c = 0; c < n_gate; ++c)
490 midx_col[target[c]] = midxA_col[c];
519 template <
typename Derived>
522 const std::vector<idx>& dims)
const {
540 if (pos + 1 > dims.size())
544 if (static_cast<idx>(rA.rows()) != dims[pos])
548 idx D = std::accumulate(std::begin(dims), std::end(dims),
549 static_cast<idx>(1), std::multiplies<idx>());
557 for (
idx k = 0; k < dims.size(); ++k) {
558 midx_row[k] = midx_col[k] = 0;
563 for (
idx i = 0; i < D; ++i) {
569 for (
idx a = 0; a < static_cast<idx>(rA.rows()); ++a) {
574 for (
idx b = 0; b < static_cast<idx>(rA.cols()); ++b) {
610 template <
typename Derived>
613 const std::initializer_list<idx>& dims)
const {
614 return this->
expandout(A, pos, std::vector<idx>(dims));
633 template <
typename Derived>
648 std::vector<idx> dims(n, d);
676 const idx D =
static_cast<idx>(U.rows());
683 else if (U == this->
H)
685 else if (U == this->
X)
687 else if (U == this->
Y)
689 else if (U == this->
Z)
691 else if (U == this->
S)
693 else if (U == this->
T)
702 else if (U == this->
CZ)
704 else if (U == this->
CNOTba)
706 else if (U == this->
SWAP)
715 else if (U == this->
FRED)
bool check_nonzero_size(const T &x) noexcept
Definition: util.h:123
Dimension(s) mismatch matrix size exception.
Definition: exception.h:300
cmat SWAP
SWAP gate.
Definition: gates.h:58
constexpr idx maxn
Maximum number of allowed qubits/qudits (subsystems)
Definition: constants.h:67
bool check_subsys_match_dims(const std::vector< idx > &subsys, const std::vector< idx > &dims)
Definition: util.h:219
Derived Id(idx D=2) const
Identity gate.
Definition: gates.h:336
~Gates()=default
Default destructor.
cplx omega(idx D)
D-th root of unity.
Definition: constants.h:89
Custom exception.
Definition: exception.h:600
cmat RZ(double theta) const
Qubit rotation of theta about the Z axis.
Definition: gates.h:155
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > dyn_mat
Dynamic Eigen matrix over the field specified by Scalar.
Definition: types.h:81
idx multiidx2n(const idx *const midx, idx numdims, const idx *const dims) noexcept
Definition: util.h:71
dyn_mat< typename Derived::Scalar > expandout(const Eigen::MatrixBase< Derived > &A, idx pos, const std::initializer_list< idx > &dims) const
Expands out.
Definition: gates.h:612
void n2multiidx(idx n, idx numdims, const idx *const dims, idx *result) noexcept
Definition: util.h:43
Singleton policy class, used internally to implement the singleton pattern via CRTP (Curiously recurr...
Definition: singleton.h:80
Subsystems mismatch dimensions exception.
Definition: exception.h:365
const Singleton class that implements most commonly used gates
Definition: gates.h:40
Quantum++ main namespace.
Definition: circuits.h:35
cmat Xd(idx D=2) const
Generalized X gate for qudits.
Definition: gates.h:315
Invalid dimension(s) exception.
Definition: exception.h:269
cmat S
S gate.
Definition: gates.h:51
cmat MODMUL(idx a, idx N, idx n) const
Modular multiplication gate for qubits Implements .
Definition: gates.h:263
cmat T
T gate.
Definition: gates.h:52
cmat FRED
Fredkin gate.
Definition: gates.h:62
cmat CNOTba
Controlled-NOT target->control gate.
Definition: gates.h:57
cmat Zd(idx D=2) const
Generalized Z gate for qudits.
Definition: gates.h:174
cmat H
Hadamard gate.
Definition: gates.h:47
cmat Rn(double theta, const std::vector< double > &n) const
Qubit rotation of theta about the 3-dimensional real (unit) vector n.
Definition: gates.h:105
cmat Id2
Identity gate.
Definition: gates.h:46
cmat X
Pauli Sigma-X gate.
Definition: gates.h:48
dyn_mat< typename Derived::Scalar > powm(const Eigen::MatrixBase< Derived > &A, idx n)
Fast matrix power based on the SQUARE-AND-MULTIPLY algorithm.
Definition: functions.h:800
cmat Fd(idx D=2) const
Quantum Fourier transform gate for qudits.
Definition: gates.h:226
dyn_mat< typename Derived::Scalar > expandout(const Eigen::MatrixBase< Derived > &A, idx pos, const std::vector< idx > &dims) const
Expands out.
Definition: gates.h:521
bool check_square_mat(const Eigen::MatrixBase< Derived > &A)
Definition: util.h:99
cmat RX(double theta) const
Qubit rotation of theta about the X axis.
Definition: gates.h:127
std::string get_name(const cmat &U) const
Get the name of the most common qubit gates.
Definition: gates.h:663
constexpr double pi
Definition: constants.h:72
cmat SWAPd(idx D=2) const
SWAP gate for qudits.
Definition: gates.h:195
Argument out of range exception.
Definition: exception.h:515
Eigen::MatrixXcd cmat
Complex (double precision) dynamic Eigen matrix.
Definition: types.h:64
bool check_dims(const std::vector< idx > &dims)
Definition: util.h:134
bigint modmul(bigint a, bigint b, bigint p)
Modular multiplication without overflow.
Definition: number_theory.h:304
cmat CNOT
Controlled-NOT control target gate.
Definition: gates.h:55
std::size_t idx
Non-negative integer index, make sure you use an unsigned type.
Definition: types.h:39
cmat Z
Pauli Sigma-Z gate.
Definition: gates.h:50
cmat CZ
Controlled-Phase gate.
Definition: gates.h:56
Matrix is not square exception.
Definition: exception.h:149
std::vector< idx > complement(std::vector< idx > subsys, idx n)
Constructs the complement of a subsystem vector.
Definition: functions.h:1780
cmat RY(double theta) const
Qubit rotation of theta about the Y axis.
Definition: gates.h:141
cmat Y
Pauli Sigma-Y gate.
Definition: gates.h:49
Gates()
Initializes the gates.
Definition: gates.h:67
dyn_mat< typename Derived::Scalar > expandout(const Eigen::MatrixBase< Derived > &A, idx pos, idx n, idx d=2) const
Expands out.
Definition: gates.h:635
cmat TOF
Toffoli gate.
Definition: gates.h:61
bigint gcd(bigint a, bigint b)
Greatest common divisor of two integers.
Definition: number_theory.h:115
dyn_mat< typename Derived::Scalar > CTRL(const Eigen::MatrixBase< Derived > &A, const std::vector< idx > &ctrl, const std::vector< idx > &target, idx n, idx d=2) const
Generates the multi-partite multiple-controlled-A gate in matrix form.
Definition: gates.h:364
Object has zero size exception.
Definition: exception.h:134