SLIP  1.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
linear_algebra_eigen.hpp
Go to the documentation of this file.
1 /*
2  * Copyright(c):
3  * Signal Image and Communications (SIC) Department
4  * http://www.sic.sp2mi.univ-poitiers.fr/
5  * - University of Poitiers, France http://www.univ-poitiers.fr
6  * - XLIM Institute UMR CNRS 7252 http://www.xlim.fr/
7  *
8  * and
9  *
10  * D2 Fluid, Thermic and Combustion
11  * - University of Poitiers, France http://www.univ-poitiers.fr
12  * - PPRIME Institute - UPR CNRS 3346 http://www.pprime.fr
13  * - ISAE-ENSMA http://www.ensma.fr
14  *
15  * Contributor(s):
16  * The SLIP team,
17  * Benoit Tremblais <tremblais_AT_sic.univ-poitiers.fr>,
18  * Laurent David <laurent.david_AT_lea.univ-poitiers.fr>,
19  * Ludovic Chatellier <ludovic.chatellier_AT_univ-poitiers.fr>,
20  * Lionel Thomas <lionel.thomas_AT_univ-poitiers.fr>,
21  * Denis Arrivault <arrivault_AT_sic.univ-poitiers.fr>,
22  * Julien Dombre <julien.dombre_AT_univ-poitiers.fr>.
23  *
24  * Description:
25  * The Simple Library of Image Processing (SLIP) is a new image processing
26  * library. It is written in the C++ language following as much as possible
27  * the ISO/ANSI C++ standard. It is consequently compatible with any system
28  * satisfying the ANSI C++ complience. It works on different Unix , Linux ,
29  * Mircrosoft Windows and Mac OS X plateforms. SLIP is a research library that
30  * was created by the Signal, Image and Communications (SIC) departement of
31  * the XLIM, UMR 7252 CNRS Institute in collaboration with the Fluids, Thermic
32  * and Combustion departement of the P', UPR 3346 CNRS Institute of the
33  * University of Poitiers.
34  *
35  * The SLIP Library source code has been registered to the APP (French Agency
36  * for the Protection of Programs) by the University of Poitiers and CNRS,
37  * under registration number IDDN.FR.001.300034.000.S.P.2010.000.21000.
38 
39  * http://www.sic.sp2mi.univ-poitiers.fr/slip/
40  *
41  * This software is governed by the CeCILL-C license under French law and
42  * abiding by the rules of distribution of free software. You can use,
43  * modify and/ or redistribute the software under the terms of the CeCILL-C
44  * license as circulated by CEA, CNRS and INRIA at the following URL
45  * http://www.cecill.info.
46  * As a counterpart to the access to the source code and rights to copy,
47  * modify and redistribute granted by the license, users are provided only
48  * with a limited warranty and the software's author, the holder of the
49  * economic rights, and the successive licensors have only limited
50  * liability.
51  *
52  * In this respect, the user's attention is drawn to the risks associated
53  * with loading, using, modifying and/or developing or reproducing the
54  * software by the user in light of its specific status of free software,
55  * that may mean that it is complicated to manipulate, and that also
56  * therefore means that it is reserved for developers and experienced
57  * professionals having in-depth computer knowledge. Users are therefore
58  * encouraged to load and test the software's suitability as regards their
59  * requirements in conditions enabling the security of their systems and/or
60  * data to be ensured and, more generally, to use and operate it in the
61  * same conditions as regards security.
62  *
63  * The fact that you are presently reading this means that you have had
64  * knowledge of the CeCILL-C license and that you accept its terms.
65  */
66 
67 
75 #ifndef SLIP_LINEAR_ALGEBRA_EIGEN_HPP
76 #define SLIP_LINEAR_ALGEBRA_EIGEN_HPP
77 
78 #include <cmath>
79 #include <complex>
80 #include <algorithm>
81 #include <map>
82 #include "Vector.hpp"
83 #include "Array2d.hpp"
84 #include "linear_algebra.hpp"
85 #include "linear_algebra_qr.hpp"
86 #include "linear_algebra_svd.hpp"
88 #include "macros.hpp"
89 #include "norms.hpp"
90 #include "noise.hpp"
91 #include "apply.hpp"
92 #include "complex_cast.hpp"
93 
94 namespace slip
95 {
96 
97 
120  template <class Matrix1,
121  class Vector1,
122  class Matrix2>
123  inline
124  void hermitian_eigen(const Matrix1 & A,
125  Vector1& EigenValues,
126  Matrix2& EigenVectors)
127  {
128  typedef typename Matrix1::value_type value_type;
129  std::size_t A_rows = A.rows();
130  std::size_t A_cols = A.cols();
131 
132  Matrix1 U;
133  Matrix1 V;
134  Matrix1 AA;
135  if(A_rows >= A_cols)
136  {
137  AA.resize(A_cols,A_cols);
138  U.resize(A_cols,A_cols);
139  EigenValues.resize(A_cols);
140  EigenVectors.resize(A_cols,A_cols);
141  //compute A^HA
142  for(std::size_t i = 0; i < A_cols; ++i)
143  {
144  for(std::size_t j = 0; j < A_cols; ++j)
145  {
146  AA(i,j) = slip::hermitian_inner_product(A.col_begin(i),A.col_end(i),A.col_begin(j),value_type(0));
147  }
148  }
149  //compute the svd
150  slip::svd(AA,U,EigenValues.begin(),EigenValues.end(),EigenVectors);
151 
152  }
153  else
154  {
155  AA.resize(A_rows,A_rows);
156  V.resize(A_rows,A_rows);
157  EigenValues.resize(A_rows);
158  EigenVectors.resize(A_rows,A_rows);
159  //compute AA^H
160  for(std::size_t i = 0; i < A_rows; ++i)
161  {
162  for(std::size_t j = 0; j < A_rows; ++j)
163  {
164  AA(i,j) = slip::hermitian_inner_product(A.row_begin(i),A.row_end(i),A.row_begin(j),value_type(0));
165  }
166  }
167  //compute the svd
168  slip::svd(AA,EigenVectors,EigenValues.begin(),EigenValues.end(),V);
169  }
170 
171  slip::apply(EigenValues.begin(),EigenValues.end(),EigenValues.begin(),std::sqrt);
172  }
173 
174 
175 
176 
202  template <class Matrix1,class Vector1>
203  inline
204  void eigen(const Matrix1 & A, Vector1 & E, bool sort=false)
205  {
206  typedef typename Matrix1::value_type value_type;
207  slip::Array2d<value_type> H(A.rows(),A.cols());
208  slip::Array2d<value_type> Z(A.rows(),A.cols());
209  slip::Array2d<value_type> D(A.rows(),A.cols());
210  Matrix1 Atmp(A);
211  slip::balance(Atmp,D);
212  slip::schur(A,H,Z,E,false);
213  //check is E is a real vector
214  bool real = true;
215  for(std::size_t i = 0 ; i < E.size() ; ++i)
216  {
217  if(std::abs(std::imag(E[i])) > slip::epsilon<typename slip::lin_alg_traits<typename Vector1::value_type>::value_type >())
218  {
219  real = false;
220  break;
221  }
222  }
223  if(sort && real)
224  {
226  typedef typename Vector1::value_type complex_type;
227  slip::Vector<real> Er(E.size());
228  for(std::size_t i = 0; i < E.size(); ++i)
229  {
230  Er[i] = std::real(E[i]);
231  }
232  std::sort(Er.begin(),Er.end(),std::greater<real>());
233  E.fill(typename Vector1::value_type(0));
234 
235 
236  for(std::size_t i = 0; i < E.size(); ++i)
237  {
238  // E[i].real() = Er[i];
239  //E[i].imag() = real(0);
240  E[i] = complex_type(Er[i],real(0));
241  }
242  }
243  else
244  {
245  std::sort(E.begin(),E.end(),slip::greater_abs<typename Vector1::value_type>());
246  }
247  }
248 
249 
265  template <class Matrix1>
266  inline
268  spectral_radius(const Matrix1 & A)
269  {
270 
272  slip::Vector<std::complex<value_type> > MEigVal(A.rows());
273  slip::eigen(A,MEigVal,true);
274  return std::abs(MEigVal[0]);
275  }
276 
277 
278 
279 
280 
281 } // end slip
282 
283 #endif //SLIP_LINEAR_ALGEBRA_EIGEN_HPP
Provides a class to manipulate 2d dynamic and generic arrays.
slip::lin_alg_traits< typename Matrix1::value_type >::value_type spectral_radius(const Matrix1 &A)
Spectral radius of a matrix .
bool schur(const Matrix1 &M, Matrix2 &H, Matrix3 &Z, Vector &Eig, bool compute_Z, typename slip::lin_alg_traits< typename Matrix1::value_type >::value_type precision=typename slip::lin_alg_traits< typename Matrix1::value_type >::value_type(1.0E-12))
computes the shur decomposition of a square Matrix and copy the eigenvalues in the Eig vector: Algor...
Provides common linear algebra algorithms.
void real(const Matrix1 &C, Matrix2 &R)
Extract the real Matrix of a complex Matrix. .
HyperVolume< T > abs(const HyperVolume< T > &M)
void eigen(const Matrix1 &A, Vector1 &E, bool sort=false)
Eigen Values Computation for non symmetric matrix.
void hermitian_eigen(const Matrix1 &A, Vector1 &EigenValues, Matrix2 &EigenVectors)
Eigen Values Computation of an hermitian semi-definite positive matrix.
Provides some macros which are used for using complex as real.
Numerical Vector class. This container statisfies the RandomAccessContainer concepts of the Standard ...
Definition: Vector.hpp:104
Provides some mathematical functors and constants.
HyperVolume< T > sqrt(const HyperVolume< T > &M)
Compare two element according to their absolute value. Return true if std::abs(__x) > std::abs( __y)...
Definition: macros.hpp:171
std::iterator_traits< RandomAccessIterator1 >::value_type hermitian_inner_product(RandomAccessIterator1 first1, RandomAccessIterator1 last1, RandomAccessIterator2 first2, typename std::iterator_traits< RandomAccessIterator1 >::value_type init)
Computes the hermitian inner-product of two ranges X and Y: .
void svd(const Matrix1 &M, Matrix2 &U, RandomAccessIterator S_first, RandomAccessIterator S_last, Matrix3 &V, const int max_it=75)
(thin) Singular Value Decomposition Given a matrix M, this function computes its singular value decom...
Provides some QR decomposition algorithms.
Provides some algorithms to apply C like functions to ranges.
Provides some algorithms to add noise to ranges.
void balance(Matrix1 &A, Matrix2 &D)
applies a diagonal similarity transform to the square matrix A to make the rows and columns as close ...
Provides some Singular Value Decomposition (SVD) algorithms.
void apply(InputIterator first, InputIterator last, OutputIterator result, typename std::iterator_traits< OutputIterator >::value_type(*function)(typename std::iterator_traits< InputIterator >::value_type))
Applies a C-function to each element of a range.
Definition: apply.hpp:128
Provides a class to manipulate numerical vectors.
This is a two-dimensional dynamic and generic container. This container statisfies the Bidirectionnal...
Definition: Array2d.hpp:135
Provides some algorithms to compute norms.