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 // Thyra: Interfaces and Support for Abstract Numerical Algorithms
4 //
5 // Copyright 2004 NTESS and the Thyra contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef THYRA_DEFAULT_SCALED_ADJOINT_LINEAR_OP_DEF_HPP
11 #define THYRA_DEFAULT_SCALED_ADJOINT_LINEAR_OP_DEF_HPP
12 
13 
14 #include "Thyra_DefaultScaledAdjointLinearOp_decl.hpp"
15 #include "Thyra_VectorSpaceBase.hpp"
16 #include "Thyra_AssertOp.hpp"
17 
18 
19 namespace Thyra {
20 
21 
22 //Constructors/initializers/accessors
23 
24 
25 template<class Scalar>
27  const Scalar &scalar
28  ,const EOpTransp &transp
30  )
31 {
32  initializeImpl(scalar,transp,Op,false);
33 }
34 
35 
36 template<class Scalar>
38  const Scalar &scalar
39  ,const EOpTransp &transp
40  ,const Teuchos::RCP<const LinearOpBase<Scalar> > &Op
41  )
42 {
43  initializeImpl(scalar,transp,Op,false);
44 }
45 
46 
47 template<class Scalar>
50 {
51  return getOpImpl().getNonconstObj();
52 }
53 
54 
55 template<class Scalar>
58 {
59  return getOpImpl();
60 }
61 
62 
63 template<class Scalar>
65 {
67  origOp_.uninitialize();
68  overallScalar_ = ST::zero();
69  overallTransp_ = NOTRANS;
70  allScalarETransp_ = Teuchos::null;
71 
72 }
73 
74 
75 // Overridden from Teuchos::Describable
76 
77 
78 template<class Scalar>
80 {
81  assertInitialized();
82  std::ostringstream oss;
83  oss << Teuchos::Describable::description() << "{"
84  << overallScalar() << ","<<toString(overallTransp())<<","
85  << origOp_->description() << "}";
86  return oss.str();
87 }
88 
89 
90 template<class Scalar>
92  Teuchos::FancyOStream &out_arg
93  ,const Teuchos::EVerbosityLevel verbLevel
94  ) const
95 {
97  using Teuchos::RCP;
99  using Teuchos::OSTab;
100  assertInitialized();
101  RCP<FancyOStream> out = rcp(&out_arg,false);
102  OSTab tab(out);
103  switch(verbLevel) {
105  case Teuchos::VERB_LOW:
106  *out << this->description() << std::endl;
107  break;
109  case Teuchos::VERB_HIGH:
111  {
112  *out
114  << "rangeDim=" << this->range()->dim()
115  << ",domainDim=" << this->domain()->dim() << "}\n";
116  OSTab tab2(out);
117  *out
118  << "overallScalar="<< overallScalar() << std::endl
119  << "overallTransp="<<toString(overallTransp()) << std::endl
120  << "Constituent transformations:\n";
121  for( int i = 0; i <= my_index_; ++i ) {
122  const ScalarETransp<Scalar> &scalar_transp = (*allScalarETransp_)[my_index_-i];
123  OSTab tab3(out,i+1);
124  if(scalar_transp.scalar != ST::one() && scalar_transp.transp != NOTRANS)
125  *out << "scalar="<<scalar_transp.scalar<<",transp="<<toString(scalar_transp.transp)<<std::endl;
126  else if(scalar_transp.scalar != ST::one())
127  *out << "scalar="<<scalar_transp.scalar<<std::endl;
128  else if( scalar_transp.transp != NOTRANS )
129  *out << "transp="<<toString(scalar_transp.transp)<<std::endl;
130  else
131  *out << "no-transformation\n";
132  }
133  tab.incrTab(my_index_+2);
134  *out << "origOp = " << Teuchos::describe(*origOp_,verbLevel);
135  break;
136  }
137  default:
138  TEUCHOS_TEST_FOR_EXCEPT(true); // Should never be called!
139  }
140 }
141 
142 
143 // Overridden from LinearOpBase
144 
145 
146 template<class Scalar>
149 {
150  assertInitialized();
151  return ( real_trans(this->overallTransp())==NOTRANS
152  ? this->getOrigOp()->range() : this->getOrigOp()->domain() );
153 }
154 
155 
156 template<class Scalar>
159 {
160  assertInitialized();
161  return ( real_trans(this->overallTransp())==NOTRANS
162  ? this->getOrigOp()->domain() : this->getOrigOp()->range() );
163 }
164 
165 
166 template<class Scalar>
169 {
170  return Teuchos::null; // Not supported yet but could be
171 }
172 
173 
174 // Overridden from ScaledAdointLinearOpBase
175 
176 
177 template<class Scalar>
179 {
180  return overallScalar_;
181 }
182 
183 
184 template<class Scalar>
186 {
187  return overallTransp_;
188 }
189 
190 
191 template<class Scalar>
194 {
195  return origOp_.getNonconstObj();
196 }
197 
198 
199 template<class Scalar>
202 {
203  return origOp_;
204 }
205 
206 
207 // protected
208 
209 
210 // Overridden from LinearOpBase
211 
212 
213 template<class Scalar>
215 {
216  assertInitialized();
217  return Thyra::opSupported(
218  *this->getOrigOp(), trans_trans(this->overallTransp(), M_trans) );
219 }
220 
221 
222 template<class Scalar>
224  const EOpTransp M_trans,
225  const MultiVectorBase<Scalar> &X,
226  const Ptr<MultiVectorBase<Scalar> > &Y,
227  const Scalar alpha,
228  const Scalar beta
229  ) const
230 {
231  using Teuchos::as;
232  assertInitialized();
233  Thyra::apply(
234  *this->getOrigOp(), trans_trans(M_trans, this->overallTransp()),
235  X, Y, as<Scalar>(this->overallScalar()*alpha), beta
236  );
237 }
238 
239 
240 // private
241 
242 
243 template<class Scalar>
245  const Scalar &scalar
246  ,const EOpTransp &transp
247  ,const Teuchos::RCP<const LinearOpBase<Scalar> > &Op
248  ,const bool isConst
249  )
250 {
252 #ifdef TEUCHOS_DEBUG
254  Op.get()==NULL, std::invalid_argument
255  ,"DefaultScaledAdjointLinearOp<"<<ST::name()<<">::initialize(scalar,transp,Op): "
256  "Error!, Op.get()==NULL is not allowed!"
257  );
258 #endif // TEUCHOS_DEBUG
260  saOp = Teuchos::rcp_dynamic_cast<const DefaultScaledAdjointLinearOp<Scalar> >(Op);
261  if(saOp.get()) {
262  origOp_ = saOp->origOp_;
263  overallScalar_ = saOp->overallScalar_*scalar;
264  overallTransp_ = trans_trans(saOp->overallTransp_,transp) ;
265  my_index_ = saOp->my_index_ + 1;
266  allScalarETransp_ = saOp->allScalarETransp_;
267  }
268  else {
269  if(isConst)
270  origOp_.initialize(Op);
271  else
272  origOp_.initialize(Teuchos::rcp_const_cast<LinearOpBase<Scalar> >(Op));
273  overallScalar_ = scalar;
274  overallTransp_ = transp;
275  my_index_ = 0;
276  allScalarETransp_ = Teuchos::rcp(new allScalarETransp_t());
277  }
278  allScalarETransp_->push_back(ScalarETransp<Scalar>(scalar,transp));
279  // Set the object label
280  std::string Op_label = Op->getObjectLabel();
281  if(Op_label.length()==0)
282  Op_label = "ANYM";
283  std::ostringstream label;
284  if(scalar!=ST::one())
285  label << scalar << "*";
286  switch(transp) {
287  case NOTRANS:
288  break; // No output
289  case CONJ:
290  label << "conj";
291  break;
292  case TRANS:
293  label << "trans";
294  break;
295  case CONJTRANS:
296  label << "adj";
297  break;
298  default:
299  TEUCHOS_TEST_FOR_EXCEPT("Invalid EOpTransp value!");
300  }
301  label << "(" << Op_label << ")";
302  this->setObjectLabel(label.str());
303 }
304 
305 
306 template<class Scalar>
307 typename DefaultScaledAdjointLinearOp<Scalar>::CNLOC
308 DefaultScaledAdjointLinearOp<Scalar>::getOpImpl() const
309 {
310  assertInitialized();
311  if( my_index_ > 0 ) {
312  const ScalarETransp<Scalar> &scalar_transp = allScalarETransp_->at(my_index_);
314  Op = Teuchos::rcp(new DefaultScaledAdjointLinearOp<Scalar>());
315  Op->origOp_ = origOp_;
316  Op->overallScalar_ = overallScalar_/scalar_transp.scalar;
317  Op->overallTransp_ = trans_trans(overallTransp_,scalar_transp.transp);
318  Op->my_index_ = my_index_ - 1;
319  Op->allScalarETransp_ = allScalarETransp_;
320  return CNLOC(
321  Teuchos::rcp_implicit_cast<LinearOpBase<Scalar> >(Op)
322  );
323  }
324  return origOp_;
325 }
326 
327 
328 } // namespace Thyra
329 
330 
331 #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)