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