CEDRIC  Revision_backup-2009-02
CMDS.h
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * Copyright (C) 2008 Max Hermann
4  *
5  * This file is part of the "CEDRIC Event Display" application.
6  *
7  *****************************************************************************/
8 
9 #ifndef REDUKT_CMDS_H
10 #define REDUKT_CMDS_H
11 
12 #define HAVE_IETL
13 
14 #include "Eigenvalue.h"
15 #include "Cholesky.h"
16 #include "ublasTools.h"
17 
18 #include <boost/numeric/ublas/matrix.hpp>
19 #include <boost/numeric/ublas/vector.hpp>
20 #include <boost/numeric/ublas/operation.hpp>
21 
22 #ifdef HAVE_IETL
23 #include "Lanczos.h"
24 #endif
25 
26 #include <assert.h>
27 
28 
35 template<class ValueType>
36 class CMDS
37 {
38 public:
39  typedef ublas::matrix<ValueType> Matrix;
40  typedef ublas::vector<ValueType> Vector;
41 
43  {
46 //#ifdef HAVE_IETL
48 //#endif
49  };
50 
57  CMDS( Matrix& D, int method = (int)MethodQR ): m_D(D), m_method(method)
58  {
59  using namespace ublas; // for column
60  using namespace ublasTools;
61 
62  assert( D.size1() == D.size2() );
63 
64  // square components of D and multiply by -0.5
65  for( unsigned int i=0; i < D.size1(); ++i )
66  for( unsigned int j=0; j < D.size2(); ++j )
67  D(i,j) = -0.5 * D(i,j)*D(i,j);
68 
69  // double-center D to get Torgersons scalar product matrix
70  double_center( D );
71 
72  // force symmetric matrix
74  {
75  //cout << "Matrix not fully symmetric, assuming it should be!" << endl;
76  //cout << "Replacing upper with lower triangular matrix..." << std::flush;
77  for( unsigned int i=0; i < D.size1(); ++i )
78  for( unsigned int j=0; j < i; ++j )
79  D(j,i) = D(i,j);
80  //cout << "done" << endl;
81  }
82 
83  // compute decomposition D=XX'
84  if( method == MethodCholesky )
85  {
86  Cholesky<double> cholesky( D );
87  m_D = ublas::trans( cholesky.getL() );
88 
89  // no eigenvalues here ;-)
90  }
91 #ifdef HAVE_IETL
92  if( method == MethodLanczos )
93  {
94  // computation is done in project() function
95  }
96 #endif
97  else // MethodCholesky
98  {
99  //cout << "Computing Eigendecomposition..." << std::flush;
100  Eigenvalue<double> evd( D );
101  //cout << "done" << endl;
102 
103  // get eigenvalues
104  m_realEV = evd.getRealEigenvalues();
105 
106  // overwrite D matrix with eigenvector matrix
107  m_D = evd.getV();
108  }
109 
110 
111  // leave projection to user
112  }
113 
116  const Vector& getEigenvalues() const { return m_realEV; }
117 
119  void project( int dim=2 )
120  {
121  assert( (dim >= 1) && (dim <= (int)m_D.size1()) );
122 
123  if( m_method == MethodQR )
124  {
125  Matrix S( dim, dim );
126  for( int i=0; i < dim; ++i )
127  for( int j=0; j < dim; ++j )
128  S(i,j) = (i==j ? sqrt(m_realEV[i]) : 0.0);
129 
130  m_D.resize( m_D.size1(), dim );
131 
132  m_D = prod( m_D, S );
133  }
134 #ifdef HAVE_IETL
135  if( m_method == MethodLanczos )
136  {
137  Lanczos<Matrix,Vector> lanczos( m_D, dim );
138 
139  m_D.resize( m_D.size1(), dim );
140 
141  m_realEV.resize( dim );
142 
143  // store eigenvectors in columns of D
144  for( int i=0; i < dim; ++i )
145  {
146  m_realEV[i] = lanczos.getEigenvalue( i );
147  ublas::column( m_D, i ) = lanczos.getEigenvector( i );
148  }
149 
150  Matrix S( dim, dim );
151  for( int i=0; i < dim; ++i )
152  for( int j=0; j < dim; ++j )
153  S(i,j) = (i==j ? sqrt(m_realEV[i]) : 0.0);
154 
155  m_D = prod( m_D, S );
156  }
157 #endif
158  else // MethodCholesky
159  {
160  m_D.resize( dim, m_D.size2() ); // points in columns
161  m_D = ublas::trans( m_D ); // transpose for output
162  }
163  }
164 
165 private:
166  Matrix& m_D;
167  Vector m_realEV;
168  int m_method;
169 };
170 
171 #endif // REDUKT_CMDS_H
Definition: Cholesky.h:45
const Vector & getEigenvalues() const
Definition: CMDS.h:116
const Matrix & getV() const
Definition: Eigenvalue.h:150
const Vector & getEigenvector(unsigned int i) const
Definition: Lanczos.h:131
Definition: Eigenvalue.h:60
if IETL is not available MethodCholesky is used instead
Definition: CMDS.h:47
ublas::vector< ValueType > Vector
Definition: CMDS.h:40
ublas::matrix< ValueType > Matrix
Definition: CMDS.h:39
Classical Multidimensional Scaling (suited for small instances)
Definition: CMDS.h:36
complete eigendecomposition (infeasible for lager instances)
Definition: CMDS.h:44
void double_center(ublas::matrix< ValueType > &D)
Double center matrix, i.e. substract column and row means and add in grand mean.
Definition: ublasTools.h:175
double getEigenvalue(unsigned int i) const
Definition: Lanczos.h:137
CMDS(Matrix &D, int method=(int) MethodQR)
Perform classical multidimensional scaling.
Definition: CMDS.h:57
const Vector & getRealEigenvalues() const
Definition: Eigenvalue.h:158
void project(int dim=2)
Project referenced matrix D to dim dimensions.
Definition: CMDS.h:119
default method
Definition: CMDS.h:45
Compute k greatest eigenvectors of a Matrix.
Definition: Lanczos.h:29
DecompositionMethod
Definition: CMDS.h:42
Matrix getL() const
Definition: Cholesky.h:61