mlpack 3.4.2
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
18namespace mlpack {
19namespace 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
Randomized SVD is a matrix factorization that is based on randomized matrix approximation techniques,...
size_t MaxIterations() const
Get the number of iterations for the power method.
double & Epsilon()
Modify the value used for decomposition stability.
size_t & MaxIterations()
Modify the number of iterations for the power method.
void Apply(const arma::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 matrix dataset using randomized SVD.
size_t IteratedPower() const
Get the size of the normalized power iterations.
RandomizedSVD(const size_t iteratedPower=0, const size_t maxIterations=2, const double eps=1e-7)
Create object for the randomized SVD method.
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...
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.
double Epsilon() const
Get the value used for decomposition stability.
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 & IteratedPower()
Modify the size of the normalized power iterations.
Linear algebra utility functions, generally performed on matrices or vectors.
Definition: cv.hpp:1
The core includes that mlpack expects; standard C++ includes and Armadillo.