OpenWalnut  1.5.0dev
WPrincipalComponentAnalysis.cpp
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #include <vector>
26 #include "WPrincipalComponentAnalysis.h"
27 
29 {
30  m_isValidPCA = false;
31 }
32 
34 {
35 }
36 
37 void WPrincipalComponentAnalysis::analyzeData( const vector<WPosition>& inputData )
38 {
39  m_isValidPCA = true;
40  m_inputPointCount = inputData.size();
41  if( m_inputPointCount > 0 )
42  m_dimensions = inputData.at( 0 ).size();
43  m_covarianceSolver.analyzeData( inputData );
44  EigenSolver<MatrixXd> es( m_covarianceSolver.getCovariance() );
45  m_eigenSolver = es;
48 }
50 {
51  int count = m_eigenSolver.eigenvalues().size();
52  m_eigenVectors.reserve( count );
53  m_eigenVectors.resize( count );
54  m_eigenValues.reserve( count );
55  m_eigenValues.resize( count );
56  for( int index = 0; index < count; index++ )
57  {
58  complex<double> lambda = m_eigenSolver.eigenvalues()[index];
59  if( lambda.imag() != 0.0 )
60  m_isValidPCA = false;
61  m_eigenValues[index] = lambda.real();
62 
63  VectorXcd vector = m_eigenSolver.eigenvectors().col( index );
64  WVector3d newPosition;
65  size_t vectorSize = static_cast<size_t>( vector.size() );
66  for( size_t dimension = 0; dimension < vectorSize && dimension < newPosition.size(); dimension++ )
67  {
68  complex<double> value = vector[dimension];
69  newPosition[dimension] = value.real();
70  }
71  m_eigenVectors[index] = newPosition;
72  }
74 }
76 {
77  if( m_inputPointCount == 0 ) return;
78  for( size_t d1 = 0; d1 < m_dimensions - 1; d1++ )
79  for( size_t d2 = d1 + 1; d2 < m_dimensions; d2++ )
80  if( m_eigenValues[d1] < m_eigenValues[d2] )
81  swapEigenVectors( d1, d2 );
82 }
83 void WPrincipalComponentAnalysis::swapEigenVectors( size_t eigenVectorIndex1, size_t eigenVectorIndex2 )
84 {
85  for( size_t dimension = 0; dimension < m_eigenValues.size(); dimension++ )
86  {
87  double prevValue = m_eigenVectors[eigenVectorIndex1][dimension];
88  m_eigenVectors[eigenVectorIndex1][dimension] = m_eigenVectors[eigenVectorIndex2][dimension];
89  m_eigenVectors[eigenVectorIndex2][dimension] = prevValue;
90  }
91  double prevValue = m_eigenValues[eigenVectorIndex1];
92  m_eigenValues[eigenVectorIndex1] = m_eigenValues[eigenVectorIndex2];
93  m_eigenValues[eigenVectorIndex2] = prevValue;
94 }
96 {
97  return m_covarianceSolver.getMean();
98 }
100 {
101  return m_eigenVectors;
102 }
104 {
105  return m_eigenValues;
106 }
WPosition getMean()
Returns the mean coordinate of the input point data set.
MatrixXd getCovariance()
Returns the covariance matrix corresponding to the input point data set.
void analyzeData(const vector< WPosition > &dataSet)
Analyzes the dimension covariances of a point data set.
size_t size() const
The number of entries.
Definition: WMatrixFixed.h:203
This only is a 3d double vector.
void extractEigenData()
Does the actual Eigen Value and Vector Analysis.
size_t m_dimensions
Dimension count used in the input data.
void sortByVarianceDescending()
Sorts the Point distribution direction by the descending strength.
vector< double > getEigenValues()
Returns Eigen Values (equals how much the directions of getDirections() are distributed).
vector< WVector3d > m_eigenVectors
Main point distribution directions.
virtual ~WPrincipalComponentAnalysis()
Destroys the Principal Component Analysis instance.
WPosition getMean()
Returns the mean coordinate of all input points.
vector< double > m_eigenValues
Lambda values for A*x-Lambda*x=0.
void swapEigenVectors(size_t eigenVectorIndex1, size_t eigenVectorIndex2)
Replaces two Eigen Vectors and its Variances by each other.
bool m_isValidPCA
Indicator whether calculation is still valid.
WCovarianceSolver m_covarianceSolver
Instance to analyze the covariances of the point data between each dimension pair.
size_t m_inputPointCount
Point count of the input data.
vector< WVector3d > getEigenVectors()
Returns the point distribution directions.
WPrincipalComponentAnalysis()
Creates the Principal Component Analysis instance.
EigenSolver< MatrixXd > m_eigenSolver
Instance for solving Eigen Values and Vectors.
void analyzeData(const vector< WPosition > &inputData)
Analyzes a point data set using the Principal Component Analysis algorithm.