00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef THYRA_DEFAULT_SCALED_ADJOINT_LINEAR_OP_DEF_HPP
00031 #define THYRA_DEFAULT_SCALED_ADJOINT_LINEAR_OP_DEF_HPP
00032
00033
00034 #include "Thyra_DefaultScaledAdjointLinearOp_decl.hpp"
00035
00036
00037 namespace Thyra {
00038
00039
00040
00041
00042
00043 template<class Scalar>
00044 void DefaultScaledAdjointLinearOp<Scalar>::initialize(
00045 const Scalar &scalar
00046 ,const EOpTransp &transp
00047 ,const Teuchos::RCP<LinearOpBase<Scalar> > &Op
00048 )
00049 {
00050 initializeImpl(scalar,transp,Op,false);
00051 }
00052
00053
00054 template<class Scalar>
00055 void DefaultScaledAdjointLinearOp<Scalar>::initialize(
00056 const Scalar &scalar
00057 ,const EOpTransp &transp
00058 ,const Teuchos::RCP<const LinearOpBase<Scalar> > &Op
00059 )
00060 {
00061 initializeImpl(scalar,transp,Op,false);
00062 }
00063
00064
00065 template<class Scalar>
00066 Teuchos::RCP<LinearOpBase<Scalar> >
00067 DefaultScaledAdjointLinearOp<Scalar>::getNonconstOp()
00068 {
00069 return getOpImpl().getNonconstObj();
00070 }
00071
00072
00073 template<class Scalar>
00074 Teuchos::RCP<const LinearOpBase<Scalar> >
00075 DefaultScaledAdjointLinearOp<Scalar>::getOp() const
00076 {
00077 return getOpImpl();
00078 }
00079
00080
00081 template<class Scalar>
00082 void DefaultScaledAdjointLinearOp<Scalar>::uninitialize()
00083 {
00084 typedef Teuchos::ScalarTraits<Scalar> ST;
00085 origOp_.uninitialize();
00086 overallScalar_ = ST::zero();
00087 overallTransp_ = NOTRANS;
00088 allScalarETransp_ = Teuchos::null;
00089
00090 }
00091
00092
00093
00094
00095
00096 template<class Scalar>
00097 std::string DefaultScaledAdjointLinearOp<Scalar>::description() const
00098 {
00099 assertInitialized();
00100 typedef Teuchos::ScalarTraits<Scalar> ST;
00101 std::ostringstream oss;
00102 oss << Teuchos::Describable::description() << "{"
00103 << overallScalar() << ","<<toString(overallTransp())<<","
00104 << origOp_->description() << "}";
00105 return oss.str();
00106 }
00107
00108
00109 template<class Scalar>
00110 void DefaultScaledAdjointLinearOp<Scalar>::describe(
00111 Teuchos::FancyOStream &out_arg
00112 ,const Teuchos::EVerbosityLevel verbLevel
00113 ) const
00114 {
00115 typedef Teuchos::ScalarTraits<Scalar> ST;
00116 using Teuchos::RCP;
00117 using Teuchos::FancyOStream;
00118 using Teuchos::OSTab;
00119 assertInitialized();
00120 RCP<FancyOStream> out = rcp(&out_arg,false);
00121 OSTab tab(out);
00122 switch(verbLevel) {
00123 case Teuchos::VERB_DEFAULT:
00124 case Teuchos::VERB_LOW:
00125 *out << this->description() << std::endl;
00126 break;
00127 case Teuchos::VERB_MEDIUM:
00128 case Teuchos::VERB_HIGH:
00129 case Teuchos::VERB_EXTREME:
00130 {
00131 *out
00132 << Teuchos::Describable::description() << "{"
00133 << "rangeDim=" << this->range()->dim()
00134 << ",domainDim=" << this->domain()->dim() << "}\n";
00135 OSTab tab2(out);
00136 *out
00137 << "overallScalar="<< overallScalar() << std::endl
00138 << "overallTransp="<<toString(overallTransp()) << std::endl
00139 << "Constituent transformations:\n";
00140 for( int i = 0; i <= my_index_; ++i ) {
00141 const ScalarETransp<Scalar> &scalar_transp = (*allScalarETransp_)[my_index_-i];
00142 OSTab tab3(out,i+1);
00143 if(scalar_transp.scalar != ST::one() && scalar_transp.transp != NOTRANS)
00144 *out << "scalar="<<scalar_transp.scalar<<",transp="<<toString(scalar_transp.transp)<<std::endl;
00145 else if(scalar_transp.scalar != ST::one())
00146 *out << "scalar="<<scalar_transp.scalar<<std::endl;
00147 else if( scalar_transp.transp != NOTRANS )
00148 *out << "transp="<<toString(scalar_transp.transp)<<std::endl;
00149 else
00150 *out << "no-transformation\n";
00151 }
00152 tab.incrTab(my_index_+2);
00153 *out << "origOp = " << Teuchos::describe(*origOp_,verbLevel);
00154 break;
00155 }
00156 default:
00157 TEST_FOR_EXCEPT(true);
00158 }
00159 }
00160
00161
00162
00163
00164
00165 template<class Scalar>
00166 Teuchos::RCP< const VectorSpaceBase<Scalar> >
00167 DefaultScaledAdjointLinearOp<Scalar>::range() const
00168 {
00169 assertInitialized();
00170 return ( real_trans(this->overallTransp())==NOTRANS
00171 ? this->getOrigOp()->range() : this->getOrigOp()->domain() );
00172 }
00173
00174
00175 template<class Scalar>
00176 Teuchos::RCP< const VectorSpaceBase<Scalar> >
00177 DefaultScaledAdjointLinearOp<Scalar>::domain() const
00178 {
00179 assertInitialized();
00180 return ( real_trans(this->overallTransp())==NOTRANS
00181 ? this->getOrigOp()->domain() : this->getOrigOp()->range() );
00182 }
00183
00184
00185 template<class Scalar>
00186 Teuchos::RCP<const LinearOpBase<Scalar> >
00187 DefaultScaledAdjointLinearOp<Scalar>::clone() const
00188 {
00189 return Teuchos::null;
00190 }
00191
00192
00193
00194
00195
00196 template<class Scalar>
00197 Scalar DefaultScaledAdjointLinearOp<Scalar>::overallScalar() const
00198 {
00199 return overallScalar_;
00200 }
00201
00202
00203 template<class Scalar>
00204 EOpTransp DefaultScaledAdjointLinearOp<Scalar>::overallTransp() const
00205 {
00206 return overallTransp_;
00207 }
00208
00209
00210 template<class Scalar>
00211 Teuchos::RCP<LinearOpBase<Scalar> >
00212 DefaultScaledAdjointLinearOp<Scalar>::getNonconstOrigOp()
00213 {
00214 return origOp_.getNonconstObj();
00215 }
00216
00217
00218 template<class Scalar>
00219 Teuchos::RCP<const LinearOpBase<Scalar> >
00220 DefaultScaledAdjointLinearOp<Scalar>::getOrigOp() const
00221 {
00222 return origOp_;
00223 }
00224
00225
00226
00227
00228
00229
00230
00231
00232 template<class Scalar>
00233 bool DefaultScaledAdjointLinearOp<Scalar>::opSupported(EOpTransp M_trans) const
00234 {
00235 assertInitialized();
00236 return Thyra::opSupported(
00237 *this->getOrigOp(), trans_trans(this->overallTransp(),M_trans) );
00238 }
00239
00240
00241 template<class Scalar>
00242 void DefaultScaledAdjointLinearOp<Scalar>::apply(
00243 const EOpTransp M_trans
00244 ,const MultiVectorBase<Scalar> &X
00245 ,MultiVectorBase<Scalar> *Y
00246 ,const Scalar alpha
00247 ,const Scalar beta
00248 ) const
00249 {
00250 assertInitialized();
00251 Thyra::apply(
00252 *this->getOrigOp(),trans_trans(M_trans,this->overallTransp())
00253 ,X,Y,Scalar(this->overallScalar()*alpha),beta
00254 );
00255 }
00256
00257
00258
00259
00260
00261 template<class Scalar>
00262 void DefaultScaledAdjointLinearOp<Scalar>::initializeImpl(
00263 const Scalar &scalar
00264 ,const EOpTransp &transp
00265 ,const Teuchos::RCP<const LinearOpBase<Scalar> > &Op
00266 ,const bool isConst
00267 )
00268 {
00269 typedef Teuchos::ScalarTraits<Scalar> ST;
00270 #ifdef TEUCHOS_DEBUG
00271 TEST_FOR_EXCEPTION(
00272 Op.get()==NULL, std::invalid_argument
00273 ,"DefaultScaledAdjointLinearOp<"<<ST::name()<<">::initialize(scalar,transp,Op): "
00274 "Error!, Op.get()==NULL is not allowed!"
00275 );
00276 #endif // TEUCHOS_DEBUG
00277 Teuchos::RCP<const DefaultScaledAdjointLinearOp<Scalar> >
00278 saOp = Teuchos::rcp_dynamic_cast<const DefaultScaledAdjointLinearOp<Scalar> >(Op);
00279 if(saOp.get()) {
00280 origOp_ = saOp->origOp_;
00281 overallScalar_ = saOp->overallScalar_*scalar;
00282 overallTransp_ = trans_trans(saOp->overallTransp_,transp) ;
00283 my_index_ = saOp->my_index_ + 1;
00284 allScalarETransp_ = saOp->allScalarETransp_;
00285 }
00286 else {
00287 if(isConst)
00288 origOp_.initialize(Op);
00289 else
00290 origOp_.initialize(Teuchos::rcp_const_cast<LinearOpBase<Scalar> >(Op));
00291 overallScalar_ = scalar;
00292 overallTransp_ = transp;
00293 my_index_ = 0;
00294 allScalarETransp_ = Teuchos::rcp(new allScalarETransp_t());
00295 }
00296 allScalarETransp_->push_back(ScalarETransp<Scalar>(scalar,transp));
00297
00298 std::string Op_label = Op->getObjectLabel();
00299 if(Op_label.length()==0)
00300 Op_label = "ANYM";
00301 std::ostringstream label;
00302 if(scalar!=ST::one())
00303 label << scalar << "*";
00304 switch(transp) {
00305 case NOTRANS:
00306 break;
00307 case CONJ:
00308 label << "conj";
00309 break;
00310 case TRANS:
00311 label << "trans";
00312 break;
00313 case CONJTRANS:
00314 label << "adj";
00315 break;
00316 default:
00317 TEST_FOR_EXCEPT("Invalid EOpTransp value!");
00318 }
00319 label << "(" << Op_label << ")";
00320 this->setObjectLabel(label.str());
00321 }
00322
00323
00324 template<class Scalar>
00325 typename DefaultScaledAdjointLinearOp<Scalar>::CNLOC
00326 DefaultScaledAdjointLinearOp<Scalar>::getOpImpl() const
00327 {
00328 assertInitialized();
00329 if( my_index_ > 0 ) {
00330 const ScalarETransp<Scalar> &scalar_transp = allScalarETransp_->at(my_index_);
00331 Teuchos::RCP<DefaultScaledAdjointLinearOp<Scalar> >
00332 Op = Teuchos::rcp(new DefaultScaledAdjointLinearOp<Scalar>());
00333 Op->origOp_ = origOp_;
00334 Op->overallScalar_ = overallScalar_/scalar_transp.scalar;
00335 Op->overallTransp_ = trans_trans(overallTransp_,scalar_transp.transp);
00336 Op->my_index_ = my_index_ - 1;
00337 Op->allScalarETransp_ = allScalarETransp_;
00338 return CNLOC(
00339 Teuchos::rcp_implicit_cast<LinearOpBase<Scalar> >(Op)
00340 );
00341 }
00342 return origOp_;
00343 }
00344
00345
00346 }
00347
00348
00349 #endif // THYRA_DEFAULT_SCALED_ADJOINT_LINEAR_OP_DEF_HPP