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_VECTOR_SIMOPT_HPP
45 #define ROL_VECTOR_SIMOPT_HPP
46 
47 #include "ROL_Vector.hpp"
48 
49 /** @ingroup la_group
50     \class ROL::Vector_SimOpt
51     \brief Defines the linear algebra or vector space interface for simulation-based optimization.
52 */
53 
54 namespace ROL {
55 
56 template<class Real>
57 class Vector_SimOpt : public Vector<Real> {
58 private:
59   ROL::Ptr<Vector<Real> > vec1_;
60   ROL::Ptr<Vector<Real> > vec2_;
61   mutable ROL::Ptr<Vector<Real> > dual_vec1_;
62   mutable ROL::Ptr<Vector<Real> > dual_vec2_;
63   mutable ROL::Ptr<Vector_SimOpt<Real> > dual_vec_;
64 
65 public:
Vector_SimOpt(const ROL::Ptr<Vector<Real>> & vec1,const ROL::Ptr<Vector<Real>> & vec2)66   Vector_SimOpt( const ROL::Ptr<Vector<Real> > &vec1, const ROL::Ptr<Vector<Real> > &vec2 )
67     : vec1_(vec1), vec2_(vec2) {
68     dual_vec1_ = (vec1_->dual()).clone();
69     dual_vec2_ = (vec2_->dual()).clone();
70   }
71 
plus(const Vector<Real> & x)72   void plus( const Vector<Real> &x ) {
73     const Vector_SimOpt<Real> &xs = dynamic_cast<const Vector_SimOpt<Real>&>(
74       dynamic_cast<const Vector<Real>&>(x));
75     vec1_->plus(*(xs.get_1()));
76     vec2_->plus(*(xs.get_2()));
77   }
78 
scale(const Real alpha)79   void scale( const Real alpha ) {
80     vec1_->scale(alpha);
81     vec2_->scale(alpha);
82   }
83 
axpy(const Real alpha,const Vector<Real> & x)84   void axpy( const Real alpha, const Vector<Real> &x ) {
85     const Vector_SimOpt<Real> &xs = dynamic_cast<const Vector_SimOpt<Real>&>(
86       dynamic_cast<const Vector<Real>&>(x));
87     vec1_->axpy(alpha,*(xs.get_1()));
88     vec2_->axpy(alpha,*(xs.get_2()));
89   }
90 
dot(const Vector<Real> & x) const91   Real dot( const Vector<Real> &x ) const {
92     const Vector_SimOpt<Real> &xs = dynamic_cast<const Vector_SimOpt<Real>&>(
93       dynamic_cast<const Vector<Real>&>(x));
94     return vec1_->dot(*(xs.get_1())) + vec2_->dot(*(xs.get_2()));
95   }
96 
norm() const97   Real norm() const {
98     Real norm1 = vec1_->norm();
99     Real norm2 = vec2_->norm();
100     return sqrt( norm1*norm1 + norm2*norm2 );
101   }
102 
clone() const103   ROL::Ptr<Vector<Real> > clone() const {
104     return ROL::makePtr<Vector_SimOpt>(vec1_->clone(),vec2_->clone());
105   }
106 
dual(void) const107   const Vector<Real> & dual(void) const {
108     dual_vec1_->set(vec1_->dual());
109     dual_vec2_->set(vec2_->dual());
110     dual_vec_ = ROL::makePtr<Vector_SimOpt<Real>>(dual_vec1_,dual_vec2_);
111     return *dual_vec_;
112   }
113 
basis(const int i) const114   ROL::Ptr<Vector<Real> > basis( const int i )  const {
115     int n1 = (vec1_)->dimension();
116     if ( i < n1 ) {
117       ROL::Ptr<Vector<Real> > e1 = (vec1_)->basis(i);
118       ROL::Ptr<Vector<Real> > e2 = (vec2_)->clone(); e2->zero();
119       ROL::Ptr<Vector<Real> > e  = ROL::makePtr<Vector_SimOpt<Real>>(e1,e2);
120       return e;
121     }
122     else {
123       ROL::Ptr<Vector<Real> > e1 = (vec1_)->clone(); e1->zero();
124       ROL::Ptr<Vector<Real> > e2 = (vec2_)->basis(i-n1);
125       ROL::Ptr<Vector<Real> > e  = ROL::makePtr<Vector_SimOpt<Real>>(e1,e2);
126       return e;
127     }
128   }
129 
applyUnary(const Elementwise::UnaryFunction<Real> & f)130   void applyUnary( const Elementwise::UnaryFunction<Real> &f ) {
131 
132     vec1_->applyUnary(f);
133     vec2_->applyUnary(f);
134 
135   }
136 
applyBinary(const Elementwise::BinaryFunction<Real> & f,const Vector<Real> & x)137   void applyBinary( const Elementwise::BinaryFunction<Real> &f, const Vector<Real> &x ) {
138     const Vector_SimOpt<Real> &xs = dynamic_cast<const Vector_SimOpt<Real>&>(x);
139 
140     vec1_->applyBinary(f,*xs.get_1());
141     vec2_->applyBinary(f,*xs.get_2());
142 
143   }
144 
reduce(const Elementwise::ReductionOp<Real> & r) const145   Real reduce( const Elementwise::ReductionOp<Real> &r ) const {
146 
147     Real result = r.initialValue();
148     r.reduce(vec1_->reduce(r),result);
149     r.reduce(vec2_->reduce(r),result);
150     return result;
151   }
152 
setScalar(const Real C)153   void setScalar( const Real C ) {
154     vec1_->setScalar(C);
155     vec2_->setScalar(C);
156   }
157 
randomize(const Real l=0.0,const Real u=1.0)158   void randomize( const Real l=0.0, const Real u=1.0 ) {
159     vec1_->randomize(l,u);
160     vec2_->randomize(l,u);
161   }
162 
163 
dimension() const164   int dimension() const {
165     return (vec1_)->dimension() + (vec2_)->dimension();
166   }
167 
get_1() const168   ROL::Ptr<const Vector<Real> > get_1() const {
169     return vec1_;
170   }
171 
get_2() const172   ROL::Ptr<const Vector<Real> > get_2() const {
173     return vec2_;
174   }
175 
get_1()176   ROL::Ptr<Vector<Real> > get_1() {
177     return vec1_;
178   }
179 
get_2()180   ROL::Ptr<Vector<Real> > get_2() {
181     return vec2_;
182   }
183 
set_1(const Vector<Real> & vec)184   void set_1(const Vector<Real>& vec) {
185     vec1_->set(vec);
186   }
187 
set_2(const Vector<Real> & vec)188   void set_2(const Vector<Real>& vec) {
189     vec2_->set(vec);
190   }
191 
print(std::ostream & outStream) const192   void print( std::ostream &outStream ) const {
193     outStream << "Sim: ";
194     vec1_->print(outStream);
195     outStream << "Opt: ";
196     vec2_->print(outStream);
197   }
198 };
199 
200 template<template<typename> class V, typename Real, typename P = Ptr<Vector<Real>>>
201 inline typename std::enable_if<std::is_base_of<Vector<Real>,V<Real>>::value,P>::type
make_Vector_SimOpt(const Ptr<V<Real>> & vsim,const Ptr<V<Real>> & vopt)202 make_Vector_SimOpt( const Ptr<V<Real>>& vsim, const Ptr<V<Real>>& vopt ) {
203   return makePtr<Vector_SimOpt<Real>>(vsim,vopt);
204 }
205 
206 } // namespace ROL
207 
208 #endif
209