32 #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
53 template<
typename Derived1,
typename Derived2>
55 const Eigen::MatrixBase<Derived1>& state,
56 const Eigen::MatrixBase<Derived2>& A,
57 const std::vector<idx>& ctrl,
58 const std::vector<idx>& subsys,
59 const std::vector<idx>& dims)
66 if (!std::is_same<
typename Derived1::Scalar,
67 typename Derived2::Scalar>::value)
84 idx d = ctrl.size() > 0 ? dims[ctrl[0]] : 1;
85 for (
idx i = 1; i < ctrl.size(); ++i)
86 if (dims[ctrl[i]] != d)
100 std::vector<idx> subsys_dims(subsys.size());
101 for (
idx i = 0; i < subsys.size(); ++i)
102 subsys_dims[i] = dims[subsys[i]];
107 std::vector<idx> ctrlgate = ctrl;
108 ctrlgate.insert(std::end(ctrlgate), std::begin(subsys), std::end(subsys));
109 std::sort(std::begin(ctrlgate), std::end(ctrlgate));
120 std::vector<dyn_mat<typename Derived1::Scalar>> Ai;
121 std::vector<dyn_mat<typename Derived1::Scalar>> Aidagger;
122 for (
idx i = 0; i < std::max(d, static_cast<idx>(2)); ++i)
124 Ai.push_back(
powm(rA, i));
128 idx D = rstate.rows();
130 idx ctrlsize = ctrl.size();
138 std::vector<idx> ctrlgatebar =
complement(ctrlgate, n);
141 for (
idx i = 0; i < ctrlgatebar.size(); ++i)
142 DCTRLAbar *= dims[ctrlgatebar[i]];
144 for (
idx k = 0; k < n; ++k)
146 for (
idx k = 0; k < subsys.size(); ++k)
147 CdimsA[k] = dims[subsys[k]];
148 for (
idx k = 0; k < ctrlgatebar.size(); ++k)
149 CdimsCTRLAbar[k] = dims[ctrlgatebar[k]];
154 auto coeff_idx_ket = [=](
idx _i,
idx _m,
idx _r) noexcept
155 -> std::pair<typename Derived1::Scalar, idx>
158 typename Derived1::Scalar coeff = 0;
167 for (
idx k = 0; k < ctrl.size(); ++k)
174 CdimsCTRLAbar, CmidxCTRLAbar);
175 for (
idx k = 0; k < n - ctrlgate.size(); ++k)
177 Cmidx[ctrlgatebar[k]] = CmidxCTRLAbar[k];
182 for (
idx k = 0; k < subsys.size(); ++k)
184 Cmidx[subsys[k]] = CmidxA[k];
191 for (
idx _n = 0; _n < DA; ++_n)
194 for (
idx k = 0; k < subsys.size(); ++k)
196 Cmidx[subsys[k]] = CmidxA[k];
198 coeff += Ai[_i](_m, _n) *
202 return std::make_pair(coeff, indx);
208 auto coeff_idx_rho = [=](
idx _i1,
idx _m1,
210 -> std::tuple<typename Derived1::Scalar, idx, idx>
214 typename Derived1::Scalar coeff = 0;
226 for (
idx k = 0; k < ctrl.size(); ++k)
228 Cmidxrow[ctrl[k]] = _i1;
229 Cmidxcol[ctrl[k]] = _i2;
234 CdimsCTRLAbar, CmidxCTRLAbarrow);
236 CdimsCTRLAbar, CmidxCTRLAbarcol);
237 for (
idx k = 0; k < n - ctrlgate.size(); ++k)
239 Cmidxrow[ctrlgatebar[k]] = CmidxCTRLAbarrow[k];
240 Cmidxcol[ctrlgatebar[k]] = CmidxCTRLAbarcol[k];
246 for (
idx k = 0; k < subsys.size(); ++k)
248 Cmidxrow[subsys[k]] = CmidxArow[k];
249 Cmidxcol[subsys[k]] = CmidxAcol[k];
257 for (
idx _n1 = 0; _n1 < DA; ++_n1)
260 for (
idx k = 0; k < subsys.size(); ++k)
262 Cmidxrow[subsys[k]] = CmidxArow[k];
264 for (
idx _n2 = 0; _n2 < DA; ++_n2)
267 for (
idx k = 0; k < subsys.size(); ++k)
269 Cmidxcol[subsys[k]] = CmidxAcol[k];
271 coeff += Ai[_i1](_m1, _n1) *
274 Aidagger[_i2](_n2, _m2);
278 return std::make_tuple(coeff, idxrow, idxcol);
293 #pragma omp parallel for collapse(2)
294 for (
idx m = 0; m < DA; ++m)
295 for (
idx r = 0; r < DCTRLAbar; ++r)
299 result(coeff_idx_ket(1, m, r).second) =
300 coeff_idx_ket(1, m, r).first;
303 for (
idx i = 0; i < d; ++i)
305 result(coeff_idx_ket(i, m, r).second) =
306 coeff_idx_ket(i, m, r).first;
325 #pragma omp parallel for collapse(4)
326 for (
idx m1 = 0; m1 < DA; ++m1)
327 for (
idx r1 = 0; r1 < DCTRLAbar; ++r1)
328 for (
idx m2 = 0; m2 < DA; ++m2)
329 for (
idx r2 = 0; r2 < DCTRLAbar; ++r2)
332 auto coeff_idxes = coeff_idx_rho(1, m1, r1,
334 result(std::get<1>(coeff_idxes),
335 std::get<2>(coeff_idxes)) =
336 std::get<0>(coeff_idxes);
340 for (
idx i1 = 0; i1 < d; ++i1)
341 for (
idx i2 = 0; i2 < d; ++i2)
343 auto coeff_idxes = coeff_idx_rho(
346 result(std::get<1>(coeff_idxes),
347 std::get<2>(coeff_idxes)) =
348 std::get<0>(coeff_idxes);
375 template<
typename Derived1,
typename Derived2>
377 const Eigen::MatrixBase<Derived1>& state,
378 const Eigen::MatrixBase<Derived2>& A,
379 const std::vector<idx>& ctrl,
380 const std::vector<idx>& subsys,
391 static_cast<idx>(std::llround(std::log2(rstate.rows()) /
393 std::vector<idx> dims(n, d);
395 return applyCTRL(rstate, rA, ctrl, subsys, dims);
411 template<
typename Derived1,
typename Derived2>
413 const Eigen::MatrixBase<Derived1>& state,
414 const Eigen::MatrixBase<Derived2>& A,
415 const std::vector<idx>& subsys,
416 const std::vector<idx>& dims)
424 if (!std::is_same<
typename Derived1::Scalar,
425 typename Derived2::Scalar>::value)
449 std::vector<idx> subsys_dims(subsys.size());
450 for (
idx i = 0; i < subsys.size(); ++i)
451 subsys_dims[i] = dims[subsys[i]];
464 return applyCTRL(rstate, rA, {}, subsys, dims);
475 return applyCTRL(rstate, rA, {}, subsys, dims);
496 template<
typename Derived1,
typename Derived2>
498 const Eigen::MatrixBase<Derived1>& state,
499 const Eigen::MatrixBase<Derived2>& A,
500 const std::vector<idx>& subsys,
511 static_cast<idx>(std::llround(std::log2(rstate.rows()) /
513 std::vector<idx> dims(n, d);
515 return apply(rstate, rA, subsys, dims);
526 template<
typename Derived>
528 const std::vector<cmat>& Ks)
530 const cmat& rrho = rho;
541 if (Ks[0].rows() != rrho.rows())
545 if (it.rows() != Ks[0].rows() || it.cols() != Ks[0].rows())
548 cmat result = cmat::Zero(rrho.rows(), rrho.rows());
550 #pragma omp parallel for
551 for (
idx i = 0; i < Ks.size(); ++i)
555 result += Ks[i] * rrho *
adjoint(Ks[i]);
572 template<
typename Derived>
574 const std::vector<cmat>& Ks,
575 const std::vector<idx>& subsys,
576 const std::vector<idx>& dims)
578 const cmat& rrho = rho;
603 std::vector<idx> subsys_dims(subsys.size());
604 for (
idx i = 0; i < subsys.size(); ++i)
605 subsys_dims[i] = dims[subsys[i]];
616 if (it.rows() != Ks[0].rows() || it.cols() != Ks[0].rows())
619 cmat result = cmat::Zero(rrho.rows(), rrho.rows());
621 for (
idx i = 0; i < Ks.size(); ++i)
622 result +=
apply(rrho, Ks[i], subsys, dims);
637 template<
typename Derived>
639 const std::vector<cmat>& Ks,
640 const std::vector<idx>& subsys,
643 const cmat& rrho = rho;
650 static_cast<idx>(std::llround(std::log2(rrho.rows()) /
652 std::vector<idx> dims(n, d);
654 return apply(rrho, Ks, subsys, dims);
679 if (it.rows() != Ks[0].rows() || it.cols() != Ks[0].rows())
682 idx D =
static_cast<idx>(Ks[0].rows());
684 cmat result(D * D, D * D);
685 cmat MN = cmat::Zero(D, D);
686 bra A = bra::Zero(D);
687 ket B = ket::Zero(D);
688 cmat EMN = cmat::Zero(D, D);
690 #pragma omp parallel for collapse(2)
691 for (
idx m = 0; m < D; ++m)
693 for (
idx n = 0; n < D; ++n)
699 for (
idx i = 0; i < Ks.size(); ++i)
700 EMN += Ks[i] * MN *
adjoint(Ks[i]);
703 for (
idx a = 0; a < D; ++a)
706 for (
idx b = 0; b < D; ++b)
710 result(a * D + b, m * D + n) =
711 static_cast<cmat>(A * EMN * B).value();
716 EMN = cmat::Zero(D, D);
750 if (it.rows() != Ks[0].rows() || it.cols() != Ks[0].rows())
753 idx D =
static_cast<idx>(Ks[0].rows());
757 cmat MES = cmat::Zero(D * D, 1);
758 for (
idx a = 0; a < D; ++a)
763 cmat result = cmat::Zero(D * D, D * D);
765 #pragma omp parallel for
766 for (
idx i = 0; i < Ks.size(); ++i)
770 result +=
kron(cmat::Identity(D, D), Ks[i]) * Omega
799 idx D =
static_cast<idx>(std::llround(
800 std::sqrt(static_cast<double>(A.rows()))));
801 if (D * D != static_cast<idx>(A.rows()))
806 std::vector<cmat> result;
808 for (
idx i = 0; i < D * D; ++i)
810 if (std::abs(ev(i)) >
eps)
812 std::sqrt(std::abs(ev(i))) *
reshape(evec.col(i), D, D));
833 idx D =
static_cast<idx>(std::llround(
834 std::sqrt(static_cast<double>(A.rows()))));
835 if (D * D != static_cast<idx>(A.rows()))
838 cmat result(D * D, D * D);
840 #pragma omp parallel for collapse(4)
841 for (
idx a = 0; a < D; ++a)
842 for (
idx b = 0; b < D; ++b)
843 for (
idx m = 0; m < D; ++m)
844 for (
idx n = 0; n < D; ++n)
845 result(a * D + b, m * D + n) = A(m * D + a, n * D + b);
865 idx D =
static_cast<idx>(std::llround(
866 std::sqrt(static_cast<double>(A.rows()))));
867 if (D * D != static_cast<idx>(A.rows()))
870 cmat result(D * D, D * D);
872 #pragma omp parallel for collapse(4)
873 for (
idx a = 0; a < D; ++a)
874 for (
idx b = 0; b < D; ++b)
875 for (
idx m = 0; m < D; ++m)
876 for (
idx n = 0; n < D; ++n)
877 result(m * D + a, n * D + b) = A(a * D + b, m * D + n);
896 template<
typename Derived>
898 const std::vector<idx>& dims)
913 if (dims.size() != 2)
930 auto worker = [=](
idx i,
idx j) noexcept
931 ->
typename Derived::Scalar
933 typename Derived::Scalar
sum = 0;
934 for (
idx m = 0; m < DA; ++m)
935 sum += rA(m * DB + i) * std::conj(rA(m * DB + j));
940 #pragma omp parallel for collapse(2)
941 for (
idx j = 0; j < DB; ++j)
942 for (
idx i = 0; i < DB; ++i)
943 result(i, j) = worker(i, j);
955 auto worker = [=](
idx i,
idx j) noexcept
956 ->
typename Derived::Scalar
958 typename Derived::Scalar
sum = 0;
959 for (
idx m = 0; m < DA; ++m)
960 sum += rA(m * DB + i, m * DB + j);
965 #pragma omp parallel for collapse(2)
966 for (
idx j = 0; j < DB; ++j)
967 for (
idx i = 0; i < DB; ++i)
968 result(i, j) = worker(i, j);
992 template<
typename Derived>
994 const std::vector<idx>& dims)
1009 if (dims.size() != 2)
1026 auto worker = [=](
idx i,
idx j) noexcept
1027 ->
typename Derived::Scalar
1029 typename Derived::Scalar
sum = 0;
1030 for (
idx m = 0; m < DB; ++m)
1031 sum += rA(i * DB + m) * std::conj(rA(j * DB + m));
1036 #pragma omp parallel for collapse(2)
1037 for (
idx j = 0; j < DA; ++j)
1038 for (
idx i = 0; i < DA; ++i)
1039 result(i, j) = worker(i, j);
1051 #pragma omp parallel for collapse(2)
1052 for (
idx j = 0; j < DA; ++j)
1053 for (
idx i = 0; i < DA; ++i)
1054 result(i, j) =
trace(rA.block(i * DB, j * DB, DB, DB));
1078 template<
typename Derived>
1080 const std::vector<idx>& subsys,
1081 const std::vector<idx>& dims)
1100 idx D =
static_cast<idx>(rA.rows());
1101 idx n = dims.size();
1102 idx nsubsys = subsys.size();
1103 idx nsubsysbar = n - nsubsys;
1105 for (
idx i = 0; i < nsubsys; ++i)
1106 dimsubsys *= dims[subsys[i]];
1107 idx dimsubsysbar = D / dimsubsys;
1117 std::vector<idx> subsys_bar =
complement(subsys, n);
1118 std::copy(std::begin(subsys_bar), std::end(subsys_bar),
1119 std::begin(Csubsysbar));
1121 for (
idx i = 0; i < n; ++i)
1125 for (
idx i = 0; i < nsubsys; ++i)
1127 Csubsys[i] = subsys[i];
1128 Cdimssubsys[i] = dims[subsys[i]];
1130 for (
idx i = 0; i < nsubsysbar; ++i)
1132 Cdimssubsysbar[i] = dims[subsys_bar[i]];
1146 if (subsys.size() == dims.size())
1148 result(0, 0) = (
adjoint(rA) * rA).value();
1152 if (subsys.size() == 0)
1155 auto worker = [=, &Cmidxcolsubsysbar](
idx i) noexcept
1156 ->
typename Derived::Scalar
1167 Cdimssubsysbar, Cmidxrowsubsysbar);
1169 for (
idx k = 0; k < nsubsysbar; ++k)
1171 Cmidxrow[Csubsysbar[k]] = Cmidxrowsubsysbar[k];
1172 Cmidxcol[Csubsysbar[k]] = Cmidxcolsubsysbar[k];
1174 typename Derived::Scalar sm = 0;
1175 for (
idx a = 0; a < dimsubsys; ++a)
1180 for (
idx k = 0; k < nsubsys; ++k)
1181 Cmidxrow[Csubsys[k]] = Cmidxcol[Csubsys[k]]
1193 for (
idx j = 0; j < dimsubsysbar; ++j)
1197 Cdimssubsysbar, Cmidxcolsubsysbar);
1198 #pragma omp parallel for
1199 for (
idx i = 0; i < dimsubsysbar; ++i)
1201 result(i, j) = worker(i);
1215 if (subsys.size() == dims.size())
1217 result(0, 0) = rA.trace();
1221 if (subsys.size() == 0)
1224 auto worker = [=, &Cmidxcolsubsysbar](
idx i) noexcept
1225 ->
typename Derived::Scalar
1236 Cdimssubsysbar, Cmidxrowsubsysbar);
1238 for (
idx k = 0; k < nsubsysbar; ++k)
1240 Cmidxrow[Csubsysbar[k]] = Cmidxrowsubsysbar[k];
1241 Cmidxcol[Csubsysbar[k]] = Cmidxcolsubsysbar[k];
1243 typename Derived::Scalar sm = 0;
1244 for (
idx a = 0; a < dimsubsys; ++a)
1249 for (
idx k = 0; k < nsubsys; ++k)
1250 Cmidxrow[Csubsys[k]] = Cmidxcol[Csubsys[k]]
1261 for (
idx j = 0; j < dimsubsysbar; ++j)
1265 Cdimssubsysbar, Cmidxcolsubsysbar);
1266 #pragma omp parallel for
1267 for (
idx i = 0; i < dimsubsysbar; ++i)
1269 result(i, j) = worker(i);
1295 template<
typename Derived>
1297 const std::vector<idx>& subsys,
1307 static_cast<idx>(std::llround(std::log2(rA.rows()) /
1309 std::vector<idx> dims(n, d);
1311 return ptrace(rA, subsys, dims);
1327 template<
typename Derived>
1329 const Eigen::MatrixBase<Derived>& A,
1330 const std::vector<idx>& subsys,
1331 const std::vector<idx>& dims)
1350 idx D =
static_cast<idx>(rA.rows());
1351 idx numdims = dims.size();
1352 idx numsubsys = subsys.size();
1358 for (
idx i = 0; i < numdims; ++i)
1360 for (
idx i = 0; i < numsubsys; ++i)
1361 Csubsys[i] = subsys[i];
1373 if (subsys.size() == dims.size())
1376 if (subsys.size() == 0)
1379 auto worker = [=, &Cmidxcol](
idx i) noexcept
1380 ->
typename Derived::Scalar
1386 for (
idx k = 0; k < numdims; ++k)
1387 midxcoltmp[k] = Cmidxcol[k];
1392 for (
idx k = 0; k < numsubsys; ++k)
1393 std::swap(midxcoltmp[Csubsys[k]], midxrow[Csubsys[k]]);
1401 for (
idx j = 0; j < D; ++j)
1405 #pragma omp parallel for
1406 for (
idx i = 0; i < D; ++i)
1407 result(i, j) = worker(i);
1420 if (subsys.size() == dims.size())
1421 return rA.transpose();
1423 if (subsys.size() == 0)
1426 auto worker = [=, &Cmidxcol](
idx i) noexcept
1427 ->
typename Derived::Scalar
1433 for (
idx k = 0; k < numdims; ++k)
1434 midxcoltmp[k] = Cmidxcol[k];
1439 for (
idx k = 0; k < numsubsys; ++k)
1440 std::swap(midxcoltmp[Csubsys[k]], midxrow[Csubsys[k]]);
1447 for (
idx j = 0; j < D; ++j)
1451 #pragma omp parallel for
1452 for (
idx i = 0; i < D; ++i)
1453 result(i, j) = worker(i);
1477 template<
typename Derived>
1479 const Eigen::MatrixBase<Derived>& A,
1480 const std::vector<idx>& subsys,
1490 static_cast<idx>(std::llround(std::log2(rA.rows()) /
1492 std::vector<idx> dims(n, d);
1509 template<
typename Derived>
1511 const Eigen::MatrixBase<Derived>& A,
1512 const std::vector<idx>& perm,
1513 const std::vector<idx>& dims)
1532 if (perm.size() != dims.size())
1536 idx D =
static_cast<idx>(rA.rows());
1537 idx numdims = dims.size();
1553 for (
idx i = 0; i < numdims; ++i)
1558 result.resize(D, 1);
1560 auto worker = [&Cdims, &Cperm, numdims](
idx i) noexcept
1572 for (
idx k = 0; k < numdims; ++k)
1574 permdims[k] = Cdims[Cperm[k]];
1575 midxtmp[k] = midx[Cperm[k]];
1581 #pragma omp parallel for
1582 for (
idx i = 0; i < D; ++i)
1583 result(worker(i)) = rA(i);
1599 for (
idx i = 0; i < numdims; ++i)
1602 Cdims[i + numdims] = dims[i];
1604 Cperm[i + numdims] = perm[i] + numdims;
1606 result.resize(D * D, 1);
1610 const_cast<typename Derived::Scalar*
>(rA.data()), D * D, 1);
1612 auto worker = [&Cdims, &Cperm, numdims](
idx i) noexcept
1624 for (
idx k = 0; k < 2 * numdims; ++k)
1626 permdims[k] = Cdims[Cperm[k]];
1627 midxtmp[k] = midx[Cperm[k]];
1633 #pragma omp parallel for
1634 for (
idx i = 0; i < D * D; ++i)
1635 result(worker(i)) = rA(i);
1657 template<
typename Derived>
1659 const Eigen::MatrixBase<Derived>& A,
1660 const std::vector<idx>& perm,
1670 static_cast<idx>(std::llround(std::log2(rA.rows()) /
1672 std::vector<idx> dims(n, d);
bool _check_cvector(const Eigen::MatrixBase< Derived > &A)
Definition: util.h:110
constexpr idx maxn
Maximum number of allowed qu(d)its (subsystems)
Definition: constants.h:82
std::vector< cmat > choi2kraus(const cmat &A)
Orthogonal Kraus operators from Choi matrix.
Definition: operations.h:791
bool _check_subsys_match_dims(const std::vector< idx > &subsys, const std::vector< idx > &dims)
Definition: util.h:189
bool _check_dims_match_mat(const std::vector< idx > &dims, const Eigen::MatrixBase< Derived > &A)
Definition: util.h:141
Eigen::MatrixXd dmat
Real (double precision) dynamic Eigen matrix.
Definition: types.h:61
bool _check_dims_match_cvect(const std::vector< idx > &dims, const Eigen::MatrixBase< Derived > &V)
Definition: util.h:154
constexpr double eps
Used to decide whether a number or expression in double precision is zero or not. ...
Definition: constants.h:75
Eigen::RowVectorXcd bra
Complex (double precision) dynamic Eigen row vector.
Definition: types.h:51
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:1510
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > dyn_mat
Dynamic Eigen matrix over the field specified by Scalar.
Definition: types.h:73
Eigen::VectorXcd ket
Complex (double precision) dynamic Eigen column vector.
Definition: types.h:46
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:412
Quantum++ main namespace.
Definition: codes.h:30
bool _check_square_mat(const Eigen::MatrixBase< Derived > &A)
Definition: util.h:83
dyn_col_vect< double > hevals(const Eigen::MatrixBase< Derived > &A)
Hermitian eigenvalues.
Definition: functions.h:352
cmat choi2super(const cmat &A)
Converts Choi matrix to superoperator matrix.
Definition: operations.h:825
cmat super2choi(const cmat &A)
Converts superoperator matrix to Choi matrix.
Definition: operations.h:857
std::vector< T > complement(std::vector< T > subsys, idx N)
Constructs the complement of a subsystem vector.
Definition: functions.h:1652
dyn_mat< typename Derived::Scalar > ptrace1(const Eigen::MatrixBase< Derived > &A, const std::vector< idx > &dims)
Partial trace.
Definition: operations.h:897
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:798
dyn_mat< typename Derived::Scalar > ptrace2(const Eigen::MatrixBase< Derived > &A, const std::vector< idx > &dims)
Partial trace.
Definition: operations.h:993
bool _check_perm(const std::vector< idx > &perm)
Definition: util.h:256
idx _multiidx2n(const idx *midx, idx numdims, const idx *dims) noexcept
Definition: util.h:60
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)
Matrix power.
Definition: functions.h:701
cmat hevects(const Eigen::MatrixBase< Derived > &A)
Hermitian eigenvectors.
Definition: functions.h:375
bool _check_nonzero_size(const T &x) noexcept
Definition: util.h:119
cmat kraus2choi(const std::vector< cmat > &Ks)
Choi matrix.
Definition: operations.h:739
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:1079
Derived::Scalar trace(const Eigen::MatrixBase< Derived > &A)
Trace.
Definition: functions.h:121
cmat kraus2super(const std::vector< cmat > &Ks)
Superoperator matrix.
Definition: operations.h:668
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:54
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:1328
Eigen::MatrixXcd cmat
Complex (double precision) dynamic Eigen matrix.
Definition: types.h:56
void _n2multiidx(idx n, idx numdims, const idx *dims, idx *result) noexcept
Definition: util.h:47
std::size_t idx
Non-negative integer index.
Definition: types.h:36
bool _check_dims(const std::vector< idx > &dims)
Definition: util.h:125
Derived::Scalar sum(const Eigen::MatrixBase< Derived > &A)
Element-wise sum of A.
Definition: functions.h:194
dyn_mat< typename Derived::Scalar > reshape(const Eigen::MatrixBase< Derived > &A, idx rows, idx cols)
Reshape.
Definition: functions.h:1026