STK++ 0.9.13
STK_ISymEigen.h
Go to the documentation of this file.
1/*--------------------------------------------------------------------*/
2/* Copyright (C) 2004-2016 Serge Iovleff, Université Lille 1, Inria
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this program; if not, write to the
16 Free Software Foundation, Inc.,
17 59 Temple Place,
18 Suite 330,
19 Boston, MA 02111-1307
20 USA
21
22 Contact : S..._Dot_I..._At_stkpp_Dot_org (see copyright for ...)
23*/
24
25/*
26 * Project: stkpp::Algebra
27 * Purpose: Define The Interface SymEigen Class.
28 * Author: Serge Iovleff, S..._Dot_I..._At_stkpp_Dot_org (see copyright for ...)
29 **/
30
35#ifndef STK_ISYMEIGEN_H
36#define STK_ISYMEIGEN_H
37
38#include <Sdk.h>
39#include "STK_Algebra_Util.h"
40
43
44namespace STK
45{
63template<class Derived>
64class ISymEigen: public IRunnerBase, public IRecursiveTemplate<Derived>
65{
66 protected:
69
71 enum
72 {
78
79 };
89 ISymEigen( SquareArray const& data, bool ref =false);
93 template<class OtherDerived>
99
100 public:
102 inline ~ISymEigen() {}
108 {
109 range_ = eigen.range_;
110 trace_ = eigen.trace_; // trace of the matrix
111 norm_ = eigen.norm_; // norm of the matrix
112 rank_ = eigen.rank_; // rank of the matrix
113 det_ = eigen.det_; // determinant of the matrix
114 eigenVectors_ = eigen.eigenVectors_;
115 eigenValues_ = eigen.eigenValues_;
116 SupportEigenVectors_ = eigen.SupportEigenVectors_;
117 return *this;
118 }
119 // getters
121 inline Range const& range() const { return range_;}
123 inline Type const& norm() const { return norm_;}
125 inline int const& rank() const { return rank_;}
127 inline Type const& det() const { return det_;}
129 inline Type const& trace() const { return trace_;}
131 inline CArraySquare<Type, size_> const& rotation() const{ return eigenVectors_;}
135 inline CArrayVector<Type, size_> const& eigenValues() const { return eigenValues_;}
136
140 template<class OtherDerived>
142 {
143 STK_STATIC_ASSERT(OtherDerived::structure_==(int)Arrays::square_,YOU_HAVE_TO_USE_A_SQUARE_MATRIX_IN_THIS_METHOD)
144 range_ = data.range(); trace_ = 0; norm_ = 0.; rank_ = 0; det_ = 0.;
145 eigenVectors_ = data;
147 SupportEigenVectors_.resize(2*data.size());
148 this->hasRun_ = false;
149 }
150 // computation
155 template<class ArraySquare>
157 {
159 if(tol==0) { tol = Arithmetic<Type>::min();}
160 // compute and return PD^{-1}P'
161 return (res = eigenVectors_ * eigenValues_.diagonalize().safeInverse(tol) * eigenVectors_.transpose());
162 }
168 template<class ArraySquare>
170 {
172 if(tol==0) { tol = Arithmetic<Type>::min();}
173 // compute and return PD^{-1/2}P'
174 return(res = eigenVectors_ * eigenValues_.diagonalize().sqrt().safeInverse(tol) * eigenVectors_.transpose());
175 }
180 template<class ArraySquare>
182 {
184 if(tol==0) { tol = Arithmetic<Type>::min();}
185 // compute and return PD^{1/2}P'
187 }
189 virtual bool run()
190 {
191 if (eigenVectors_.empty()) { return true;}
192 return this->asDerived().runImpl();
193 }
194
195 protected:
203 int rank_;
216};
217
218/* @brief Default constructor */
219template<class Derived>
221 : Base()
222 , range_(), trace_(Type(0)), norm_(Type(0)), rank_(Type(0)), det_(Type(0))
223 , eigenVectors_()
224 , eigenValues_()
226{
227 STK_STATIC_ASSERT( SquareArray::structure_==(int)Arrays::square_
228 || SquareArray::structure_==(int)Arrays::symmetric_
229 || SquareArray::structure_==(int)Arrays::upper_symmetric_
230 || SquareArray::structure_==(int)Arrays::lower_symmetric_
231 ,YOU_HAVE_TO_USE_A_SQUARE_MATRIX_IN_THIS_METHOD)
232}
233/* @brief Constructor
234 * The original data set can be overwritten by the eigenvectors if it is
235 * stored in a CSquareXd. Observe that in this case the base index have
236 * to be 0.
237 * @param data reference on a symmetric square matrix
238 * @param ref @c true if we overwrite the data set, @c false otherwise
239 */
240template<class Derived>
242 : Base()
243 , range_(data.range()), trace_(Type(0)), norm_(Type(0)), rank_(Type(0)), det_(Type(0))
244 , eigenVectors_(data, ref)
245 , eigenValues_(data.size(), 0.)
246 , SupportEigenVectors_(2*data.size(), 0)
247{
248 STK_STATIC_ASSERT( SquareArray::structure_==(int)Arrays::square_
249 || SquareArray::structure_==(int)Arrays::symmetric_
250 || SquareArray::structure_==(int)Arrays::upper_symmetric_
251 || SquareArray::structure_==(int)Arrays::lower_symmetric_
252 ,YOU_HAVE_TO_USE_A_SQUARE_MATRIX_IN_THIS_METHOD)
253}
254/* @brief template constructor
255 * @param data reference on a symmetric square expression
256 */
257template<class Derived>
258template<class OtherDerived>
260 : Base()
261 , range_(data.range()), trace_(Type(0)), norm_(0.), rank_(0), det_(0.)
262 , eigenVectors_(data.asDerived())
263 , eigenValues_(data.size(), 0.)
264 , SupportEigenVectors_(2*data.size(), 0)
265{
266 STK_STATIC_ASSERT( SquareArray::structure_==(int)Arrays::square_
267 || SquareArray::structure_==(int)Arrays::symmetric_
268 || SquareArray::structure_==(int)Arrays::upper_symmetric_
269 || SquareArray::structure_==(int)Arrays::lower_symmetric_
270 ,YOU_HAVE_TO_USE_A_SQUARE_MATRIX_IN_THIS_METHOD)
271}
272/* Copy constructor.
273 * @param eigen the EigenValue to copy
274 **/
275template<class Derived>
277 : Base(eigen)
278 , range_(eigen.range_), trace_(eigen.trace_), norm_(eigen.norm_), rank_(eigen.rank_), det_(eigen.det_)
279 , eigenVectors_(eigen.eigenVectors_)
280 , eigenValues_(eigen.eigenValues_)
281 , SupportEigenVectors_(eigen.SupportEigenVectors_)
282{
283 STK_STATIC_ASSERT( SquareArray::structure_==(int)Arrays::square_
284 || SquareArray::structure_==(int)Arrays::symmetric_
285 || SquareArray::structure_==(int)Arrays::upper_symmetric_
286 || SquareArray::structure_==(int)Arrays::lower_symmetric_
287 ,YOU_HAVE_TO_USE_A_SQUARE_MATRIX_IN_THIS_METHOD)
288}
289
290/* finalize the computation by computing the rank, the trace norm and the
291 * determinant of the matrix.
292 **/
293template<class Derived>
295{
296 // compute sign and trace
297 trace_ = 0.;
298 int s = 1;
299 for (int i=eigenValues_.begin(); i< eigenValues_.end(); ++i )
300 {
301 Type value = eigenValues_[i];
302 s *= sign(value);
303 trace_ += value;
304 }
305
306 // compute norm_ (2-norm) and determinant
307 norm_ = eigenValues_.maxElt();
308 det_ = 0;
309 if (eigenValues_.abs().minElt() > 0)
310 { det_ = s * std::exp(eigenValues_.abs().log().sum());}
311
312 // compute norm_ rank_
313 rank_ = eigenValues_.size(); // full rank
315 for (int i=eigenValues_.begin(); i< eigenValues_.end(); ++i )
316 { if (std::abs(eigenValues_[i]) < tol) { rank_--;}}
317}
318
319} // namespace STK
320
321#endif //STK_ISYMEIGEN_H
In this file we define and implement utilies class and method for the Algebra project.
In this file we implement the final class CArraySquare.
In this file we implement the final class CArrayVector.
#define STK_STATIC_ASSERT(COND, MSG)
This file include all the other header files of the project Sdk.
TransposeOperator< Derived > const transpose() const
DiagonalizeOperator< Derived > const diagonalize() const
Derived & resize(Range const &I, Range const &J)
resize the Array.
bool empty() const
Interface base class for all classes implementing the curious recursive template paradigm.
Derived & asDerived()
static cast : return a reference of this with a cast to the derived class.
Abstract base class for all classes having a.
Definition STK_IRunner.h:65
bool hasRun_
true if run has been used, false otherwise
Definition STK_IRunner.h:98
The class ISymEigen is an interface class for the method computing the eigenvalue Decomposition of a ...
Range const & range() const
Type norm_
trace norm
Type const & norm() const
CArraySquare< Type, size_ > const & eigenVectors() const
hidden::AlgebraTraits< Derived >::SquareArray SquareArray
void finalizeStep()
finalize the computation by computing the trace, rank, trace norm and determinant of the matrix.
Range range_
range of the original data set.
ISymEigen()
Default constructor.
ArraySquare & ginv(ArraySquare &res) const
Compute the generalized inverse of the symmetric matrix and put the result in res.
hidden::Traits< SquareArray >::Type Type
ISymEigen(ExprBase< OtherDerived > const &data)
template constructor
Type trace_
trace norm
CArrayVector< Type, size_ > eigenValues_
Array of the eigenvalues.
ISymEigen(SquareArray const &data, bool ref=false)
Constructor The original data set can be overwritten by the eigenvectors if it is stored in a CSquare...
Type det_
determinant
ISymEigen & operator=(ISymEigen const &eigen)
Operator = : overwrite the ISymEigen with eigen.
ArraySquare & ginvsqrt(ArraySquare &res) const
Compute the generalized square root inverse of the symmetric matrix and put the result in res.
~ISymEigen()
virtual destructor
CArraySquare< Type, size_ > eigenVectors_
Square matrix or the eigenvectors.
CVectorXi SupportEigenVectors_
Array for the support of the eigenvectors.
ArraySquare & gsqrt(ArraySquare &res) const
Compute the square root of the symmetric matrix and put the result in res.
ISymEigen(ISymEigen const &eigen)
Copy constructor.
Type const & trace() const
CArrayVector< Type, size_ > const & eigenValues() const
CArraySquare< Type, size_ > const & rotation() const
int const & rank() const
IRunnerBase Base
virtual bool run()
Find the eigenvalues and eigenvectors of the matrix.
void setData(ExprBase< OtherDerived > const &data)
overloading of setData.
Type const & det() const
The MultidimRegression class allows to regress a multidimensional output variable among a multivariat...
Index sub-vector region: Specialization when the size is unknown.
Definition STK_Range.h:265
@ lower_symmetric_
lower symmetric matrix/array/expression
@ symmetric_
symmetric matrix/array/expression
@ upper_symmetric_
upper symmetric matrix/array/expression
@ square_
square matrix/array/expression
Type sign(Type const &x, Type const &y=Type(1))
template sign value sign(x) * y: Type should be an integral type
Definition STK_Misc.h:53
The namespace STK is the main domain space of the Statistical ToolKit project.
Arithmetic properties of STK fundamental types.
traits class for the algebra methods.