14 #include "ROL_LinearAlgebra.hpp"
15 #include "ROL_LAPACK.hpp"
34 std::vector<Ptr<Vector<Real>>>
Y_;
54 Ptr<Elementwise::NormalRandom<Real>>
nrand_;
56 Ptr<std::normal_distribution<Real>>
dist_;
59 const int nvec(Y.size());
60 const Real
zero(0), one(1);
62 std::vector<Real> normQ(nvec,0);
64 for (
int j = 0; j < nvec; ++j) {
66 if (rjj > ROL_EPSILON<Real>()) {
67 for (
int k = 0; k <
orthIt_; ++k) {
68 for (
int i = 0; i < j; ++i) {
69 rij = Y[i]->dot(*Y[j]);
70 Y[j]->axpy(-rij,*Y[i]);
72 normQ[j] = Y[j]->norm();
74 for (
int i = 0; i < j; ++i) {
75 rij = std::abs(Y[i]->dot(*Y[j]));
76 if (rij >
orthTol_*normQ[j]*normQ[i]) {
85 if (rjj >
zero) Y[j]->scale(one/rjj);
89 int LSsolver(LA::Matrix<Real> &A, LA::Matrix<Real> &B,
bool trans =
false)
const {
91 char TRANS = (trans ?
'T' :
'N');
94 int NRHS = B.numCols();
96 int LDB = std::max(M,N);
97 std::vector<Real> WORK(1);
100 lapack_.GELS(TRANS,M,N,NRHS,A.values(),LDA,B.values(),LDB,&WORK[0],LWORK,&INFO);
102 LWORK =
static_cast<int>(WORK[0]);
104 lapack_.GELS(TRANS,M,N,NRHS,A.values(),LDA,B.values(),LDB,&WORK[0],LWORK,&INFO);
115 int K = std::min(M,N);
117 std::vector<Real> S(K);
118 LA::Matrix<Real> U(M,K);
120 LA::Matrix<Real> VT(K,N);
122 std::vector<Real> WORK(1), WORK0(1);
125 lapack_.GESVD(JOBU,JOBVT,M,N,A.values(),LDA,&S[0],U.values(),LDU,VT.values(),LDVT,&WORK[0],LWORK,&WORK0[0],&INFO);
126 LWORK =
static_cast<int>(WORK[0]);
128 lapack_.GESVD(JOBU,JOBVT,M,N,A.values(),LDA,&S[0],U.values(),LDU,VT.values(),LDVT,&WORK[0],LWORK,&WORK0[0],&INFO);
129 for (
int i = 0; i < M; ++i) {
130 for (
int j = 0; j < N; ++j) {
132 for (
int k = 0; k < r; ++k) {
133 A(i,j) += S[k] * U(i,k) * VT(k,j);
146 int K = std::min(M,N);
148 std::vector<Real> TAU(K);
149 std::vector<Real> WORK(1);
152 lapack_.GEQRF(M,N,
X_.values(),LDA,&TAU[0],&WORK[0],LWORK,&INFO);
153 LWORK =
static_cast<int>(WORK[0]);
155 lapack_.GEQRF(M,N,
X_.values(),LDA,&TAU[0],&WORK[0],LWORK,&INFO);
158 lapack_.ORGQR(M,N,K,
X_.values(),LDA,&TAU[0],&WORK[0],LWORK,&INFO);
159 LWORK =
static_cast<int>(WORK[0]);
161 lapack_.ORGQR(M,N,K,
X_.values(),LDA,&TAU[0],&WORK[0],LWORK,&INFO);
176 int infoP(0), infoQ(0), infoLS1(0), infoLS2(0), infoLRA(0);
181 LA::Matrix<Real> L(
s_,
k_), R(
s_,
k_);
182 for (
int i = 0; i <
s_; ++i) {
183 for (
int j = 0; j <
k_; ++j) {
184 L(i,j) =
Phi_[i]->dot(*
Y_[j]);
186 for (
int k = 0; k <
ncol_; ++k) R(i,j) +=
Psi_(k,i) *
X_(k,j);
191 LA::Matrix<Real> Zmat(s_,
k_);
192 for (
int i = 0; i <
k_; ++i) {
193 for (
int j = 0; j <
s_; ++j) Zmat(j,i) =
Z_(i,j);
196 for (
int i = 0; i <
k_; ++i) {
197 for (
int j = 0; j <
k_; ++j)
C_(j,i) = Zmat(i,j);
204 return std::abs(infoP)+std::abs(infoQ)+std::abs(infoLS1)
205 +std::abs(infoLS2)+std::abs(infoLRA);
212 Real orthTol = 1e-8,
int orthIt = 2,
bool truncate =
false,
213 unsigned dom_seed = 0,
unsigned rng_seed = 0)
218 nrand_ = makePtr<Elementwise::NormalRandom<Real>>(mu,sig,dom_seed);
219 unsigned seed = rng_seed;
220 if (seed == 0) seed = std::chrono::system_clock::now().time_since_epoch().count();
221 gen_ = makePtr<std::mt19937_64>(seed);
222 dist_ = makePtr<std::normal_distribution<Real>>(mu,sig);
225 rank_ = std::min(rank, maxRank_);
226 k_ = std::min(2*rank_+1, maxRank_);
227 s_ = std::min(2*
k_ +1, maxRank_);
231 for (
int i = 0; i <
k_; ++i) {
245 X_.putScalar(zero);
Z_.putScalar(zero);
C_.putScalar(zero);
246 for (
int i = 0; i <
k_; ++i)
Y_[i]->
zero();
249 for (
int i = 0; i <
s_; ++i) {
251 for (
int j = 0; j <
ncol_; ++j)
Psi_(j,i) = (*dist_)(*gen_);
253 for (
int i = 0; i <
k_; ++i) {
255 for (
int j = 0; j <
ncol_; ++j)
Omega_(j,i) = (*dist_)(*gen_);
263 int sold =
s_, kold =
k_;
269 for (
int i = sold; i <
s_; ++i)
Phi_.push_back(
Phi_[0]->clone());
272 for (
int i = kold; i <
k_; ++i) {
273 Y_.push_back(
Y_[0]->clone());
278 if (
out_ != nullPtr ) {
279 *
out_ << std::string(80,
'=') << std::endl;
280 *
out_ <<
" ROL::Sketch::setRank" << std::endl;
281 *
out_ <<
" **** Rank = " <<
rank_ << std::endl;
282 *
out_ <<
" **** k = " <<
k_ << std::endl;
283 *
out_ <<
" **** s = " <<
s_ << std::endl;
284 *
out_ << std::string(80,
'=') << std::endl;
294 if ( col >=
ncol_ || col < 0 )
return 1;
296 for (
int i = 0; i <
k_; ++i) {
298 for (
int j = 0; j <
ncol_; ++j)
X_(j,i) *= eta;
306 for (
int i = 0; i <
s_; ++i) {
308 for (
int j = 0; j <
s_; ++j) {
310 Z_(i,j) += nu*
Psi_(col,j)*hphi;
313 if (
out_ != nullPtr ) {
314 *
out_ << std::string(80,
'=') << std::endl;
315 *
out_ <<
" ROL::Sketch::advance" << std::endl;
316 *
out_ <<
" **** col = " << col << std::endl;
317 *
out_ <<
" **** norm(h) = " << h.
norm() << std::endl;
318 *
out_ << std::string(80,
'=') << std::endl;
330 if ( col >=
ncol_ || col < 0 )
return 2;
335 if (flag > 0 )
return 3;
338 if (flag > 0 )
return 4;
341 if (flag > 0 )
return 5;
345 for (
int i = 0; i <
k_; ++i) {
347 for (
int j = 0; j <
k_; ++j) coeff +=
C_(i,j) *
X_(col,j);
350 if (
out_ != nullPtr ) {
351 *
out_ << std::string(80,
'=') << std::endl;
352 *
out_ <<
" ROL::Sketch::reconstruct" << std::endl;
353 *
out_ <<
" **** col = " << col << std::endl;
354 *
out_ <<
" **** norm(a) = " << a.
norm() << std::endl;
355 *
out_ << std::string(80,
'=') << std::endl;
360 bool test(
const int rank, std::ostream &outStream = std::cout,
const int verbosity = 0) {
361 const Real one(1), tol(std::sqrt(ROL_EPSILON<Real>()));
362 using seed_type = std::mt19937_64::result_type;
363 seed_type
const seed = 123;
364 std::mt19937_64 eng{seed};
365 std::uniform_real_distribution<Real> dist(static_cast<Real>(0),static_cast<Real>(1));
367 std::vector<Ptr<Vector<Real>>> U(rank);
368 LA::Matrix<Real>
V(
ncol_,rank);
369 for (
int i = 0; i < rank; ++i) {
370 U[i] =
Y_[0]->clone();
371 U[i]->randomize(-one,one);
372 for (
int j = 0; j <
ncol_; ++j)
V(j,i) = dist(eng);
376 std::vector<Ptr<Vector<Real>>> A(
ncol_);
377 for (
int i = 0; i <
ncol_; ++i) {
378 A[i] =
Y_[0]->clone(); A[i]->zero();
379 for (
int j = 0; j < rank; ++j) {
380 A[i]->axpy(
V(i,j),*U[j]);
385 bool flagP =
testP(outStream, verbosity);
387 bool flagQ =
testQ(outStream, verbosity);
389 Real nerr(0), maxerr(0);
390 Ptr<Vector<Real>> err =
Y_[0]->clone();
391 for (
int i = 0; i <
ncol_; ++i) {
393 err->axpy(-one,*A[i]);
395 maxerr = (nerr > maxerr ? nerr : maxerr);
398 std::ios_base::fmtflags oflags(outStream.flags());
399 outStream << std::scientific << std::setprecision(3) << std::endl;
400 outStream <<
" TEST RECONSTRUCTION: Max Error = "
401 << std::setw(12) << std::right << maxerr
402 << std::endl << std::endl;
403 outStream.flags(oflags);
405 return flagP & flagQ & (maxerr < tol ?
true :
false);
411 bool testQ(std::ostream &outStream = std::cout,
const int verbosity = 0) {
412 const Real one(1), tol(std::sqrt(ROL_EPSILON<Real>()));
414 Real qij(0), err(0), maxerr(0);
415 std::ios_base::fmtflags oflags(outStream.flags());
416 if (verbosity > 0) outStream << std::scientific << std::setprecision(3);
418 outStream << std::endl
419 <<
" Printing Q'Q...This should be approximately equal to I"
420 << std::endl << std::endl;
422 for (
int i = 0; i <
k_; ++i) {
423 for (
int j = 0; j <
k_; ++j) {
424 qij =
Y_[i]->dot(*
Y_[j]);
425 err = (i==j ? std::abs(qij-one) : std::abs(qij));
426 maxerr = (err > maxerr ? err : maxerr);
427 if (verbosity > 1) outStream << std::setw(12) << std::right << qij;
429 if (verbosity > 1) outStream << std::endl;
430 if (maxerr > tol)
break;
433 outStream << std::endl <<
" TEST ORTHOGONALIZATION: Max Error = "
434 << std::setw(12) << std::right << maxerr
436 outStream.flags(oflags);
438 return (maxerr < tol ?
true :
false);
441 bool testP(std::ostream &outStream = std::cout,
const int verbosity = 0) {
442 const Real
zero(0), one(1), tol(std::sqrt(ROL_EPSILON<Real>()));
444 Real qij(0), err(0), maxerr(0);
445 std::ios_base::fmtflags oflags(outStream.flags());
446 if (verbosity > 0) outStream << std::scientific << std::setprecision(3);
448 outStream << std::endl
449 <<
" Printing P'P...This should be approximately equal to I"
450 << std::endl << std::endl;
452 for (
int i = 0; i <
k_; ++i) {
453 for (
int j = 0; j <
k_; ++j) {
455 for (
int k = 0; k <
ncol_; ++k) qij +=
X_(k,i) *
X_(k,j);
456 err = (i==j ? std::abs(qij-one) : std::abs(qij));
457 maxerr = (err > maxerr ? err : maxerr);
458 if (verbosity > 1) outStream << std::setw(12) << std::right << qij;
460 if (verbosity > 1) outStream << std::endl;
461 if (maxerr > tol)
break;
464 outStream << std::endl <<
" TEST ORTHOGONALIZATION: Max Error = "
465 << std::setw(12) << std::right << maxerr
467 outStream.flags(oflags);
469 return (maxerr < tol ?
true :
false);
void setStream(Ptr< std::ostream > &out)
Ptr< std::normal_distribution< Real > > dist_
std::vector< Ptr< Vector< Real > > > Y_
virtual ROL::Ptr< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
virtual int dimension() const
Return dimension of the vector space.
virtual void axpy(const Real alpha, const Vector &x)
Compute where .
int reconstruct(Vector< Real > &a, const int col)
Ptr< std::mt19937_64 > gen_
Contains definitions of custom data types in ROL.
Provides an interface for randomized sketching.
int LSsolver(LA::Matrix< Real > &A, LA::Matrix< Real > &B, bool trans=false) const
std::vector< Ptr< Vector< Real > > > Upsilon_
virtual void zero()
Set to zero vector.
Defines the linear algebra or vector space interface.
Ptr< Elementwise::NormalRandom< Real > > nrand_
virtual Real dot(const Vector &x) const =0
Compute where .
Objective_SerialSimOpt(const Ptr< Obj > &obj, const V &ui) z0_ zero()
Sketch(const Vector< Real > &x, int ncol, int rank, Real orthTol=1e-8, int orthIt=2, bool truncate=false, unsigned dom_seed=0, unsigned rng_seed=0)
bool testQ(std::ostream &outStream=std::cout, const int verbosity=0)
void reset(bool randomize=true)
void mgs2(std::vector< Ptr< Vector< Real >>> &Y) const
bool testP(std::ostream &outStream=std::cout, const int verbosity=0)
bool test(const int rank, std::ostream &outStream=std::cout, const int verbosity=0)
LAPACK< int, Real > lapack_
LA::Matrix< Real > Omega_
int advance(Real nu, const Vector< Real > &h, int col, Real eta=1.0)
virtual Real norm() const =0
Returns where .
std::vector< Ptr< Vector< Real > > > Phi_
int lowRankApprox(LA::Matrix< Real > &A, int r) const