Thyra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Thyra_DefaultScaledAdjointLinearOp_def.hpp
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Thyra: Interfaces and Support for Abstract Numerical Algorithms
5 // Copyright (2004) 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 Roscoe A. Bartlett (bartlettra@ornl.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 
43 #ifndef THYRA_DEFAULT_SCALED_ADJOINT_LINEAR_OP_DEF_HPP
44 #define THYRA_DEFAULT_SCALED_ADJOINT_LINEAR_OP_DEF_HPP
45 
46 
47 #include "Thyra_DefaultScaledAdjointLinearOp_decl.hpp"
48 #include "Thyra_VectorSpaceBase.hpp"
49 #include "Thyra_AssertOp.hpp"
50 
51 
52 namespace Thyra {
53 
54 
55 //Constructors/initializers/accessors
56 
57 
58 template<class Scalar>
60  const Scalar &scalar
61  ,const EOpTransp &transp
63  )
64 {
65  initializeImpl(scalar,transp,Op,false);
66 }
67 
68 
69 template<class Scalar>
71  const Scalar &scalar
72  ,const EOpTransp &transp
73  ,const Teuchos::RCP<const LinearOpBase<Scalar> > &Op
74  )
75 {
76  initializeImpl(scalar,transp,Op,false);
77 }
78 
79 
80 template<class Scalar>
83 {
84  return getOpImpl().getNonconstObj();
85 }
86 
87 
88 template<class Scalar>
91 {
92  return getOpImpl();
93 }
94 
95 
96 template<class Scalar>
98 {
100  origOp_.uninitialize();
101  overallScalar_ = ST::zero();
102  overallTransp_ = NOTRANS;
103  allScalarETransp_ = Teuchos::null;
104 
105 }
106 
107 
108 // Overridden from Teuchos::Describable
109 
110 
111 template<class Scalar>
113 {
114  assertInitialized();
115  std::ostringstream oss;
116  oss << Teuchos::Describable::description() << "{"
117  << overallScalar() << ","<<toString(overallTransp())<<","
118  << origOp_->description() << "}";
119  return oss.str();
120 }
121 
122 
123 template<class Scalar>
125  Teuchos::FancyOStream &out_arg
126  ,const Teuchos::EVerbosityLevel verbLevel
127  ) const
128 {
130  using Teuchos::RCP;
131  using Teuchos::FancyOStream;
132  using Teuchos::OSTab;
133  assertInitialized();
134  RCP<FancyOStream> out = rcp(&out_arg,false);
135  OSTab tab(out);
136  switch(verbLevel) {
138  case Teuchos::VERB_LOW:
139  *out << this->description() << std::endl;
140  break;
142  case Teuchos::VERB_HIGH:
144  {
145  *out
147  << "rangeDim=" << this->range()->dim()
148  << ",domainDim=" << this->domain()->dim() << "}\n";
149  OSTab tab2(out);
150  *out
151  << "overallScalar="<< overallScalar() << std::endl
152  << "overallTransp="<<toString(overallTransp()) << std::endl
153  << "Constituent transformations:\n";
154  for( int i = 0; i <= my_index_; ++i ) {
155  const ScalarETransp<Scalar> &scalar_transp = (*allScalarETransp_)[my_index_-i];
156  OSTab tab3(out,i+1);
157  if(scalar_transp.scalar != ST::one() && scalar_transp.transp != NOTRANS)
158  *out << "scalar="<<scalar_transp.scalar<<",transp="<<toString(scalar_transp.transp)<<std::endl;
159  else if(scalar_transp.scalar != ST::one())
160  *out << "scalar="<<scalar_transp.scalar<<std::endl;
161  else if( scalar_transp.transp != NOTRANS )
162  *out << "transp="<<toString(scalar_transp.transp)<<std::endl;
163  else
164  *out << "no-transformation\n";
165  }
166  tab.incrTab(my_index_+2);
167  *out << "origOp = " << Teuchos::describe(*origOp_,verbLevel);
168  break;
169  }
170  default:
171  TEUCHOS_TEST_FOR_EXCEPT(true); // Should never be called!
172  }
173 }
174 
175 
176 // Overridden from LinearOpBase
177 
178 
179 template<class Scalar>
182 {
183  assertInitialized();
184  return ( real_trans(this->overallTransp())==NOTRANS
185  ? this->getOrigOp()->range() : this->getOrigOp()->domain() );
186 }
187 
188 
189 template<class Scalar>
192 {
193  assertInitialized();
194  return ( real_trans(this->overallTransp())==NOTRANS
195  ? this->getOrigOp()->domain() : this->getOrigOp()->range() );
196 }
197 
198 
199 template<class Scalar>
202 {
203  return Teuchos::null; // Not supported yet but could be
204 }
205 
206 
207 // Overridden from ScaledAdointLinearOpBase
208 
209 
210 template<class Scalar>
212 {
213  return overallScalar_;
214 }
215 
216 
217 template<class Scalar>
219 {
220  return overallTransp_;
221 }
222 
223 
224 template<class Scalar>
227 {
228  return origOp_.getNonconstObj();
229 }
230 
231 
232 template<class Scalar>
235 {
236  return origOp_;
237 }
238 
239 
240 // protected
241 
242 
243 // Overridden from LinearOpBase
244 
245 
246 template<class Scalar>
248 {
249  assertInitialized();
250  return Thyra::opSupported(
251  *this->getOrigOp(), trans_trans(this->overallTransp(), M_trans) );
252 }
253 
254 
255 template<class Scalar>
257  const EOpTransp M_trans,
258  const MultiVectorBase<Scalar> &X,
259  const Ptr<MultiVectorBase<Scalar> > &Y,
260  const Scalar alpha,
261  const Scalar beta
262  ) const
263 {
264  using Teuchos::as;
265  assertInitialized();
266  Thyra::apply(
267  *this->getOrigOp(), trans_trans(M_trans, this->overallTransp()),
268  X, Y, as<Scalar>(this->overallScalar()*alpha), beta
269  );
270 }
271 
272 
273 // private
274 
275 
276 template<class Scalar>
278  const Scalar &scalar
279  ,const EOpTransp &transp
280  ,const Teuchos::RCP<const LinearOpBase<Scalar> > &Op
281  ,const bool isConst
282  )
283 {
285 #ifdef TEUCHOS_DEBUG
287  Op.get()==NULL, std::invalid_argument
288  ,"DefaultScaledAdjointLinearOp<"<<ST::name()<<">::initialize(scalar,transp,Op): "
289  "Error!, Op.get()==NULL is not allowed!"
290  );
291 #endif // TEUCHOS_DEBUG
293  saOp = Teuchos::rcp_dynamic_cast<const DefaultScaledAdjointLinearOp<Scalar> >(Op);
294  if(saOp.get()) {
295  origOp_ = saOp->origOp_;
296  overallScalar_ = saOp->overallScalar_*scalar;
297  overallTransp_ = trans_trans(saOp->overallTransp_,transp) ;
298  my_index_ = saOp->my_index_ + 1;
299  allScalarETransp_ = saOp->allScalarETransp_;
300  }
301  else {
302  if(isConst)
303  origOp_.initialize(Op);
304  else
305  origOp_.initialize(Teuchos::rcp_const_cast<LinearOpBase<Scalar> >(Op));
306  overallScalar_ = scalar;
307  overallTransp_ = transp;
308  my_index_ = 0;
309  allScalarETransp_ = Teuchos::rcp(new allScalarETransp_t());
310  }
311  allScalarETransp_->push_back(ScalarETransp<Scalar>(scalar,transp));
312  // Set the object label
313  std::string Op_label = Op->getObjectLabel();
314  if(Op_label.length()==0)
315  Op_label = "ANYM";
316  std::ostringstream label;
317  if(scalar!=ST::one())
318  label << scalar << "*";
319  switch(transp) {
320  case NOTRANS:
321  break; // No output
322  case CONJ:
323  label << "conj";
324  break;
325  case TRANS:
326  label << "trans";
327  break;
328  case CONJTRANS:
329  label << "adj";
330  break;
331  default:
332  TEUCHOS_TEST_FOR_EXCEPT("Invalid EOpTransp value!");
333  }
334  label << "(" << Op_label << ")";
335  this->setObjectLabel(label.str());
336 }
337 
338 
339 template<class Scalar>
340 typename DefaultScaledAdjointLinearOp<Scalar>::CNLOC
341 DefaultScaledAdjointLinearOp<Scalar>::getOpImpl() const
342 {
343  assertInitialized();
344  if( my_index_ > 0 ) {
345  const ScalarETransp<Scalar> &scalar_transp = allScalarETransp_->at(my_index_);
347  Op = Teuchos::rcp(new DefaultScaledAdjointLinearOp<Scalar>());
348  Op->origOp_ = origOp_;
349  Op->overallScalar_ = overallScalar_/scalar_transp.scalar;
350  Op->overallTransp_ = trans_trans(overallTransp_,scalar_transp.transp);
351  Op->my_index_ = my_index_ - 1;
352  Op->allScalarETransp_ = allScalarETransp_;
353  return CNLOC(
354  Teuchos::rcp_implicit_cast<LinearOpBase<Scalar> >(Op)
355  );
356  }
357  return origOp_;
358 }
359 
360 
361 } // namespace Thyra
362 
363 
364 #endif // THYRA_DEFAULT_SCALED_ADJOINT_LINEAR_OP_DEF_HPP
RCP< const VectorSpaceBase< Scalar > > range() const
Return the range space of the logical linear operator.
EOpTransp
Enumeration for determining how a linear operator is applied. `*.
RCP< const LinearOpBase< Scalar > > getOrigOp() const
basic_OSTab< char > OSTab
std::string description() const
Outputs DefaultScaledAdjointLinearOp&lt;Scalar&gt;{this-&gt;getOrigOp().description()) along with the dimensio...
basic_FancyOStream< char > FancyOStream
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Use the non-transposed operator.
EOpTransp real_trans(EOpTransp transp)
Return NOTRANS or TRANS for real scalar valued operators and this also is used for determining struct...
Use the transposed operator with complex-conjugate clements (same as TRANS for real scalar types)...
RCP< LinearOpBase< Scalar > > getNonconstOp()
Return the non-const linear operator passed into initialize().
void initialize(const Scalar &scalar, const EOpTransp &transp, const RCP< LinearOpBase< Scalar > > &Op)
Initialize with an operator with by defining adjoint (transpose) and scaling arguments.
Use the non-transposed operator with complex-conjugate elements (same as NOTRANS for real scalar type...
Use the transposed operator.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
RCP< const LinearOpBase< Scalar > > getOp() const
Return the const linear operator passed into initialize().
Interface for a collection of column vectors called a multi-vector.
EOpTransp trans_trans(EOpTransp trans1, EOpTransp trans2)
Combine two transpose arguments.
Concrete decorator LinearOpBase subclass that wraps a LinearOpBase object and adds on an extra scalin...
virtual std::string description() const
void uninitialize()
Set to uninitialized and (optionally) extract the objects passed into initialize().
TEUCHOSCORE_LIB_DLL_EXPORT std::string toString(const EVerbosityLevel verbLevel)
void applyImpl(const EOpTransp M_trans, const MultiVectorBase< Scalar > &X, const Ptr< MultiVectorBase< Scalar > > &Y, const Scalar alpha, const Scalar beta) const
Apply the linear operator (or its transpose) to a multi-vector : Y = alpha*op(M)*X + beta*Y...
Base class for all linear operators.
RCP< const LinearOpBase< Scalar > > clone() const
TypeTo as(const TypeFrom &t)
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
Prints out the original operator as well as all of the scalings and transpositions in the order that ...
RCP< const VectorSpaceBase< Scalar > > domain() const
Return the domain space of the logical linear operator.
bool opSupportedImpl(EOpTransp M_trans) const
Return if the operation is supported on the logical linear operator.
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)