27 #ifndef CLASSES_GATES_H_
28 #define CLASSES_GATES_H_
66 H << 1 / std::sqrt(2.), 1 / std::sqrt(2.),
67 1 / std::sqrt(2.), -1 / std::sqrt(2.);
72 T << 1, 0, 0, std::exp(1_i *
pi / 4.0);
73 CNOT.block(2, 2, 2, 2) =
X;
80 SWAP.block(1, 1, 2, 2) =
X;
81 TOF.block(6, 6, 2, 2) =
X;
103 cmat Rn(
double theta,
const std::vector<double>& n)
const
110 "n is not a 3-dimensional vector!");
114 result = std::cos(theta / 2) *
Id2
115 - 1_i * std::sin(theta / 2) * (n[0] *
X + n[1] *
Y + n[2] *
Z);
138 cmat result = cmat::Zero(D, D);
139 for (
idx i = 0; i < D; ++i)
140 result(i, i) = std::pow(
omega(D), i);
165 #pragma omp parallel for collapse(2)
166 #endif // WITH_OPENMP_
167 for (
idx j = 0; j < D; ++j)
168 for (
idx i = 0; i < D; ++i)
169 result(i, j) = 1 / std::sqrt(D) * std::pow(
omega(D), i * j);
191 return Fd(D).inverse() *
Zd(D) *
Fd(D);
203 template<
typename Derived = Eigen::MatrixXcd>
212 return Derived::Identity(D, D);
230 template<
typename Derived>
232 const std::vector<idx>& ctrl,
233 const std::vector<idx>& subsys,
250 if (ctrl.size() == 0)
252 if (subsys.size() == 0)
266 std::vector<idx> ctrlgate = ctrl;
267 ctrlgate.insert(std::end(ctrlgate), std::begin(subsys),
269 std::sort(std::begin(ctrlgate), std::end(ctrlgate));
271 std::vector<idx> dims(N, d);
280 if (rA.rows() != std::llround(std::pow(d, subsys.size())))
298 idx Ngate = subsys.size();
299 idx Nctrl = ctrl.size();
300 idx Nsubsys_bar = N - ctrlgate.size();
301 idx D =
static_cast<idx>(std::llround(std::pow(d, N)));
302 idx DA =
static_cast<idx>(rA.rows());
303 idx Dsubsys_bar =
static_cast<idx>(
304 std::llround(std::pow(d, Nsubsys_bar)));
307 std::vector<idx> subsys_bar =
complement(ctrlgate, N);
308 std::copy(std::begin(subsys_bar), std::end(subsys_bar),
309 std::begin(Csubsys_bar));
311 for (
idx k = 0; k < N; ++k)
313 midx_row[k] = midx_col[k] = 0;
317 for (
idx k = 0; k < Nsubsys_bar; ++k)
323 for (
idx k = 0; k < Ngate; ++k)
325 midxA_row[k] = midxA_col[k] = 0;
330 typename Derived::Scalar>
335 for (
idx i = 0; i < Dsubsys_bar; ++i)
339 for (
idx k = 0; k < d; ++k)
343 for (
idx a = 0; a < DA; ++a)
351 for (
idx c = 0; c < Nctrl; ++c)
352 midx_row[ctrl[c]] = midx_col[ctrl[c]] = k;
355 for (
idx c = 0; c < Nsubsys_bar; ++c)
356 midx_row[Csubsys_bar[c]] = midx_col[Csubsys_bar[c]] =
360 for (
idx c = 0; c < Ngate; ++c)
361 midx_row[subsys[c]] = midxA_row[c];
364 for (
idx b = 0; b < DA; ++b)
370 for (
idx c = 0; c < Ngate; ++c)
371 midx_col[subsys[c]] = midxA_col[c];
400 template<
typename Derived>
402 const Eigen::MatrixBase<Derived>& A,
idx pos,
403 const std::vector<idx>& dims)
const
411 throw Exception(
"qpp::Gates::expandout()",
416 throw Exception(
"qpp::Gates::expandout()",
421 throw Exception(
"qpp::Gates::expandout()",
425 if (pos > dims.size() - 1)
426 throw Exception(
"qpp::Gates::expandout()",
430 if (static_cast<idx>(rA.rows()) != dims[pos])
431 throw Exception(
"qpp::Gates::expandout()",
435 idx D = std::accumulate(std::begin(dims), std::end(dims),
436 static_cast<idx>(1), std::multiplies<idx>());
438 typename Derived::Scalar>
445 for (
idx k = 0; k < dims.size(); ++k)
447 midx_row[k] = midx_col[k] = 0;
452 for (
idx i = 0; i < D; ++i)
459 for (
idx a = 0; a < static_cast<idx>(rA.rows());
467 b < static_cast<idx>(rA.cols()); ++b)
504 template<
typename Derived>
506 const Eigen::MatrixBase<Derived>& A,
idx pos,
507 const std::initializer_list<idx>& dims)
const
509 return this->
expandout(A, pos, std::vector<idx>(dims));
528 template<
typename Derived>
530 const Eigen::MatrixBase<Derived>& A,
idx pos,
idx N,
idx d = 2)
537 throw Exception(
"qpp::Gates::expandout()",
542 throw Exception(
"qpp::Gates::expandout()",
546 std::vector<idx> dims(N, d);
bool check_nonzero_size(const T &x) noexcept
Definition: util.h:127
dyn_mat< typename Derived::Scalar > expandout(const Eigen::MatrixBase< Derived > &A, idx pos, const std::vector< idx > &dims) const
Expands out.
Definition: gates.h:401
cmat SWAP
SWAP gate.
Definition: gates.h:55
constexpr idx maxn
Maximum number of allowed qubits/qudits (subsystems)
Definition: constants.h:74
bool check_subsys_match_dims(const std::vector< idx > &subsys, const std::vector< idx > &dims)
Definition: util.h:198
~Gates()=default
Default destructor.
cplx omega(idx D)
D-th root of unity.
Definition: constants.h:96
dyn_mat< typename Derived::Scalar > expandout(const Eigen::MatrixBase< Derived > &A, idx pos, idx N, idx d=2) const
Expands out.
Definition: gates.h:529
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > dyn_mat
Dynamic Eigen matrix over the field specified by Scalar.
Definition: types.h:78
idx multiidx2n(const idx *const midx, idx numdims, const idx *const dims) noexcept
Definition: util.h:71
void n2multiidx(idx n, idx numdims, const idx *const dims, idx *result) noexcept
Definition: util.h:48
cmat Zd(idx D) const
Generalized Z gate for qudits.
Definition: gates.h:130
Singleton policy class, used internally to implement the singleton pattern via CRTP (Curiously recurr...
Definition: singleton.h:77
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:231
const Singleton class that implements most commonly used gates
Definition: gates.h:37
Quantum++ main namespace.
Definition: codes.h:30
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:505
cmat S
S gate.
Definition: gates.h:48
std::vector< T > complement(std::vector< T > subsys, idx N)
Constructs the complement of a subsystem vector.
Definition: functions.h:1814
cmat T
T gate.
Definition: gates.h:49
cmat FRED
Fredkin gate.
Definition: gates.h:59
cmat CNOTba
Controlled-NOT target control gate.
Definition: gates.h:54
cmat Fd(idx D) const
Fourier transform gate for qudits.
Definition: gates.h:154
cmat H
Hadamard gate.
Definition: gates.h:44
cmat Id2
Identity gate.
Definition: gates.h:43
cmat X
Pauli Sigma-X gate.
Definition: gates.h:45
Generates custom exceptions, used when validating function parameters.
Definition: exception.h:39
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:778
bool check_square_mat(const Eigen::MatrixBase< Derived > &A)
Definition: util.h:99
Derived Id(idx D) const
Identity gate.
Definition: gates.h:204
constexpr double pi
Definition: constants.h:79
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:103
Eigen::MatrixXcd cmat
Complex (double precision) dynamic Eigen matrix.
Definition: types.h:61
bool check_dims(const std::vector< idx > &dims)
Definition: util.h:140
cmat CNOT
Controlled-NOT control target gate.
Definition: gates.h:52
std::size_t idx
Non-negative integer index.
Definition: types.h:36
cmat Z
Pauli Sigma-Z gate.
Definition: gates.h:47
cmat CZ
Controlled-Phase gate.
Definition: gates.h:53
cmat Y
Pauli Sigma-Y gate.
Definition: gates.h:46
Gates()
Initializes the gates.
Definition: gates.h:64
cmat TOF
Toffoli gate.
Definition: gates.h:58
cmat Xd(idx D) const
Generalized X gate for qudits.
Definition: gates.h:183