48 #include "ROL_LinearAlgebra.hpp"
49 #include "ROL_LAPACK.hpp"
82 Ptr<Elementwise::NormalRandom<Real>>
nrand_;
84 Ptr<std::normal_distribution<Real>>
dist_;
92 int K = std::min(M,N);
94 std::vector<Real> TAU(K);
95 std::vector<Real> WORK(1);
98 lapack_.GEQRF(M,N,
X_.values(),LDA,&TAU[0],&WORK[0],LWORK,&INFO);
99 LWORK =
static_cast<int>(WORK[0]);
101 lapack_.GEQRF(M,N,
X_.values(),LDA,&TAU[0],&WORK[0],LWORK,&INFO);
104 lapack_.ORGQR(M,N,K,
X_.values(),LDA,&TAU[0],&WORK[0],LWORK,&INFO);
105 LWORK =
static_cast<int>(WORK[0]);
107 lapack_.ORGQR(M,N,K,
X_.values(),LDA,&TAU[0],&WORK[0],LWORK,&INFO);
116 std::vector<Real> normQ(
k_,0);
118 for (
int j = 0; j <
k_; ++j) {
120 if (rjj > ROL_EPSILON<Real>()) {
121 for (
int k = 0; k <
orthIt_; ++k) {
122 for (
int i = 0; i < j; ++i) {
123 rij = Y[i]->dot(*Y[j]);
124 Y[j]->axpy(-rij,*Y[i]);
126 normQ[j] = Y[j]->norm();
128 for (
int i = 0; i < j; ++i) {
129 rij = std::abs(Y[i]->dot(*Y[j]));
130 if (rij >
orthTol_*normQ[j]*normQ[i]) {
141 Y[j]->scale(one/rjj);
153 int LSsolver(LA::Matrix<Real> &A, LA::Matrix<Real> &B,
const bool trans =
false)
const {
155 char TRANS = (trans ?
'T' :
'N');
158 int NRHS = B.numCols();
160 int LDB = std::max(M,N);
161 std::vector<Real> WORK(1);
164 lapack_.GELS(TRANS,M,N,NRHS,A.values(),LDA,B.values(),LDB,&WORK[0],LWORK,&INFO);
166 LWORK =
static_cast<int>(WORK[0]);
168 lapack_.GELS(TRANS,M,N,NRHS,A.values(),LDA,B.values(),LDB,&WORK[0],LWORK,&INFO);
179 int K = std::min(M,N);
181 std::vector<Real> S(K);
182 LA::Matrix<Real> U(M,K);
184 LA::Matrix<Real> VT(K,N);
186 std::vector<Real> WORK(1), WORK0(1);
189 lapack_.GESVD(JOBU,JOBVT,M,N,A.values(),LDA,&S[0],U.values(),LDU,VT.values(),LDVT,&WORK[0],LWORK,&WORK0[0],&INFO);
190 LWORK =
static_cast<int>(WORK[0]);
192 lapack_.GESVD(JOBU,JOBVT,M,N,A.values(),LDA,&S[0],U.values(),LDU,VT.values(),LDVT,&WORK[0],LWORK,&WORK0[0],&INFO);
193 for (
int i = 0; i < M; ++i) {
194 for (
int j = 0; j < N; ++j) {
196 for (
int k = 0; k < r; ++k) {
197 A(i,j) += S[k] * U(i,k) * VT(k,j);
205 int infoP(0), infoQ(0), infoLS1(0), infoLS2(0), infoLRA(0);
210 LA::Matrix<Real> L(
s_,
k_), R(
s_,
k_);
211 for (
int i = 0; i <
s_; ++i) {
212 for (
int j = 0; j <
k_; ++j) {
213 L(i,j) =
Phi_[i]->dot(*
Y_[j]);
215 for (
int k = 0; k <
ncol_; ++k) {
216 R(i,j) +=
Psi_(k,i) *
X_(k,j);
222 LA::Matrix<Real> Z(s_,
k_);
223 for (
int i = 0; i <
k_; ++i) {
224 for (
int j = 0; j <
s_; ++j) {
229 for (
int i = 0; i <
k_; ++i) {
230 for (
int j = 0; j <
k_; ++j) {
241 return std::abs(infoP)+std::abs(infoQ)+std::abs(infoLS1)
242 +std::abs(infoLS2)+std::abs(infoLRA);
248 X_.scale(zero);
Z_.scale(zero);
C_.scale(zero);
249 for (
int i = 0; i <
s_; ++i) {
251 for (
int j = 0; j <
ncol_; ++j) {
252 Psi_(j,i) = (*dist_)(*gen_);
255 for (
int i = 0; i <
k_; ++i) {
258 for (
int j = 0; j <
ncol_; ++j) {
259 Omega_(j,i) = (*dist_)(*gen_);
290 const Real orthTol = 1e-8,
const int orthIt = 2,
291 const bool truncate =
false,
292 const unsigned dom_seed = 0,
const unsigned rng_seed = 0)
297 nrand_ = makePtr<Elementwise::NormalRandom<Real>>(mu,sig,dom_seed);
298 unsigned seed = rng_seed;
300 seed = std::chrono::system_clock::now().time_since_epoch().count();
302 gen_ = makePtr<std::mt19937_64>(seed);
303 dist_ = makePtr<std::normal_distribution<Real>>(mu,sig);
306 rank_ = std::min(rank, maxRank_);
307 k_ = std::min(2*rank_+1, maxRank_);
308 s_ = std::min(2*
k_ +1, maxRank_);
313 for (
int i = 0; i <
k_; ++i) {
317 for (
int i = 0; i <
s_; ++i) {
331 int sold =
s_, kold =
k_;
337 for (
int i = sold; i <
s_; ++i) {
342 for (
int i = kold; i <
k_; ++i) {
343 Y_.push_back(
Y_[0]->clone());
348 if (
out_ != nullPtr ) {
349 *
out_ << std::string(80,
'=') << std::endl;
350 *
out_ <<
" ROL::Sketch::setRank" << std::endl;
351 *
out_ <<
" **** Rank = " <<
rank_ << std::endl;
352 *
out_ <<
" **** k = " <<
k_ << std::endl;
353 *
out_ <<
" **** s = " <<
s_ << std::endl;
354 *
out_ << std::string(80,
'=') << std::endl;
368 if ( col >=
ncol_ || col < 0 ) {
373 for (
int i = 0; i <
k_; ++i) {
375 for (
int j = 0; j <
ncol_; ++j) {
385 for (
int i = 0; i <
s_; ++i) {
387 for (
int j = 0; j <
s_; ++j) {
389 Z_(i,j) += nu*
Psi_(col,j)*hphi;
392 if (
out_ != nullPtr ) {
393 *
out_ << std::string(80,
'=') << std::endl;
394 *
out_ <<
" ROL::Sketch::advance" << std::endl;
395 *
out_ <<
" **** col = " << col << std::endl;
396 *
out_ <<
" **** norm(h) = " << h.
norm() << std::endl;
397 *
out_ << std::string(80,
'=') << std::endl;
409 if ( col >=
ncol_ || col < 0 ) {
433 for (
int i = 0; i <
k_; ++i) {
435 for (
int j = 0; j <
k_; ++j) {
436 coeff +=
C_(i,j) *
X_(col,j);
440 if (
out_ != nullPtr ) {
441 *
out_ << std::string(80,
'=') << std::endl;
442 *
out_ <<
" ROL::Sketch::reconstruct" << std::endl;
443 *
out_ <<
" **** col = " << col << std::endl;
444 *
out_ <<
" **** norm(a) = " << a.
norm() << std::endl;
445 *
out_ << std::string(80,
'=') << std::endl;
450 bool test(
const int rank, std::ostream &outStream = std::cout,
const int verbosity = 0) {
451 const Real one(1), tol(std::sqrt(ROL_EPSILON<Real>()));
453 std::vector<Ptr<Vector<Real>>> U(rank);
454 LA::Matrix<Real>
V(
ncol_,rank);
455 for (
int i = 0; i < rank; ++i) {
456 U[i] =
Y_[0]->clone();
457 U[i]->randomize(-one,one);
458 for (
int j = 0; j <
ncol_; ++j) {
459 V(j,i) =
static_cast<Real
>(rand())/static_cast<Real>(RAND_MAX);
464 std::vector<Ptr<Vector<Real>>> A(
ncol_);
465 for (
int i = 0; i <
ncol_; ++i) {
466 A[i] =
Y_[0]->clone(); A[i]->zero();
467 for (
int j = 0; j < rank; ++j) {
468 A[i]->axpy(
V(i,j),*U[j]);
473 bool flagP =
testP(outStream, verbosity);
475 bool flagQ =
testQ(outStream, verbosity);
477 Real nerr(0), maxerr(0);
478 Ptr<Vector<Real>> err =
Y_[0]->clone();
479 for (
int i = 0; i <
ncol_; ++i) {
481 err->axpy(-one,*A[i]);
483 maxerr = (nerr > maxerr ? nerr : maxerr);
486 std::ios_base::fmtflags oflags(outStream.flags());
487 outStream << std::scientific << std::setprecision(3) << std::endl;
488 outStream <<
" TEST RECONSTRUCTION: Max Error = "
489 << std::setw(12) << std::right << maxerr
490 << std::endl << std::endl;
491 outStream.flags(oflags);
493 return flagP & flagQ & (maxerr < tol ?
true :
false);
499 bool testQ(std::ostream &outStream = std::cout,
const int verbosity = 0) {
500 const Real one(1), tol(std::sqrt(ROL_EPSILON<Real>()));
502 Real qij(0), err(0), maxerr(0);
503 std::ios_base::fmtflags oflags(outStream.flags());
505 outStream << std::scientific << std::setprecision(3);
508 outStream << std::endl
509 <<
" Printing Q'Q...This should be approximately equal to I"
510 << std::endl << std::endl;
512 for (
int i = 0; i <
k_; ++i) {
513 for (
int j = 0; j <
k_; ++j) {
514 qij =
Y_[i]->dot(*
Y_[j]);
515 err = (i==j ? std::abs(qij-one) : std::abs(qij));
516 maxerr = (err > maxerr ? err : maxerr);
518 outStream << std::setw(12) << std::right << qij;
522 outStream << std::endl;
529 outStream << std::endl <<
" TEST ORTHOGONALIZATION: Max Error = "
530 << std::setw(12) << std::right << maxerr
532 outStream.flags(oflags);
534 return (maxerr < tol ?
true :
false);
537 bool testP(std::ostream &outStream = std::cout,
const int verbosity = 0) {
538 const Real
zero(0), one(1), tol(std::sqrt(ROL_EPSILON<Real>()));
540 Real qij(0), err(0), maxerr(0);
541 std::ios_base::fmtflags oflags(outStream.flags());
543 outStream << std::scientific << std::setprecision(3);
546 outStream << std::endl
547 <<
" Printing P'P...This should be approximately equal to I"
548 << std::endl << std::endl;
550 for (
int i = 0; i <
k_; ++i) {
551 for (
int j = 0; j <
k_; ++j) {
553 for (
int k = 0; k <
ncol_; ++k) {
554 qij +=
X_(k,i) *
X_(k,j);
556 err = (i==j ? std::abs(qij-one) : std::abs(qij));
557 maxerr = (err > maxerr ? err : maxerr);
559 outStream << std::setw(12) << std::right << qij;
563 outStream << std::endl;
570 outStream << std::endl <<
" TEST ORTHOGONALIZATION: Max Error = "
571 << std::setw(12) << std::right << maxerr
573 outStream.flags(oflags);
575 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.
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()
int advance(const Real nu, Vector< Real > &h, const int col, const Real eta=1.0)
int lowRankApprox(LA::Matrix< Real > &A, const int r) const
bool testQ(std::ostream &outStream=std::cout, const int verbosity=0)
Sketch(const Vector< Real > &x, const int ncol, const int rank, const Real orthTol=1e-8, const int orthIt=2, const bool truncate=false, const unsigned dom_seed=0, const unsigned rng_seed=0)
void setRank(const int rank)
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_
virtual Real norm() const =0
Returns where .
std::vector< Ptr< Vector< Real > > > Phi_
int LSsolver(LA::Matrix< Real > &A, LA::Matrix< Real > &B, const bool trans=false) const