Tomographer  v2.0
Tomographer C++ Framework Documentation
param_rho_a.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) 2015 ETH Zurich, Institute for Theoretical Physics, Philippe Faist
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24  * SOFTWARE.
25  */
26 
27 #ifndef TOMOGRAPHER_DENSEDM_PARAM_RHO_A_H
28 #define TOMOGRAPHER_DENSEDM_PARAM_RHO_A_H
29 
37 #include <Eigen/Core>
38 #include <Eigen/StdVector>
39 
41 #include <tomographer2/tools/cxxutil.h> // tomographer_assert()
43 
44 #include <boost/math/constants/constants.hpp>
45 
46 
47 namespace Tomographer
48 {
49 
50 // based on http://mathworld.wolfram.com/GeneralizedGell-MannMatrix.html
51 
52 namespace tomo_internal
53 {
54 
55 template<typename DMTypes_, typename Coeffs>
56 struct GenGellMannFunctor12
57 {
58  typedef DMTypes_ DMTypes;
59  typedef typename DMTypes::MatrixType::Index MatIndex;
60  GenGellMannFunctor12(DMTypes matq_, MatIndex j_, MatIndex k_)
61  : matq(matq_),
62  j(j_),
63  k(k_)
64  {
65  tomographer_assert(j < k);
66  tomographer_assert(k <= (MatIndex)matq.dim());
67  }
68  DMTypes matq;
69  MatIndex j;
70  MatIndex k;
71 
72  template<typename Index>
73  inline const typename DMTypes::ComplexScalar operator() (Index row, Index col) const
74  {
75  if (row == j && col == k) {
76  return Coeffs::CoeffJK();
77  }
78  if (row == k && col == j) {
79  return Coeffs::CoeffKJ();
80  }
81  return 0;
82  }
83 };
84 
85 template<typename DMTypes>
86 struct coeffs1 {
87  static inline typename DMTypes::ComplexScalar CoeffJK() { return typename DMTypes::ComplexScalar(1, 0); }
88  static inline typename DMTypes::ComplexScalar CoeffKJ() { return typename DMTypes::ComplexScalar(1, 0); }
89 };
90 template<typename DMTypes>
91 struct coeffs2 {
92  static inline typename DMTypes::ComplexScalar CoeffJK() { return typename DMTypes::ComplexScalar(0, -1); }
93  static inline typename DMTypes::ComplexScalar CoeffKJ() { return typename DMTypes::ComplexScalar(0, +1); }
94 };
95 
96 template<typename DMTypes>
97 struct GenGellMannFunctor1
98 {
99  typedef GenGellMannFunctor12<DMTypes, coeffs1<DMTypes> > type;
100 };
101 template<typename DMTypes>
102 struct GenGellMannFunctor2
103 {
104  typedef GenGellMannFunctor12<DMTypes, coeffs2<DMTypes> > type;
105 };
106 
107 
108 template<typename DMTypes_>
109 struct GenGellMannFunctor3
110 {
111  typedef GenGellMannFunctor3<DMTypes_> type;
112 
113  typedef DMTypes_ DMTypes;
114  typedef typename DMTypes::RealScalar RealScalar;
115  typedef typename DMTypes::MatrixType::Index MatIndex;
116 
117  GenGellMannFunctor3(DMTypes matq_, MatIndex l_)
118  : matq(matq_),
119  l(l_)
120  {
121  // remember: l = 0, 1, ..., d-2 and not: 1, ..., d-1
122  normalization = std::sqrt( RealScalar(2) / ((l+1)*(l+2)) );
123  tomographer_assert(l < (MatIndex)matq.dim()-1);
124  }
125  DMTypes matq;
126  MatIndex l;
127  RealScalar normalization;
128 
129  template<typename Index>
130  inline const typename DMTypes::ComplexScalar operator() (Index row, Index col) const
131  {
132  if (row != col) {
133  return 0;
134  } else if (row <= l) {
135  return normalization;
136  } else if (row == l+1) {
137  return - (l+1) * normalization;
138  } else {
139  // row > l+1
140  return 0;
141  }
142  }
143 };
144 
145 } // namespace tomo_internal
146 } // namespace Tomographer
147 
148 namespace Eigen { namespace internal {
149 // ---
150 // functor_traits for GenGellMannFunctor12
151 template<typename DMTypes, typename coeffs>
152 struct functor_traits<Tomographer::tomo_internal::GenGellMannFunctor12<DMTypes, coeffs> >
153 {
154  enum { Cost = 4*NumTraits<typename DMTypes::ComplexScalar>::AddCost, PacketAccess = false, IsRepeatable = true };
155 };
156 // functor_has_linear_access for GenGellMannFunctor12
157 template<typename DMTypes, typename coeffs>
158 struct functor_has_linear_access<Tomographer::tomo_internal::GenGellMannFunctor12<DMTypes, coeffs> >
159 { enum { ret = 0 }; };
160 // functor_traits for GenGellMannFunctor3
161 template<typename DMTypes>
162 struct functor_traits<Tomographer::tomo_internal::GenGellMannFunctor3<DMTypes> >
163 { enum { Cost = 4*NumTraits<typename DMTypes::ComplexScalar>::AddCost, PacketAccess = false, IsRepeatable = true }; };
164 // functor_has_linear_access for GenGellMannFunctor3
165 template<typename DMTypes>
166 struct functor_has_linear_access<Tomographer::tomo_internal::GenGellMannFunctor3<DMTypes> >
167 { enum { ret = 0 }; };
168 // ---
169 } } // namespace Eigen::internal, Eigen
170 
171 namespace Tomographer {
172 namespace DenseDM {
173 
184 template<typename DMTypes_>
185 class ParamA
186 {
187 public:
189  typedef DMTypes_ DMTypes;
191  typedef typename DMTypes::MatrixType MatrixType;
195  typedef typename DMTypes::RealScalar RealScalar;
196 
197 private:
198  const DMTypes _dmt;
199 
202 
203 public:
211  ParamA(DMTypes dmt_)
212  : _dmt(dmt_)
213  {
214  // calculate and cache the generalized Gell-Mann matrices
215  lambda.resize(_dmt.ndof());
216  std::size_t count = 0;
217  // first kind
218  for (std::size_t j = 0; j < _dmt.dim(); ++j) {
219  for (std::size_t k = j+1; k < _dmt.dim(); ++k) {
220  lambda[count] = MatrixType::NullaryExpr(
221  _dmt.dim(),
222  _dmt.dim(),
223  typename tomo_internal::GenGellMannFunctor1<DMTypes>::type(_dmt, j, k)
224  );
225  ++count;
226  }
227  }
228  // second kind
229  for (std::size_t j = 0; j < _dmt.dim(); ++j) {
230  for (std::size_t k = j+1; k < _dmt.dim(); ++k) {
231  lambda[count] = MatrixType::NullaryExpr(
232  _dmt.dim(),
233  _dmt.dim(),
234  typename tomo_internal::GenGellMannFunctor2<DMTypes>::type(_dmt, j, k)
235  );
236  ++count;
237  }
238  }
239  // third kind
240  for (std::size_t l = 0; l < _dmt.dim()-1; ++l) {
241  lambda[count] = MatrixType::NullaryExpr(
242  _dmt.dim(),
243  _dmt.dim(),
244  typename tomo_internal::GenGellMannFunctor3<DMTypes>::type(_dmt, l)
245  );
246  ++count;
247  }
248  // got them all?
249  tomographer_assert(count == lambda.size());
250  tomographer_assert(count == (std::size_t)_dmt.ndof());
251  }
252 
269  inline const MatrixType & getLambda(std::size_t j) const
270  {
271  tomographer_assert(j < _dmt.ndof());
272  return lambda[j];
273  }
274 
283  inline VectorParamNdofType
285  {
286  VectorParamNdofType a(_dmt.initVectorParamNdofType());
287  tomographer_assert((std::size_t)a.size() == _dmt.ndof());
288  tomographer_assert((std::size_t)rho.rows() == _dmt.dim());
289  tomographer_assert((std::size_t)rho.cols() == _dmt.dim());
290  for (std::size_t n = 0; n < lambda.size(); ++n) {
291  a(n) = (rho * lambda[n].template selfadjointView<Eigen::Lower>())
292  .real().trace() * boost::math::constants::half_root_two<RealScalar>();
293  }
294  return a;
295  }
296 
302  inline MatrixType
303  aToRho(const Eigen::Ref<const VectorParamNdofType> & a, RealScalar trace = 1.0) const
304  {
305  MatrixType rho(_dmt.initMatrixType());
306  tomographer_assert((std::size_t)a.size() == _dmt.ndof());
307  tomographer_assert((std::size_t)rho.rows() == _dmt.dim());
308  tomographer_assert((std::size_t)rho.cols() == _dmt.dim());
309  rho = trace * MatrixType::Identity(rho.rows(), rho.cols()) / _dmt.dim();
310  for (std::size_t n = 0; n < lambda.size(); ++n) {
311  rho += a(n) * lambda[n].template selfadjointView<Eigen::Lower>()
312  * boost::math::constants::half_root_two<RealScalar>();
313  }
314  return rho;
315  }
316 
317 }; // class ParamA
318 
319 
320 } // namespace DenseDM
321 } // namespace Tomographer
322 
323 #endif
Base namespace for the Tomographer project.
Definition: densellh.h:44
DMTypes::MatrixType MatrixType
The Matrix type to use to describe hermitian matrices.
Definition: param_rho_a.h:191
C++ types for describing dense density matrices in various parameterizations.
DMTypes_ DMTypes
The C++ types for quantum objects and parameterizations.
Definition: param_rho_a.h:189
MatrixType aToRho(const Eigen::Ref< const VectorParamNdofType > &a, RealScalar trace=1.0) const
Reconstruct a hermitian traceless matrix from its A Parameterization.
Definition: param_rho_a.h:303
T internal(T...args)
T resize(T...args)
Basic utilities for dealing with Eigen matrices and other types.
DMTypes::RealScalar RealScalar
The real scalar type. Usually this is double.
Definition: param_rho_a.h:195
VectorParamNdofType rhoToA(const Eigen::Ref< const MatrixType > &rho) const
Compute the A Parameterization of a hermitian matrix.
Definition: param_rho_a.h:284
Some C++ utilities, with a tad of C++11 tricks.
const MatrixType & getLambda(std::size_t j) const
Generalized Gell-Mann matrices.
Definition: param_rho_a.h:269
Parameterization of density matrices in su(N) generators.
Definition: param_rho_a.h:185
T size(T...args)
STL class.
ParamA(DMTypes dmt_)
Construct an object which can perform A parameterization transformations.
Definition: param_rho_a.h:211
DMTypes::VectorParamNdofType VectorParamNdofType
The Matrix type to use to describe the A Parameterization of a hermitian matrix.
Definition: param_rho_a.h:193
T sqrt(T...args)
RealScalar_ RealScalar
Real scalar type, given in template parameter. Usually double is fine.
Definition: dmtypes.h:119