ROL
ROL_Lanczos.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ************************************************************************
3 //
4 // Rapid Optimization Library (ROL) Package
5 // Copyright (2014) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact lead developers:
38 // Drew Kouri (dpkouri@sandia.gov) and
39 // Denis Ridzal (dridzal@sandia.gov)
40 //
41 // ************************************************************************
42 // @HEADER
43 
44 #ifndef ROL_LANCZOS_H
45 #define ROL_LANCZOS_H
46 
47 #include "ROL_Krylov.hpp"
48 #include "ROL_LinearOperator.hpp"
49 #include "ROL_Vector.hpp"
50 #include "ROL_Types.hpp"
51 
52 #include "Teuchos_LAPACK.hpp"
53 
54 namespace ROL {
55 
64 template<class Real>
65 class Lanczos {
66 
67  template <typename T> using RCP = Teuchos::RCP<T>;
68  template <typename T> using vector = std::vector<T>;
69 
70  template typename vector<Real> size_type uint;
71 
72  typedef Vector<Real> V;
74 
75  typedef Teuchos::ParameterList PL;
76 
77 private:
78 
79  Teuchos::LAPACK<int,Real> lapack_;
80 
81  vector<RCP<V> > Q_; // Orthogonal basis
82  vector<Real> alpha_; // Diagonal recursion coefficients
83  vector<Real> beta_; // Sub/super-diagonal recursion coefficients
84 
85  // Temporary vectors for factorizations, linear solves, and eigenvalue calculations
90  vector<Real> y_; // Arnoldi expansion coefficients
91 
92  vector<Real> work_; // Scratch space for eigenvalue decomposition
93  vector<int> ipiv_; // Pivots for LU
94 
95  RCP<V> u_; // An auxilliary vector
96 
97  Real max_beta_; // maximum beta encountered
98  Real tol_beta_; // relative smallest beta allowed
99 
100  Real tol_ortho_; // Maximum orthogonality loss tolerance
101 
102  int maxit_; // Maximum number of vectors to store
103 
104  int k_; // current iterate number
105 
106 
107  // Allocte memory for Arnoldi vectors and recurions coefficients
108  void allocate( void ) {
109 
110  u_ = b.clone();
111 
112  alpha_.reserve(maxit_);
113  beta_.reserve(maxit_);
114 
115  dl_.reserve(maxit_);
116  d_.reserve(maxit_);
117  du_.reserve(maxit_);
118  du2_.reserve(maxit_);
119 
120  work_.reserve(4*maxit_);
121 
122  ipiv_.reserve(maxit_);
123 
124  y_.reserve(maxit_);
125 
126  alpha_.reserve(maxit_);
127  beta_.reserve(maxit_);
128 
129  for( uint j=0; j<maxit_; ++j ) {
130  Q_.push_back(b.clone());
131  }
132  }
133 
134 public:
135 
136  enum class FLAG_ITERATE : unsigned {
137  ITERATE_SUCCESS = 0,
138  ITERATE_SMALL_BETA, // Beta too small to continue
139  ITERATE_MAX_REACHED, // Reached maximum number of iterations
140  ITERATE_ORTHO_TOL, // Reached maximim orthogonality loss
142  };
143 
144  enum class FLAG_SOLVE : unsigned {
145  SOLVE_SUCCESS = 0,
146  SOLVE_ILLEGAL_VALUE,
147  SOLVE_SINGULAR_U,
148  SOLVE_LAST
149  };
150 
151 
152  Lanczos( Teuchos::ParameterList &PL ) {
153  PL &krylovList = parlist.sublist("General").sublist("Krylov");
154  PL &lanczosList = krylovList.sublist("Lanczos");
155 
156  Real tol_default = std::sqrt(ROL_EPSILON<Real>());
157 
158  maxit_ = krylovList_.get("Iteration Limit",10);
159  tol_beta_ = lanczosList.get("Beta Relative Tolerance", tol_default);
160  tol_ortho_ = lanczosList.get("Orthogonality Tolerance", tol_default);
161 
162  }
163 
164  void initialize( const V& b ) {
165  allocate();
166  reset(b);
167 
168  }
169 
170  void initialize( const V &x0, const V &b, const LO &A, Real &tol ) {
171  allocate();
172  reset(x0,b,A,tol);
173 
174  }
175 
176 
177  void reset( const V &b ) {
178  k_ = 0;
179  max_beta_ = 0;
180  Q_[0]->set(b);
181  beta_[0] = Q_[0]->norm();
182  max_beta_ = std::max(max_beta_,beta_[0]);
183  Q_[0]->scale(1.0/beta_[0]);
184  }
185 
186  void reset( const V &x0, const V &b, const LO &A, Real &tol ) {
187  k_ = 0;
188  max_beta_ = 0;
189  Q_[0]->set(b);
190  A.apply(*u_,x0,tol);
191  Q_[0]->axpy(-1.0,*u_);
192  beta_[0] = Q_[0]->norm();
193  max_beta_ = std::max(max_beta_,beta_[0]);
194  Q_[0]->scale(1.0/beta_[0]);
195  }
196 
197  FLAG_ITERATE iterate( const OP &A, Real &tol ) {
198 
199  if( k_ == maxit_ ) {
200  return ITERATE_MAX_REACHED;
201  }
202 
203  A.apply(*u_,*(Q_[k]),tol);
204  Real delta;
205 
206  if( k_>0 ) {
207  u_->axpy(-beta_[k],V_[k_-1]);
208  }
209  alpha_[k] = u_->dot(*(V_[k]));
210  u_->axpy(alpha_[k],V_[k_]);
211 
212  if( k_>0 ) {
213  delta = u_->dot(*(V_[k-1]));
214  u_->axpy(-delta,*(V_[k-1]));
215  }
216  delta = u_->dot(*(V_[k]));
217  alpha_[k] += delta;
218 
219  if( k_ < maxit_-1 ) {
220  u_->axpy(-delta,*(V_[k_]));
221  beta_[k+1] = u_->norm();
222  max_beta_ = std::max(max_beta_,beta_[k+1]);
223  if(beta_[k+1] < tol_beta_*max_beta_) {
224  return ITERATE_SMALL_BETA;
225  }
226 
227  V_[k+1]->set(*u_);
228  V_[k+1]->scale(1.0/beta_[k+1]);
229 
230  // Check orthogonality
231  Real dotprod = V_[k+1]->dot(*(V_[0]));
232 
233  if( std::sqrt(dotprod) > tol_ortho_ ) {
234  return ITERATE_ORTHO_TOL;
235  }
236  }
237 
238  ++k_;
239  return ITERATE_SUCCESS;
240  }
241 
242  // Compute the eigenvalues of the tridiagonal matrix T
243  void eigenvalues( std::vector<Real> &E ) {
244 
245  std::vector<Real> Z(1,0); // Don't compute eigenvectors
246 
247  int INFO;
248  int LDZ = 0;
249  const char COMPZ = 'N':
250  d_ = alpha_;
251  du_ = beta_;
252 
253  lapack_->STEQR(COMPZ,k_,&d_[0],&du_[0],&Z[0],LDZ,&work_[0],&INFO);
254 
255  if( INFO < 0 ) {
256  return SOLVE_ILLEGAL_VALUE;
257  }
258  else if( INFO > 0 ) {
259  return SOLVE_SINGULAR_U;
260  }
261 
262  }
263 
264  FLAG_SOLVE solve( V &x, Real tau=0 ) {
265 
266  const char TRANS = 'N';
267  const int NRHS = 1;
268  int INFO;
269 
270  // Fill arrays
271  for(uint j=0;j<k_;++j) {
272  d_[j] = alpha_[j]+tau;
273  }
274 
275  dl_ = beta_;
276  du_ = beta_;
277  du2_.assign(maxit_,0);
278 
279  // Do Tridiagonal LU factorization
280  lapack_->GTTRF(k_,&dl_[0],&d_[0],&du_[0],&du2_[0],&ipiv_[0],&INFO);
281 
282  // Solve the factorized system for Arnoldi expansion coefficients
283  lapack_->GTTRS(TRANS,k_,1,&dl[0],&d_[0],&du_[0],&du2_[0],&ipiv_[0],&y_[0],k_,&INFO);
284 
285  }
286 
287 
288 
289 }; // class LanczosFactorization
290 } // namespace ROL
291 
292 #endif // ROL_LANCZOS_H
void reset(const V &x0, const V &b, const LO &A, Real &tol)
vector< Real > y_
Definition: ROL_Lanczos.hpp:90
FLAG_SOLVE solve(V &x, Real tau=0)
std::vector< T > vector
Definition: ROL_Lanczos.hpp:68
vector< Real > work_
Definition: ROL_Lanczos.hpp:92
vector< Real > alpha_
Definition: ROL_Lanczos.hpp:82
Contains definitions of custom data types in ROL.
vector< int > ipiv_
Definition: ROL_Lanczos.hpp:93
LinearOperator< Real > OP
Definition: ROL_Lanczos.hpp:73
virtual void apply(Vector< Real > &Hv, const Vector< Real > &v, Real &tol) const =0
Apply linear operator.
Teuchos::LAPACK< int, Real > lapack_
Definition: ROL_Lanczos.hpp:79
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:76
Teuchos::RCP< T > RCP
Definition: ROL_Lanczos.hpp:67
FLAG_ITERATE iterate(const OP &A, Real &tol)
RCP< V > u_
Definition: ROL_Lanczos.hpp:95
Interface for computing the Lanczos vectors and approximate solutions to symmetric indefinite linear ...
Definition: ROL_Lanczos.hpp:65
vector< Real > du_
Definition: ROL_Lanczos.hpp:88
Provides the interface to apply a linear operator.
vector< RCP< V > > Q_
Definition: ROL_Lanczos.hpp:81
Vector< Real > V
Definition: ROL_Lanczos.hpp:72
void initialize(const V &b)
vector< Real > dl_
Definition: ROL_Lanczos.hpp:86
vector< Real > d_
Definition: ROL_Lanczos.hpp:87
Teuchos::ParameterList PL
Definition: ROL_Lanczos.hpp:75
template vector< Real > size_type uint
Definition: ROL_Lanczos.hpp:70
void allocate(void)
void initialize(const V &x0, const V &b, const LO &A, Real &tol)
vector< Real > du2_
Definition: ROL_Lanczos.hpp:89
vector< Real > beta_
Definition: ROL_Lanczos.hpp:83
void reset(const V &b)
Lanczos(Teuchos::ParameterList &PL)
void eigenvalues(std::vector< Real > &E)