SLIP  1.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
pca.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 
74 #ifndef SLIP_PCA_HPP
75 #define SLIP_PCA_HPP
76 
77 #include <cmath>
78 #include <map>
79 #include <complex>
80 #include <numeric>
81 #include <algorithm>
82 #include "macros.hpp"
83 #include "Matrix.hpp"
84 #include "Vector.hpp"
85 #include "linear_algebra.hpp"
86 #include "linear_algebra_eigen.hpp"
87 #include "statistics.hpp"
88 
89 namespace slip
90 {
91 
92 
105  template<class OutputMatrix>
106  inline
107  void pca_uniform_metric(OutputMatrix& metric)
108  {
109  assert (metric.rows() >= metric.cols());
110  assert (metric.rows() == metric.cols());
111  slip::identity(metric);
112  }
113 
127  template<class Matrix, class OutputMatrix>
128  inline
129  void pca_adaptative_metric(const Matrix & data,
130  OutputMatrix& metric)
131  {
132  assert (data.rows() >= data.cols());
133  assert (metric.rows() == data.cols());
134  assert (metric.rows() == metric.cols());
135  typedef typename Matrix::value_type value_type;
136  std::size_t nbvector = data.rows();
137  std::size_t size = data.cols();
138  std::size_t ncmetric = metric.cols();
139  value_type meanval = value_type(0.0);
140  value_type stddev = value_type(0.0);
141  for (std::size_t j = 0; j < size; ++j)
142  {
143  meanval = value_type(0.0);
144  for (std::size_t i = 0; i < nbvector; ++i)
145  {
146  meanval += data[i][j];
147  }
148  stddev = value_type(0.0);
149  for (std::size_t i = 0; i < nbvector; ++i)
150  {
151  stddev += (data[i][j] - meanval) * (data[i][j] - meanval);
152  }
153 
154  for (std::size_t i = 0; i < ncmetric; ++i)
155  {
156  metric[i][j] = value_type(0.0);
157  }
158  metric[j][j] = value_type(1.0) / std::sqrt(stddev);
159  }
160  }
161 
175  template<class Matrix, class OutputMatrix>
176  inline
177  void pca_center_data(const Matrix & data,
178  OutputMatrix& centerdata,
179  const bool normalize_data = false)
180  {
181  assert (data.rows() >= data.cols());
182  assert (data.rows() == centerdata.rows());
183  assert (data.cols() == centerdata.cols());
184  typedef typename Matrix::value_type value_type;
185  std::size_t nbvector = data.rows();
186  std::size_t size = data.cols();
187  // Copy datas into matrix structure
188  std::copy(data.begin(),data.end(),centerdata.begin());
189 
190  // compute means and center datas
191  value_type meanval = value_type(0.0);
192  value_type stddev = value_type(0.0);
193  for (std::size_t j = 0; j < size; ++j)
194  {
195  meanval = value_type(0.0);
196  for (std::size_t i = 0; i < nbvector; ++i)
197  {
198  meanval += data[i][j];
199  }
200  for (std::size_t i = 0; i < nbvector; ++i)
201  {
202  centerdata[i][j] -= meanval;
203  }
204  if (normalize_data)
205  {
206 
207  stddev = value_type(0.0);
208  for (std::size_t i = 0; i < nbvector; ++i)
209  {
210  stddev += (data[i][j] - meanval) * (data[i][j] - meanval);
211  }
212 
213  for (std::size_t i = 0; i < nbvector; ++i)
214  {
215  centerdata[i][j] /= stddev;
216  }
217  }
218  }
219  }
220 
238  template<class Matrix, class Matrix2, class OutputMatrix,class OutputVector>
239  inline
240  void pca_computation(const Matrix & data,
241  OutputMatrix &acp,
242  const Matrix2& metric,
243  OutputVector & eigenval)
244  {
245  assert( acp.rows() == data.rows());
246  assert( acp.cols() == data.cols());
247  assert( data.rows() >= data.cols());
248  assert( eigenval.size() == data.cols());
249  assert( metric.rows() == data.cols());
250  assert( metric.rows() == metric.cols());
251  typedef typename Matrix::value_type value_type;
252  std::size_t nbvector = data.rows();
253  std::size_t size = data.cols();
254  // Compute variance / covariance matric
255  slip::Matrix<value_type> varcovar(size,size);
256  slip::Matrix<value_type> T(nbvector,size);
257  slip::Matrix<value_type> Ttranspose(size,nbvector);
258  slip::Matrix<value_type> temp(size,nbvector);
259  slip::Matrix<value_type> P(nbvector,nbvector,value_type(0.0));
260  for (std::size_t i = 0; i < nbvector; ++i)
261  {
262  P[i][i] = value_type(1.0) / ((value_type) nbvector);
263  }
264 
265  slip::matrix_matrix_multiplies(data,metric,T);
266  slip::transpose(T,Ttranspose);
267  slip::matrix_matrix_multiplies(Ttranspose,P,temp);
268  slip::matrix_matrix_multiplies(temp,T,varcovar);
269 
270  //computes the eigen values and eigen vectors of varcovar
271  slip::Matrix<value_type> eigenvectors(size,size);
272  slip::hermitian_eigen(varcovar,eigenval,eigenvectors);
273 
274  // Compute ACP
275  slip::matrix_matrix_multiplies(T,eigenvectors,acp);
276  }
277 
278 
293  template<class Matrix, class OutputMatrix>
294  inline
296  OutputMatrix &result,
297  const std::size_t & nbaxis)
298  {
299  assert(acp.rows() == result.rows());
300  assert(nbaxis <= acp.cols());
301  assert(acp.rows() >= acp.cols());
302  std::size_t nbvector = acp.rows();
303  for (std::size_t i = 0; i < nbvector; ++i)
304  {
305  for (std::size_t j = 0; j < nbaxis; ++j)
306  {
307  result[i][j] = acp[i][j];
308  }
309  }
310  }
311 
329  template<class Matrix, class Matrix2, class OutputMatrix>
330  inline
331  void pca_data_reduction(const Matrix & data,
332  const Matrix2& metric,
333  OutputMatrix &result,
334  const std::size_t & nbaxis,
335  const bool normalize_data = false)
336  {
337  typedef typename Matrix::value_type real;
338  std::size_t nbvector = data.rows();
339  std::size_t size = data.cols();
340 
341  slip::Matrix<real> acp(nbvector,size);
342  slip::Matrix<real> centerdata(nbvector,size);
343  slip::Vector<real> eigenval(size);
344 
345  slip::pca_center_data(data,centerdata,normalize_data);
346 
347  slip::pca_computation(data,
348  acp,
349  metric,
350  eigenval);
351 
353  result,nbaxis);
354 
355  }
356 
378  template<class Matrix, class Matrix2, class OutputMatrix>
379  inline
380  void pca_data_reduction(const Matrix & data,
381  const Matrix2& metric,
382  OutputMatrix &result,
383  const bool normalize_data = false)
384  {
386  metric,
387  result, result.cols(),normalize_data);
388  }
389 
390 
391 
392 
393 }
394 
395 
396 #endif //SLIP_PCA_HPP
iterator begin()
Returns a read/write iterator that points to the first element in the Matrix. Iteration is done in or...
Definition: Matrix.hpp:2789
size_type cols() const
Returns the number of columns (second dimension size) in the Matrix.
Definition: Matrix.hpp:3512
Provides common linear algebra algorithms.
void real(const Matrix1 &C, Matrix2 &R)
Extract the real Matrix of a complex Matrix. .
void pca_uniform_metric(OutputMatrix &metric)
Get uniform metric for PCA computation.
Definition: pca.hpp:107
void pca_data_reduction(const Matrix &data, const Matrix2 &metric, OutputMatrix &result, const std::size_t &nbaxis, const bool normalize_data=false)
Data reduction using ACP.
Definition: pca.hpp:331
void hermitian_eigen(const Matrix1 &A, Vector1 &EigenValues, Matrix2 &EigenVectors)
Eigen Values Computation of an hermitian semi-definite positive matrix.
Provides some statistics algorithms.
void pca_simple_data_reduction_axis(const Matrix &acp, OutputMatrix &result, const std::size_t &nbaxis)
Reduce ACP data.
Definition: pca.hpp:295
Provides some algorithms to computes eigenvalues and eigenvectors.
void copy(_II first, _II last, _OI output_first)
Copy algorithm optimized for slip iterators.
Definition: copy_ext.hpp:177
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)
Matrix identity(const std::size_t nr, const std::size_t nc)
Returns an identity matrix which dimensions are nr*nc.
void matrix_matrix_multiplies(MatrixIterator1 M1_up, MatrixIterator1 M1_bot, MatrixIterator2 M2_up, MatrixIterator2 M2_bot, MatrixIterator3 R_up, MatrixIterator3 R_bot)
Computes the matrix matrix multiplication of 2 2d ranges.
Numerical matrix class. This container statisfies the BidirectionnalContainer concepts of the STL...
size_type rows() const
Returns the number of rows (first dimension size) in the Matrix.
Definition: Matrix.hpp:3499
iterator end()
Returns a read/write iterator that points one past the last element in the Matrix. Iteration is done in ordinary element order.
Definition: Matrix.hpp:2796
Provides a class to manipulate Numerical Matrix.
void pca_computation(const Matrix &data, OutputMatrix &acp, const Matrix2 &metric, OutputVector &eigenval)
Compute the PCA (data need to be centered)
Definition: pca.hpp:240
void transpose(const Matrix1 &M, const std::size_t nr1, const std::size_t nc1, Matrix2 &TM, const std::size_t nr2, const std::size_t nc2)
Computes the transpose of a matrix .
void pca_center_data(const Matrix &data, OutputMatrix &centerdata, const bool normalize_data=false)
Get uniform metric for PCA computation.
Definition: pca.hpp:177
void pca_adaptative_metric(const Matrix &data, OutputMatrix &metric)
Get adaptative metric for PCA computation.
Definition: pca.hpp:129
Provides a class to manipulate numerical vectors.