31 #if (__GNUC__ && !__clang__)
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)
61 const typename Eigen::MatrixBase<Derived1>::EvalReturnType& rstate
68 if ( !std::is_same<
typename Derived1::Scalar,
69 typename Derived2::Scalar>::value )
86 idx d = ctrl.size() > 0 ? dims[ctrl[0]] : 1;
87 for (
idx i = 1; i < ctrl.size(); ++i )
88 if ( dims[ctrl[i]] != d )
102 std::vector<idx> subsys_dims(subsys.size());
103 for (
idx i = 0; i < subsys.size(); ++i )
104 subsys_dims[i] = dims[subsys[i]];
109 std::vector<idx> ctrlgate = ctrl;
110 ctrlgate.insert(std::end(ctrlgate), std::begin(subsys), std::end(subsys));
111 std::sort(std::begin(ctrlgate), std::end(ctrlgate));
121 std::vector<dyn_mat<typename Derived1::Scalar>> Ai;
122 std::vector<dyn_mat<typename Derived1::Scalar>> Aidagger;
123 for (
idx i = 0; i < std::max(d, static_cast<idx>(2)); ++i )
125 Ai.push_back(
powm(rA, i));
129 idx D =
static_cast<idx>(rstate.rows());
131 idx ctrlsize = ctrl.size();
132 idx ctrlgatesize = ctrlgate.size();
133 idx subsyssize = subsys.size();
135 idx Dctrl =
static_cast<idx>(std::llround(std::pow(d, ctrlsize)));
136 idx DA =
static_cast<idx>(rA.rows());
144 std::vector<idx> ctrlgatebar =
complement(ctrlgate, n);
146 idx ctrlgatebarsize = ctrlgatebar.size();
149 for (
idx i = 0; i < ctrlgatebarsize; ++i )
150 DCTRLAbar *= dims[ctrlgatebar[i]];
152 for (
idx k = 0; k < n; ++k )
154 for (
idx k = 0; k < subsyssize; ++k )
155 CdimsA[k] = dims[subsys[k]];
156 for (
idx k = 0; k < ctrlsize; ++k )
158 for (
idx k = 0; k < ctrlgatebarsize; ++k )
159 CdimsCTRLAbar[k] = dims[ctrlgatebar[k]];
163 auto coeff_idx_ket = [&](
idx _i,
idx _m,
idx _r) noexcept
164 -> std::pair<typename Derived1::Scalar, idx>
167 typename Derived1::Scalar coeff = 0;
176 for (
idx k = 0; k < ctrlsize; ++k )
183 CdimsCTRLAbar, CmidxCTRLAbar);
184 for (
idx k = 0; k < n - ctrlgatesize; ++k )
186 Cmidx[ctrlgatebar[k]] = CmidxCTRLAbar[k];
191 for (
idx k = 0; k < subsyssize; ++k )
193 Cmidx[subsys[k]] = CmidxA[k];
200 for (
idx _n = 0; _n < DA; ++_n )
203 for (
idx k = 0; k < subsyssize; ++k )
205 Cmidx[subsys[k]] = CmidxA[k];
207 coeff += Ai[_i](_m, _n) *
211 return std::make_pair(coeff, indx);
217 auto coeff_idx_rho = [&](
idx _i1,
idx _m1,
219 -> std::tuple<typename Derived1::Scalar, idx, idx>
223 typename Derived1::Scalar coeff = 0, lhs = 1, rhs = 1;
238 CdimsCTRL, CmidxCTRLrow);
240 CdimsCTRL, CmidxCTRLcol);
242 for (
idx k = 0; k < ctrlsize; ++k )
244 Cmidxrow[ctrl[k]] = CmidxCTRLrow[k];
245 Cmidxcol[ctrl[k]] = CmidxCTRLcol[k];
250 CdimsCTRLAbar, CmidxCTRLAbarrow);
252 CdimsCTRLAbar, CmidxCTRLAbarcol);
253 for (
idx k = 0; k < n - ctrlgatesize; ++k )
255 Cmidxrow[ctrlgatebar[k]] = CmidxCTRLAbarrow[k];
256 Cmidxcol[ctrlgatebar[k]] = CmidxCTRLAbarcol[k];
262 for (
idx k = 0; k < subsys.size(); ++k )
264 Cmidxrow[subsys[k]] = CmidxArow[k];
265 Cmidxcol[subsys[k]] = CmidxAcol[k];
273 bool all_ctrl_rows_equal =
true;
274 bool all_ctrl_cols_equal =
true;
276 idx first_ctrl_row, first_ctrl_col;
279 first_ctrl_row = CmidxCTRLrow[0];
280 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);
320 lhs = (_m1 == _n1) ? 1 : 0;
323 for (
idx _n2 = 0; _n2 < DA; ++_n2 )
326 for (
idx k = 0; k < subsyssize; ++k )
328 Cmidxcol[subsys[k]] = CmidxAcol[k];
331 if ( all_ctrl_cols_equal )
333 rhs = Aidagger[first_ctrl_col](_n2, _m2);
337 rhs = (_n2 == _m2) ? 1 : 0;
342 coeff += lhs * rstate(idxrowtmp, idxcoltmp) * rhs;
346 return std::make_tuple(coeff, idxrow, idxcol);
362 #pragma omp parallel for collapse(2)
364 for (
idx m = 0; m < DA; ++m )
365 for (
idx r = 0; r < DCTRLAbar; ++r )
369 result(coeff_idx_ket(1, m, r).second) =
370 coeff_idx_ket(1, m, r).first;
373 for (
idx i = 0; i < d; ++i )
375 result(coeff_idx_ket(i, m, r).second) =
376 coeff_idx_ket(i, m, r).first;
396 #pragma omp parallel for collapse(4)
398 for (
idx m1 = 0; m1 < DA; ++m1 )
399 for (
idx r1 = 0; r1 < DCTRLAbar; ++r1 )
400 for (
idx m2 = 0; m2 < DA; ++m2 )
401 for (
idx r2 = 0; r2 < DCTRLAbar; ++r2 )
404 auto coeff_idxes = coeff_idx_rho(1, m1, r1,
406 result(std::get<1>(coeff_idxes),
407 std::get<2>(coeff_idxes)) =
408 std::get<0>(coeff_idxes);
412 for (
idx i1 = 0; i1 < Dctrl; ++i1 )
413 for (
idx i2 = 0; i2 < Dctrl; ++i2 )
415 auto coeff_idxes = coeff_idx_rho(
418 result(std::get<1>(coeff_idxes),
419 std::get<2>(coeff_idxes)) =
420 std::get<0>(coeff_idxes);
447 template<
typename Derived1,
typename Derived2>
449 const Eigen::MatrixBase<Derived1>& state,
450 const Eigen::MatrixBase<Derived2>& A,
451 const std::vector<idx>& ctrl,
452 const std::vector<idx>& subsys,
455 const typename Eigen::MatrixBase<Derived1>::EvalReturnType& rstate
471 static_cast<idx>(std::llround(std::log2(rstate.rows()) /
473 std::vector<idx> dims(n, d);
475 return applyCTRL(rstate, rA, ctrl, subsys, dims);
491 template<
typename Derived1,
typename Derived2>
493 const Eigen::MatrixBase<Derived1>& state,
494 const Eigen::MatrixBase<Derived2>& A,
495 const std::vector<idx>& subsys,
496 const std::vector<idx>& dims)
498 const typename Eigen::MatrixBase<Derived1>::EvalReturnType& rstate
505 if ( !std::is_same<
typename Derived1::Scalar,
506 typename Derived2::Scalar>::value )
530 std::vector<idx> subsys_dims(subsys.size());
531 for (
idx i = 0; i < subsys.size(); ++i )
532 subsys_dims[i] = dims[subsys[i]];
546 return applyCTRL(rstate, rA, {}, subsys, dims);
557 return applyCTRL(rstate, rA, {}, subsys, dims);
578 template<
typename Derived1,
typename Derived2>
580 const Eigen::MatrixBase<Derived1>& state,
581 const Eigen::MatrixBase<Derived2>& A,
582 const std::vector<idx>& subsys,
585 const typename Eigen::MatrixBase<Derived1>::EvalReturnType& rstate
601 static_cast<idx>(std::llround(std::log2(rstate.rows()) /
603 std::vector<idx> dims(n, d);
605 return apply(rstate, rA, subsys, dims);
616 template<
typename Derived>
618 const std::vector<cmat>& Ks)
620 const cmat& rrho = rho.derived();
628 if ( Ks.size() == 0 )
632 if ( Ks[0].rows() != rrho.rows())
635 for (
auto&& it : Ks )
636 if ( it.rows() != Ks[0].rows() || it.cols() != Ks[0].rows())
640 cmat result = cmat::Zero(rrho.rows(), rrho.rows());
643 #pragma omp parallel for
645 for (
idx i = 0; i < Ks.size(); ++i )
651 result += Ks[i] * rrho *
adjoint(Ks[i]);
668 template<
typename Derived>
670 const std::vector<cmat>& Ks,
671 const std::vector<idx>& subsys,
672 const std::vector<idx>& dims)
674 const cmat& rrho = rho.derived();
700 std::vector<idx> subsys_dims(subsys.size());
701 for (
idx i = 0; i < subsys.size(); ++i )
702 subsys_dims[i] = dims[subsys[i]];
705 if ( Ks.size() == 0 )
712 for (
auto&& it : Ks )
713 if ( it.rows() != Ks[0].rows() || it.cols() != Ks[0].rows())
717 cmat result = cmat::Zero(rrho.rows(), rrho.rows());
719 for (
idx i = 0; i < Ks.size(); ++i )
720 result +=
apply(rrho, Ks[i], subsys, dims);
735 template<
typename Derived>
737 const std::vector<cmat>& Ks,
738 const std::vector<idx>& subsys,
741 const cmat& rrho = rho.derived();
755 static_cast<idx>(std::llround(std::log2(rrho.rows()) /
757 std::vector<idx> dims(n, d);
759 return apply(rrho, Ks, subsys, dims);
777 if ( Ks.size() == 0 )
784 for (
auto&& it : Ks )
785 if ( it.rows() != Ks[0].rows() || it.cols() != Ks[0].rows())
790 idx D =
static_cast<idx>(Ks[0].rows());
792 cmat result(D * D, D * D);
793 cmat MN = cmat::Zero(D, D);
794 bra A = bra::Zero(D);
795 ket B = ket::Zero(D);
796 cmat EMN = cmat::Zero(D, D);
799 #pragma omp parallel for collapse(2)
801 for (
idx m = 0; m < D; ++m )
803 for (
idx n = 0; n < D; ++n )
811 for (
idx i = 0; i < Ks.size(); ++i )
812 EMN += Ks[i] * MN *
adjoint(Ks[i]);
815 for (
idx a = 0; a < D; ++a )
818 for (
idx b = 0; b < D; ++b )
822 result(a * D + b, m * D + n) =
823 static_cast<cmat>(A * EMN * B).value();
828 EMN = cmat::Zero(D, D);
855 if ( Ks.size() == 0 )
862 for (
auto&& it : Ks )
863 if ( it.rows() != Ks[0].rows() || it.cols() != Ks[0].rows())
868 idx D =
static_cast<idx>(Ks[0].rows());
872 cmat MES = cmat::Zero(D * D, 1);
873 for (
idx a = 0; a < D; ++a )
878 cmat result = cmat::Zero(D * D, D * D);
881 #pragma omp parallel for
883 for (
idx i = 0; i < Ks.size(); ++i )
889 result +=
kron(cmat::Identity(D, D), Ks[i]) * Omega
919 idx D =
static_cast<idx>(std::llround(
920 std::sqrt(static_cast<double>(A.rows()))));
921 if ( D * D != static_cast<idx>(A.rows()))
927 std::vector<cmat> result;
929 for (
idx i = 0; i < D * D; ++i )
931 if ( std::abs(ev(i)) >
eps )
933 std::sqrt(std::abs(ev(i))) *
reshape(evec.col(i), D, D));
955 idx D =
static_cast<idx>(std::llround(
956 std::sqrt(static_cast<double>(A.rows()))));
957 if ( D * D != static_cast<idx>(A.rows()))
961 cmat result(D * D, D * D);
964 #pragma omp parallel for collapse(4)
966 for (
idx a = 0; a < D; ++a )
967 for (
idx b = 0; b < D; ++b )
968 for (
idx m = 0; m < D; ++m )
969 for (
idx n = 0; n < D; ++n )
970 result(a * D + b, m * D + n) = A(m * D + a, n * D + b);
991 idx D =
static_cast<idx>(std::llround(
992 std::sqrt(static_cast<double>(A.rows()))));
993 if ( D * D != static_cast<idx>(A.rows()))
997 cmat result(D * D, D * D);
1000 #pragma omp parallel for collapse(4)
1002 for (
idx a = 0; a < D; ++a )
1003 for (
idx b = 0; b < D; ++b )
1004 for (
idx m = 0; m < D; ++m )
1005 for (
idx n = 0; n < D; ++n )
1006 result(m * D + a, n * D + b) = A(a * D + b, m * D + n);
1025 template<
typename Derived>
1027 const std::vector<idx>& dims)
1029 const typename Eigen::MatrixBase<Derived>::EvalReturnType& rA
1043 if ( dims.size() != 2 )
1061 auto worker = [=](
idx i,
idx j) noexcept
1062 ->
typename Derived::Scalar
1064 typename Derived::Scalar
sum = 0;
1065 for (
idx m = 0; m < DA; ++m )
1066 sum += rA(m * DB + i) * std::conj(rA(m * DB + j));
1071 #ifdef _WITH_OPENMP_
1072 #pragma omp parallel for collapse(2)
1074 for (
idx j = 0; j < DB; ++j )
1075 for (
idx i = 0; i < DB; ++i )
1076 result(i, j) = worker(i, j);
1088 auto worker = [=](
idx i,
idx j) noexcept
1089 ->
typename Derived::Scalar
1091 typename Derived::Scalar
sum = 0;
1092 for (
idx m = 0; m < DA; ++m )
1093 sum += rA(m * DB + i, m * DB + j);
1098 #ifdef _WITH_OPENMP_
1099 #pragma omp parallel for collapse(2)
1101 for (
idx j = 0; j < DB; ++j )
1102 for (
idx i = 0; i < DB; ++i )
1103 result(i, j) = worker(i, j);
1127 template<
typename Derived>
1129 const std::vector<idx>& dims)
1131 const typename Eigen::MatrixBase<Derived>::EvalReturnType& rA
1145 if ( dims.size() != 2 )
1163 auto worker = [=](
idx i,
idx j) noexcept
1164 ->
typename Derived::Scalar
1166 typename Derived::Scalar
sum = 0;
1167 for (
idx m = 0; m < DB; ++m )
1168 sum += rA(i * DB + m) * std::conj(rA(j * DB + m));
1173 #ifdef _WITH_OPENMP_
1174 #pragma omp parallel for collapse(2)
1176 for (
idx j = 0; j < DA; ++j )
1177 for (
idx i = 0; i < DA; ++i )
1178 result(i, j) = worker(i, j);
1190 #ifdef _WITH_OPENMP_
1191 #pragma omp parallel for collapse(2)
1193 for (
idx j = 0; j < DA; ++j )
1194 for (
idx i = 0; i < DA; ++i )
1195 result(i, j) =
trace(rA.block(i * DB, j * DB, DB, DB));
1219 template<
typename Derived>
1221 const std::vector<idx>& subsys,
1222 const std::vector<idx>& dims)
1224 const typename Eigen::MatrixBase<Derived>::EvalReturnType& rA
1243 idx D =
static_cast<idx>(rA.rows());
1244 idx n = dims.size();
1245 idx nsubsys = subsys.size();
1246 idx nsubsysbar = n - nsubsys;
1248 for (
idx i = 0; i < nsubsys; ++i )
1249 Dsubsys *= dims[subsys[i]];
1250 idx Dsubsysbar = D / Dsubsys;
1260 std::vector<idx> subsys_bar =
complement(subsys, n);
1261 std::copy(std::begin(subsys_bar), std::end(subsys_bar),
1262 std::begin(Csubsysbar));
1264 for (
idx i = 0; i < n; ++i )
1268 for (
idx i = 0; i < nsubsys; ++i )
1270 Csubsys[i] = subsys[i];
1271 Cdimssubsys[i] = dims[subsys[i]];
1273 for (
idx i = 0; i < nsubsysbar; ++i )
1275 Cdimssubsysbar[i] = dims[subsys_bar[i]];
1289 if ( subsys.size() == dims.size())
1291 result(0, 0) = (
adjoint(rA) * rA).value();
1295 if ( subsys.size() == 0 )
1298 auto worker = [=, &Cmidxcolsubsysbar](
idx i) noexcept
1299 ->
typename Derived::Scalar
1310 Cdimssubsysbar, Cmidxrowsubsysbar);
1312 for (
idx k = 0; k < nsubsysbar; ++k )
1314 Cmidxrow[Csubsysbar[k]] = Cmidxrowsubsysbar[k];
1315 Cmidxcol[Csubsysbar[k]] = Cmidxcolsubsysbar[k];
1317 typename Derived::Scalar sm = 0;
1318 for (
idx a = 0; a < Dsubsys; ++a )
1323 for (
idx k = 0; k < nsubsys; ++k )
1324 Cmidxrow[Csubsys[k]] = Cmidxcol[Csubsys[k]]
1336 for (
idx j = 0; j < Dsubsysbar; ++j )
1340 Cdimssubsysbar, Cmidxcolsubsysbar);
1341 #ifdef _WITH_OPENMP_
1342 #pragma omp parallel for
1344 for (
idx i = 0; i < Dsubsysbar; ++i )
1346 result(i, j) = worker(i);
1360 if ( subsys.size() == dims.size())
1362 result(0, 0) = rA.trace();
1366 if ( subsys.size() == 0 )
1369 auto worker = [=, &Cmidxcolsubsysbar](
idx i) noexcept
1370 ->
typename Derived::Scalar
1381 Cdimssubsysbar, Cmidxrowsubsysbar);
1383 for (
idx k = 0; k < nsubsysbar; ++k )
1385 Cmidxrow[Csubsysbar[k]] = Cmidxrowsubsysbar[k];
1386 Cmidxcol[Csubsysbar[k]] = Cmidxcolsubsysbar[k];
1388 typename Derived::Scalar sm = 0;
1389 for (
idx a = 0; a < Dsubsys; ++a )
1394 for (
idx k = 0; k < nsubsys; ++k )
1395 Cmidxrow[Csubsys[k]] = Cmidxcol[Csubsys[k]]
1406 for (
idx j = 0; j < Dsubsysbar; ++j )
1410 Cdimssubsysbar, Cmidxcolsubsysbar);
1411 #ifdef _WITH_OPENMP_
1412 #pragma omp parallel for
1414 for (
idx i = 0; i < Dsubsysbar; ++i )
1416 result(i, j) = worker(i);
1442 template<
typename Derived>
1444 const std::vector<idx>& subsys,
1447 const typename Eigen::MatrixBase<Derived>::EvalReturnType& rA = A.derived();
1461 static_cast<idx>(std::llround(std::log2(rA.rows()) /
1463 std::vector<idx> dims(n, d);
1465 return ptrace(rA, subsys, dims);
1481 template<
typename Derived>
1483 const Eigen::MatrixBase<Derived>& A,
1484 const std::vector<idx>& subsys,
1485 const std::vector<idx>& dims)
1487 const typename Eigen::MatrixBase<Derived>::EvalReturnType& rA = A.derived();
1505 idx D =
static_cast<idx>(rA.rows());
1506 idx numdims = dims.size();
1507 idx numsubsys = subsys.size();
1513 for (
idx i = 0; i < numdims; ++i )
1515 for (
idx i = 0; i < numsubsys; ++i )
1516 Csubsys[i] = subsys[i];
1528 if ( subsys.size() == dims.size())
1531 if ( subsys.size() == 0 )
1534 auto worker = [=, &Cmidxcol](
idx i) noexcept
1535 ->
typename Derived::Scalar
1541 for (
idx k = 0; k < numdims; ++k )
1542 midxcoltmp[k] = Cmidxcol[k];
1547 for (
idx k = 0; k < numsubsys; ++k )
1548 std::swap(midxcoltmp[Csubsys[k]], midxrow[Csubsys[k]]);
1556 for (
idx j = 0; j < D; ++j )
1561 #ifdef _WITH_OPENMP_
1562 #pragma omp parallel for
1564 for (
idx i = 0; i < D; ++i )
1565 result(i, j) = worker(i);
1578 if ( subsys.size() == dims.size())
1579 return rA.transpose();
1581 if ( subsys.size() == 0 )
1584 auto worker = [=, &Cmidxcol](
idx i) noexcept
1585 ->
typename Derived::Scalar
1591 for (
idx k = 0; k < numdims; ++k )
1592 midxcoltmp[k] = Cmidxcol[k];
1597 for (
idx k = 0; k < numsubsys; ++k )
1598 std::swap(midxcoltmp[Csubsys[k]], midxrow[Csubsys[k]]);
1605 for (
idx j = 0; j < D; ++j )
1610 #ifdef _WITH_OPENMP_
1611 #pragma omp parallel for
1613 for (
idx i = 0; i < D; ++i )
1614 result(i, j) = worker(i);
1638 template<
typename Derived>
1640 const Eigen::MatrixBase<Derived>& A,
1641 const std::vector<idx>& subsys,
1644 const typename Eigen::MatrixBase<Derived>::EvalReturnType& rA = A.derived();
1658 static_cast<idx>(std::llround(std::log2(rA.rows()) /
1660 std::vector<idx> dims(n, d);
1677 template<
typename Derived>
1679 const Eigen::MatrixBase<Derived>& A,
1680 const std::vector<idx>& perm,
1681 const std::vector<idx>& dims)
1683 const typename Eigen::MatrixBase<Derived>::EvalReturnType& rA = A.derived();
1700 if ( perm.size() != dims.size())
1705 idx D =
static_cast<idx>(rA.rows());
1706 idx numdims = dims.size();
1722 for (
idx i = 0; i < numdims; ++i )
1727 result.resize(D, 1);
1729 auto worker = [&Cdims, &Cperm, numdims](
idx i) noexcept
1741 for (
idx k = 0; k < numdims; ++k )
1743 permdims[k] = Cdims[Cperm[k]];
1744 midxtmp[k] = midx[Cperm[k]];
1750 #ifdef _WITH_OPENMP_
1751 #pragma omp parallel for
1753 for (
idx i = 0; i < D; ++i )
1754 result(worker(i)) = rA(i);
1770 for (
idx i = 0; i < numdims; ++i )
1773 Cdims[i + numdims] = dims[i];
1775 Cperm[i + numdims] = perm[i] + numdims;
1777 result.resize(D * D, 1);
1780 Eigen::Map<dyn_mat<typename Derived::Scalar>>(
1781 const_cast<typename Derived::Scalar*
>(rA.data()), D * D,
1784 auto worker = [&Cdims, &Cperm, numdims](
idx i) noexcept
1796 for (
idx k = 0; k < 2 * numdims; ++k )
1798 permdims[k] = Cdims[Cperm[k]];
1799 midxtmp[k] = midx[Cperm[k]];
1805 #ifdef _WITH_OPENMP_
1806 #pragma omp parallel for
1808 for (
idx i = 0; i < D * D; ++i )
1809 result(worker(i)) = rA(i);
1831 template<
typename Derived>
1833 const Eigen::MatrixBase<Derived>& A,
1834 const std::vector<idx>& perm,
1837 const typename Eigen::MatrixBase<Derived>::EvalReturnType& rA = A.derived();
1851 static_cast<idx>(std::llround(std::log2(rA.rows()) /
1853 std::vector<idx> dims(n, d);
bool _check_cvector(const Eigen::MatrixBase< Derived > &A)
Definition: util.h:105
constexpr idx maxn
Maximum number of allowed qu(d)its (subsystems)
Definition: constants.h:74
std::vector< cmat > choi2kraus(const cmat &A)
Orthogonal Kraus operators from Choi matrix.
Definition: operations.h:910
bool _check_subsys_match_dims(const std::vector< idx > &subsys, const std::vector< idx > &dims)
Definition: util.h:183
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:71
bool _check_dims_match_cvect(const std::vector< idx > &dims, const Eigen::MatrixBase< Derived > &V)
Definition: util.h:152
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:61
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:1678
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > dyn_mat
Dynamic Eigen matrix over the field specified by Scalar.
Definition: types.h:83
Eigen::VectorXcd ket
Complex (double precision) dynamic Eigen column vector.
Definition: types.h:56
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:492
Quantum++ main namespace.
Definition: codes.h:30
bool _check_square_mat(const Eigen::MatrixBase< Derived > &A)
Definition: util.h:84
dyn_col_vect< double > hevals(const Eigen::MatrixBase< Derived > &A)
Hermitian eigenvalues.
Definition: functions.h:391
cmat choi2super(const cmat &A)
Converts Choi matrix to superoperator matrix.
Definition: operations.h:946
cmat super2choi(const cmat &A)
Converts superoperator matrix to Choi matrix.
Definition: operations.h:982
std::vector< T > complement(std::vector< T > subsys, idx N)
Constructs the complement of a subsystem vector.
Definition: functions.h:1818
dyn_mat< typename Derived::Scalar > ptrace1(const Eigen::MatrixBase< Derived > &A, const std::vector< idx > &dims)
Partial trace.
Definition: operations.h:1026
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:900
dyn_mat< typename Derived::Scalar > ptrace2(const Eigen::MatrixBase< Derived > &A, const std::vector< idx > &dims)
Partial trace.
Definition: operations.h:1128
bool _check_perm(const std::vector< idx > &perm)
Definition: util.h:242
idx _multiidx2n(const idx *midx, idx numdims, const idx *dims) noexcept
Definition: util.h:61
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:783
cmat hevects(const Eigen::MatrixBase< Derived > &A)
Hermitian eigenvectors.
Definition: functions.h:417
bool _check_nonzero_size(const T &x) noexcept
Definition: util.h:112
cmat kraus2choi(const std::vector< cmat > &Ks)
Choi matrix.
Definition: operations.h:851
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:1220
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:773
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:1482
Eigen::MatrixXcd cmat
Complex (double precision) dynamic Eigen matrix.
Definition: types.h:66
void _n2multiidx(idx n, idx numdims, const idx *dims, idx *result) noexcept
Definition: util.h:48
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:209
dyn_mat< typename Derived::Scalar > reshape(const Eigen::MatrixBase< Derived > &A, idx rows, idx cols)
Reshape.
Definition: functions.h:1140