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 
45 #pragma once
46 #ifndef ROL_SCALEDVECTOR_HPP
47 #define ROL_SCALEDVECTOR_HPP
48 
49 /** @ingroup la_group
50     \class ROL::PrimalScaledVector
51     \brief Provides the implementation of the ROL::Vector interface
52            that handles scalings in the inner product. A more generic version
53            of ROL::PrimalScaledStdVector
54 */
55 
56 /** @ingroup la_group
57     \class ROL::DualScaledVector
58     \brief Provides the implementation of the ROL::Vector interface
59            that handles scalings in the inner product. A more generic version
60            of ROL::PrimalScaledStdVector
61 */
62 
63 #include "ROL_WrappedVector.hpp"
64 #include "ROL_VectorWorkspace.hpp"
65 
66 namespace ROL {
67 
68 // Forward declaration
69 template<typename Real> class PrimalScaledVector;
70 template<typename Real> class DualScaledVector;
71 
72 template<typename Real>
73 class PrimalScaledVector : public WrappedVector<Real> {
74 
75   using V     = Vector<Real>;
76   using VPrim = PrimalScaledVector<Real>;
77   using VDual = DualScaledVector<Real>;
78 
79 private:
80 
81   mutable Ptv<V>  scaling_vec_;
82   mutable VectorWorkspace<Real> workspace_;
83 
84   Elementwise::Multiply<Real> mult_;
85 
86 protected:
87 
getWorkspace() const88   VectorWorkspace<Real>& getWorkspace() const { return workspace_; }
89 
90   //  y <- y*x elementwise
multiply_scaling(const Ptr<V> & y) const91   void multiply_scaling( const Ptr<V>& y ) const {
92     y->applyBinary( mult_, *scaling_vec_ );
93   }
94 
95 public:
96 
PrimalScaledVector(const Ptr<V> & vec,const Ptr<V> & scaling_vec)97   PrimalScaledVector( const Ptr<V>& vec, const Ptr<V>& scaling_vec ) :
98     WrappedVector<Real>(vec), scaling_vec_(scaling_vec) {}
99 
~PrimalScaledVector()100   virtual ~PrimalScaledVector() {}
101 
dot(const V & x) const102   virtual Real dot( const V& x ) const override {
103     auto y = workspace_.copy(x);
104     multiply_scaling( y );
105     return this->getVector()->dot(*y);
106   }
107 
clone() const108   virtual Ptr<V> clone() const override {
109     return makePtr<VPrim>( this->getVector()->clone(), scaling_vec_ );
110   }
111 
basis(const int i) const112   virtual Ptr<V> basis( const int i ) const override {
113     return makePtr<VPrim>( this->getVector()->basis(i), scaling_vec_ );
114   }
115 
dual() const116   virtual void const V& dual() const override {
117     auto dual_vec = workspace_.copy( this->getVector() );
118     multiply_scaling( dual_vec );
119     return *( makePtr<VDual>( dual_vec, scaling_vec ) );
120   }
121 
getScalingVector()122   const Ptr<V>& getScalingVector() { return scaling_vec_; }
getScalingVector() const123   const Ptr<const V>& getScalingVector() const { return scaling_vec_; }
124 
setScalingVector(const Ptr<const V &> & scaling_vec) const125   void setScalingVector( const Ptr<const V&>& scaling_vec ) const {
126     scaling_vec_ = scaling_vec;
127   }
128 
129 }; // class PrimalScaledVector
130 
131 
132 
133 template<typename Real>
134 class DualScaledVector : public WrappedVector<Real> {
135 
136   using V     = Vector<Real>;
137   using VPrim = PrimalScaledVector<Real>;
138   using VDual = DualScaledVector<Real>;
139 
140 private:
141 
142   mutable Ptv<V>  scaling_vec_;
143   mutable VectorWorkspace<Real> workspace_;
144 
145   Elementwise::Divide<Real> div_;
146 
147 protected:
148 
getWorkspace() const149   VectorWorkspace<Real>& getWorkspace() const { return workspace_; }
150 
151   //  y <- y/x elementwise
divide_scaling(const<V> & y) const152   void divide_scaling( const <V>& y ) const {
153     y->applyBinary( div_, *scaling_vec_ );
154   }
155 
156 public:
157 
DualScaledVector(const Ptr<V> & vec,const Ptr<V> & scaling_vec)158   DualScaledVector( const Ptr<V>& vec, const Ptr<V>& scaling_vec ) :
159     WrappedVector<Real>(vec), scaling_vec_(scaling_vec) {}
160 
~DualScaledVector()161   virtual ~DualScaledVector() {}
162 
dot(const V & x) const163   virtual Real dot( const V& x ) const override {
164     auto y = workspace_.copy(x);
165     divide_scaling( y );
166     return this->getVector()->dot(*y);
167   }
168 
clone() const169   virtual Ptr<V> clone() const override {
170     return makePtr<VDual>( this->getVector()->clone(), scaling_vec_ );
171   }
172 
basis(const int i) const173   virtual Ptr<V> basis( const int i ) const override {
174     return makePtr<VDual>( this->getVector()->basis(i), scaling_vec_ );
175   }
176 
dual() const177   virtual void const V& dual() const override {
178     auto primal_vec = workspace_.copy( this->getVector() );
179     divide_scaling( primal_vec );
180     return *( makePtr<VPrim>( primal_vec, scaling_vec ) );
181   }
182 
getScalingVector()183   const Ptr<V>& getScalingVector() { return scaling_vec_; }
getScalingVector() const184   const Ptr<const V>& getScalingVector() const { return scaling_vec_; }
185 
setScalingVector(const Ptr<const V &> & scaling_vec) const186   void setScalingVector( const Ptr<const V&>& scaling_vec ) const {
187     scaling_vec_ = scaling_vec;
188   }
189 
190 }; // class PrimalScaledVector
191 
192 } // namespace ROL
193 
194 
195 #endif
196