randomized_svd.hpp
Go to the documentation of this file.
1 
13 #ifndef MLPACK_METHODS_RANDOMIZED_SVD_RANDOMIZED_SVD_HPP
14 #define MLPACK_METHODS_RANDOMIZED_SVD_RANDOMIZED_SVD_HPP
15 
16 #include <mlpack/prereqs.hpp>
17 
18 namespace mlpack {
19 namespace svd {
20 
67 {
68  public:
84  RandomizedSVD(const arma::mat& data,
85  arma::mat& u,
86  arma::vec& s,
87  arma::mat& v,
88  const size_t iteratedPower = 0,
89  const size_t maxIterations = 2,
90  const size_t rank = 0,
91  const double eps = 1e-7);
92 
103  RandomizedSVD(const size_t iteratedPower = 0,
104  const size_t maxIterations = 2,
105  const double eps = 1e-7);
106 
117  void Apply(const arma::sp_mat& data,
118  arma::mat& u,
119  arma::vec& s,
120  arma::mat& v,
121  const size_t rank);
122 
133  void Apply(const arma::mat& data,
134  arma::mat& u,
135  arma::vec& s,
136  arma::mat& v,
137  const size_t rank);
138 
150  template<typename MatType>
151  void Apply(const MatType& data,
152  arma::mat& u,
153  arma::vec& s,
154  arma::mat& v,
155  const size_t rank,
156  MatType rowMean)
157  {
158  if (iteratedPower == 0)
159  iteratedPower = rank + 2;
160 
161  arma::mat R, Q, Qdata;
162 
163  // Apply the centered data matrix to a random matrix, obtaining Q.
164  if (data.n_cols >= data.n_rows)
165  {
166  R = arma::randn<arma::mat>(data.n_rows, iteratedPower);
167  Q = (data.t() * R) - arma::repmat(arma::trans(R.t() * rowMean),
168  data.n_cols, 1);
169  }
170  else
171  {
172  R = arma::randn<arma::mat>(data.n_cols, iteratedPower);
173  Q = (data * R) - (rowMean * (arma::ones(1, data.n_cols) * R));
174  }
175 
176  // Form a matrix Q whose columns constitute a
177  // well-conditioned basis for the columns of the earlier Q.
178  if (maxIterations == 0)
179  {
180  arma::qr_econ(Q, v, Q);
181  }
182  else
183  {
184  arma::lu(Q, v, Q);
185  }
186 
187  // Perform normalized power iterations.
188  for (size_t i = 0; i < maxIterations; ++i)
189  {
190  if (data.n_cols >= data.n_rows)
191  {
192  Q = (data * Q) - rowMean * (arma::ones(1, data.n_cols) * Q);
193  arma::lu(Q, v, Q);
194  Q = (data.t() * Q) - arma::repmat(rowMean.t() * Q, data.n_cols, 1);
195  }
196  else
197  {
198  Q = (data.t() * Q) - arma::repmat(rowMean.t() * Q, data.n_cols, 1);
199  arma::lu(Q, v, Q);
200  Q = (data * Q) - (rowMean * (arma::ones(1, data.n_cols) * Q));
201  }
202 
203  // Computing the LU decomposition is more efficient than computing the QR
204  // decomposition, so we only use it in the last iteration, a pivoted QR
205  // decomposition which renormalizes Q, ensuring that the columns of Q are
206  // orthonormal.
207  if (i < (maxIterations - 1))
208  {
209  arma::lu(Q, v, Q);
210  }
211  else
212  {
213  arma::qr_econ(Q, v, Q);
214  }
215  }
216 
217  // Do economical singular value decomposition and compute only the
218  // approximations of the left singular vectors by using the centered data
219  // applied to Q.
220  if (data.n_cols >= data.n_rows)
221  {
222  Qdata = (data * Q) - rowMean * (arma::ones(1, data.n_cols) * Q);
223  arma::svd_econ(u, s, v, Qdata);
224  v = Q * v;
225  }
226  else
227  {
228  Qdata = (Q.t() * data) - arma::repmat(Q.t() * rowMean, 1, data.n_cols);
229  arma::svd_econ(u, s, v, Qdata);
230  u = Q * u;
231  }
232  }
233 
235  size_t IteratedPower() const { return iteratedPower; }
237  size_t& IteratedPower() { return iteratedPower; }
238 
240  size_t MaxIterations() const { return maxIterations; }
242  size_t& MaxIterations() { return maxIterations; }
243 
245  double Epsilon() const { return eps; }
247  double& Epsilon() { return eps; }
248 
249  private:
251  size_t iteratedPower;
252 
254  size_t maxIterations;
255 
257  double eps;
258 };
259 
260 } // namespace svd
261 } // namespace mlpack
262 
263 #endif
Linear algebra utility functions, generally performed on matrices or vectors.
The core includes that mlpack expects; standard C++ includes and Armadillo.
void Apply(const MatType &data, arma::mat &u, arma::vec &s, arma::mat &v, const size_t rank, MatType rowMean)
Apply Principal Component Analysis to the provided matrix data set using the randomized SVD...
size_t & IteratedPower()
Modify the size of the normalized power iterations.
RandomizedSVD(const arma::mat &data, arma::mat &u, arma::vec &s, arma::mat &v, const size_t iteratedPower=0, const size_t maxIterations=2, const size_t rank=0, const double eps=1e-7)
Create object for the randomized SVD method.
size_t MaxIterations() const
Get the number of iterations for the power method.
double Epsilon() const
Get the value used for decomposition stability.
Randomized SVD is a matrix factorization that is based on randomized matrix approximation techniques...
size_t IteratedPower() const
Get the size of the normalized power iterations.
size_t & MaxIterations()
Modify the number of iterations for the power method.
double & Epsilon()
Modify the value used for decomposition stability.
void Apply(const arma::sp_mat &data, arma::mat &u, arma::vec &s, arma::mat &v, const size_t rank)
Center the data to apply Principal Component Analysis on given sparse matrix dataset using randomized...