Tomographer  v2.0
Tomographer C++ Framework Documentation
param_herm_x.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_HERM_X_H
28 #define TOMOGRAPHER_DENSEDM_PARAM_HERM_X_H
29 
30 
31 
38 #include <cmath>
39 #include <complex>
40 
41 #include <boost/math/constants/constants.hpp>
42 
43 #include <Eigen/Core>
44 
45 #include <tomographer2/tools/cxxutil.h> // static_or_dynamic, tomographer_assert()
46 
47 
48 // // heavily inspired by Eigen::Replicate [Eigen/src/Core/Replicate.h]
49 // namespace Eigen {
50 // namespace internal {
51 // template<typename MatrixType,int RowFactor,int ColFactor>
52 // struct traits<Tomographer::DenseDM::internal::ParamHermToX<MatrixType,RowFactor,ColFactor> >
53 // : traits<MatrixType>
54 // {
55 // typedef Eigen::NumTraits<typename MatrixType::Scalar>::Real Scalar;
56 // typedef typename traits<MatrixType>::StorageKind StorageKind;
57 // typedef typename traits<MatrixType>::XprKind XprKind;
58 // enum {
59 // Factor = (RowFactor==Dynamic || ColFactor==Dynamic) ? Dynamic : RowFactor*ColFactor
60 // };
61 // typedef typename nested<MatrixType,1>::type MatrixTypeNested;
62 // typedef typename remove_reference<MatrixTypeNested>::type _MatrixTypeNested;
63 // enum {
64 // RowsAtCompileTime = (int(MatrixType::RowsAtCompileTime)==Eigen::Dynamic
65 // ? Eigen::Dynamic
66 // : MatrixType::RowsAtCompileTime*MatrixType::RowsAtCompileTime ),
67 // ColsAtCompileTime = 1,
68 // MaxRowsAtCompileTime = RowsAtCompileTime,
69 // MaxColsAtCompileTime = 1,
70 // IsRowMajor = MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1 ? 1
71 // : MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1 ? 0
72 // : (MatrixType::Flags & RowMajorBit) ? 1 : 0,
73 // Flags = (_MatrixTypeNested::Flags & HereditaryBits & ~RowMajorBit) | (IsRowMajor ? RowMajorBit : 0),
74 // CoeffReadCost = _MatrixTypeNested::CoeffReadCost * Eigen::NumTraits<typename MatrixType::Scalar>::MulCost
75 // };
76 // };
77 // } // namespace internal
78 // } // namespace Eigen
79 
80 
81 // namespace Tomographer {
82 // namespace DenseDM {
83 // namespace internal {
84 
85 // template<typename MatrixType>
86 // class ParamHermToX : public Eigen::MatrixBase<ParamHermToX<MatrixType> >
87 // {
88 // typedef typename internal::traits<ParamHermToX>::Scalar RealScalar;
89 // typedef typename internal::traits<ParamHermToX>::MatrixTypeNested MatrixTypeNested;
90 // typedef typename internal::traits<ParamHermToX>::_MatrixTypeNested _MatrixTypeNested;
91 // public:
92 
93 // typedef typename MatrixBase<ParamHermToX> Base;
94 // EIGEN_DENSE_PUBLIC_INTERFACE(ParamHermToX)
95 
96 // template<typename OriginalMatrixType>
97 // inline explicit ParamHermToX(const OriginalMatrixType& H)
98 // : _H(H), _dimtri(H.rows()*(H.rows()-1)/2)
99 // {
100 // EIGEN_STATIC_ASSERT((internal::is_same<typename internal::remove_const<MatrixType>::type,OriginalMatrixType>::value),
101 // THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE) ;
102 // tomographer_assert(H.rows() == H.cols())
103 // }
104 
105 // inline Index rows() const { return _H.rows()*_H.rows(); }
106 // inline Index cols() const { return 1; }
107 
108 // inline RealScalar coeff(Index rowId, Index colId) const
109 // {
110 // tomographer_assert(colId == 0);
111 
112 // if (rowId < _H.rows()) {
113 // return _H.coeff(rowId, rowId).real();
114 // }
115 // rowId -= _H.rows();
116 // if (rowId < _dimtri.value()) {
117 // return _H.coeff(......????)
118 // }
119 //
120 // ............ MAYBE NOT THE WAY TO GO .............
121 
122 // // try to avoid using modulo; this is a pure optimization strategy
123 // const Index actual_row = internal::traits<MatrixType>::RowsAtCompileTime==1 ? 0
124 // : RowFactor==1 ? rowId
125 // : rowId%m_matrix.rows();
126 // const Index actual_col = internal::traits<MatrixType>::ColsAtCompileTime==1 ? 0
127 // : ColFactor==1 ? colId
128 // : colId%m_matrix.cols();
129 
130 // return m_matrix.coeff(actual_row, actual_col);
131 // }
132 
133 // const _MatrixTypeNested& nestedExpression() const
134 // {
135 // return m_matrix;
136 // }
137 
138 // protected:
139 // MatrixTypeNested _H;
140 // const static_or_dynamic<Index,(MatrixType::RowsAtCompileTime==Eigen::Dynamic),
141 // Index(MatrixType::RowsAtCompileTime*(MatrixType::RowsAtCompileTime-1)/2> _dimtri;
142 // };
143 
144 // } // namespace internal
145 // } // namespace DenseDM
146 // } // namespace Tomographer
147 
148 
149 // ================================================================================
150 
151 
152 namespace Tomographer {
153 namespace DenseDM {
154 
158 template<typename DMTypes_>
159 class ParamX {
160 public:
161  typedef DMTypes_ DMTypes;
162  typedef typename DMTypes::MatrixType MatrixType;
164  typedef typename DMTypes::VectorParamType VectorParamType;
166  typedef typename DMTypes::RealScalar RealScalar;
167  typedef typename DMTypes::ComplexScalar ComplexScalar;
168  typedef typename MatrixType::Index IndexType;
169 
173  ParamX(DMTypes dmt) : _dmt(dmt) { }
174 
182  inline VectorParamType HermToX(MatrixTypeConstRef Herm) const
183  {
184  // hope RVO kicks in
185  VectorParamType x(_dmt.initVectorParamType());
186  const IndexType dimtri = (_dmt.dim2() - _dmt.dim())/2;
187 
188  tomographer_assert((IndexType)_dmt.dim() == Herm.cols()); // assert Herm is (dim x dim)
189 
190  x.block(0,0,_dmt.dim(),1) = Herm.real().diagonal();
191 
192  IndexType k = _dmt.dim();
193  IndexType n, m;
194  for (n = 1; n < (IndexType)_dmt.dim(); ++n) {
195  for (m = 0; m < n; ++m) {
196  x(k) = Herm(n,m).real() * boost::math::constants::root_two<RealScalar>();
197  x(dimtri + k) = Herm(n,m).imag() * boost::math::constants::root_two<RealScalar>();
198  ++k;
199  }
200  }
201 
202  return x;
203  }
204 
210  template<bool OnlyLowerTri = false>
211  inline MatrixType XToHerm(VectorParamTypeConstRef x) const
212  {
213  // should be optimized by compiler via RVO
214  MatrixType Herm(_dmt.initMatrixType());
215 
216  const IndexType dimtri = (_dmt.dim2()-_dmt.dim())/2;
217  tomographer_assert(x.rows() == (IndexType)_dmt.dim2() && x.cols() == 1); // assert x is (dim*dim x 1)
218 
219  Herm.diagonal().real() = x.block(0,0,_dmt.dim(),1);
220  Herm.diagonal().imag().setZero();
221 
222  IndexType k = _dmt.dim();
223  IndexType n, m;
224  for (n = 1; n < (IndexType)_dmt.dim(); ++n) {
225  for (m = 0; m < n; ++m) {
226  Herm(n,m) = boost::math::constants::half_root_two<RealScalar>() * ComplexScalar(x(k), x(dimtri + k));
227  if (!OnlyLowerTri) {
228  // complex conj. on opposite triangular part
229  Herm(m,n) = boost::math::constants::half_root_two<RealScalar>() * ComplexScalar(x(k), -x(dimtri + k));
230  }
231  ++k;
232  }
233  }
234  return Herm;
235  }
236 
237 protected:
238  const DMTypes _dmt;
239 };
240 
241 
242 
243 
244 } // namespace DenseDM
245 } // namespace Tomographer
246 
247 
248 #endif
VectorParamType HermToX(MatrixTypeConstRef Herm) const
Get the X-parameterization corresponding to a given hermitian matrix.
Definition: param_herm_x.h:182
Base namespace for the Tomographer project.
Definition: densellh.h:44
internal::traits< Matrix< _Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols > >::Index Index
Convert hermitian matrices to vectors via their X Parameterization.
Definition: param_herm_x.h:159
STL class.
MatrixType XToHerm(VectorParamTypeConstRef x) const
Get the Hermitian matrix parameterized by the "X-parameter" vector x.
Definition: param_herm_x.h:211
Some C++ utilities, with a tad of C++11 tricks.
ParamX(DMTypes dmt)
Constructor. Just give it the DMTypes instance.
Definition: param_herm_x.h:173
RealScalar_ RealScalar
Real scalar type, given in template parameter. Usually double is fine.
Definition: dmtypes.h:119