27 #ifndef INSTRUMENTS_H_
28 #define INSTRUMENTS_H_
43 template<
typename Derived>
44 std::tuple<idx, std::vector<double>, std::vector<cmat>>
measure(
45 const Eigen::MatrixBase<Derived>& A,
const std::vector<cmat>& Ks)
59 if (Ks[0].rows() != rA.rows())
63 if (it.rows() != Ks[0].rows() || it.cols() != Ks[0].rows())
68 std::vector<double> prob(Ks.size());
70 std::vector<cmat> outstates(Ks.size());
75 for (
idx i = 0; i < Ks.size(); ++i)
77 outstates[i] = cmat::Zero(rA.rows(), rA.rows());
79 prob[i] = std::abs(
trace(tmp));
81 outstates[i] = tmp / prob[i];
87 for (
idx i = 0; i < Ks.size(); ++i)
89 outstates[i] = ket::Zero(rA.rows());
92 prob[i] = std::pow(
norm(tmp), 2);
94 outstates[i] = tmp / std::sqrt(prob[i]);
102 std::discrete_distribution<idx> dd(std::begin(prob),
106 return std::make_tuple(result, prob, outstates);
121 template<
typename Derived>
122 std::tuple<idx, std::vector<double>, std::vector<cmat>>
measure(
123 const Eigen::MatrixBase<Derived>& A,
124 const std::initializer_list<cmat>& Ks)
126 return measure(A, std::vector<cmat>(Ks));
139 template<
typename Derived>
140 std::tuple<idx, std::vector<double>, std::vector<cmat>>
measure(
141 const Eigen::MatrixBase<Derived>& A,
const cmat& U)
155 if (U.rows() != rA.rows())
160 std::vector<cmat> Ks(U.rows());
161 for (
idx i = 0; i < static_cast<idx>(U.rows()); i++)
162 Ks[i] = U.col(i) *
adjoint(U.col(i));
185 template<
typename Derived>
186 std::tuple<idx, std::vector<double>, std::vector<cmat>>
188 const Eigen::MatrixBase<Derived>& A,
189 const std::vector<cmat>& Ks,
190 const std::vector<idx>& subsys,
191 const std::vector<idx>& dims)
215 std::vector<idx> subsys_dims(subsys.size());
216 for (
idx i = 0; i < subsys.size(); ++i)
217 subsys_dims[i] = dims[subsys[i]];
219 idx D =
prod(dims.begin(), dims.end());
220 idx Dsubsys =
prod(subsys_dims.begin(), subsys_dims.end());
221 idx Dbar = D / Dsubsys;
230 if (Dsubsys != static_cast<idx>(Ks[0].rows()))
234 if (it.rows() != Ks[0].rows() || it.cols() != Ks[0].rows())
240 std::vector<double> prob(Ks.size());
242 std::vector<cmat> outstates(Ks.size());
247 for (
idx i = 0; i < Ks.size(); ++i)
249 outstates[i] = cmat::Zero(Dbar, Dbar);
250 cmat tmp =
apply(rA, Ks[i], subsys, dims);
251 tmp =
ptrace(tmp, subsys, dims);
252 prob[i] = std::abs(
trace(tmp));
257 outstates[i] = tmp / prob[i];
264 for (
idx i = 0; i < Ks.size(); ++i)
266 outstates[i] = cmat::Zero(Dbar, Dbar);
267 ket tmp =
apply(rA, Ks[i], subsys, dims);
268 prob[i] = std::pow(
norm(tmp), 2);
273 tmp /= std::sqrt(prob[i]);
274 outstates[i] =
ptrace(tmp, subsys, dims);
283 std::discrete_distribution<idx> dd(std::begin(prob),
287 return std::make_tuple(result, prob, outstates);
310 template<
typename Derived>
311 std::tuple<idx, std::vector<double>, std::vector<cmat>>
313 const Eigen::MatrixBase<Derived>& A,
314 const std::initializer_list<cmat>& Ks,
315 const std::vector<idx>& subsys,
316 const std::vector<idx>& dims)
318 return measure(A, std::vector<cmat>(Ks), subsys, dims);
338 template<
typename Derived>
339 std::tuple<idx, std::vector<double>, std::vector<cmat>>
341 const Eigen::MatrixBase<Derived>& A,
342 const std::vector<cmat>& Ks,
343 const std::vector<idx>& subsys,
353 static_cast<idx>(std::llround(std::log2(rA.rows()) /
355 std::vector<idx> dims(n, d);
357 return measure(rA, Ks, subsys, dims);
380 template<
typename Derived>
381 std::tuple<idx, std::vector<double>, std::vector<cmat>>
383 const Eigen::MatrixBase<Derived>& A,
384 const std::initializer_list<cmat>& Ks,
385 const std::vector<idx>& subsys,
388 return measure(A, std::vector<cmat>(Ks), subsys, d);
408 template<
typename Derived>
409 std::tuple<idx, std::vector<double>, std::vector<cmat>>
411 const Eigen::MatrixBase<Derived>& A,
413 const std::vector<idx>& subsys,
414 const std::vector<idx>& dims)
438 std::vector<idx> subsys_dims(subsys.size());
439 for (
idx i = 0; i < subsys.size(); ++i)
440 subsys_dims[i] = dims[subsys[i]];
442 idx Dsubsys =
prod(subsys_dims.begin(), subsys_dims.end());
449 if (Dsubsys != static_cast<idx>(U.rows()))
454 std::vector<cmat> Ks(U.rows());
455 for (
idx i = 0; i < static_cast<idx>(U.rows()); i++)
456 Ks[i] = U.col(i) *
adjoint(U.col(i));
458 return measure(rA, Ks, subsys, dims);
478 template<
typename Derived>
479 std::tuple<idx, std::vector<double>, std::vector<cmat>>
481 const Eigen::MatrixBase<Derived>& A,
483 const std::vector<idx>& subsys,
493 static_cast<idx>(std::llround(std::log2(rA.rows()) /
495 std::vector<idx> dims(n, d);
497 return measure(rA, U, subsys, dims);
514 template<
typename Derived>
515 std::tuple<std::vector<idx>, double,
cmat>
517 const Eigen::MatrixBase<Derived>& A,
518 std::vector<idx> subsys,
519 std::vector<idx> dims)
545 std::vector<idx> result;
550 std::sort(std::begin(subsys), std::end(subsys), std::greater<idx>{});
555 while (subsys.size() > 0)
559 result.push_back(std::get<0>(tmp));
560 prob *= std::get<1>(tmp)[std::get<0>(tmp)];
561 cA = std::get<2>(tmp)[std::get<0>(tmp)];
564 dims.erase(std::next(dims.begin(), subsys[0]));
565 subsys.erase(subsys.begin());
568 std::reverse(std::begin(result), std::end(result));
574 return std::make_tuple(result, prob, cA);
591 template<
typename Derived>
592 std::tuple<std::vector<idx>, double,
cmat>
594 const Eigen::MatrixBase<Derived>& A,
595 std::vector<idx> subsys,
idx d = 2)
604 static_cast<idx>(std::llround(std::log2(rA.rows()) /
606 std::vector<idx> dims(n, d);
bool _check_cvector(const Eigen::MatrixBase< Derived > &A)
Definition: util.h:110
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
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: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
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:83
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:516
dyn_mat< typename Derived::Scalar > adjoint(const Eigen::MatrixBase< Derived > &A)
Adjoint.
Definition: functions.h:84
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:44
Generates custom exceptions, used when validating function parameters.
Definition: exception.h:39
bool _check_nonzero_size(const T &x) noexcept
Definition: util.h:119
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:56
std::size_t idx
Non-negative integer index.
Definition: types.h:36
bool _check_dims(const std::vector< idx > &dims)
Definition: util.h:125