31 #if (__GNUC__ && !__clang__)
32 #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
54 template<
typename Derived1,
typename Derived2>
56 const Eigen::MatrixBase<Derived1>& state,
57 const Eigen::MatrixBase<Derived2>& A,
58 const std::vector<idx>& ctrl,
59 const std::vector<idx>& subsys,
60 const std::vector<idx>& dims)
62 const typename Eigen::MatrixBase<Derived1>::EvalReturnType& rstate
69 if (!std::is_same<
typename Derived1::Scalar,
70 typename Derived2::Scalar>::value)
87 idx d = ctrl.size() > 0 ? dims[ctrl[0]] : 1;
88 for (
idx i = 1; i < ctrl.size(); ++i)
89 if (dims[ctrl[i]] != d)
103 std::vector<idx> subsys_dims(subsys.size());
104 for (
idx i = 0; i < subsys.size(); ++i)
105 subsys_dims[i] = dims[subsys[i]];
110 std::vector<idx> ctrlgate = ctrl;
111 ctrlgate.insert(std::end(ctrlgate), std::begin(subsys), std::end(subsys));
112 std::sort(std::begin(ctrlgate), std::end(ctrlgate));
122 std::vector<dyn_mat<typename Derived1::Scalar>> Ai;
123 std::vector<dyn_mat<typename Derived1::Scalar>> Aidagger;
124 for (
idx i = 0; i < std::max(d, static_cast<idx>(2)); ++i)
126 Ai.push_back(
powm(rA, i));
130 idx D =
static_cast<idx>(rstate.rows());
132 idx ctrlsize = ctrl.size();
133 idx ctrlgatesize = ctrlgate.size();
134 idx subsyssize = subsys.size();
136 idx Dctrl =
static_cast<idx>(std::llround(std::pow(d, ctrlsize)));
137 idx DA =
static_cast<idx>(rA.rows());
145 std::vector<idx> ctrlgate_bar =
complement(ctrlgate, N);
147 idx ctrlgate_barsize = ctrlgate_bar.size();
150 for (
idx i = 0; i < ctrlgate_barsize; ++i)
151 DCTRLA_bar *= dims[ctrlgate_bar[i]];
153 for (
idx k = 0; k < N; ++k)
155 for (
idx k = 0; k < subsyssize; ++k)
156 CdimsA[k] = dims[subsys[k]];
157 for (
idx k = 0; k < ctrlsize; ++k)
159 for (
idx k = 0; k < ctrlgate_barsize; ++k)
160 CdimsCTRLA_bar[k] = dims[ctrlgate_bar[k]];
164 auto coeff_idx_ket = [&](
idx i_,
idx m_,
idx r_) noexcept
165 -> std::pair<typename Derived1::Scalar, idx>
168 typename Derived1::Scalar coeff = 0;
177 for (
idx k = 0; k < ctrlsize; ++k)
184 CdimsCTRLA_bar, CmidxCTRLA_bar);
185 for (
idx k = 0; k < N - ctrlgatesize; ++k)
187 Cmidx[ctrlgate_bar[k]] = CmidxCTRLA_bar[k];
192 for (
idx k = 0; k < subsyssize; ++k)
194 Cmidx[subsys[k]] = CmidxA[k];
201 for (
idx n_ = 0; n_ < DA; ++n_)
204 for (
idx k = 0; k < subsyssize; ++k)
206 Cmidx[subsys[k]] = CmidxA[k];
208 coeff += Ai[i_](m_, n_) *
212 return std::make_pair(coeff, indx);
218 auto coeff_idx_rho = [&](
idx i1_,
idx m1_,
220 -> std::tuple<typename Derived1::Scalar, idx, idx>
224 typename Derived1::Scalar coeff = 0, lhs = 1, rhs = 1;
239 CdimsCTRL, CmidxCTRLrow);
241 CdimsCTRL, CmidxCTRLcol);
243 for (
idx k = 0; k < ctrlsize; ++k)
245 Cmidxrow[ctrl[k]] = CmidxCTRLrow[k];
246 Cmidxcol[ctrl[k]] = CmidxCTRLcol[k];
251 CdimsCTRLA_bar, CmidxCTRLA_barrow);
253 CdimsCTRLA_bar, CmidxCTRLA_barcol);
254 for (
idx k = 0; k < N - ctrlgatesize; ++k)
256 Cmidxrow[ctrlgate_bar[k]] = CmidxCTRLA_barrow[k];
257 Cmidxcol[ctrlgate_bar[k]] = CmidxCTRLA_barcol[k];
263 for (
idx k = 0; k < subsys.size(); ++k)
265 Cmidxrow[subsys[k]] = CmidxArow[k];
266 Cmidxcol[subsys[k]] = CmidxAcol[k];
274 bool all_ctrl_rows_equal =
true;
275 bool all_ctrl_cols_equal =
true;
277 idx first_ctrl_row, first_ctrl_col;
280 first_ctrl_row = CmidxCTRLrow[0];
281 first_ctrl_col = CmidxCTRLcol[0];
284 first_ctrl_row = first_ctrl_col = 1;
287 for (
idx k = 1; k < ctrlsize; ++k)
289 if (CmidxCTRLrow[k] != first_ctrl_row)
291 all_ctrl_rows_equal =
false;
295 for (
idx k = 1; k < ctrlsize; ++k)
297 if (CmidxCTRLcol[k] != first_ctrl_col)
299 all_ctrl_cols_equal =
false;
305 for (
idx n1_ = 0; n1_ < DA; ++n1_)
308 for (
idx k = 0; k < subsyssize; ++k)
310 Cmidxrow[subsys[k]] = CmidxArow[k];
314 if (all_ctrl_rows_equal)
316 lhs = Ai[first_ctrl_row](m1_, n1_);
319 lhs = (m1_ == n1_) ? 1 : 0;
322 for (
idx n2_ = 0; n2_ < DA; ++n2_)
325 for (
idx k = 0; k < subsyssize; ++k)
327 Cmidxcol[subsys[k]] = CmidxAcol[k];
330 if (all_ctrl_cols_equal)
332 rhs = Aidagger[first_ctrl_col](n2_, m2_);
335 rhs = (n2_ == m2_) ? 1 : 0;
340 coeff += lhs * rstate(idxrowtmp, idxcoltmp) * rhs;
344 return std::make_tuple(coeff, idxrow, idxcol);
360 #pragma omp parallel for collapse(2)
361 #endif // WITH_OPENMP_
362 for (
idx m = 0; m < DA; ++m)
363 for (
idx r = 0; r < DCTRLA_bar; ++r)
367 result(coeff_idx_ket(1, m, r).second) =
368 coeff_idx_ket(1, m, r).first;
370 for (
idx i = 0; i < d; ++i)
372 result(coeff_idx_ket(i, m, r).second) =
373 coeff_idx_ket(i, m, r).first;
393 #pragma omp parallel for collapse(4)
394 #endif // WITH_OPENMP_
395 for (
idx m1 = 0; m1 < DA; ++m1)
396 for (
idx r1 = 0; r1 < DCTRLA_bar; ++r1)
397 for (
idx m2 = 0; m2 < DA; ++m2)
398 for (
idx r2 = 0; r2 < DCTRLA_bar; ++r2)
401 auto coeff_idxes = coeff_idx_rho(1, m1, r1,
403 result(std::get<1>(coeff_idxes),
404 std::get<2>(coeff_idxes)) =
405 std::get<0>(coeff_idxes);
408 for (
idx i1 = 0; i1 < Dctrl; ++i1)
409 for (
idx i2 = 0; i2 < Dctrl; ++i2)
411 auto coeff_idxes = coeff_idx_rho(
414 result(std::get<1>(coeff_idxes),
415 std::get<2>(coeff_idxes)) =
416 std::get<0>(coeff_idxes);
443 template<
typename Derived1,
typename Derived2>
445 const Eigen::MatrixBase<Derived1>& state,
446 const Eigen::MatrixBase<Derived2>& A,
447 const std::vector<idx>& ctrl,
448 const std::vector<idx>& subsys,
451 const typename Eigen::MatrixBase<Derived1>::EvalReturnType& rstate
467 std::vector<idx> dims(N, d);
469 return applyCTRL(rstate, rA, ctrl, subsys, dims);
485 template<
typename Derived1,
typename Derived2>
487 const Eigen::MatrixBase<Derived1>& state,
488 const Eigen::MatrixBase<Derived2>& A,
489 const std::vector<idx>& subsys,
490 const std::vector<idx>& dims)
492 const typename Eigen::MatrixBase<Derived1>::EvalReturnType& rstate
499 if (!std::is_same<
typename Derived1::Scalar,
500 typename Derived2::Scalar>::value)
524 std::vector<idx> subsys_dims(subsys.size());
525 for (
idx i = 0; i < subsys.size(); ++i)
526 subsys_dims[i] = dims[subsys[i]];
540 return applyCTRL(rstate, rA, {}, subsys, dims);
551 return applyCTRL(rstate, rA, {}, subsys, dims);
572 template<
typename Derived1,
typename Derived2>
574 const Eigen::MatrixBase<Derived1>& state,
575 const Eigen::MatrixBase<Derived2>& A,
576 const std::vector<idx>& subsys,
579 const typename Eigen::MatrixBase<Derived1>::EvalReturnType& rstate
595 std::vector<idx> dims(N, d);
597 return apply(rstate, rA, subsys, dims);
608 template<
typename Derived>
610 const std::vector<cmat>& Ks)
612 const cmat& rA = A.derived();
624 if (Ks[0].rows() != rA.rows())
628 if (it.rows() != Ks[0].rows() || it.cols() != Ks[0].rows())
632 cmat result = cmat::Zero(rA.rows(), rA.rows());
635 #pragma omp parallel for
636 #endif // WITH_OPENMP_
637 for (
idx i = 0; i < Ks.size(); ++i)
641 #endif // WITH_OPENMP_
643 result += Ks[i] * rA *
adjoint(Ks[i]);
660 template<
typename Derived>
662 const std::vector<cmat>& Ks,
663 const std::vector<idx>& subsys,
664 const std::vector<idx>& dims)
666 const cmat& rA = A.derived();
692 std::vector<idx> subsys_dims(subsys.size());
693 for (
idx i = 0; i < subsys.size(); ++i)
694 subsys_dims[i] = dims[subsys[i]];
705 if (it.rows() != Ks[0].rows() || it.cols() != Ks[0].rows())
709 cmat result = cmat::Zero(rA.rows(), rA.rows());
711 for (
idx i = 0; i < Ks.size(); ++i)
712 result +=
apply(rA, Ks[i], subsys, dims);
727 template<
typename Derived>
729 const std::vector<cmat>& Ks,
730 const std::vector<idx>& subsys,
733 const cmat& rA = A.derived();
747 std::vector<idx> dims(N, d);
749 return apply(rA, Ks, subsys, dims);
775 if (it.rows() != Ks[0].rows() || it.cols() != Ks[0].rows())
780 idx D =
static_cast<idx>(Ks[0].rows());
782 cmat result(D * D, D * D);
783 cmat MN = cmat::Zero(D, D);
784 bra A = bra::Zero(D);
785 ket B = ket::Zero(D);
786 cmat EMN = cmat::Zero(D, D);
789 #pragma omp parallel for collapse(2)
790 #endif // WITH_OPENMP_
791 for (
idx m = 0; m < D; ++m)
793 for (
idx n = 0; n < D; ++n)
797 #endif // WITH_OPENMP_
801 for (
idx i = 0; i < Ks.size(); ++i)
802 EMN += Ks[i] * MN *
adjoint(Ks[i]);
805 for (
idx a = 0; a < D; ++a)
808 for (
idx b = 0; b < D; ++b)
812 result(a * D + b, m * D + n) =
813 static_cast<cmat>(A * EMN * B).value();
818 EMN = cmat::Zero(D, D);
853 if (it.rows() != Ks[0].rows() || it.cols() != Ks[0].rows())
858 idx D =
static_cast<idx>(Ks[0].rows());
862 cmat MES = cmat::Zero(D * D, 1);
863 for (
idx a = 0; a < D; ++a)
868 cmat result = cmat::Zero(D * D, D * D);
871 #pragma omp parallel for
872 #endif // WITH_OPENMP_
873 for (
idx i = 0; i < Ks.size(); ++i)
877 #endif // WITH_OPENMP_
879 result +=
kron(cmat::Identity(D, D), Ks[i]) * Omega
911 if (D * D != static_cast<idx>(A.rows()))
917 std::vector<cmat> result;
919 for (
idx i = 0; i < D * D; ++i)
921 if (std::abs(ev(i)) >
eps)
923 std::sqrt(std::abs(ev(i))) *
reshape(evec.col(i), D, D));
947 if (D * D != static_cast<idx>(A.rows()))
951 cmat result(D * D, D * D);
954 #pragma omp parallel for collapse(4)
955 #endif // WITH_OPENMP_
956 for (
idx a = 0; a < D; ++a)
957 for (
idx b = 0; b < D; ++b)
958 for (
idx m = 0; m < D; ++m)
959 for (
idx n = 0; n < D; ++n)
960 result(a * D + b, m * D + n) = A(m * D + a, n * D + b);
983 if (D * D != static_cast<idx>(A.rows()))
987 cmat result(D * D, D * D);
990 #pragma omp parallel for collapse(4)
991 #endif // WITH_OPENMP_
992 for (
idx a = 0; a < D; ++a)
993 for (
idx b = 0; b < D; ++b)
994 for (
idx m = 0; m < D; ++m)
995 for (
idx n = 0; n < D; ++n)
996 result(m * D + a, n * D + b) = A(a * D + b, m * D + n);
1014 template<
typename Derived>
1016 const std::vector<idx>& dims)
1018 const typename Eigen::MatrixBase<Derived>::EvalReturnType& rA
1032 if (dims.size() != 2)
1050 auto worker = [=](
idx i,
idx j) noexcept
1051 ->
typename Derived::Scalar
1053 typename Derived::Scalar
sum = 0;
1054 for (
idx m = 0; m < DA; ++m)
1055 sum += rA(m * DB + i) * std::conj(rA(m * DB + j));
1061 #pragma omp parallel for collapse(2)
1062 #endif // WITH_OPENMP_
1063 for (
idx j = 0; j < DB; ++j)
1064 for (
idx i = 0; i < DB; ++i)
1065 result(i, j) = worker(i, j);
1077 auto worker = [=](
idx i,
idx j) noexcept
1078 ->
typename Derived::Scalar
1080 typename Derived::Scalar
sum = 0;
1081 for (
idx m = 0; m < DA; ++m)
1082 sum += rA(m * DB + i, m * DB + j);
1088 #pragma omp parallel for collapse(2)
1089 #endif // WITH_OPENMP_
1090 for (
idx j = 0; j < DB; ++j)
1091 for (
idx i = 0; i < DB; ++i)
1092 result(i, j) = worker(i, j);
1115 template<
typename Derived>
1133 std::vector<idx> dims(2, d);
1151 template<
typename Derived>
1153 const std::vector<idx>& dims)
1155 const typename Eigen::MatrixBase<Derived>::EvalReturnType& rA
1169 if (dims.size() != 2)
1187 auto worker = [=](
idx i,
idx j) noexcept
1188 ->
typename Derived::Scalar
1190 typename Derived::Scalar
sum = 0;
1191 for (
idx m = 0; m < DB; ++m)
1192 sum += rA(i * DB + m) * std::conj(rA(j * DB + m));
1198 #pragma omp parallel for collapse(2)
1199 #endif // WITH_OPENMP_
1200 for (
idx j = 0; j < DA; ++j)
1201 for (
idx i = 0; i < DA; ++i)
1202 result(i, j) = worker(i, j);
1215 #pragma omp parallel for collapse(2)
1216 #endif // WITH_OPENMP_
1217 for (
idx j = 0; j < DA; ++j)
1218 for (
idx i = 0; i < DA; ++i)
1219 result(i, j) =
trace(rA.block(i * DB, j * DB, DB, DB));
1242 template<
typename Derived>
1260 std::vector<idx> dims(2, d);
1279 template<
typename Derived>
1281 const std::vector<idx>& subsys,
1282 const std::vector<idx>& dims)
1284 const typename Eigen::MatrixBase<Derived>::EvalReturnType& rA
1303 idx D =
static_cast<idx>(rA.rows());
1304 idx N = dims.size();
1305 idx Nsubsys = subsys.size();
1306 idx Nsubsys_bar = N - Nsubsys;
1308 for (
idx i = 0; i < Nsubsys; ++i)
1309 Dsubsys *= dims[subsys[i]];
1310 idx Dsubsys_bar = D / Dsubsys;
1320 std::vector<idx> subsys_bar =
complement(subsys, N);
1321 std::copy(std::begin(subsys_bar), std::end(subsys_bar),
1322 std::begin(Csubsys_bar));
1324 for (
idx i = 0; i < N; ++i)
1328 for (
idx i = 0; i < Nsubsys; ++i)
1330 Csubsys[i] = subsys[i];
1331 Cdimssubsys[i] = dims[subsys[i]];
1333 for (
idx i = 0; i < Nsubsys_bar; ++i)
1335 Cdimssubsys_bar[i] = dims[subsys_bar[i]];
1349 if (subsys.size() == dims.size())
1351 result(0, 0) = (
adjoint(rA) * rA).value();
1355 if (subsys.size() == 0)
1358 auto worker = [=, &Cmidxcolsubsys_bar](
idx i) noexcept
1359 ->
typename Derived::Scalar
1370 Cdimssubsys_bar, Cmidxrowsubsys_bar);
1372 for (
idx k = 0; k < Nsubsys_bar; ++k)
1374 Cmidxrow[Csubsys_bar[k]] = Cmidxrowsubsys_bar[k];
1375 Cmidxcol[Csubsys_bar[k]] = Cmidxcolsubsys_bar[k];
1377 typename Derived::Scalar sm = 0;
1378 for (
idx a = 0; a < Dsubsys; ++a)
1383 for (
idx k = 0; k < Nsubsys; ++k)
1384 Cmidxrow[Csubsys[k]] = Cmidxcol[Csubsys[k]]
1396 for (
idx j = 0; j < Dsubsys_bar; ++j)
1400 Cdimssubsys_bar, Cmidxcolsubsys_bar);
1402 #pragma omp parallel for
1403 #endif // WITH_OPENMP_
1404 for (
idx i = 0; i < Dsubsys_bar; ++i)
1406 result(i, j) = worker(i);
1420 if (subsys.size() == dims.size())
1422 result(0, 0) = rA.trace();
1426 if (subsys.size() == 0)
1429 auto worker = [=, &Cmidxcolsubsys_bar](
idx i) noexcept
1430 ->
typename Derived::Scalar
1441 Cdimssubsys_bar, Cmidxrowsubsys_bar);
1443 for (
idx k = 0; k < Nsubsys_bar; ++k)
1445 Cmidxrow[Csubsys_bar[k]] = Cmidxrowsubsys_bar[k];
1446 Cmidxcol[Csubsys_bar[k]] = Cmidxcolsubsys_bar[k];
1448 typename Derived::Scalar sm = 0;
1449 for (
idx a = 0; a < Dsubsys; ++a)
1454 for (
idx k = 0; k < Nsubsys; ++k)
1455 Cmidxrow[Csubsys[k]] = Cmidxcol[Csubsys[k]]
1466 for (
idx j = 0; j < Dsubsys_bar; ++j)
1470 Cdimssubsys_bar, Cmidxcolsubsys_bar);
1472 #pragma omp parallel for
1473 #endif // WITH_OPENMP_
1474 for (
idx i = 0; i < Dsubsys_bar; ++i)
1476 result(i, j) = worker(i);
1502 template<
typename Derived>
1504 const std::vector<idx>& subsys,
1507 const typename Eigen::MatrixBase<Derived>::EvalReturnType& rA = A.derived();
1521 std::vector<idx> dims(N, d);
1523 return ptrace(rA, subsys, dims);
1539 template<
typename Derived>
1541 const Eigen::MatrixBase<Derived>& A,
1542 const std::vector<idx>& subsys,
1543 const std::vector<idx>& dims)
1545 const typename Eigen::MatrixBase<Derived>::EvalReturnType& rA = A.derived();
1563 idx D =
static_cast<idx>(rA.rows());
1564 idx N = dims.size();
1565 idx Nsubsys = subsys.size();
1571 for (
idx i = 0; i < N; ++i)
1573 for (
idx i = 0; i < Nsubsys; ++i)
1574 Csubsys[i] = subsys[i];
1586 if (subsys.size() == dims.size())
1589 if (subsys.size() == 0)
1592 auto worker = [=, &Cmidxcol](
idx i) noexcept
1593 ->
typename Derived::Scalar
1599 for (
idx k = 0; k < N; ++k)
1600 midxcoltmp[k] = Cmidxcol[k];
1605 for (
idx k = 0; k < Nsubsys; ++k)
1606 std::swap(midxcoltmp[Csubsys[k]], midxrow[Csubsys[k]]);
1614 for (
idx j = 0; j < D; ++j)
1620 #pragma omp parallel for
1621 #endif // WITH_OPENMP_
1622 for (
idx i = 0; i < D; ++i)
1623 result(i, j) = worker(i);
1636 if (subsys.size() == dims.size())
1637 return rA.transpose();
1639 if (subsys.size() == 0)
1642 auto worker = [=, &Cmidxcol](
idx i) noexcept
1643 ->
typename Derived::Scalar
1649 for (
idx k = 0; k < N; ++k)
1650 midxcoltmp[k] = Cmidxcol[k];
1655 for (
idx k = 0; k < Nsubsys; ++k)
1656 std::swap(midxcoltmp[Csubsys[k]], midxrow[Csubsys[k]]);
1663 for (
idx j = 0; j < D; ++j)
1669 #pragma omp parallel for
1670 #endif // WITH_OPENMP_
1671 for (
idx i = 0; i < D; ++i)
1672 result(i, j) = worker(i);
1696 template<
typename Derived>
1698 const Eigen::MatrixBase<Derived>& A,
1699 const std::vector<idx>& subsys,
1702 const typename Eigen::MatrixBase<Derived>::EvalReturnType& rA = A.derived();
1716 std::vector<idx> dims(N, d);
1733 template<
typename Derived>
1735 const Eigen::MatrixBase<Derived>& A,
1736 const std::vector<idx>& perm,
1737 const std::vector<idx>& dims)
1739 const typename Eigen::MatrixBase<Derived>::EvalReturnType& rA = A.derived();
1756 if (perm.size() != dims.size())
1761 idx D =
static_cast<idx>(rA.rows());
1762 idx N = dims.size();
1778 for (
idx i = 0; i < N; ++i)
1783 result.resize(D, 1);
1785 auto worker = [&Cdims, &Cperm, N](
idx i) noexcept
1797 for (
idx k = 0; k < N; ++k)
1799 permdims[k] = Cdims[Cperm[k]];
1800 midxtmp[k] = midx[Cperm[k]];
1807 #pragma omp parallel for
1808 #endif // WITH_OPENMP_
1809 for (
idx i = 0; i < D; ++i)
1810 result(worker(i)) = rA(i);
1826 for (
idx i = 0; i < N; ++i)
1829 Cdims[i + N] = dims[i];
1831 Cperm[i + N] = perm[i] + N;
1833 result.resize(D * D, 1);
1836 Eigen::Map<dyn_mat<typename Derived::Scalar >>(
1837 const_cast<typename Derived::Scalar*
>(rA.data()), D *
1841 auto worker = [&Cdims, &Cperm, N](
idx i) noexcept
1853 for (
idx k = 0; k < 2 * N; ++k)
1855 permdims[k] = Cdims[Cperm[k]];
1856 midxtmp[k] = midx[Cperm[k]];
1863 #pragma omp parallel for
1864 #endif // WITH_OPENMP_
1865 for (
idx i = 0; i < D * D; ++i)
1866 result(worker(i)) = rA(i);
1888 template<
typename Derived>
1890 const Eigen::MatrixBase<Derived>& A,
1891 const std::vector<idx>& perm,
1894 const typename Eigen::MatrixBase<Derived>::EvalReturnType& rA = A.derived();
1908 std::vector<idx> dims(N, d);
bool check_nonzero_size(const T &x) noexcept
Definition: util.h:127
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
bool check_cvector(const Eigen::MatrixBase< Derived > &A)
Definition: util.h:120
std::vector< cmat > choi2kraus(const cmat &A)
Orthogonal Kraus operators from Choi matrix.
Definition: operations.h:900
Eigen::MatrixXd dmat
Real (double precision) dynamic Eigen matrix.
Definition: types.h:66
constexpr double eps
Used to decide whether a number or expression in double precision is zero or not. ...
Definition: constants.h:67
Eigen::RowVectorXcd bra
Complex (double precision) dynamic Eigen row vector.
Definition: types.h:56
dyn_mat< typename Derived::Scalar > syspermute(const Eigen::MatrixBase< Derived > &A, const std::vector< idx > &perm, const std::vector< idx > &dims)
Subsystem permutation.
Definition: operations.h:1734
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > dyn_mat
Dynamic Eigen matrix over the field specified by Scalar.
Definition: types.h:78
bool check_dims_match_mat(const std::vector< idx > &dims, const Eigen::MatrixBase< Derived > &A)
Definition: util.h:156
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
Eigen::VectorXcd ket
Complex (double precision) dynamic Eigen column vector.
Definition: types.h:51
dyn_mat< typename Derived1::Scalar > apply(const Eigen::MatrixBase< Derived1 > &state, const Eigen::MatrixBase< Derived2 > &A, const std::vector< idx > &subsys, const std::vector< idx > &dims)
Applies the gate A to the part subsys of the multi-partite state vector or density matrix state...
Definition: operations.h:486
Quantum++ main namespace.
Definition: codes.h:30
bool check_perm(const std::vector< idx > &perm)
Definition: util.h:257
idx get_num_subsys(idx sz, idx d)
Definition: util.h:370
dyn_col_vect< double > hevals(const Eigen::MatrixBase< Derived > &A)
Hermitian eigenvalues.
Definition: functions.h:387
cmat choi2super(const cmat &A)
Converts Choi matrix to superoperator matrix.
Definition: operations.h:936
cmat super2choi(const cmat &A)
Converts superoperator matrix to Choi matrix.
Definition: operations.h:972
std::vector< T > complement(std::vector< T > subsys, idx N)
Constructs the complement of a subsystem vector.
Definition: functions.h:1814
bool check_dims_match_cvect(const std::vector< idx > &dims, const Eigen::MatrixBase< Derived > &A)
Definition: util.h:167
dyn_mat< typename Derived::Scalar > ptrace1(const Eigen::MatrixBase< Derived > &A, const std::vector< idx > &dims)
Partial trace.
Definition: operations.h:1015
dyn_mat< typename Derived::Scalar > adjoint(const Eigen::MatrixBase< Derived > &A)
Adjoint.
Definition: functions.h:84
dyn_mat< typename T::Scalar > kron(const T &head)
Kronecker product.
Definition: functions.h:895
dyn_mat< typename Derived::Scalar > ptrace2(const Eigen::MatrixBase< Derived > &A, const std::vector< idx > &dims)
Partial trace.
Definition: operations.h:1152
Generates custom exceptions, used when validating function parameters.
Definition: exception.h:39
dyn_mat< typename Derived::Scalar > transpose(const Eigen::MatrixBase< Derived > &A)
Transpose.
Definition: functions.h:44
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
idx get_dim_subsys(idx sz, idx N)
Definition: util.h:378
cmat hevects(const Eigen::MatrixBase< Derived > &A)
Hermitian eigenvectors.
Definition: functions.h:413
cmat kraus2choi(const std::vector< cmat > &Ks)
Choi matrix.
Definition: operations.h:841
dyn_mat< typename Derived::Scalar > ptrace(const Eigen::MatrixBase< Derived > &A, const std::vector< idx > &subsys, const std::vector< idx > &dims)
Partial trace.
Definition: operations.h:1280
bool check_square_mat(const Eigen::MatrixBase< Derived > &A)
Definition: util.h:99
Derived::Scalar trace(const Eigen::MatrixBase< Derived > &A)
Trace.
Definition: functions.h:127
cmat kraus2super(const std::vector< cmat > &Ks)
Superoperator matrix.
Definition: operations.h:763
dyn_mat< typename Derived1::Scalar > applyCTRL(const Eigen::MatrixBase< Derived1 > &state, const Eigen::MatrixBase< Derived2 > &A, const std::vector< idx > &ctrl, const std::vector< idx > &subsys, const std::vector< idx > &dims)
Applies the controlled-gate A to the part subsys of the multi-partite state vector or density matrix ...
Definition: operations.h:55
dyn_mat< typename Derived::Scalar > ptranspose(const Eigen::MatrixBase< Derived > &A, const std::vector< idx > &subsys, const std::vector< idx > &dims)
Partial transpose.
Definition: operations.h:1540
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
std::size_t idx
Non-negative integer index.
Definition: types.h:36
Derived::Scalar sum(const Eigen::MatrixBase< Derived > &A)
Element-wise sum of A.
Definition: functions.h:209
dyn_mat< typename Derived::Scalar > reshape(const Eigen::MatrixBase< Derived > &A, idx rows, idx cols)
Reshape.
Definition: functions.h:1135