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});
181 cmat result = cmat::Zero(D, D);
182 for (
idx i = 0; i < D; ++i)
183 result(i, i) = std::pow(
omega(D), static_cast<double>(i));
201 cmat result = cmat::Zero(D * D, D * D);
204 #pragma omp parallel for collapse(2) 205 #endif // WITH_OPENMP_ 207 for (
idx j = 0; j < D; ++j)
208 for (
idx i = 0; i < D; ++i)
209 result(D * i + j, i + D * j) = 1;
234 #pragma omp parallel for collapse(2) 235 #endif // WITH_OPENMP_ 237 for (
idx j = 0; j < D; ++j)
238 for (
idx i = 0; i < D; ++i)
239 result(i, j) = 1 / std::sqrt(D) *
240 std::pow(
omega(D), static_cast<double>(i * j));
261 return Fd(D).inverse() *
Zd(D) *
Fd(D);
273 template <
typename Derived = Eigen::MatrixXcd>
281 return Derived::Identity(D, D);
299 template <
typename Derived>
301 CTRL(
const Eigen::MatrixBase<Derived>& A,
const std::vector<idx>& ctrl,
302 const std::vector<idx>& subsys,
idx n,
idx d = 2)
const {
316 if (ctrl.size() == 0)
318 if (subsys.size() == 0)
330 std::vector<idx> ctrlgate = ctrl;
331 ctrlgate.insert(std::end(ctrlgate), std::begin(subsys),
333 std::sort(std::begin(ctrlgate), std::end(ctrlgate));
335 std::vector<idx> dims(n, d);
345 static_cast<Index
>(std::llround(std::pow(d, subsys.size()))))
362 idx n_gate = subsys.size();
363 idx n_ctrl = ctrl.size();
364 idx n_subsys_bar = n - ctrlgate.size();
365 idx D =
static_cast<idx>(std::llround(std::pow(d, n)));
366 idx DA =
static_cast<idx>(rA.rows());
368 static_cast<idx>(std::llround(std::pow(d, n_subsys_bar)));
371 std::vector<idx> subsys_bar =
complement(ctrlgate, n);
372 std::copy(std::begin(subsys_bar), std::end(subsys_bar),
373 std::begin(Csubsys_bar));
375 for (
idx k = 0; k < n; ++k) {
376 midx_row[k] = midx_col[k] = 0;
380 for (
idx k = 0; k < n_subsys_bar; ++k) {
385 for (
idx k = 0; k < n_gate; ++k) {
386 midxA_row[k] = midxA_col[k] = 0;
395 for (
idx i = 0; i < Dsubsys_bar; ++i) {
398 for (
idx k = 0; k < d; ++k) {
401 for (
idx a = 0; a < DA; ++a) {
408 for (
idx c = 0; c < n_ctrl; ++c)
409 midx_row[ctrl[c]] = midx_col[ctrl[c]] = k;
412 for (
idx c = 0; c < n_subsys_bar; ++c)
413 midx_row[Csubsys_bar[c]] = midx_col[Csubsys_bar[c]] =
417 for (
idx c = 0; c < n_gate; ++c)
418 midx_row[subsys[c]] = midxA_row[c];
421 for (
idx b = 0; b < DA; ++b) {
426 for (
idx c = 0; c < n_gate; ++c)
427 midx_col[subsys[c]] = midxA_col[c];
456 template <
typename Derived>
459 const std::vector<idx>& dims)
const {
477 if (pos > dims.size() - 1)
481 if (static_cast<idx>(rA.rows()) != dims[pos])
485 idx D = std::accumulate(std::begin(dims), std::end(dims),
486 static_cast<idx>(1), std::multiplies<idx>());
494 for (
idx k = 0; k < dims.size(); ++k) {
495 midx_row[k] = midx_col[k] = 0;
500 for (
idx i = 0; i < D; ++i) {
506 for (
idx a = 0; a < static_cast<idx>(rA.rows()); ++a) {
511 for (
idx b = 0; b < static_cast<idx>(rA.cols()); ++b) {
547 template <
typename Derived>
550 const std::initializer_list<idx>& dims)
const {
551 return this->
expandout(A, pos, std::vector<idx>(dims));
570 template <
typename Derived>
585 std::vector<idx> dims(n, d);
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:75
bool check_subsys_match_dims(const std::vector< idx > &subsys, const std::vector< idx > &dims)
Definition: util.h:210
Derived Id(idx D=2) const
Identity gate.
Definition: gates.h:274
~Gates()=default
Default destructor.
cplx omega(idx D)
D-th root of unity.
Definition: constants.h:97
Custom exception.
Definition: exception.h:571
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:549
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: codes.h:35
cmat Xd(idx D=2) const
Generalized X gate for qudits.
Definition: gates.h:254
Invalid dimension(s) exception.
Definition: exception.h:269
cmat S
S gate.
Definition: gates.h:51
std::vector< T > complement(std::vector< T > subsys, idx N)
Constructs the complement of a subsystem vector.
Definition: functions.h:1733
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:751
cmat Fd(idx D=2) const
Quantum Fourier transform gate for qudits.
Definition: gates.h:224
dyn_mat< typename Derived::Scalar > expandout(const Eigen::MatrixBase< Derived > &A, idx pos, const std::vector< idx > &dims) const
Expands out.
Definition: gates.h:458
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
constexpr double pi
Definition: constants.h:80
cmat SWAPd(idx D=2) const
SWAP gate for qudits.
Definition: gates.h:194
Parameter 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
cmat CNOT
Controlled-NOT control target gate.
Definition: gates.h:55
std::size_t idx
Non-negative integer index.
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
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:572
cmat TOF
Toffoli gate.
Definition: gates.h:61
Object has zero size exception.
Definition: exception.h:134
dyn_mat< typename Derived::Scalar > CTRL(const Eigen::MatrixBase< Derived > &A, const std::vector< idx > &ctrl, const std::vector< idx > &subsys, idx n, idx d=2) const
Generates the multi-partite multiple-controlled-A gate in matrix form.
Definition: gates.h:301