Tomographer  v5.3
Tomographer C++ Framework Documentation
random_unitary.h
Go to the documentation of this file.
1 /* This file is part of the Tomographer project, which is distributed under the
2  * terms of the MIT license.
3  *
4  * The MIT License (MIT)
5  *
6  * Copyright (c) 2016 ETH Zurich, Institute for Theoretical Physics, Philippe Faist
7  * Copyright (c) 2017 Caltech, Institute for Quantum Information and Matter, Philippe Faist
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a copy
10  * of this software and associated documentation files (the "Software"), to deal
11  * in the Software without restriction, including without limitation the rights
12  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13  * copies of the Software, and to permit persons to whom the Software is
14  * furnished to do so, subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice shall be included in
17  * all copies or substantial portions of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25  * SOFTWARE.
26  */
27 
28 #ifndef RANDOM_UNITARY_H
29 #define RANDOM_UNITARY_H
30 
38 #include <iostream>
39 #include <random>
40 
41 #include <Eigen/Core>
42 
45 #include <tomographer/tools/cxxutil.h> // tomographer_assert()
46 
47 
48 namespace Tomographer {
49 namespace MathTools {
50 
51 
61 template<typename DerU, typename Rng, typename Log>
62 inline void randomUnitary(Eigen::MatrixBase<DerU> & U, Rng & rng, Log & logger)
63 {
64  { using namespace Eigen; EIGEN_STATIC_ASSERT_LVALUE(DerU); }
65 
66  tomographer_assert(U.rows() == U.cols());
67  const Eigen::Index n = U.rows();
68 
69  logger.longdebug("randomUnitary()", [&](std::ostream & stream) {
70  stream << "n = " << n ;
71  });
72 
73  typedef typename DerU::Scalar Scalar;
76 
77  // first, get a matrix of normally distributed random numbers
78  MatrixType A(n,n);
79 
80  std::normal_distribution<> normdist(0.0, 1.0);
81  A = Tomographer::Tools::denseRandom<MatrixType>(rng, normdist, n, n);
82 
83  // logger.longdebug("randomUnitary()", [&](std::ostream& str) {
84  // str << "got A = \n" << A;
85  // });
86 
87  // Gram-Schmidt orthogonalization
88 
89  for (Eigen::Index j = 0; j < n; ++j) {
90 
91  VectorType v = VectorType::Zero(n);
92  v = A.col(j);
93  //auto v = A.col(j);
94 
95  for (Eigen::Index k = 0; k < j; ++k) {
96  Scalar p = U.col(k).adjoint() * v;
97  v = v - p*U.col(k);
98  }
99 
100  U.col(j) = v / v.norm();
101 
102  // logger.longdebug("randomUnitary()", [&](std::ostream & str) {
103  // str << "dealt with column " << j << " = " << v.transpose() << "\n"
104  // << "\t--> " << U.col(j).transpose() << "\n"
105  // << "\tnorm = " << U.col(j).squaredNorm() << " == " << U.col(j).adjoint() * U.col(j);
106  // });
107  }
108 
109  logger.longdebug("randomUnitary()", [&](std::ostream& str) {
110  str << "randomUnitary: got U = \n" << U << "\n"
111  << "Check: U*U.adjoint() ==\n" << U*U.adjoint() << "\n"
112  << "Check: U.adjoint()*U ==\n" << U.adjoint()*U;
113  });
114 }
115 
117 template<typename Der1, typename Rng>
118 inline void randomUnitary(Eigen::MatrixBase<Der1> & U, Rng & rng)
119 {
120  randomUnitary<Der1, Rng>(U, rng, Logger::vacuum_logger);
121 }
122 
123 
124 } // namespace MathTools
125 } // namespace Tomographer
126 
127 
128 #endif
Base namespace for the Tomographer project.
Definition: densellh.h:45
ColXpr col(Index i)
void randomUnitary(Eigen::MatrixBase< DerU > &U, Rng &rng, Log &logger)
Generate a Haar-distributed random unitary.
Basic utilities for dealing with Eigen matrices and other types.
Some C++ utilities, with a tad of C++11 tricks.
const AdjointReturnType adjoint() const
STL class.
#define tomographer_assert(...)
Assertion test macro.
Definition: cxxdefs.h:84
Utilities for logging messages.