27 #ifndef INSTRUMENTS_H_
28 #define INSTRUMENTS_H_
43 template<
typename Derived>
44 std::tuple<idx, std::vector < double>, std::vector<cmat>>
47 const Eigen::MatrixBase<Derived>& A,
const std::vector <cmat>& Ks)
61 if (Ks[0].rows() != rA.rows())
65 if (it.rows() != Ks[0].rows() || it.cols() != Ks[0].rows())
70 std::vector <double> prob(Ks.size());
72 std::vector <cmat> outstates(Ks.size());
77 for (
idx i = 0; i < Ks.size(); ++i)
79 outstates[i] = cmat::Zero(rA.rows(), rA.rows());
81 prob[i] = std::abs(
trace(tmp));
83 outstates[i] = tmp / prob[i];
89 for (
idx i = 0; i < Ks.size(); ++i)
91 outstates[i] = ket::Zero(rA.rows());
94 prob[i] = std::pow(
norm(tmp), 2);
96 outstates[i] = tmp / std::sqrt(prob[i]);
104 std::discrete_distribution<idx> dd(std::begin(prob),
108 return std::make_tuple(result, prob, outstates);
123 template<
typename Derived>
124 std::tuple<idx, std::vector < double>, std::vector<cmat>>
127 const Eigen::MatrixBase<Derived>& A,
128 const std::initializer_list<cmat>& Ks)
130 return measure(A, std::vector<cmat>(Ks));
143 template<
typename Derived>
144 std::tuple<idx, std::vector < double>, std::vector<cmat>>
147 const Eigen::MatrixBase<Derived>& A,
const cmat& U)
161 if (U.rows() != rA.rows())
166 std::vector <cmat> Ks(U.rows());
167 for (
idx i = 0; i < static_cast<idx>(U.rows()); i++)
168 Ks[i] = U.col(i) *
adjoint(U.col(i));
191 template<
typename Derived>
192 std::tuple<idx, std::vector < double>, std::vector<cmat>>
195 const Eigen::MatrixBase<Derived>& A,
196 const std::vector <cmat>& Ks,
197 const std::vector <idx>& subsys,
198 const std::vector <idx>& dims)
222 std::vector <idx> subsys_dims(subsys.size());
223 for (
idx i = 0; i < subsys.size(); ++i)
224 subsys_dims[i] = dims[subsys[i]];
226 idx D =
prod(dims.begin(), dims.end());
227 idx Dsubsys =
prod(subsys_dims.begin(), subsys_dims.end());
228 idx Dbar = D / Dsubsys;
237 if (Dsubsys != static_cast<idx>(Ks[0].rows()))
241 if (it.rows() != Ks[0].rows() || it.cols() != Ks[0].rows())
247 std::vector <double> prob(Ks.size());
249 std::vector <cmat> outstates(Ks.size());
254 for (
idx i = 0; i < Ks.size(); ++i)
256 outstates[i] = cmat::Zero(Dbar, Dbar);
257 cmat tmp =
apply(rA, Ks[i], subsys, dims);
258 tmp =
ptrace(tmp, subsys, dims);
259 prob[i] = std::abs(
trace(tmp));
264 outstates[i] = tmp / prob[i];
271 for (
idx i = 0; i < Ks.size(); ++i)
273 outstates[i] = cmat::Zero(Dbar, Dbar);
274 ket tmp =
apply(rA, Ks[i], subsys, dims);
275 prob[i] = std::pow(
norm(tmp), 2);
280 tmp /= std::sqrt(prob[i]);
281 outstates[i] =
ptrace(tmp, subsys, dims);
290 std::discrete_distribution<idx> dd(std::begin(prob),
294 return std::make_tuple(result, prob, outstates);
317 template<
typename Derived>
318 std::tuple<idx, std::vector < double>, std::vector<cmat>>
321 const Eigen::MatrixBase<Derived>& A,
322 const std::initializer_list<cmat>& Ks,
323 const std::vector <idx>& subsys,
324 const std::vector <idx>& dims)
326 return measure(A, std::vector<cmat>(Ks), subsys, dims);
346 template<
typename Derived>
347 std::tuple<idx, std::vector < double>, std::vector<cmat>>
350 const Eigen::MatrixBase<Derived>& A,
351 const std::vector <cmat>& Ks,
352 const std::vector <idx>& subsys,
362 static_cast<idx>(std::llround(std::log2(rA.rows()) /
364 std::vector <idx> dims(n, d);
366 return measure(rA, Ks, subsys, dims);
389 template<
typename Derived>
390 std::tuple<idx, std::vector < double>, std::vector<cmat>>
393 const Eigen::MatrixBase<Derived>& A,
394 const std::initializer_list<cmat>& Ks,
395 const std::vector <idx>& subsys,
398 return measure(A, std::vector<cmat>(Ks), subsys, d);
418 template<
typename Derived>
419 std::tuple<idx, std::vector < double>, std::vector<cmat>>
422 const Eigen::MatrixBase<Derived>& A,
424 const std::vector <idx>& subsys,
425 const std::vector <idx>& dims)
449 std::vector <idx> subsys_dims(subsys.size());
450 for (
idx i = 0; i < subsys.size(); ++i)
451 subsys_dims[i] = dims[subsys[i]];
453 idx Dsubsys =
prod(subsys_dims.begin(), subsys_dims.end());
460 if (Dsubsys != static_cast<idx>(U.rows()))
465 std::vector <cmat> Ks(U.rows());
466 for (
idx i = 0; i < static_cast<idx>(U.rows()); i++)
467 Ks[i] = U.col(i) *
adjoint(U.col(i));
469 return measure(rA, Ks, subsys, dims);
489 template<
typename Derived>
490 std::tuple<idx, std::vector < double>, std::vector<cmat>>
493 const Eigen::MatrixBase<Derived>& A,
495 const std::vector <idx>& subsys,
505 static_cast<idx>(std::llround(std::log2(rA.rows()) /
507 std::vector <idx> dims(n, d);
509 return measure(rA, U, subsys, dims);
526 template<
typename Derived>
527 std::tuple<std::vector < idx>, double,
cmat>
530 const Eigen::MatrixBase<Derived>& A,
531 std::vector <idx> subsys,
532 std::vector <idx> dims)
558 std::vector <idx> result;
563 std::sort(std::begin(subsys), std::end(subsys), std::greater<idx>{});
568 while (subsys.size() > 0)
572 result.push_back(std::get<0>(tmp));
573 prob *= std::get<1>(tmp)[std::get<0>(tmp)];
574 cA = std::get<2>(tmp)[std::get<0>(tmp)];
577 dims.erase(std::next(dims.begin(), subsys[0]));
578 subsys.erase(subsys.begin());
581 std::reverse(std::begin(result), std::end(result));
587 return std::make_tuple(result, prob, cA);
604 template<
typename Derived>
605 std::tuple<std::vector < idx>, double,
cmat>
608 const Eigen::MatrixBase<Derived>& A,
609 std::vector <idx> subsys,
idx d = 2)
618 static_cast<idx>(std::llround(std::log2(rA.rows()) /
620 std::vector <idx> dims(n, d);
bool _check_cvector(const Eigen::MatrixBase< Derived > &A)
Definition: util.h:104
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:135
Derived::Scalar prod(const Eigen::MatrixBase< Derived > &A)
Element-wise product of A.
Definition: functions.h:213
constexpr double eps
Used to decide whether a number or expression in double precision is zero or not. ...
Definition: constants.h:75
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > dyn_mat
Dynamic Eigen matrix over the field specified by Scalar.
Definition: types.h:84
std::tuple< std::vector< idx >, double, cmat > measure_seq(const Eigen::MatrixBase< Derived > &A, std::vector< idx > subsys, std::vector< idx > dims)
Sequentially measures the part subsys of the multi-partite state vector or density matrix A in the co...
Definition: instruments.h:529
Eigen::VectorXcd ket
Complex (double precision) dynamic Eigen column vector.
Definition: types.h:57
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
double norm(const Eigen::MatrixBase< Derived > &A)
Frobenius norm.
Definition: functions.h:231
bool _check_square_mat(const Eigen::MatrixBase< Derived > &A)
Definition: util.h:77
dyn_mat< typename Derived::Scalar > adjoint(const Eigen::MatrixBase< Derived > &A)
Adjoint.
Definition: functions.h:84
Generates custom exceptions, used when validating function parameters.
Definition: exception.h:39
bool _check_nonzero_size(const T &x) noexcept
Definition: util.h:113
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
static RandomDevices & get_instance() noexcept(std::is_nothrow_constructible< RandomDevices >::value)
Definition: singleton.h:90
Eigen::MatrixXcd cmat
Complex (double precision) dynamic Eigen matrix.
Definition: types.h:67
std::tuple< idx, std::vector< double >, std::vector< cmat > > measure(const Eigen::MatrixBase< Derived > &A, const std::vector< cmat > &Ks)
Measures the state A using the set of Kraus operators Ks.
Definition: instruments.h:46
std::size_t idx
Non-negative integer index.
Definition: types.h:36
bool _check_dims(const std::vector< idx > &dims)
Definition: util.h:119