Quantum++  v1.0.0-beta1
C++11 quantum computing library
instruments.h
Go to the documentation of this file.
1 /*
2  * Quantum++
3  *
4  * Copyright (c) 2013 - 2016 Vlad Gheorghiu (vgheorgh@gmail.com)
5  *
6  * This file is part of Quantum++.
7  *
8  * Quantum++ is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * Quantum++ is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with Quantum++. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
27 #ifndef INSTRUMENTS_H_
28 #define INSTRUMENTS_H_
29 
30 // instruments
31 namespace qpp
32 {
43 template<typename Derived>
45  const Eigen::MatrixBase<Derived>& phi,
46  const Eigen::MatrixBase<Derived>& psi,
47  const std::vector<idx>& subsys,
48  const std::vector<idx>& dims)
49 {
50  const dyn_col_vect<typename Derived::Scalar>& rphi = phi.derived();
51  const dyn_col_vect<typename Derived::Scalar>& rpsi = psi.derived();
52 
53  // EXCEPTION CHECKS
54 
55  // check zero-size
57  throw Exception("qpp::ip()", Exception::Type::ZERO_SIZE);
58 
59  // check zero-size
61  throw Exception("qpp::ip()", Exception::Type::ZERO_SIZE);
62 
63  // check column vector
64  if (!internal::check_cvector(rphi))
65  throw Exception("qpp::schmidtcoeffs()",
67 
68  // check column vector
69  if (!internal::check_cvector(rpsi))
70  throw Exception("qpp::schmidtcoeffs()",
72 
73  // check that dims is a valid dimension vector
74  if (!internal::check_dims(dims))
75  throw Exception("qpp::ip()", Exception::Type::DIMS_INVALID);
76 
77  // check that subsys are valid
78  if (!internal::check_subsys_match_dims(subsys, dims))
79  throw Exception("qpp::ip()",
81 
82  // check that dims match state vector psi
83  if (!internal::check_dims_match_cvect(dims, rpsi))
84  throw Exception("qpp::ip()",
86 
87  // check that subsys match state vector phi
88  std::vector<idx> subsys_dims(subsys.size());
89  for (idx i = 0; i < subsys.size(); ++i)
90  subsys_dims[i] = dims[subsys[i]];
91  if (!internal::check_dims_match_cvect(subsys_dims, rphi))
92  throw Exception("qpp::ip()",
94  // END EXCEPTION CHECKS
95 
96  idx Dsubsys = prod(std::begin(subsys_dims), std::end(subsys_dims));
97 
98  idx D = static_cast<idx>(rpsi.rows());
99  idx Dsubsys_bar = D / Dsubsys;
100 
101  idx N = dims.size();
102  idx Nsubsys = subsys.size();
103  idx Nsubsys_bar = N - Nsubsys;
104 
105  idx Cdims[maxn];
106  idx Csubsys[maxn];
107  idx Cdimssubsys[maxn];
108  idx Csubsys_bar[maxn];
109  idx Cdimssubsys_bar[maxn];
110 
111  std::vector<idx> subsys_bar = complement(subsys, N);
112  std::copy(std::begin(subsys_bar), std::end(subsys_bar),
113  std::begin(Csubsys_bar));
114 
115  for (idx i = 0; i < N; ++i)
116  {
117  Cdims[i] = dims[i];
118  }
119  for (idx i = 0; i < Nsubsys; ++i)
120  {
121  Csubsys[i] = subsys[i];
122  Cdimssubsys[i] = dims[subsys[i]];
123  }
124  for (idx i = 0; i < Nsubsys_bar; ++i)
125  {
126  Cdimssubsys_bar[i] = dims[subsys_bar[i]];
127  }
128 
129  auto worker = [=](idx b) noexcept
130  -> typename Derived::Scalar
131  {
132  idx Cmidxrow[maxn];
133  idx Cmidxrowsubsys[maxn];
134  idx Cmidxcolsubsys_bar[maxn];
135 
136  /* get the col multi-indexes of the complement */
137  internal::n2multiidx(b, Nsubsys_bar,
138  Cdimssubsys_bar, Cmidxcolsubsys_bar);
139  /* write it in the global row multi-index */
140  for (idx k = 0; k < Nsubsys_bar; ++k)
141  {
142  Cmidxrow[Csubsys_bar[k]] = Cmidxcolsubsys_bar[k];
143  }
144 
145  typename Derived::Scalar result = 0;
146  for (idx a = 0; a < Dsubsys; ++a)
147  {
148  /* get the row multi-indexes of the subsys */
149  internal::n2multiidx(a, Nsubsys,
150  Cdimssubsys, Cmidxrowsubsys);
151  /* write it in the global row multi-index */
152  for (idx k = 0; k < Nsubsys; ++k)
153  {
154  Cmidxrow[Csubsys[k]] = Cmidxrowsubsys[k];
155  }
156  // compute the row index
157  idx i = internal::multiidx2n(Cmidxrow, N, Cdims);
158 
159  result += std::conj(rphi(a)) * rpsi(i);
160  }
161 
162  return result;
163  }; /* end worker */
164 
165  dyn_col_vect<typename Derived::Scalar> result(Dsubsys_bar);
166 #ifdef WITH_OPENMP_
167 #pragma omp parallel for
168 #endif // WITH_OPENMP_
169  for (idx m = 0; m < Dsubsys_bar; ++m)
170  result(m) = worker(m);
171 
172  return result;
173 }
174 
185 template<typename Derived>
187  const Eigen::MatrixBase<Derived>& phi,
188  const Eigen::MatrixBase<Derived>& psi,
189  const std::vector<idx>& subsys,
190  idx d = 2)
191 {
192  const dyn_col_vect<typename Derived::Scalar>& rphi = phi.derived();
193  const dyn_col_vect<typename Derived::Scalar>& rpsi = psi.derived();
194 
195  // EXCEPTION CHECKS
196 
197  if (!internal::check_nonzero_size(rpsi))
198  throw Exception("qpp::ip()", Exception::Type::ZERO_SIZE);
199 
200  // check valid dims
201  if (d == 0)
202  throw Exception("qpp::ip()", Exception::Type::DIMS_INVALID);
203  // END EXCEPTION CHECKS
204 
205  idx N = internal::get_num_subsys(static_cast<idx>(rpsi.rows()), d);
206  std::vector<idx> dims(N, d); // local dimensions vector
207  return ip(phi, psi, subsys, dims);
208 }
209 
210 // full measurements
220 template<typename Derived>
221 std::tuple<idx, std::vector<double>, std::vector<cmat>>
222 measure(const Eigen::MatrixBase<Derived>& A, const std::vector<cmat>& Ks)
223 {
224  const dyn_mat<typename Derived::Scalar>& rA = A.derived();
225 
226  // EXCEPTION CHECKS
227 
228  // check zero-size
230  throw Exception("qpp::measure()", Exception::Type::ZERO_SIZE);
231 
232  // check the Kraus operators
233  if (Ks.size() == 0)
234  throw Exception("qpp::measure()", Exception::Type::ZERO_SIZE);
235  if (!internal::check_square_mat(Ks[0]))
236  throw Exception("qpp::measure()", Exception::Type::MATRIX_NOT_SQUARE);
237  if (Ks[0].rows() != rA.rows())
238  throw Exception("qpp::measure()",
240  for (auto&& it : Ks)
241  if (it.rows() != Ks[0].rows() || it.cols() != Ks[0].rows())
242  throw Exception("qpp::measure()", Exception::Type::DIMS_NOT_EQUAL);
243  // END EXCEPTION CHECKS
244 
245  // probabilities
246  std::vector<double> prob(Ks.size());
247  // resulting states
248  std::vector<cmat> outstates(Ks.size());
249 
250  //************ density matrix ************//
251  if (internal::check_square_mat(rA)) // square matrix
252  {
253  for (idx i = 0; i < Ks.size(); ++i)
254  {
255  outstates[i] = cmat::Zero(rA.rows(), rA.rows());
256  cmat tmp = Ks[i] * rA * adjoint(Ks[i]); // un-normalized;
257  prob[i] = std::abs(trace(tmp)); // probability
258  if (prob[i] > eps)
259  outstates[i] = tmp / prob[i]; // normalized
260  }
261  }
262  //************ ket ************//
263  else if (internal::check_cvector(rA)) // column vector
264  {
265  for (idx i = 0; i < Ks.size(); ++i)
266  {
267  outstates[i] = ket::Zero(rA.rows());
268  ket tmp = Ks[i] * rA; // un-normalized;
269  // probability
270  prob[i] = std::pow(norm(tmp), 2);
271  if (prob[i] > eps)
272  outstates[i] = tmp / std::sqrt(prob[i]); // normalized
273  }
274  } else
275  throw Exception("qpp::measure()",
277 
278  // sample from the probability distribution
279  std::discrete_distribution<idx> dd(std::begin(prob),
280  std::end(prob));
281  idx result = dd(RandomDevices::get_instance().rng_);
282 
283  return std::make_tuple(result, prob, outstates);
284 }
285 
286 // std::initializer_list overload, avoids ambiguity for 2-element lists, see
287 // http://stackoverflow.com
288 // /questions/26750039/ambiguity-when-using-initializer-list-as-parameter
298 template<typename Derived>
299 std::tuple<idx, std::vector<double>, std::vector<cmat>>
300 measure(const Eigen::MatrixBase<Derived>& A,
301  const std::initializer_list<cmat>& Ks)
302 {
303  return measure(A, std::vector<cmat>(Ks));
304 }
305 
316 template<typename Derived>
317 std::tuple<idx, std::vector<double>, std::vector<cmat>>
318 measure(const Eigen::MatrixBase<Derived>& A, const cmat& U)
319 {
320  const dyn_mat<typename Derived::Scalar>& rA = A.derived();
321 
322  // EXCEPTION CHECKS
323 
324  // check zero-size
326  throw Exception("qpp::measure()", Exception::Type::ZERO_SIZE);
327 
328  // check the unitary basis matrix U
330  throw Exception("qpp::measure()", Exception::Type::ZERO_SIZE);
332  throw Exception("qpp::measure()", Exception::Type::MATRIX_NOT_SQUARE);
333  if (U.rows() != rA.rows())
334  throw Exception("qpp::measure()",
336  // END EXCEPTION CHECKS
337 
338  std::vector<cmat> Ks(U.rows());
339  for (idx i = 0; i < static_cast<idx>(U.rows()); ++i)
340  Ks[i] = U.col(i) * adjoint(U.col(i));
341 
342  return measure(rA, Ks);
343 }
344 
345 // partial measurements
363 template<typename Derived>
364 std::tuple<idx, std::vector<double>, std::vector<cmat>>
365 measure(const Eigen::MatrixBase<Derived>& A,
366  const std::vector<cmat>& Ks,
367  const std::vector<idx>& subsys,
368  const std::vector<idx>& dims)
369 {
370  const typename Eigen::MatrixBase<Derived>::EvalReturnType& rA
371  = A.derived();
372 
373  // EXCEPTION CHECKS
374 
375  // check zero-size
377  throw Exception("qpp::measure()", Exception::Type::ZERO_SIZE);
378 
379  // check that dimension is valid
380  if (!internal::check_dims(dims))
381  throw Exception("qpp::measure()", Exception::Type::DIMS_INVALID);
382 
383  // check that dims match rho matrix
384  if (!internal::check_dims_match_mat(dims, rA))
385  throw Exception("qpp::measure()",
387 
388  // check subsys is valid w.r.t. dims
389  if (!internal::check_subsys_match_dims(subsys, dims))
390  throw Exception("qpp::measure()",
392 
393  std::vector<idx> subsys_dims(subsys.size());
394  for (idx i = 0; i < subsys.size(); ++i)
395  subsys_dims[i] = dims[subsys[i]];
396 
397  idx D = prod(std::begin(dims), std::end(dims));
398  idx Dsubsys = prod(std::begin(subsys_dims), std::end(subsys_dims));
399  idx Dsubsys_bar = D / Dsubsys;
400 
401  // check the Kraus operators
402  if (Ks.size() == 0)
403  throw Exception("qpp::measure()",
405  if (!internal::check_square_mat(Ks[0]))
406  throw Exception("qpp::measure()",
408  if (Dsubsys != static_cast<idx>(Ks[0].rows()))
409  throw Exception("qpp::measure()",
411  for (auto&& it : Ks)
412  if (it.rows() != Ks[0].rows() || it.cols() != Ks[0].rows())
413  throw Exception("qpp::measure()",
415  // END EXCEPTION CHECKS
416 
417  // probabilities
418  std::vector<double> prob(Ks.size());
419  // resulting states
420  std::vector<cmat> outstates(Ks.size(), cmat::Zero(Dsubsys_bar, Dsubsys_bar));
421 
422  //************ density matrix ************//
423  if (internal::check_square_mat(rA)) // square matrix
424  {
425  for (idx i = 0; i < Ks.size(); ++i)
426  {
427  cmat tmp = apply(rA, Ks[i], subsys, dims);
428  tmp = ptrace(tmp, subsys, dims);
429  prob[i] = std::abs(trace(tmp)); // probability
430  if (prob[i] > eps)
431  {
432  // normalized output state
433  // corresponding to measurement result i
434  outstates[i] = tmp / prob[i];
435  }
436  }
437  }
438  //************ ket ************//
439  else if (internal::check_cvector(rA)) // column vector
440  {
441  for (idx i = 0; i < Ks.size(); ++i)
442  {
443  ket tmp = apply(rA, Ks[i], subsys, dims);
444  prob[i] = std::pow(norm(tmp), 2);
445  if (prob[i] > eps)
446  {
447  // normalized output state
448  // corresponding to measurement result i
449  tmp /= std::sqrt(prob[i]);
450  outstates[i] = ptrace(tmp, subsys, dims);
451  }
452  }
453  } else
454  throw Exception("qpp::measure()",
456 
457  // sample from the probability distribution
458  std::discrete_distribution<idx> dd(std::begin(prob),
459  std::end(prob));
460  idx result = dd(RandomDevices::get_instance().rng_);
461 
462  return std::make_tuple(result, prob, outstates);
463 }
464 
465 // std::initializer_list overload, avoids ambiguity for 2-element lists, see
466 // http://stackoverflow.com
467 // /questions/26750039/ambiguity-when-using-initializer-list-as-parameter
485 template<typename Derived>
486 std::tuple<idx, std::vector<double>, std::vector<cmat>>
487 measure(const Eigen::MatrixBase<Derived>& A,
488  const std::initializer_list<cmat>& Ks,
489  const std::vector<idx>& subsys,
490  const std::vector<idx>& dims)
491 {
492  return measure(A, std::vector<cmat>(Ks), subsys, dims);
493 }
494 
512 template<typename Derived>
513 std::tuple<idx, std::vector<double>, std::vector<cmat>>
514 measure(const Eigen::MatrixBase<Derived>& A,
515  const std::vector<cmat>& Ks,
516  const std::vector<idx>& subsys,
517  idx d = 2)
518 {
519  const typename Eigen::MatrixBase<Derived>::EvalReturnType& rA
520  = A.derived();
521 
522  // EXCEPTION CHECKS
523 
524  // check zero size
526  throw Exception("qpp::measure()", Exception::Type::ZERO_SIZE);
527 
528  // check valid dims
529  if (d == 0)
530  throw Exception("qpp::measure()", Exception::Type::DIMS_INVALID);
531  // END EXCEPTION CHECKS
532 
533  idx N = internal::get_num_subsys(static_cast<idx>(rA.rows()), d);
534  std::vector<idx> dims(N, d); // local dimensions vector
535 
536  return measure(rA, Ks, subsys, dims);
537 }
538 
539 // std::initializer_list overload, avoids ambiguity for 2-element lists, see
540 // http://stackoverflow.com
541 // /questions/26750039/ambiguity-when-using-initializer-list-as-parameter
559 template<typename Derived>
560 std::tuple<idx, std::vector<double>, std::vector<cmat>>
561 measure(const Eigen::MatrixBase<Derived>& A,
562  const std::initializer_list<cmat>& Ks,
563  const std::vector<idx>& subsys,
564  idx d = 2)
565 {
566  return measure(A, std::vector<cmat>(Ks), subsys, d);
567 }
568 
587 template<typename Derived>
588 std::tuple<idx, std::vector<double>, std::vector<cmat>>
589 measure(const Eigen::MatrixBase<Derived>& A,
590  const cmat& V,
591  const std::vector<idx>& subsys,
592  const std::vector<idx>& dims)
593 {
594  const typename Eigen::MatrixBase<Derived>::EvalReturnType& rA
595  = A.derived();
596 
597  // EXCEPTION CHECKS
598 
599  // check zero-size
601  throw Exception("qpp::measure()", Exception::Type::ZERO_SIZE);
602 
603  // check that dimension is valid
604  if (!internal::check_dims(dims))
605  throw Exception("qpp::measure()", Exception::Type::DIMS_INVALID);
606 
607  // check subsys is valid w.r.t. dims
608  if (!internal::check_subsys_match_dims(subsys, dims))
609  throw Exception("qpp::measure()",
611 
612  std::vector<idx> subsys_dims(subsys.size());
613  for (idx i = 0; i < subsys.size(); ++i)
614  subsys_dims[i] = dims[subsys[i]];
615 
616  idx Dsubsys = prod(std::begin(subsys_dims), std::end(subsys_dims));
617 
618  // check the matrix V
620  throw Exception("qpp::measure()", Exception::Type::ZERO_SIZE);
621 // if (!internal::check_square_mat(U))
622 // throw Exception("qpp::measure()", Exception::Type::MATRIX_NOT_SQUARE);
623  if (Dsubsys != static_cast<idx>(V.rows()))
624  throw Exception("qpp::measure()",
626  // END EXCEPTION CHECKS
627 
628  // number of basis (rank-1 POVM) elements
629  idx M = static_cast<idx>(V.cols());
630 
631  //************ ket ************//
632  if (internal::check_cvector(rA))
633  {
634  const ket& rpsi = A.derived();
635  // check that dims match state vector
636  if (!internal::check_dims_match_cvect(dims, rA))
637  throw Exception("qpp::measure()",
639 
640  std::vector<double> prob(M); // probabilities
641  std::vector<cmat> outstates(M); // resulting states
642 
643 #ifdef WITH_OPENMP_
644 #pragma omp parallel for
645 #endif // WITH_OPENMP_
646  for (idx i = 0; i < M; ++i)
647  outstates[i] = ip(static_cast<const ket&>(V.col(i)),
648  rpsi, subsys, dims);
649 
650  for (idx i = 0; i < M; ++i)
651  {
652  double tmp = norm(outstates[i]);
653  prob[i] = tmp * tmp;
654  if (prob[i] > eps)
655  {
656  // normalized output state
657  // corresponding to measurement result m
658  outstates[i] /= tmp;
659  }
660  }
661 
662  // sample from the probability distribution
663  std::discrete_distribution<idx> dd(std::begin(prob),
664  std::end(prob));
665  idx result = dd(RandomDevices::get_instance().rng_);
666 
667  return std::make_tuple(result, prob, outstates);
668  }
669  //************ density matrix ************//
670  else if (internal::check_square_mat(rA))
671  {
672  // check that dims match rho matrix
673  if (!internal::check_dims_match_mat(dims, rA))
674  throw Exception("qpp::measure()",
676 
677  std::vector<cmat> Ks(M);
678  for (idx i = 0; i < M; ++i)
679  Ks[i] = V.col(i) * adjoint(V.col(i));
680 
681  return measure(rA, Ks, subsys, dims);
682  }
683  //************ Exception: not ket nor density matrix ************//
684  throw Exception("qpp::measure()",
686 }
687 
706 template<typename Derived>
707 std::tuple<idx, std::vector<double>, std::vector<cmat>>
708 measure(const Eigen::MatrixBase<Derived>& A,
709  const cmat& V,
710  const std::vector<idx>& subsys,
711  idx d = 2)
712 {
713  const typename Eigen::MatrixBase<Derived>::EvalReturnType& rA
714  = A.derived();
715 
716  // EXCEPTION CHECKS
717 
718  // check zero size
720  throw Exception("qpp::measure()", Exception::Type::ZERO_SIZE);
721 
722  // check valid dims
723  if (d == 0)
724  throw Exception("qpp::measure()", Exception::Type::DIMS_INVALID);
725  // END EXCEPTION CHECKS
726 
727  idx N = internal::get_num_subsys(static_cast<idx>(rA.rows()), d);
728  std::vector<idx> dims(N, d); // local dimensions vector
729 
730  return measure(rA, V, subsys, dims);
731 }
732 
747 template<typename Derived>
748 std::tuple<std::vector<idx>, double, cmat>
749 measure_seq(const Eigen::MatrixBase<Derived>& A,
750  std::vector<idx> subsys,
751  std::vector<idx> dims)
752 {
753 // typename std::remove_const<
754 // typename Eigen::MatrixBase<Derived>::EvalReturnType
755 // >::type cA = A.derived();
756 
757  dyn_mat<typename Derived::Scalar> cA = A.derived();
758 
759  // EXCEPTION CHECKS
760 
761  // check zero-size
763  throw Exception("qpp::measure_seq()", Exception::Type::ZERO_SIZE);
764 
765  // check that dimension is valid
766  if (!internal::check_dims(dims))
767  throw Exception("qpp::measure_seq()", Exception::Type::DIMS_INVALID);
768 
769  // check that dims match rho matrix
770  if (!internal::check_dims_match_mat(dims, cA))
771  throw Exception("qpp::measure_seq()",
773 
774  // check subsys is valid w.r.t. dims
775  if (!internal::check_subsys_match_dims(subsys, dims))
776  throw Exception("qpp::measure_seq()",
778  // END EXCEPTION CHECKS
779 
780  std::vector<idx> result;
781  double prob = 1;
782 
783  // sort subsys in decreasing order,
784  // the order of measurements does not matter
785  std::sort(std::begin(subsys), std::end(subsys), std::greater<idx> {});
786 
787  //************ density matrix or column vector ************//
789  {
790  while (subsys.size() > 0)
791  {
792  auto tmp = measure(
793  cA, Gates::get_instance().Id(dims[subsys[0]]),
794  {subsys[0]}, dims
795  );
796  result.push_back(std::get<0>(tmp));
797  prob *= std::get<1>(tmp)[std::get<0>(tmp)];
798  cA = std::get<2>(tmp)[std::get<0>(tmp)];
799 
800  // remove the subsystem
801  dims.erase(std::next(std::begin(dims), subsys[0]));
802  subsys.erase(std::begin(subsys));
803  }
804  // order result in increasing order with respect to subsys
805  std::reverse(std::begin(result), std::end(result));
806  } else
807  throw Exception("qpp::measure_seq()",
809 
810  return std::make_tuple(result, prob, cA);
811 }
812 
827 template<typename Derived>
828 std::tuple<std::vector<idx>, double, cmat>
829 measure_seq(const Eigen::MatrixBase<Derived>& A,
830  std::vector<idx> subsys,
831  idx d = 2)
832 {
833  const typename Eigen::MatrixBase<Derived>::EvalReturnType& rA
834  = A.derived();
835 
836  // EXCEPTION CHECKS
837 
838  // check zero size
840  throw Exception("qpp::measure_seq()", Exception::Type::ZERO_SIZE);
841 
842  // check valid dims
843  if (d == 0)
844  throw Exception("qpp::measure_seq()", Exception::Type::DIMS_INVALID);
845  // END EXCEPTION CHECKS
846 
847  idx N = internal::get_num_subsys(static_cast<idx>(rA.rows()), d);
848  std::vector<idx> dims(N, d); // local dimensions vector
849 
850  return measure_seq(rA, subsys, dims);
851 }
852 
853 } /* namespace qpp */
854 
855 #endif /* INSTRUMENTS_H_ */
bool check_nonzero_size(const T &x) noexcept
Definition: util.h:112
constexpr idx maxn
Maximum number of allowed qu(d)its (subsystems)
Definition: constants.h:74
bool check_subsys_match_dims(const std::vector< idx > &subsys, const std::vector< idx > &dims)
Definition: util.h:183
bool check_cvector(const Eigen::MatrixBase< Derived > &A)
Definition: util.h:105
Derived::Scalar prod(const Eigen::MatrixBase< Derived > &A)
Element-wise product of A.
Definition: functions.h:231
constexpr double eps
Used to decide whether a number or expression in double precision is zero or not. ...
Definition: constants.h:67
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:141
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:485
Quantum++ main namespace.
Definition: codes.h:30
double norm(const Eigen::MatrixBase< Derived > &A)
Frobenius norm.
Definition: functions.h:252
idx get_num_subsys(idx sz, idx d)
Definition: util.h:355
bool check_dims_match_cvect(const std::vector< idx > &dims, const Eigen::MatrixBase< Derived > &V)
Definition: util.h:152
std::vector< T > complement(std::vector< T > subsys, idx N)
Constructs the complement of a subsystem vector.
Definition: functions.h:1814
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:749
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:222
Generates custom exceptions, used when validating function parameters.
Definition: exception.h:39
void n2multiidx(idx n, idx numdims, const idx *dims, idx *result) noexcept
Definition: util.h:48
dyn_col_vect< typename Derived::Scalar > ip(const Eigen::MatrixBase< Derived > &phi, const Eigen::MatrixBase< Derived > &psi, const std::vector< idx > &subsys, const std::vector< idx > &dims)
Generalized inner product.
Definition: instruments.h:44
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:1209
bool check_square_mat(const Eigen::MatrixBase< Derived > &A)
Definition: util.h:84
Derived::Scalar trace(const Eigen::MatrixBase< Derived > &A)
Trace.
Definition: functions.h:127
Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > dyn_col_vect
Dynamic Eigen column vector over the field specified by Scalar.
Definition: types.h:90
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:61
bool check_dims(const std::vector< idx > &dims)
Definition: util.h:125
std::size_t idx
Non-negative integer index.
Definition: types.h:36
idx multiidx2n(const idx *midx, idx numdims, const idx *dims) noexcept
Definition: util.h:61