ROL
step/krylov/test_01.cpp
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 
48 #include "ROL_StdVector.hpp"
49 #include "ROL_GMRES.hpp"
50 #include "ROL_KrylovFactory.hpp"
51 #include "ROL_RandomVector.hpp"
52 #include "ROL_ParameterList.hpp"
53 
54 #include "ROL_Stream.hpp"
55 #include "Teuchos_GlobalMPISession.hpp"
56 
57 #include<iomanip>
58 
59 // Identity operator for preconditioner
60 template<class Real>
61 class Identity : public ROL::LinearOperator<Real> {
63 public:
64  void apply( V& Hv, const V& v, Real &tol ) const {
65  Hv.set(v);
66  }
67 }; // class Identity
68 
69 
70 // Apply a tridiagonal Toeplitz matrix to a ROL::StdVector to test Krylov solvers
71 template<class Real>
73 
74  typedef std::vector<Real> vector;
77 
78  typedef typename vector::size_type uint;
79 
80 private:
81 
82  Real a_; // subdiagonal
83  Real b_; // diagonal
84  Real c_; // superdiagonal
85 
86  ROL::LAPACK<int,Real> lapack_;
87 
88 public:
89 
90  TridiagonalToeplitzOperator( Real &a, Real &b, Real &c ) : a_(a), b_(b), c_(c) {}
91 
92  // Tridiagonal multiplication
93  void apply( V &Hv, const V &v, Real &tol ) const {
94 
95 
96 
97  SV &Hvs = dynamic_cast<SV&>(Hv);
98  ROL::Ptr<vector> Hvp = Hvs.getVector();
99 
100  const SV &vs = dynamic_cast<const SV&>(v);
101  ROL::Ptr<const vector> vp = vs.getVector();
102 
103  uint n = vp->size();
104 
105  (*Hvp)[0] = b_*(*vp)[0] + c_*(*vp)[1];
106 
107  for(uint k=1; k<n-1; ++k) {
108  (*Hvp)[k] = a_*(*vp)[k-1] + b_*(*vp)[k] + c_*(*vp)[k+1];
109  }
110 
111  (*Hvp)[n-1] = a_*(*vp)[n-2] + b_*(*vp)[n-1];
112 
113  }
114 
115  // Tridiagonal solve - compare against GMRES
116  void applyInverse( V &Hv, const V &v, Real &tol ) const {
117 
118 
119 
120  SV &Hvs = dynamic_cast<SV&>(Hv);
121  ROL::Ptr<vector> Hvp = Hvs.getVector();
122 
123  const SV &vs = dynamic_cast<const SV&>(v);
124  ROL::Ptr<const vector> vp = vs.getVector();
125 
126  uint n = vp->size();
127 
128  const char TRANS = 'N';
129  const int NRHS = 1;
130 
131  vector dl(n-1,a_);
132  vector d(n,b_);
133  vector du(n-1,c_);
134  vector du2(n-2,0.0);
135 
136  std::vector<int> ipiv(n);
137  int info;
138 
139  Hv.set(v); // LAPACK will modify this in place
140 
141  // Do Tridiagonal LU factorization
142  lapack_.GTTRF(n,&dl[0],&d[0],&du[0],&du2[0],&ipiv[0],&info);
143 
144  // Solve the system with the LU factors
145  lapack_.GTTRS(TRANS,n,NRHS,&dl[0],&d[0],&du[0],&du2[0],&ipiv[0],&(*Hvp)[0],n,&info);
146 
147  }
148 
149 }; // class TridiagonalToeplitzOperator
150 
151 
152 
153 typedef double RealT;
154 
155 int main(int argc, char *argv[]) {
156 
157 
158 
159 
160  typedef std::vector<RealT> vector;
161  typedef ROL::StdVector<RealT> SV;
162 
163  typedef typename vector::size_type uint;
164 
165  Teuchos::GlobalMPISession mpiSession(&argc, &argv);
166 
167  int iprint = argc - 1;
168  ROL::Ptr<std::ostream> outStream;
169  ROL::nullstream bhs; // outputs nothing
170  if (iprint > 0)
171  outStream = ROL::makePtrFromRef(std::cout);
172  else
173  outStream = ROL::makePtrFromRef(bhs);
174 
175  int errorFlag = 0;
176 
177  try {
178 
179  ROL::ParameterList parlist;
180  ROL::ParameterList &gList = parlist.sublist("General");
181  ROL::ParameterList &kList = gList.sublist("Krylov");
182 
183  kList.set("Type","GMRES");
184  kList.set("Iteration Limit",20);
185  kList.set("Absolute Tolerance",1.e-8);
186  kList.set("Relative Tolerance",1.e-6);
187  kList.set("Use Initial Guess",false);
188 
189  uint dim = 10;
190 
191  ROL::Ptr<vector> xp = ROL::makePtr<vector>(dim,0.0);
192  ROL::Ptr<vector> yp = ROL::makePtr<vector>(dim,0.0);
193  ROL::Ptr<vector> zp = ROL::makePtr<vector>(dim,0.0);
194  ROL::Ptr<vector> bp = ROL::makePtr<vector>(dim,0.0);
195 
196  SV x(xp); // Exact solution
197  SV y(yp); // Solution using direct solve
198  SV z(zp); // Solution using GMRES
199 
200  SV b(bp); // Right-hand-side
201 
202  RealT left = -1.0;
203  RealT right = 1.0;
204 
205  ROL::RandomizeVector(x,left,right);
206 
207  RealT sub = -1.0;
208  RealT diag = 2.0;
209  RealT super = -1.0;
210 
211  TridiagonalToeplitzOperator<RealT> T(sub,diag,super);
212  Identity<RealT> I;
213 
214  RealT tol = 0.0;
215 
216  T.apply(b,x,tol);
217 
218  T.applyInverse(y,b,tol);
219 
220  ROL::Ptr<ROL::Krylov<RealT> > krylov = ROL::KrylovFactory<RealT>( parlist );
221 
222  int iter;
223  int flag;
224 
225  krylov->run(z,T,b,I,iter,flag);
226 
227  *outStream << std::setw(10) << "Exact"
228  << std::setw(10) << "LAPACK"
229  << std::setw(10) << "GMRES " << std::endl;
230  *outStream << "---------------------------------" << std::endl;
231 
232  for(uint k=0;k<dim;++k) {
233  *outStream << std::setw(10) << (*xp)[k] << " "
234  << std::setw(10) << (*yp)[k] << " "
235  << std::setw(10) << (*zp)[k] << " " << std::endl;
236  }
237 
238  *outStream << "GMRES performed " << iter << " iterations." << std::endl;
239 
240  z.axpy(-1.0,x);
241 
242  if( z.norm() > std::sqrt(ROL::ROL_EPSILON<RealT>()) ) {
243  ++errorFlag;
244  }
245 
246  }
247  catch (std::logic_error& err) {
248  *outStream << err.what() << "\n";
249  errorFlag = -1000;
250  }; // end try
251 
252  if (errorFlag != 0)
253  std::cout << "End Result: TEST FAILED\n";
254  else
255  std::cout << "End Result: TEST PASSED\n";
256 
257  return 0;
258 }
typename PV< Real >::size_type size_type
Ptr< const std::vector< Element > > getVector() const
void RandomizeVector(Vector< Real > &x, const Real &lower=0.0, const Real &upper=1.0)
Fill a ROL::Vector with uniformly-distributed random numbers in the interval [lower,upper].
void apply(V &Hv, const V &v, Real &tol) const
Apply linear operator.
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:80
Defines a no-output stream class ROL::NullStream and a function makeStreamPtr which either wraps a re...
void apply(V &Hv, const V &v, Real &tol) const
Apply linear operator.
TridiagonalToeplitzOperator(Real &a, Real &b, Real &c)
ROL::LAPACK< int, Real > lapack_
Provides the interface to apply a linear operator.
void applyInverse(V &Hv, const V &v, Real &tol) const
Apply inverse of linear operator.
basic_nullstream< char, char_traits< char >> nullstream
Definition: ROL_Stream.hpp:72
int main(int argc, char *argv[])
virtual void set(const Vector &x)
Set where .
Definition: ROL_Vector.hpp:209
constexpr auto dim
ROL::Vector< Real > V