Thyra Version of the Day
Loading...
Searching...
No Matches
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
19namespace Thyra {
20
21
22//Constructors/initializers/accessors
23
24
25template<class Scalar>
27 const Scalar &scalar
28 ,const EOpTransp &transp
30 )
31{
32 initializeImpl(scalar,transp,Op,false);
33}
34
35
36template<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
47template<class Scalar>
50{
51 return getOpImpl().getNonconstObj();
52}
53
54
55template<class Scalar>
58{
59 return getOpImpl();
60}
61
62
63template<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
78template<class Scalar>
80{
81 assertInitialized();
82 std::ostringstream oss;
84 << overallScalar() << ","<<toString(overallTransp())<<","
85 << origOp_->description() << "}";
86 return oss.str();
87}
88
89
90template<class Scalar>
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) {
106 *out << this->description() << std::endl;
107 break;
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
146template<class Scalar>
149{
150 assertInitialized();
151 return ( real_trans(this->overallTransp())==NOTRANS
152 ? this->getOrigOp()->range() : this->getOrigOp()->domain() );
153}
154
155
156template<class Scalar>
159{
160 assertInitialized();
161 return ( real_trans(this->overallTransp())==NOTRANS
162 ? this->getOrigOp()->domain() : this->getOrigOp()->range() );
163}
164
165
166template<class Scalar>
169{
170 return Teuchos::null; // Not supported yet but could be
171}
172
173
174// Overridden from ScaledAdointLinearOpBase
175
176
177template<class Scalar>
179{
180 return overallScalar_;
181}
182
183
184template<class Scalar>
186{
187 return overallTransp_;
188}
189
190
191template<class Scalar>
194{
195 return origOp_.getNonconstObj();
196}
197
198
199template<class Scalar>
202{
203 return origOp_;
204}
205
206
207// protected
208
209
210// Overridden from LinearOpBase
211
212
213template<class Scalar>
215{
216 assertInitialized();
217 return Thyra::opSupported(
218 *this->getOrigOp(), trans_trans(this->overallTransp(), M_trans) );
219}
220
221
222template<class Scalar>
224 const EOpTransp M_trans,
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
243template<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
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
306template<class Scalar>
307typename DefaultScaledAdjointLinearOp<Scalar>::CNLOC
308DefaultScaledAdjointLinearOp<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
virtual std::string description() const
T * get() const
Concrete decorator LinearOpBase subclass that wraps a LinearOpBase object and adds on an extra scalin...
RCP< LinearOpBase< Scalar > > getNonconstOp()
Return the non-const linear operator passed into initialize().
bool opSupportedImpl(EOpTransp M_trans) const
Return if the operation is supported on the logical linear operator.
std::string description() const
Outputs DefaultScaledAdjointLinearOp<Scalar>{this->getOrigOp().description()) along with the dimensio...
RCP< const VectorSpaceBase< Scalar > > domain() const
Return the domain space of the logical linear operator.
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 ...
void uninitialize()
Set to uninitialized and (optionally) extract the objects passed into initialize().
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.
RCP< const LinearOpBase< Scalar > > clone() const
RCP< const LinearOpBase< Scalar > > getOrigOp() const
RCP< const VectorSpaceBase< Scalar > > range() const
Return the range space of the logical linear operator.
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.
RCP< const LinearOpBase< Scalar > > getOp() const
Return the const linear operator passed into initialize().
Base class for all linear operators.
Interface for a collection of column vectors called a multi-vector.
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
EOpTransp
Enumeration for determining how a linear operator is applied. `*.
const char * toString(EConj conj)
Return a string name for a EOpTransp value. `*.
EOpTransp real_trans(EOpTransp transp)
Return NOTRANS or TRANS for real scalar valued operators and this also is used for determining struct...
EOpTransp trans_trans(EOpTransp trans1, EOpTransp trans2)
Combine two transpose arguments.
@ TRANS
Use the transposed operator.
@ NOTRANS
Use the non-transposed operator.
@ CONJTRANS
Use the transposed operator with complex-conjugate clements (same as TRANS for real scalar types).
@ CONJ
Use the non-transposed operator with complex-conjugate elements (same as NOTRANS for real scalar type...
TypeTo as(const TypeFrom &t)
T_To & dyn_cast(T_From &from)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)