ROL
ROL_StdLinearOperator.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_STDLINEAROPERATOR_H
45 #define ROL_STDLINEAROPERATOR_H
46 
47 #include "ROL_LinearOperator.hpp"
48 #include "ROL_StdVector.hpp"
49 
50 #include "Teuchos_BLAS.hpp"
51 #include "Teuchos_LAPACK.hpp"
52 
63 namespace ROL {
64 
65 template <class Real>
66 class StdLinearOperator : public LinearOperator<Real> {
67 
68  template <typename T> using RCP = Teuchos::RCP<T>;
69 
71 
72  typedef std::vector<Real> vector;
73 
74 private:
75 
77  int N_;
78  int INFO_;
79 
80  mutable vector PLU_;
81  mutable std::vector<int> ipiv_;
82 
83  Teuchos::BLAS<int,Real> blas_;
84  Teuchos::LAPACK<int,Real> lapack_;
85 
86 public:
87 
89 
90  StdLinearOperator( RCP<std::vector<Real> > &A ) : A_(A) {
91  int N2 = A_->size();
92  N_ = (std::round(std::sqrt(N2)));
93  bool isSquare = N_*N_ == N2;
94  TEUCHOS_TEST_FOR_EXCEPTION( !isSquare, std::invalid_argument,
95  "Error: vector representation of matrix must have a square "
96  "number of elements.");
97  ipiv_.reserve(N_);
98  }
99 
100  virtual ~StdLinearOperator() {}
101 
103  void update( const Vector<Real> &x, bool flag = true, int iter = -1 ) {
104  RCP<const vector> xp = Teuchos::dyn_cast<const SV>(x).getVector();
105  update(*xp,flag,iter);
106  }
107 
108  virtual void update( const std::vector<Real> &x, bool flag = true, int iter = -1 ) {}
109 
110  // Matrix multiplication
112  void apply( Vector<Real> &Hv, const Vector<Real> &v, Real &tol ) const {
113  using Teuchos::dyn_cast;
114  RCP<vector> Hvp = dyn_cast<SV>(Hv).getVector();
115  RCP<const vector> vp = dyn_cast<const SV>(v).getVector();
116  apply(*Hvp,*vp,tol);
117  }
118 
119  virtual void apply( std::vector<Real> &Hv, const std::vector<Real> &v, Real &tol ) const {
120  int LDA = N_;
121 
122  blas_.GEMV(Teuchos::NO_TRANS,N_,N_,1.0,&(*A_)[0],LDA,&(v)[0],1,0.0,&(Hv)[0],1);
123  }
124 
125  // Matrix multiplication with transpose
127  void applyAdjoint( Vector<Real> &Hv, const Vector<Real> &v, Real &tol ) const {
128  using Teuchos::dyn_cast;
129  RCP<vector> Hvp = dyn_cast<SV>(Hv).getVector();
130  RCP<const vector> vp = dyn_cast<const SV>(v).getVector();
131  applyAdjoint(*Hvp,*vp,tol);
132  }
133 
134  virtual void applyAdjoint( std::vector<Real> &Hv, const std::vector<Real> &v, Real &tol ) const {
135  int LDA = N_;
136 
137  blas_.GEMV(Teuchos::TRANS,N_,N_,1.0,&(*A_)[0],LDA,&(v)[0],1,0.0,&(Hv)[0],1);
138  }
139 
140 
141  // Solve the system
142 
144  void applyInverse( Vector<Real> &Hv, const Vector<Real> &v, Real &tol ) const {
145  using Teuchos::dyn_cast;
146  RCP<vector> Hvp = dyn_cast<SV>(Hv).getVector();
147  RCP<const vector> vp = dyn_cast<const SV>(v).getVector();
148  applyInverse(*Hvp,*vp,tol);
149  }
150 
151  virtual void applyInverse( std::vector<Real> &Hv, const std::vector<Real> &v, Real &tol ) const {
152 
153  const int LDA = N_;
154  const int LDB = N_;
155  int INFO;
156  int NRHS = 1;
157 
158  Hv = v;
159  PLU_ = *A_;
160 
161  // Do LU factorization
162  lapack_.GETRF(N_,N_,&PLU_[0],LDA,&ipiv_[0],&INFO);
163 
164  TEUCHOS_TEST_FOR_EXCEPTION(INFO>0,std::logic_error,"Error in StdLinearOperator::applyInverse(): "
165  "Zero diagonal element encountered in matrix factor U(" << INFO << "," << INFO << ").");
166 
167  TEUCHOS_TEST_FOR_EXCEPTION(INFO<0,std::logic_error,"Error in StdLinearOperator::applyInverse(): "
168  "Illegal value encountered in element " << -INFO << " when performing LU factorization.");
169 
170  // Solve factored system
171  lapack_.GETRS('N',N_,NRHS,&PLU_[0],LDA,&ipiv_[0],&Hv[0],LDB,&INFO);
172 
173  TEUCHOS_TEST_FOR_EXCEPTION(INFO<0,std::logic_error,"Error in StdLinearOperator::applyInverse(): "
174  "Illegal value encountered in element " << -INFO << " when solving the factorized system. ");
175 
176  }
177 
178  // Solve the system with transposed matrix
179 
181  void applyAdjointInverse( Vector<Real> &Hv, const Vector<Real> &v, Real &tol ) const {
182  using Teuchos::dyn_cast;
183  RCP<vector> Hvp = dyn_cast<SV>(Hv).getVector();
184  RCP<const vector> vp = dyn_cast<const SV>(v).getVector();
185  applyAdjointInverse(*Hvp,*vp,tol);
186  }
187 
188  virtual void applyAdjointInverse( std::vector<Real> &Hv, const std::vector<Real> &v, Real &tol ) const {
189 
190  const int LDA = N_;
191  const int LDB = N_;
192  int INFO;
193  int NRHS = 1;
194 
195  Hv = v;
196  PLU_ = *A_;
197 
198  // Do LU factorization
199  lapack_.GETRF(N_,N_,&PLU_[0],LDA,&ipiv_[0],&INFO);
200 
201  TEUCHOS_TEST_FOR_EXCEPTION(INFO>0,std::logic_error,"Error in StdLinearOperator::applyAdjointInverse(): "
202  "Zero diagonal element encountered in matrix factor U(" << INFO << "," << INFO << ").");
203 
204  TEUCHOS_TEST_FOR_EXCEPTION(INFO<0,std::logic_error,"Error in StdLinearOperator::applyAdjointInverse(): "
205  "Illegal value encountered in element " << -INFO << " when performing LU factorization.");
206 
207  // Solve factored system
208  lapack_.GETRS('T',N_,NRHS,&PLU_[0],LDA,&ipiv_[0],&Hv[0],LDB,&INFO);
209 
210  TEUCHOS_TEST_FOR_EXCEPTION(INFO<0,std::logic_error,"Error in StdLinearOperator::applyAdjointInverse(): "
211  "Illegal value encountered in element " << -INFO << " when solving the factorized system. ");
212 
213  }
214 
215 }; // class LinearOperator
216 
217 } // namespace ROL
218 
219 #endif
Provides the std::vector implementation to apply a linear operator, which is a std::vector representa...
void apply(Vector< Real > &Hv, const Vector< Real > &v, Real &tol) const
Apply linear operator.
void applyInverse(Vector< Real > &Hv, const Vector< Real > &v, Real &tol) const
Apply inverse of linear operator.
virtual void applyAdjoint(std::vector< Real > &Hv, const std::vector< Real > &v, Real &tol) const
StdLinearOperator(RCP< std::vector< Real > > &A)
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:76
void applyAdjointInverse(Vector< Real > &Hv, const Vector< Real > &v, Real &tol) const
Apply adjoint of the inverse linear operator.
void update(const Vector< Real > &x, bool flag=true, int iter=-1)
Update linear operator.
Provides the interface to apply a linear operator.
virtual void applyInverse(std::vector< Real > &Hv, const std::vector< Real > &v, Real &tol) const
void applyAdjoint(Vector< Real > &Hv, const Vector< Real > &v, Real &tol) const
Apply adjoint of linear operator.
Teuchos::BLAS< int, Real > blas_
Teuchos::LAPACK< int, Real > lapack_
virtual void update(const std::vector< Real > &x, bool flag=true, int iter=-1)
virtual void applyAdjointInverse(std::vector< Real > &Hv, const std::vector< Real > &v, Real &tol) const
virtual void apply(std::vector< Real > &Hv, const std::vector< Real > &v, Real &tol) const
RCP< std::vector< Real > > A_