Quantum++  v1.0-rc2
A modern C++11 quantum computing library
instruments.h
Go to the documentation of this file.
1 /*
2  * Quantum++
3  *
4  * Copyright (c) 2013 - 2017 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 namespace qpp
31 {
42 template<typename Derived>
44  const Eigen::MatrixBase<Derived>& phi,
45  const Eigen::MatrixBase<Derived>& psi,
46  const std::vector<idx>& subsys,
47  const std::vector<idx>& dims)
48 {
49  const dyn_col_vect<typename Derived::Scalar>& rphi = phi.derived();
50  const dyn_col_vect<typename Derived::Scalar>& rpsi = psi.derived();
51 
52  // EXCEPTION CHECKS
53 
54  // check zero-size
56  throw exception::ZeroSize("qpp::ip()");
57 
58  // check zero-size
60  throw exception::ZeroSize("qpp::ip()");
61 
62  // check column vector
63  if (!internal::check_cvector(rphi))
64  throw exception::MatrixNotCvector("qpp::ip()");
65 
66  // check column vector
67  if (!internal::check_cvector(rpsi))
68  throw exception::MatrixNotCvector("qpp::ip()");
69 
70  // check that dims is a valid dimension vector
71  if (!internal::check_dims(dims))
72  throw exception::DimsInvalid("qpp::ip()");
73 
74  // check that subsys are valid
75  if (!internal::check_subsys_match_dims(subsys, dims))
76  throw exception::SubsysMismatchDims("qpp::ip()");
77 
78  // check that dims match state vector psi
79  if (!internal::check_dims_match_cvect(dims, rpsi))
80  throw exception::DimsMismatchCvector("qpp::ip()");
81 
82  // check that subsys match state vector phi
83  std::vector<idx> subsys_dims(subsys.size());
84  for (idx i = 0; i < subsys.size(); ++i)
85  subsys_dims[i] = dims[subsys[i]];
86  if (!internal::check_dims_match_cvect(subsys_dims, rphi))
87  throw exception::DimsMismatchCvector("qpp::ip()");
88  // END EXCEPTION CHECKS
89 
90  idx Dsubsys = prod(std::begin(subsys_dims), std::end(subsys_dims));
91 
92  idx D = static_cast<idx>(rpsi.rows());
93  idx Dsubsys_bar = D / Dsubsys;
94 
95  idx N = dims.size();
96  idx Nsubsys = subsys.size();
97  idx Nsubsys_bar = N - Nsubsys;
98 
99  idx Cdims[maxn];
100  idx Csubsys[maxn];
101  idx Cdimssubsys[maxn];
102  idx Csubsys_bar[maxn];
103  idx Cdimssubsys_bar[maxn];
104 
105  std::vector<idx> subsys_bar = complement(subsys, N);
106  std::copy(std::begin(subsys_bar), std::end(subsys_bar),
107  std::begin(Csubsys_bar));
108 
109  for (idx i = 0; i < N; ++i)
110  {
111  Cdims[i] = dims[i];
112  }
113  for (idx i = 0; i < Nsubsys; ++i)
114  {
115  Csubsys[i] = subsys[i];
116  Cdimssubsys[i] = dims[subsys[i]];
117  }
118  for (idx i = 0; i < Nsubsys_bar; ++i)
119  {
120  Cdimssubsys_bar[i] = dims[subsys_bar[i]];
121  }
122 
123  auto worker = [&](idx b) noexcept
124  -> typename Derived::Scalar
125  {
126  idx Cmidxrow[maxn];
127  idx Cmidxrowsubsys[maxn];
128  idx Cmidxcolsubsys_bar[maxn];
129 
130  /* get the col multi-indexes of the complement */
131  internal::n2multiidx(b, Nsubsys_bar,
132  Cdimssubsys_bar, Cmidxcolsubsys_bar);
133  /* write it in the global row multi-index */
134  for (idx k = 0; k < Nsubsys_bar; ++k)
135  {
136  Cmidxrow[Csubsys_bar[k]] = Cmidxcolsubsys_bar[k];
137  }
138 
139  typename Derived::Scalar result = 0;
140  for (idx a = 0; a < Dsubsys; ++a)
141  {
142  /* get the row multi-indexes of the subsys */
143  internal::n2multiidx(a, Nsubsys,
144  Cdimssubsys, Cmidxrowsubsys);
145  /* write it in the global row multi-index */
146  for (idx k = 0; k < Nsubsys; ++k)
147  {
148  Cmidxrow[Csubsys[k]] = Cmidxrowsubsys[k];
149  }
150  // compute the row index
151  idx i = internal::multiidx2n(Cmidxrow, N, Cdims);
152 
153  result += std::conj(rphi(a)) * rpsi(i);
154  }
155 
156  return result;
157  }; /* end worker */
158 
159  dyn_col_vect<typename Derived::Scalar> result(Dsubsys_bar);
160 #ifdef WITH_OPENMP_
161 #pragma omp parallel for
162 #endif // WITH_OPENMP_
163  for (idx m = 0; m < Dsubsys_bar; ++m)
164  result(m) = worker(m);
165 
166  return result;
167 }
168 
179 template<typename Derived>
181  const Eigen::MatrixBase<Derived>& phi,
182  const Eigen::MatrixBase<Derived>& psi,
183  const std::vector<idx>& subsys,
184  idx d = 2)
185 {
186  const dyn_col_vect<typename Derived::Scalar>& rphi = phi.derived();
187  const dyn_col_vect<typename Derived::Scalar>& rpsi = psi.derived();
188 
189  // EXCEPTION CHECKS
190 
191  if (!internal::check_nonzero_size(rpsi))
192  throw exception::ZeroSize("qpp::ip()");
193 
194  // check valid dims
195  if (d < 2)
196  throw exception::DimsInvalid("qpp::ip()");
197  // END EXCEPTION CHECKS
198 
199  idx N = internal::get_num_subsys(static_cast<idx>(rpsi.rows()), d);
200  std::vector<idx> dims(N, d); // local dimensions vector
201  return ip(phi, psi, subsys, dims);
202 }
203 
204 // full measurements
214 template<typename Derived>
215 std::tuple<idx, std::vector<double>, std::vector<cmat>>
216 measure(const Eigen::MatrixBase<Derived>& A, const std::vector<cmat>& Ks)
217 {
218  const dyn_mat<typename Derived::Scalar>& rA = A.derived();
219 
220  // EXCEPTION CHECKS
221 
222  // check zero-size
224  throw exception::ZeroSize("qpp::measure()");
225 
226  // check the Kraus operators
227  if (Ks.size() == 0)
228  throw exception::ZeroSize("qpp::measure()");
229  if (!internal::check_square_mat(Ks[0]))
230  throw exception::MatrixNotSquare("qpp::measure()");
231  if (Ks[0].rows() != rA.rows())
232  throw exception::DimsMismatchMatrix("qpp::measure()");
233  for (auto&& it : Ks)
234  if (it.rows() != Ks[0].rows() || it.cols() != Ks[0].rows())
235  throw exception::DimsNotEqual("qpp::measure()");
236  // END EXCEPTION CHECKS
237 
238  // probabilities
239  std::vector<double> prob(Ks.size());
240  // resulting states
241  std::vector<cmat> outstates(Ks.size());
242 
243  //************ density matrix ************//
244  if (internal::check_square_mat(rA)) // square matrix
245  {
246  for (idx i = 0; i < Ks.size(); ++i)
247  {
248  outstates[i] = cmat::Zero(rA.rows(), rA.rows());
249  cmat tmp = Ks[i] * rA * adjoint(Ks[i]); // un-normalized;
250  prob[i] = std::abs(trace(tmp)); // probability
251  if (prob[i] > eps)
252  outstates[i] = tmp / prob[i]; // normalized
253  }
254  }
255  //************ ket ************//
256  else if (internal::check_cvector(rA)) // column vector
257  {
258  for (idx i = 0; i < Ks.size(); ++i)
259  {
260  outstates[i] = ket::Zero(rA.rows());
261  ket tmp = Ks[i] * rA; // un-normalized;
262  // probability
263  prob[i] = std::pow(norm(tmp), 2);
264  if (prob[i] > eps)
265  outstates[i] = tmp / std::sqrt(prob[i]); // normalized
266  }
267  } else
268  throw exception::MatrixNotSquareNorCvector("qpp::measure()");
269 
270  // sample from the probability distribution
271  std::discrete_distribution<idx> dd(std::begin(prob),
272  std::end(prob));
273  idx result = dd(RandomDevices::get_instance().get_prng());
274 
275  return std::make_tuple(result, prob, outstates);
276 }
277 
278 // std::initializer_list overload, avoids ambiguity for 2-element lists, see
279 // http://stackoverflow.com
280 // /questions/26750039/ambiguity-when-using-initializer-list-as-parameter
290 template<typename Derived>
291 std::tuple<idx, std::vector<double>, std::vector<cmat>>
292 measure(const Eigen::MatrixBase<Derived>& A,
293  const std::initializer_list<cmat>& Ks)
294 {
295  return measure(A, std::vector<cmat>(Ks));
296 }
297 
308 template<typename Derived>
309 std::tuple<idx, std::vector<double>, std::vector<cmat>>
310 measure(const Eigen::MatrixBase<Derived>& A, const cmat& U)
311 {
312  const dyn_mat<typename Derived::Scalar>& rA = A.derived();
313 
314  // EXCEPTION CHECKS
315 
316  // check zero-size
318  throw exception::ZeroSize("qpp::measure()");
319 
320  // check the unitary basis matrix U
322  throw exception::ZeroSize("qpp::measure()");
324  throw exception::MatrixNotSquare("qpp::measure()");
325  if (U.rows() != rA.rows())
326  throw exception::DimsMismatchMatrix("qpp::measure()");
327  // END EXCEPTION CHECKS
328 
329  std::vector<cmat> Ks(U.rows());
330  for (idx i = 0; i < static_cast<idx>(U.rows()); ++i)
331  Ks[i] = U.col(i) * adjoint(U.col(i));
332 
333  return measure(rA, Ks);
334 }
335 
336 // partial measurements
354 template<typename Derived>
355 std::tuple<idx, std::vector<double>, std::vector<cmat>>
356 measure(const Eigen::MatrixBase<Derived>& A,
357  const std::vector<cmat>& Ks,
358  const std::vector<idx>& subsys,
359  const std::vector<idx>& dims)
360 {
361  const typename Eigen::MatrixBase<Derived>::EvalReturnType& rA = A.derived();
362 
363  // EXCEPTION CHECKS
364 
365  // check zero-size
367  throw exception::ZeroSize("qpp::measure()");
368 
369  // check that dimension is valid
370  if (!internal::check_dims(dims))
371  throw exception::DimsInvalid("qpp::measure()");
372 
373  // check that dims match rho matrix
374  if (!internal::check_dims_match_mat(dims, rA))
375  throw exception::DimsMismatchMatrix("qpp::measure()");
376 
377  // check subsys is valid w.r.t. dims
378  if (!internal::check_subsys_match_dims(subsys, dims))
379  throw exception::SubsysMismatchDims("qpp::measure()");
380 
381  std::vector<idx> subsys_dims(subsys.size());
382  for (idx i = 0; i < subsys.size(); ++i)
383  subsys_dims[i] = dims[subsys[i]];
384 
385  idx D = prod(std::begin(dims), std::end(dims));
386  idx Dsubsys = prod(std::begin(subsys_dims), std::end(subsys_dims));
387  idx Dsubsys_bar = D / Dsubsys;
388 
389  // check the Kraus operators
390  if (Ks.size() == 0)
391  throw exception::ZeroSize("qpp::measure()");
392  if (!internal::check_square_mat(Ks[0]))
393  throw exception::MatrixNotSquare("qpp::measure()");
394  if (Dsubsys != static_cast<idx>(Ks[0].rows()))
395  throw exception::DimsMismatchMatrix("qpp::measure()");
396  for (auto&& it : Ks)
397  if (it.rows() != Ks[0].rows() || it.cols() != Ks[0].rows())
398  throw exception::DimsNotEqual("qpp::measure()");
399  // END EXCEPTION CHECKS
400 
401  // probabilities
402  std::vector<double> prob(Ks.size());
403  // resulting states
404  std::vector<cmat> outstates(Ks.size(),
405  cmat::Zero(Dsubsys_bar, Dsubsys_bar));
406 
407  //************ density matrix ************//
408  if (internal::check_square_mat(rA)) // square matrix
409  {
410  for (idx i = 0; i < Ks.size(); ++i)
411  {
412  cmat tmp = apply(rA, Ks[i], subsys, dims);
413  tmp = ptrace(tmp, subsys, dims);
414  prob[i] = std::abs(trace(tmp)); // probability
415  if (prob[i] > eps)
416  {
417  // normalized output state
418  // corresponding to measurement result i
419  outstates[i] = tmp / prob[i];
420  }
421  }
422  }
423  //************ ket ************//
424  else if (internal::check_cvector(rA)) // column vector
425  {
426  for (idx i = 0; i < Ks.size(); ++i)
427  {
428  ket tmp = apply(rA, Ks[i], subsys, dims);
429  prob[i] = std::pow(norm(tmp), 2);
430  if (prob[i] > eps)
431  {
432  // normalized output state
433  // corresponding to measurement result i
434  tmp /= std::sqrt(prob[i]);
435  outstates[i] = ptrace(tmp, subsys, dims);
436  }
437  }
438  } else
439  throw exception::MatrixNotSquareNorCvector("qpp::measure()");
440 
441  // sample from the probability distribution
442  std::discrete_distribution<idx> dd(std::begin(prob),
443  std::end(prob));
444  idx result = dd(RandomDevices::get_instance().get_prng());
445 
446  return std::make_tuple(result, prob, outstates);
447 }
448 
449 // std::initializer_list overload, avoids ambiguity for 2-element lists, see
450 // http://stackoverflow.com
451 // /questions/26750039/ambiguity-when-using-initializer-list-as-parameter
469 template<typename Derived>
470 std::tuple<idx, std::vector<double>, std::vector<cmat>>
471 measure(const Eigen::MatrixBase<Derived>& A,
472  const std::initializer_list<cmat>& Ks,
473  const std::vector<idx>& subsys,
474  const std::vector<idx>& dims)
475 {
476  return measure(A, std::vector<cmat>(Ks), subsys, dims);
477 }
478 
496 template<typename Derived>
497 std::tuple<idx, std::vector<double>, std::vector<cmat>>
498 measure(const Eigen::MatrixBase<Derived>& A,
499  const std::vector<cmat>& Ks,
500  const std::vector<idx>& subsys,
501  idx d = 2)
502 {
503  const typename Eigen::MatrixBase<Derived>::EvalReturnType& rA
504  = A.derived();
505 
506  // EXCEPTION CHECKS
507 
508  // check zero size
510  throw exception::ZeroSize("qpp::measure()");
511 
512  // check valid dims
513  if (d < 2)
514  throw exception::DimsInvalid("qpp::measure()");
515  // END EXCEPTION CHECKS
516 
517  idx N = internal::get_num_subsys(static_cast<idx>(rA.rows()), d);
518  std::vector<idx> dims(N, d); // local dimensions vector
519 
520  return measure(rA, Ks, subsys, dims);
521 }
522 
523 // std::initializer_list overload, avoids ambiguity for 2-element lists, see
524 // http://stackoverflow.com
525 // /questions/26750039/ambiguity-when-using-initializer-list-as-parameter
543 template<typename Derived>
544 std::tuple<idx, std::vector<double>, std::vector<cmat>>
545 measure(const Eigen::MatrixBase<Derived>& A,
546  const std::initializer_list<cmat>& Ks,
547  const std::vector<idx>& subsys,
548  idx d = 2)
549 {
550  return measure(A, std::vector<cmat>(Ks), subsys, d);
551 }
552 
571 template<typename Derived>
572 std::tuple<idx, std::vector<double>, std::vector<cmat>>
573 measure(const Eigen::MatrixBase<Derived>& A,
574  const cmat& V,
575  const std::vector<idx>& subsys,
576  const std::vector<idx>& dims)
577 {
578  const typename Eigen::MatrixBase<Derived>::EvalReturnType& rA
579  = A.derived();
580 
581  // EXCEPTION CHECKS
582 
583  // check zero-size
585  throw exception::ZeroSize("qpp::measure()");
586 
587  // check that dimension is valid
588  if (!internal::check_dims(dims))
589  throw exception::DimsInvalid("qpp::measure()");
590 
591  // check subsys is valid w.r.t. dims
592  if (!internal::check_subsys_match_dims(subsys, dims))
593  throw exception::SubsysMismatchDims("qpp::measure()");
594 
595  std::vector<idx> subsys_dims(subsys.size());
596  for (idx i = 0; i < subsys.size(); ++i)
597  subsys_dims[i] = dims[subsys[i]];
598 
599  idx Dsubsys = prod(std::begin(subsys_dims), std::end(subsys_dims));
600 
601  // check the matrix V
603  throw exception::ZeroSize("qpp::measure()");
604  if (Dsubsys != static_cast<idx>(V.rows()))
605  throw exception::DimsMismatchMatrix("qpp::measure()");
606  // END EXCEPTION CHECKS
607 
608  // number of basis (rank-1 POVM) elements
609  idx M = static_cast<idx>(V.cols());
610 
611  //************ ket ************//
612  if (internal::check_cvector(rA))
613  {
614  const ket& rpsi = A.derived();
615  // check that dims match state vector
616  if (!internal::check_dims_match_cvect(dims, rA))
617  throw exception::DimsMismatchCvector("qpp::measure()");
618 
619  std::vector<double> prob(M); // probabilities
620  std::vector<cmat> outstates(M); // resulting states
621 
622 #ifdef WITH_OPENMP_
623 #pragma omp parallel for
624 #endif // WITH_OPENMP_
625  for (idx i = 0; i < M; ++i)
626  outstates[i] = ip(static_cast<const ket&>(V.col(i)),
627  rpsi, subsys, dims);
628 
629  for (idx i = 0; i < M; ++i)
630  {
631  double tmp = norm(outstates[i]);
632  prob[i] = tmp * tmp;
633  if (prob[i] > eps)
634  {
635  // normalized output state
636  // corresponding to measurement result m
637  outstates[i] /= tmp;
638  }
639  }
640 
641  // sample from the probability distribution
642  std::discrete_distribution<idx> dd(std::begin(prob),
643  std::end(prob));
644  idx result = dd(RandomDevices::get_instance().get_prng());
645 
646  return std::make_tuple(result, prob, outstates);
647  }
648  //************ density matrix ************//
649  else if (internal::check_square_mat(rA))
650  {
651  // check that dims match rho matrix
652  if (!internal::check_dims_match_mat(dims, rA))
653  throw exception::DimsMismatchMatrix("qpp::measure()");
654 
655  std::vector<cmat> Ks(M);
656  for (idx i = 0; i < M; ++i)
657  Ks[i] = V.col(i) * adjoint(V.col(i));
658 
659  return measure(rA, Ks, subsys, dims);
660  }
661  //************ Exception: not ket nor density matrix ************//
662  throw exception::MatrixNotSquareNorCvector("qpp::measure()");
663 }
664 
683 template<typename Derived>
684 std::tuple<idx, std::vector<double>, std::vector<cmat>>
685 measure(const Eigen::MatrixBase<Derived>& A,
686  const cmat& V,
687  const std::vector<idx>& subsys,
688  idx d = 2)
689 {
690  const typename Eigen::MatrixBase<Derived>::EvalReturnType& rA
691  = A.derived();
692 
693  // EXCEPTION CHECKS
694 
695  // check zero size
697  throw exception::ZeroSize("qpp::measure()");
698 
699  // check valid dims
700  if (d < 2)
701  throw exception::DimsInvalid("qpp::measure()");
702  // END EXCEPTION CHECKS
703 
704  idx N = internal::get_num_subsys(static_cast<idx>(rA.rows()), d);
705  std::vector<idx> dims(N, d); // local dimensions vector
706 
707  return measure(rA, V, subsys, dims);
708 }
709 
724 template<typename Derived>
725 std::tuple<std::vector<idx>, double, cmat>
726 measure_seq(const Eigen::MatrixBase<Derived>& A,
727  std::vector<idx> subsys,
728  std::vector<idx> dims)
729 {
730 // typename std::remove_const<
731 // typename Eigen::MatrixBase<Derived>::EvalReturnType
732 // >::type cA = A.derived();
733 
734  dyn_mat<typename Derived::Scalar> cA = A.derived();
735 
736  // EXCEPTION CHECKS
737 
738  // check zero-size
740  throw exception::ZeroSize("qpp::measure_seq()");
741 
742  // check that dimension is valid
743  if (!internal::check_dims(dims))
744  throw exception::DimsInvalid("qpp::measure_seq()");
745 
746 
747  // check square matrix or column vector
749  {
750  // check that dims match rho matrix
751  if (!internal::check_dims_match_mat(dims, cA))
752  throw exception::DimsMismatchMatrix("qpp::measure_seq()");
753  } else if (internal::check_cvector(cA))
754  {
755  // check that dims match psi column vector
756  if (!internal::check_dims_match_cvect(dims, cA))
757  throw exception::DimsMismatchMatrix("qpp::measure_seq()");
758  } else
759  throw exception::MatrixNotSquareNorCvector("qpp::measure_seq()");
760 
761  // check subsys is valid w.r.t. dims
762  if (!internal::check_subsys_match_dims(subsys, dims))
763  throw exception::SubsysMismatchDims("qpp::measure_seq()");
764  // END EXCEPTION CHECKS
765 
766  std::vector<idx> result;
767  double prob = 1;
768 
769  // sort subsys in decreasing order,
770  // the order of measurements does not matter
771  std::sort(std::begin(subsys), std::end(subsys), std::greater<idx> {});
772 
773  //************ density matrix or column vector ************//
774  while (subsys.size() > 0)
775  {
776  auto tmp = measure(
777  cA, Gates::get_instance().Id(dims[subsys[0]]),
778  {subsys[0]}, dims
779  );
780  result.push_back(std::get<0>(tmp));
781  prob *= std::get<1>(tmp)[std::get<0>(tmp)];
782  cA = std::get<2>(tmp)[std::get<0>(tmp)];
783 
784  // remove the subsystem
785  dims.erase(std::next(std::begin(dims), subsys[0]));
786  subsys.erase(std::begin(subsys));
787  }
788  // order result in increasing order with respect to subsys
789  std::reverse(std::begin(result), std::end(result));
790 
791  return std::make_tuple(result, prob, cA);
792 }
793 
808 template<typename Derived>
809 std::tuple<std::vector<idx>, double, cmat>
810 measure_seq(const Eigen::MatrixBase<Derived>& A,
811  std::vector<idx> subsys,
812  idx d = 2)
813 {
814  const typename Eigen::MatrixBase<Derived>::EvalReturnType& rA
815  = A.derived();
816 
817  // EXCEPTION CHECKS
818 
819  // check zero size
821  throw exception::ZeroSize("qpp::measure_seq()");
822 
823  // check valid dims
824  if (d < 2)
825  throw exception::DimsInvalid("qpp::measure_seq()");
826  // END EXCEPTION CHECKS
827 
828  idx N = internal::get_num_subsys(static_cast<idx>(rA.rows()), d);
829  std::vector<idx> dims(N, d); // local dimensions vector
830 
831  return measure_seq(rA, subsys, dims);
832 }
833 
834 } /* namespace qpp */
835 
836 #endif /* INSTRUMENTS_H_ */
bool check_nonzero_size(const T &x) noexcept
Definition: util.h:129
Dimensions not equal exception.
Definition: exception.h:304
Dimension(s) mismatch matrix size exception.
Definition: exception.h:322
constexpr idx maxn
Maximum number of allowed qubits/qudits (subsystems)
Definition: constants.h:71
bool check_subsys_match_dims(const std::vector< idx > &subsys, const std::vector< idx > &dims)
Definition: util.h:221
bool check_cvector(const Eigen::MatrixBase< Derived > &A)
Definition: util.h:122
Derived::Scalar prod(const Eigen::MatrixBase< Derived > &A)
Element-wise product of A.
Definition: functions.h:227
constexpr double eps
Used to decide whether a number or expression in double precision is zero or not. ...
Definition: constants.h:64
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > dyn_mat
Dynamic Eigen matrix over the field specified by Scalar.
Definition: types.h:77
bool check_dims_match_mat(const std::vector< idx > &dims, const Eigen::MatrixBase< Derived > &A)
Definition: util.h:158
idx multiidx2n(const idx *const midx, idx numdims, const idx *const dims) noexcept
Definition: util.h:70
void n2multiidx(idx n, idx numdims, const idx *const dims, idx *result) noexcept
Definition: util.h:40
Subsystems mismatch dimensions exception.
Definition: exception.h:395
Eigen::VectorXcd ket
Complex (double precision) dynamic Eigen column vector.
Definition: types.h:50
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:473
Matrix is not a column vector exception.
Definition: exception.h:168
Quantum++ main namespace.
Definition: codes.h:30
double norm(const Eigen::MatrixBase< Derived > &A)
Frobenius norm.
Definition: functions.h:248
idx get_num_subsys(idx sz, idx d)
Definition: util.h:391
Matrix is not square nor column vector exception.
Definition: exception.h:219
Invalid dimension(s) exception.
Definition: exception.h:287
std::vector< T > complement(std::vector< T > subsys, idx N)
Constructs the complement of a subsystem vector.
Definition: functions.h:1811
bool check_dims_match_cvect(const std::vector< idx > &dims, const Eigen::MatrixBase< Derived > &A)
Definition: util.h:174
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:726
dyn_mat< typename Derived::Scalar > adjoint(const Eigen::MatrixBase< Derived > &A)
Adjoint.
Definition: functions.h:81
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:216
Dimension(s) mismatch column vector size exception.
Definition: exception.h:340
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:43
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:1241
bool check_square_mat(const Eigen::MatrixBase< Derived > &A)
Definition: util.h:101
Derived::Scalar trace(const Eigen::MatrixBase< Derived > &A)
Trace.
Definition: functions.h:124
Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > dyn_col_vect
Dynamic Eigen column vector over the field specified by Scalar.
Definition: types.h:89
static RandomDevices & get_instance() noexcept(std::is_nothrow_constructible< RandomDevices >::value)
Definition: singleton.h:89
Eigen::MatrixXcd cmat
Complex (double precision) dynamic Eigen matrix.
Definition: types.h:60
bool check_dims(const std::vector< idx > &dims)
Definition: util.h:142
std::size_t idx
Non-negative integer index.
Definition: types.h:35
Matrix is not square exception.
Definition: exception.h:151
Object has zero size exception.
Definition: exception.h:134