Statismo  0.10.1
 All Classes Namespaces Functions Typedefs
RandSVD.h
1 /*
2  * This file is part of the statismo library.
3  *
4  * Author: Marcel Luethi (marcel.luethi@unibas.ch)
5  *
6  * Copyright (c) 2011 University of Basel
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * Redistributions of source code must retain the above copyright notice,
14  * this list of conditions and the following disclaimer.
15  *
16  * Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in the
18  * documentation and/or other materials provided with the distribution.
19  *
20  * Neither the name of the project's author nor the names of its
21  * contributors may be used to endorse or promote products derived from
22  * this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
30  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35  *
36  */
37 
38 #ifndef __RANDSVD_H
39 #define __RANDSVD_H
40 
41 #include <cmath>
42 
43 #include <iostream>
44 #include <limits>
45 
46 #include <boost/random.hpp>
47 
48 #include <Eigen/Dense>
49 
50 namespace statismo {
54 template <typename ScalarType>
55 class RandSVD {
56  public:
57 
58  typedef Eigen::Matrix<ScalarType, Eigen::Dynamic, 1> VectorType;
59  typedef Eigen::Matrix<ScalarType, Eigen::Dynamic, Eigen::Dynamic,
60  Eigen::RowMajor> MatrixType;
61 
62  RandSVD(const MatrixType& A, unsigned k) {
63 
64  unsigned n = A.rows();
65 
66 
67  static boost::minstd_rand randgen(static_cast<unsigned>(time(0)));
68  static boost::normal_distribution<> dist(0, 1);
69  static boost::variate_generator<boost::minstd_rand, boost::normal_distribution<> > r(randgen, dist);
70 
71  // create gaussian random amtrix
72  MatrixType Omega(n, k);
73  for (unsigned i =0; i < n ; i++) {
74  for (unsigned j = 0; j < k ; j++) {
75  Omega(i,j) = r();
76  }
77  }
78 
79 
80  MatrixType Y = A * A.transpose() * A * Omega;
81  Eigen::FullPivHouseholderQR<MatrixType> qr(Y);
82  MatrixType Q = qr.matrixQ().leftCols(k + k);
83 
84  MatrixType B = Q.transpose() * A;
85 
86  typedef Eigen::JacobiSVD<MatrixType> SVDType;
87  SVDType SVD(B, Eigen::ComputeThinU);
88  MatrixType Uhat = SVD.matrixU();
89  m_D = SVD.singularValues();
90  m_U = (Q * Uhat).leftCols(k);
91  }
92 
93  MatrixType matrixU() const {
94  return m_U;
95  }
96 
97  VectorType singularValues() const {
98  return m_D;
99  }
100 
101 
102  private:
103  VectorType m_D;
104  MatrixType m_U;
105 };
106 
107 
108 } // namespace statismo;
109 #endif // __LANCZOS_H
Definition: RandSVD.h:55
float ScalarType
the type that is used for all vector and matrices throughout the library.
Definition: CommonTypes.h:60