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 #include <mlpack/methods/cf/cf.hpp>
18 
19 namespace mlpack {
20 namespace svd {
21 
68 {
69  public:
85  RandomizedSVD(const arma::mat& data,
86  arma::mat& u,
87  arma::vec& s,
88  arma::mat& v,
89  const size_t iteratedPower = 0,
90  const size_t maxIterations = 2,
91  const size_t rank = 0,
92  const double eps = 1e-7);
93 
104  RandomizedSVD(const size_t iteratedPower = 0,
105  const size_t maxIterations = 2,
106  const double eps = 1e-7);
107 
118  void Apply(const arma::sp_mat& data,
119  arma::mat& u,
120  arma::vec& s,
121  arma::mat& v,
122  const size_t rank);
123 
134  void Apply(const arma::mat& data,
135  arma::mat& u,
136  arma::vec& s,
137  arma::mat& v,
138  const size_t rank);
139 
151  template<typename MatType>
152  void Apply(const MatType& data,
153  arma::mat& u,
154  arma::vec& s,
155  arma::mat& v,
156  const size_t rank,
157  MatType rowMean)
158  {
159  if (iteratedPower == 0)
160  iteratedPower = rank + 2;
161 
162  arma::mat R, Q, Qdata;
163 
164  // Apply the centered data matrix to a random matrix, obtaining Q.
165  if (data.n_cols >= data.n_rows)
166  {
167  R = arma::randn<arma::mat>(data.n_rows, iteratedPower);
168  Q = (data.t() * R) - arma::repmat(arma::trans(R.t() * rowMean),
169  data.n_cols, 1);
170  }
171  else
172  {
173  R = arma::randn<arma::mat>(data.n_cols, iteratedPower);
174  Q = (data * R) - (rowMean * (arma::ones(1, data.n_cols) * R));
175  }
176 
177  // Form a matrix Q whose columns constitute a
178  // well-conditioned basis for the columns of the earlier Q.
179  if (maxIterations == 0)
180  {
181  arma::qr_econ(Q, v, Q);
182  }
183  else
184  {
185  arma::lu(Q, v, Q);
186  }
187 
188  // Perform normalized power iterations.
189  for (size_t i = 0; i < maxIterations; ++i)
190  {
191  if (data.n_cols >= data.n_rows)
192  {
193  Q = (data * Q) - rowMean * (arma::ones(1, data.n_cols) * Q);
194  arma::lu(Q, v, Q);
195  Q = (data.t() * Q) - arma::repmat(rowMean.t() * Q, data.n_cols, 1);
196  }
197  else
198  {
199  Q = (data.t() * Q) - arma::repmat(rowMean.t() * Q, data.n_cols, 1);
200  arma::lu(Q, v, Q);
201  Q = (data * Q) - (rowMean * (arma::ones(1, data.n_cols) * Q));
202  }
203 
204  // Computing the LU decomposition is more efficient than computing the QR
205  // decomposition, so we only use it in the last iteration, a pivoted QR
206  // decomposition which renormalizes Q, ensuring that the columns of Q are
207  // orthonormal.
208  if (i < (maxIterations - 1))
209  {
210  arma::lu(Q, v, Q);
211  }
212  else
213  {
214  arma::qr_econ(Q, v, Q);
215  }
216  }
217 
218  // Do economical singular value decomposition and compute only the
219  // approximations of the left singular vectors by using the centered data
220  // applied to Q.
221  if (data.n_cols >= data.n_rows)
222  {
223  Qdata = (data * Q) - rowMean * (arma::ones(1, data.n_cols) * Q);
224  arma::svd_econ(u, s, v, Qdata);
225  v = Q * v;
226  }
227  else
228  {
229  Qdata = (Q.t() * data) - arma::repmat(Q.t() * rowMean, 1, data.n_cols);
230  arma::svd_econ(u, s, v, Qdata);
231  u = Q * u;
232  }
233  }
234 
236  size_t IteratedPower() const { return iteratedPower; }
238  size_t& IteratedPower() { return iteratedPower; }
239 
241  size_t MaxIterations() const { return maxIterations; }
243  size_t& MaxIterations() { return maxIterations; }
244 
246  double Epsilon() const { return eps; }
248  double& Epsilon() { return eps; }
249 
250  private:
252  size_t iteratedPower;
253 
255  size_t maxIterations;
256 
258  double eps;
259 };
260 
261 } // namespace svd
262 } // namespace mlpack
263 
264 #endif
.hpp
Definition: add_to_po.hpp:21
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...