Tomographer  v1.0a
Tomographer C++ Framework Documentation
pos_semidef_util.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 
28 #ifndef POS_SEMIDEF_UTIL
29 #define POS_SEMIDEF_UTIL
30 
37 #include <Eigen/Core>
38 #include <Eigen/Eigenvalues>
39 
40 
41 namespace Tomographer {
42 namespace Tools {
43 
44 
53 template<typename VectorType>
55  const typename Eigen::NumTraits<typename VectorType::Scalar>::Real tolerance = 1e-8)
56 {
57  typedef typename Eigen::NumTraits<typename VectorType::Scalar>::Real RealScalar;
58  typedef typename VectorType::Index Index;
59 
60  RealScalar trace = 0;
61  RealScalar new_excess_trace = 0;
62  Index k;
63  Index num_pos = 0;
64  for (k = 0; k < vec.size(); ++k) {
65  trace += vec(k);
66  if (vec(k) < tolerance) {
67  new_excess_trace += tolerance - vec(k);
68  } else {
69  ++num_pos;
70  }
71  }
72 
73  eigen_assert(trace >= vec.size()*tolerance);
74 
75  RealScalar remove_from_each = new_excess_trace / num_pos;
76  for (k = 0; k < vec.size(); ++k) {
77  if (vec(k) < tolerance) {
78  vec(k) = tolerance;
79  } else {
80  vec(k) -= remove_from_each;
81  }
82  }
83 }
84 
92 template<typename MatrixType, typename Der>
93 inline MatrixType force_pos_semidef(const Eigen::MatrixBase<Der> & rho,
94  const typename Eigen::NumTraits<typename MatrixType::Scalar>::Real tolerance = 1e-8)
95 {
96  typedef typename Eigen::SelfAdjointEigenSolver<MatrixType>::RealVectorType RealVectorType;
97 
99  rho.template cast<typename MatrixType::Scalar>()
100  );
101  auto U = eig_rho_ref.eigenvectors();
102  RealVectorType d = eig_rho_ref.eigenvalues();
103 
104  force_pos_vec_keepsum<RealVectorType>(d, tolerance);
105 
106  return U * d.asDiagonal() * U.adjoint();
107 }
108 
109 
117 template<typename MatrixType>
120  tolerance = 1e-8)
121 {
123  auto U = eig_A_ref.eigenvectors();
124  auto d = eig_A_ref.eigenvalues();
125 
126  typedef typename Eigen::SelfAdjointEigenSolver<MatrixType>::RealVectorType RealVectorType;
127 
128  force_pos_vec_keepsum<RealVectorType>(d, tolerance);
129 
130  return U * d.cwiseSqrt().asDiagonal() * U.adjoint();
131 }
132 
141 template<typename MatrixType>
144  tolerance = 1e-8)
145 {
147  auto U = eig_A_ref.eigenvectors();
148  auto d = eig_A_ref.eigenvalues();
149 
150  typedef typename Eigen::SelfAdjointEigenSolver<MatrixType>::RealVectorType RealVectorType;
151 
152  force_pos_vec_keepsum<RealVectorType>(d, tolerance);
153 
154  for (typename MatrixType::Index k = 0; k < d.size(); ++k) {
155  if (d(k) > tolerance) {
156  d(k) = 1 / std::sqrt(d(k));
157  }
158  }
159 
160  return U * d.asDiagonal() * U.adjoint();
161 }
162 
163 
164 
165 
166 } // Tools
167 } // Tomographer
168 
169 
170 
171 
172 
173 #endif
Base namespace for the Tomographer project.
Definition: dmmhrw.h:51
const RealVectorType & eigenvalues() const
MatrixType safe_operator_sqrt(const Eigen::Ref< const MatrixType > &A, const typename Eigen::NumTraits< typename MatrixType::Scalar >::Real tolerance=1e-8)
Safe version of operator square root for positive semidefinite matrices.
MatrixType force_pos_semidef(const Eigen::MatrixBase< Der > &rho, const typename Eigen::NumTraits< typename MatrixType::Scalar >::Real tolerance=1e-8)
Make sure that rho is numerically positive semidefinite.
internal::plain_col_type< MatrixType, RealScalar >::type RealVectorType
const MatrixType & eigenvectors() const
void force_pos_vec_keepsum(Eigen::Ref< VectorType > vec, const typename Eigen::NumTraits< typename VectorType::Scalar >::Real tolerance=1e-8)
Make sure that the given vector is numerically positive.
T sqrt(T...args)
MatrixType safe_operator_inv_sqrt(const Eigen::Ref< const MatrixType > &A, const typename Eigen::NumTraits< typename MatrixType::Scalar >::Real tolerance=1e-8)
Safe version of operator inverse square root for positive semidefinite matrices.