Thyra_DefaultScaledAdjointLinearOp_def.hpp

00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 //    Thyra: Interfaces and Support for Abstract Numerical Algorithms
00005 //                 Copyright (2004) Sandia Corporation
00006 // 
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 // 
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //  
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //  
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00025 // 
00026 // ***********************************************************************
00027 // @HEADER
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 //Constructors/initializers/accessors
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 // Overridden from Teuchos::Describable
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); // Should never be called!
00158   }
00159 }
00160 
00161 
00162 // Overridden from LinearOpBase
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; // Not supported yet but could be
00190 }
00191 
00192 
00193 // Overridden from ScaledAdointLinearOpBase
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 // protected
00227 
00228 
00229 // Overridden from SingleScalarLinearOpBase
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 // private
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   // Set the object label
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; // No output
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 } // namespace Thyra
00347 
00348 
00349 #endif  // THYRA_DEFAULT_SCALED_ADJOINT_LINEAR_OP_DEF_HPP

Generated on Wed May 12 21:26:54 2010 for Thyra Operator/Vector Support by  doxygen 1.4.7