PlayaSimpleComposedOpImpl.hpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                 Playa: Programmable Linear Algebra
00005 //                 Copyright 2012 Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Kevin Long (kevin.long@ttu.edu)
00038 // 
00039 
00040 /* @HEADER@ */
00041 
00042 #ifndef PLAYA_SIMPLE_COMPOSED_OP_IMPL_HPP
00043 #define PLAYA_SIMPLE_COMPOSED_OP_IMPL_HPP
00044 
00045 
00046 
00047 #include "PlayaSimpleComposedOpDecl.hpp"
00048 #include "PlayaSimpleIdentityOpDecl.hpp"
00049 #include "PlayaSimpleZeroOpDecl.hpp"
00050 #include "PlayaOut.hpp"
00051 #include "PlayaTabs.hpp"
00052 
00053 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00054 #include "PlayaLinearOperatorImpl.hpp"
00055 #include "PlayaSimpleIdentityOpImpl.hpp"
00056 #include "PlayaSimpleZeroOpImpl.hpp"
00057 #endif
00058 
00059 
00060 namespace Playa
00061 {
00062 using namespace Teuchos;
00063 
00064 
00065 
00066 
00067 /*
00068  * ------ composed operator  
00069  */
00070 template <class Scalar> inline
00071 SimpleComposedOp<Scalar>::SimpleComposedOp(const Array<LinearOperator<Scalar> >& ops)
00072   : LinearOpWithSpaces<Scalar>(
00073     ops[ops.size()-1].domain(), ops[0].range()
00074     ) 
00075   , ops_(ops)
00076 {
00077   TEUCHOS_TEST_FOR_EXCEPT(ops_.size() <= 1);
00078   for (int i=1; i<ops_.size(); i++)
00079   {
00080     TEUCHOS_TEST_FOR_EXCEPT(!(ops[i].range() == ops[i-1].domain()));
00081   }
00082 }
00083   
00084 
00085 
00086 template <class Scalar> inline
00087 void SimpleComposedOp<Scalar>::apply(Teuchos::ETransp transApplyType,
00088   const Vector<Scalar>& in,
00089   Vector<Scalar> out) const
00090 {
00091   Tabs tab(0);
00092   PLAYA_MSG2(this->verb(), tab << "SimpleComposedOp::apply()");
00093   if (transApplyType == Teuchos::NO_TRANS)
00094   {
00095     Vector<Scalar> tmpIn = in.copy();
00096     for (int i=0; i<ops_.size(); i++)
00097     {
00098       Tabs tab1;
00099       Vector<Scalar> tmpOut;
00100       int j = ops_.size()-1-i;
00101       PLAYA_MSG2(this->verb(), tab1 << "applying op #" << j 
00102         << " of " << ops_.size());
00103       ops_[j].apply(tmpIn, tmpOut);
00104       tmpIn = tmpOut;
00105     }
00106     out.acceptCopyOf(tmpIn);
00107   }
00108 
00109   else if (transApplyType == Teuchos::TRANS)
00110   {
00111     Vector<Scalar> tmpIn = in.copy();
00112     for (int i=0; i<ops_.size(); i++)
00113     {
00114       Tabs tab1;
00115       Vector<Scalar> tmpOut;
00116       PLAYA_MSG2(this->verb(), tab1 << "applying transpose op #" << i
00117         << " of " << ops_.size());
00118       ops_[i].applyTranspose(tmpIn, tmpOut);
00119       tmpIn = tmpOut;
00120     }
00121     out.acceptCopyOf(tmpIn);
00122   }
00123   else
00124   {
00125     TEUCHOS_TEST_FOR_EXCEPT(transApplyType != Teuchos::TRANS && transApplyType != Teuchos::NO_TRANS);
00126   }
00127   PLAYA_MSG2(this->verb(), tab << "done SimpleComposedOp::apply()");
00128 }
00129   
00130 
00131 
00132 
00133 template <class Scalar> inline
00134 std::string SimpleComposedOp<Scalar>::description() const 
00135 {
00136   std::string rtn="(";
00137   for (int i=0; i<ops_.size(); i++)
00138   {
00139     if (i > 0) rtn += "*";
00140     rtn += ops_[i].description();
00141   }
00142   rtn += ")";
00143   return rtn;
00144 }
00145 
00146 
00147 template <class Scalar> inline
00148 void SimpleComposedOp<Scalar>::print(std::ostream& os) const 
00149 {
00150   Tabs tab(0);
00151   os << tab << "ComposedOperator[" << std::endl;
00152   for (int i=0; i<ops_.size(); i++)
00153   {
00154     Tabs tab1;
00155     os << tab1 << "factor #" << i << std::endl;
00156     Tabs tab2;
00157     os << tab2 << ops_[i].description() << std::endl;
00158     os << std::endl;
00159   }
00160   os << tab << "]" <<  std::endl;
00161 }
00162 
00163 
00164 template <class Scalar> inline
00165 LinearOperator<Scalar> composedOperator(
00166   const Array<LinearOperator<Scalar> >& ops)
00167 {
00168   /* We will strip out any identity operators, and if we find a zero
00169   * operator the whole works becomes a zero operator */ 
00170   Array<LinearOperator<Scalar> > strippedOps;
00171 
00172   for (int i=0; i<ops.size(); i++)
00173   {
00174     LinearOperator<Scalar> op_i = ops[i];
00175 
00176     /* if a factor is zero, the whole operator is
00177      * a zero operator */
00178     const SimpleZeroOp<Scalar>* zPtr 
00179       = dynamic_cast<const SimpleZeroOp<Scalar>*>(op_i.ptr().get());
00180 
00181     if (zPtr != 0) 
00182     {
00183       VectorSpace<Scalar> r = ops[0].range();
00184       VectorSpace<Scalar> d = ops[ops.size()-1].domain();
00185       return zeroOperator(d, r);
00186     }
00187 
00188     /* if a factor is the identity, skip it */
00189     const SimpleIdentityOp<Scalar>* IPtr 
00190       = dynamic_cast<const SimpleIdentityOp<Scalar>*>(op_i.ptr().get());  
00191     if (IPtr != 0) 
00192     {
00193       continue;
00194     }
00195 
00196     strippedOps.append(op_i);
00197   }
00198   
00199   TEUCHOS_TEST_FOR_EXCEPT(strippedOps.size() < 1);
00200   if (strippedOps.size()==1) return strippedOps[0];
00201   
00202   RCP<LinearOperatorBase<Scalar> > op 
00203     = rcp(new SimpleComposedOp<Scalar>(strippedOps));
00204   return op;
00205 }
00206 
00207 template <class Scalar> inline
00208 LinearOperator<Scalar> operator*(const LinearOperator<Scalar>& A, 
00209   const LinearOperator<Scalar>& B)
00210 {
00211   return composedOperator(Array<LinearOperator<Scalar> >(tuple(A,B)));
00212 }
00213   
00214 
00215 }
00216 
00217 #endif

Site Contact