TSFSimpleComposedOpImpl.hpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 /* ***********************************************************************
00003 // 
00004 //           TSFExtended: Trilinos Solver Framework Extended
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 #ifndef TSF_SIMPLE_COMPOSED_OP_IMPL_HPP
00030 #define TSF_SIMPLE_COMPOSED_OP_IMPL_HPP
00031 
00032 
00033 
00034 #include "TSFSimpleComposedOpDecl.hpp"
00035 #include "TSFSimpleIdentityOpDecl.hpp"
00036 #include "TSFSimpleZeroOpDecl.hpp"
00037 #include "SundanceOut.hpp"
00038 #include "SundanceTabs.hpp"
00039 
00040 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00041 #include "TSFLinearOperatorImpl.hpp"
00042 #include "TSFSimpleIdentityOpImpl.hpp"
00043 #include "TSFSimpleZeroOpImpl.hpp"
00044 #include "TSFSimplifiedLinearOpBaseImpl.hpp"
00045 #endif
00046 
00047 
00048 namespace TSFExtended
00049 {
00050 using namespace Teuchos;
00051 using namespace Sundance;
00052 
00053 
00054 
00055 /*
00056  * ------ composed operator  
00057  */
00058 template <class Scalar> inline
00059 SimpleComposedOp<Scalar>::SimpleComposedOp(const Array<LinearOperator<Scalar> >& ops)
00060   : SimplifiedLinearOpWithSpaces<Scalar>(
00061     ops[ops.size()-1].domain(), ops[0].range()
00062     ) 
00063   , ops_(ops)
00064 {
00065   TEST_FOR_EXCEPT(ops_.size() <= 1);
00066   for (int i=1; i<ops_.size(); i++)
00067   {
00068     TEST_FOR_EXCEPT(!(ops[i].range() == ops[i-1].domain()));
00069   }
00070 }
00071   
00072 
00073 
00074 template <class Scalar> inline
00075 void SimpleComposedOp<Scalar>::applyOp(const Thyra::EOpTransp M_trans,
00076   const Vector<Scalar>& in,
00077   Vector<Scalar> out) const
00078 {
00079   Tabs tab(0);
00080   SUNDANCE_MSG2(this->verb(), tab << "SimpleComposedOp::applyOp()");
00081   if (M_trans == Thyra::NOTRANS)
00082   {
00083     Vector<Scalar> tmpIn = in.copy();
00084     for (int i=0; i<ops_.size(); i++)
00085     {
00086       Tabs tab1;
00087       Vector<Scalar> tmpOut;
00088       int j = ops_.size()-1-i;
00089       SUNDANCE_MSG2(this->verb(), tab1 << "applying op #" << j 
00090         << " of " << ops_.size());
00091       ops_[j].apply(tmpIn, tmpOut);
00092       tmpIn = tmpOut;
00093     }
00094     out.acceptCopyOf(tmpIn);
00095   }
00096 
00097   else if (M_trans == Thyra::TRANS)
00098   {
00099     Vector<Scalar> tmpIn = in.copy();
00100     for (int i=0; i<ops_.size(); i++)
00101     {
00102       Tabs tab1;
00103       Vector<Scalar> tmpOut;
00104       SUNDANCE_MSG2(this->verb(), tab1 << "applying transpose op #" << i
00105         << " of " << ops_.size());
00106       ops_[i].applyTranspose(tmpIn, tmpOut);
00107       tmpIn = tmpOut;
00108     }
00109     out.acceptCopyOf(tmpIn);
00110   }
00111   else
00112   {
00113     TEST_FOR_EXCEPT(M_trans != Thyra::TRANS && M_trans != Thyra::NOTRANS);
00114   }
00115   SUNDANCE_MSG2(this->verb(), tab << "done SimpleComposedOp::applyOp()");
00116 }
00117   
00118 
00119 
00120 
00121 template <class Scalar> inline
00122 std::string SimpleComposedOp<Scalar>::description() const 
00123 {
00124   std::string rtn="(";
00125   for (int i=0; i<ops_.size(); i++)
00126   {
00127     if (i > 0) rtn += "*";
00128     rtn += ops_[i].description();
00129   }
00130   rtn += ")";
00131   return rtn;
00132 }
00133 
00134 
00135 template <class Scalar> inline
00136 void SimpleComposedOp<Scalar>::print(std::ostream& os) const 
00137 {
00138   Tabs tab(0);
00139   os << tab << "ComposedOperator[" << std::endl;
00140   for (int i=0; i<ops_.size(); i++)
00141   {
00142     Tabs tab1;
00143     os << tab1 << "factor #" << i << std::endl;
00144     Tabs tab2;
00145     os << tab2 << ops_[i].description() << std::endl;
00146     os << std::endl;
00147   }
00148   os << tab << "]" <<  std::endl;
00149 }
00150 
00151 
00152 template <class Scalar> inline
00153 LinearOperator<Scalar> composedOperator(
00154   const Array<LinearOperator<Scalar> >& ops)
00155 {
00156   /* We will strip out any identity operators, and if we find a zero
00157   * operator the whole works becomes a zero operator */ 
00158   Array<LinearOperator<Scalar> > strippedOps;
00159 
00160   for (int i=0; i<ops.size(); i++)
00161   {
00162     LinearOperator<Scalar> op_i = ops[i];
00163 
00164     /* if a factor is zero, the whole operator is
00165      * a zero operator */
00166     const SimpleZeroOp<Scalar>* zPtr 
00167       = dynamic_cast<const SimpleZeroOp<Scalar>*>(op_i.ptr().get());
00168 
00169     if (zPtr != 0) 
00170     {
00171       VectorSpace<Scalar> r = ops[0].range();
00172       VectorSpace<Scalar> d = ops[ops.size()-1].domain();
00173       return zeroOperator(d, r);
00174     }
00175 
00176     /* if a factor is the identity, skip it */
00177     const SimpleIdentityOp<Scalar>* IPtr 
00178       = dynamic_cast<const SimpleIdentityOp<Scalar>*>(op_i.ptr().get());  
00179     if (IPtr != 0) 
00180     {
00181       continue;
00182     }
00183 
00184     strippedOps.append(op_i);
00185   }
00186   
00187   TEST_FOR_EXCEPT(strippedOps.size() < 1);
00188   if (strippedOps.size()==1) return strippedOps[0];
00189   
00190   RCP<LinearOpBase<Scalar> > op 
00191     = rcp(new SimpleComposedOp<Scalar>(strippedOps));
00192   return op;
00193 }
00194 
00195 template <class Scalar> inline
00196 LinearOperator<Scalar> operator*(const LinearOperator<Scalar>& A, 
00197   const LinearOperator<Scalar>& B)
00198 {
00199   return composedOperator(Array<LinearOperator<Scalar> >(tuple(A,B)));
00200 }
00201   
00202 
00203 }
00204 
00205 #endif

Site Contact