RTOp Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
RTOpPack_RTOpTHelpers_decl.hpp
Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 // RTOp: Interfaces and Support Software for Vector Reduction Transformation
00005 //       Operations
00006 //                Copyright (2006) Sandia Corporation
00007 // 
00008 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00009 // license for use of this work by or on behalf of the U.S. Government.
00010 // 
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 
00039 // 
00040 // ***********************************************************************
00041 // @HEADER
00042 
00043 #ifndef RTOPPACK_RTOP_T_HELPERS_DECL_HPP
00044 #define RTOPPACK_RTOP_T_HELPERS_DECL_HPP
00045 
00046 
00047 //#define RTOPPACK_RTOPT_HELPER_DUMP_OUTPUT
00048 
00049 
00050 #include <typeinfo>
00051 
00052 
00053 #include "RTOpPack_RTOpT.hpp"
00054 #include "Teuchos_StandardMemberCompositionMacros.hpp"
00055 #include "Teuchos_ScalarTraits.hpp"
00056 #include "Teuchos_dyn_cast.hpp"
00057 #include "Teuchos_TypeNameTraits.hpp"
00058 
00059 
00060 #ifdef RTOPPACK_RTOPT_HELPER_DUMP_OUTPUT
00061 #  include "Teuchos_VerboseObject.hpp"
00062 namespace RTOpPack { extern bool rtop_helpers_dump_all; }
00063 #endif // RTOPPACK_RTOPT_HELPER_DUMP_OUTPUT
00064 
00065 
00066 namespace RTOpPack {
00067 
00068 
00073 template<class Scalar>
00074 struct ScalarIndex {
00076   Scalar scalar;
00078   Ordinal  index;
00080   ScalarIndex( const Scalar &_scalar, const Ordinal &_index )
00081     : scalar(_scalar), index(_index)
00082     {}
00084   ScalarIndex()
00085     : scalar(ScalarTraits<Scalar>::zero()), index(-1)
00086     {}
00087 };
00088 
00089 
00094 template<class Scalar>
00095 std::ostream& operator<<(std::ostream &out, const ScalarIndex<Scalar> &scalarIndex)
00096 {
00097   out << "{"<<scalarIndex.scalar<<","<<scalarIndex.index<<"}";
00098   return out;
00099 }
00100 
00101 
00105 template <class Scalar>
00106 class PrimitiveTypeTraits<Scalar, ScalarIndex<Scalar> > {
00107 public:
00109   typedef PrimitiveTypeTraits<Scalar,Scalar> ScalarPrimitiveTypeTraits;
00111   typedef typename ScalarPrimitiveTypeTraits::primitiveType primitiveType;
00113   static int numPrimitiveObjs() { return ScalarPrimitiveTypeTraits::numPrimitiveObjs(); }
00115   static int numIndexObjs() { return 1; }
00117   static int numCharObjs() { return 0; }
00119   static void extractPrimitiveObjs(
00120     const ScalarIndex<Scalar> &obj,
00121     const ArrayView<primitiveType> &primitiveObjs,
00122     const ArrayView<index_type> &indexObjs,
00123     const ArrayView<char> &charObjs
00124     )
00125     {
00126       assertInput(primitiveObjs, indexObjs, charObjs);
00127       ScalarPrimitiveTypeTraits::extractPrimitiveObjs(
00128         obj.scalar, primitiveObjs, Teuchos::null, Teuchos::null );
00129       indexObjs[0] = obj.index;
00130     }
00132   static void loadPrimitiveObjs(
00133     const ArrayView<const primitiveType> &primitiveObjs,
00134     const ArrayView<const index_type> &indexObjs,
00135     const ArrayView<const char> &charObjs,
00136     const Ptr<ScalarIndex<Scalar> > &obj
00137     )
00138     {
00139       assertInput(primitiveObjs, indexObjs, charObjs);
00140       ScalarPrimitiveTypeTraits::loadPrimitiveObjs(
00141         primitiveObjs, Teuchos::null, Teuchos::null,
00142         Teuchos::outArg(obj->scalar) );
00143       obj->index = indexObjs[0];
00144     }
00145 private:
00146   static void assertInput(
00147     const ArrayView<const primitiveType> &primitiveObjs,
00148     const ArrayView<const index_type> &indexObjs,
00149     const ArrayView<const char> &charObjs
00150     )
00151     {
00152 #ifdef TEUCHOS_DEBUG
00153       TEUCHOS_TEST_FOR_EXCEPT(
00154         primitiveObjs.size()!=ScalarPrimitiveTypeTraits::numPrimitiveObjs()
00155         || indexObjs.size()!=1
00156         || charObjs.size()!=0 );
00157 #endif
00158     }
00159 };
00160 
00161 
00166 template<class ConcreteReductObj>
00167 class DefaultReductTarget : public ReductTarget {
00168 public:
00170   DefaultReductTarget( const ConcreteReductObj &concreteReductObj )
00171     : concreteReductObj_(concreteReductObj)
00172     {}
00174   void set( const ConcreteReductObj &concreteReductObj )
00175     { concreteReductObj_ = concreteReductObj; }
00177   const ConcreteReductObj& get() const
00178     { return concreteReductObj_; }
00180   std::string description() const;
00181 private:
00182   ConcreteReductObj concreteReductObj_;
00183 };
00184 
00185 
00190 template<class ConcreteReductObj>
00191 const RCP<DefaultReductTarget<ConcreteReductObj> >
00192 defaultReductTarget( const ConcreteReductObj &concreteReductObj )
00193 {
00194   return Teuchos::rcp(
00195     new DefaultReductTarget<ConcreteReductObj>(concreteReductObj));
00196 }
00197 
00198 
00221 template<class Scalar>
00222 void validate_apply_op(
00223   const RTOpT<Scalar> &op,
00224   const int allowed_num_sub_vecs,
00225   const int allowed_num_targ_sub_vecs,
00226   const bool expect_reduct_obj,
00227   const ArrayView<const ConstSubVectorView<Scalar> > &sub_vecs,
00228   const ArrayView<const SubVectorView<Scalar> > &targ_sub_vecs,
00229   const Ptr<const ReductTarget> &reduct_obj
00230   );
00231 
00232 
00233 //
00234 // Reduction object operator support
00235 //
00236 
00237 
00239 enum EBasicReductTypes { REDUCT_TYPE_SUM, REDUCT_TYPE_MAX, REDUCT_TYPE_MIN };
00240 
00241 
00243 template<class ConcreteReductObj, int ReductionType>
00244 class BasicReductObjReductionOp {
00245 public:
00247   inline void operator()(const ConcreteReductObj& in_reduct, ConcreteReductObj& inout_reduct) const
00248     {
00249       return in_reduct.this_reduction_type_needs_a_specialization();
00250     }
00251 };
00252 
00253 
00255 template<class ConcreteReductObj>
00256 class BasicReductObjReductionOp<ConcreteReductObj, REDUCT_TYPE_SUM> {
00257 public:
00259   inline void operator()(const ConcreteReductObj& in_reduct, ConcreteReductObj& inout_reduct) const
00260     {
00261       inout_reduct += in_reduct;
00262     }
00263 };
00264 
00265 
00267 template<class ConcreteReductObj>
00268 class BasicReductObjReductionOp<ConcreteReductObj, REDUCT_TYPE_MAX> {
00269 public:
00271   inline void operator()(const ConcreteReductObj& in_reduct, ConcreteReductObj& inout_reduct) const
00272     {
00273       inout_reduct = std::max(inout_reduct, in_reduct);
00274     }
00275 };
00276 
00277 
00279 template<class ConcreteReductObj>
00280 class BasicReductObjReductionOp<ConcreteReductObj, REDUCT_TYPE_MIN> {
00281 public:
00283   inline void operator()(const ConcreteReductObj& in_reduct, ConcreteReductObj& inout_reduct) const
00284     {
00285       inout_reduct = std::min(inout_reduct, in_reduct);
00286     }
00287 };
00288 
00289 
00291 template<class Scalar>
00292 class SumScalarReductObjReduction {
00293 public:
00295   inline void operator()(const Scalar& in_reduct, Scalar& inout_reduct) const
00296     {
00297       inout_reduct += in_reduct;
00298     }
00299 };
00300 // 2008/07/03: rabart: Above: I have broken from the Thyra guideline of
00301 // passing in-out arguments as const Ptr<Type>& and used raw non-const
00302 // reference Type& instead to allow the user function to be more readable.
00303 
00304 
00306 template<class Scalar, class ConcreteReductObj, class ReductObjReduction>
00307 class ROpScalarReductionWithOpBase : public RTOpT<Scalar>
00308 {
00309 public:
00310 
00312   using RTOpT<Scalar>::apply_op;
00313 
00315   typedef typename RTOpT<Scalar>::primitive_value_type primitive_value_type;
00316 
00318   ROpScalarReductionWithOpBase(
00319     const ConcreteReductObj &initReductObjValue_in = ScalarTraits<Scalar>::zero(),
00320     ReductObjReduction reductObjReduction_in = ReductObjReduction()
00321     )
00322     : initReductObjValue_(initReductObjValue_in),
00323       reductObjReduction_(reductObjReduction_in)
00324     {}
00325 
00327   const ConcreteReductObj& getRawVal( const ReductTarget &reduct_obj ) const
00328     {
00329       using Teuchos::dyn_cast;
00330       return dyn_cast<const DefaultReductTarget<ConcreteReductObj> >(reduct_obj).get();
00331     }
00332 
00334   void setRawVal( const ConcreteReductObj &rawVal,
00335     const Ptr<ReductTarget> &reduct_obj
00336     ) const
00337     {
00338       using Teuchos::dyn_cast;
00339       dyn_cast<DefaultReductTarget<ConcreteReductObj> >(*reduct_obj).set(rawVal);
00340     }
00341 
00343   ConcreteReductObj operator()(const ReductTarget& reduct_obj ) const
00344     {
00345       return this->getRawVal(reduct_obj);
00346     }
00347 
00350 
00352   void get_reduct_type_num_entries_impl(
00353     const Ptr<int> &num_values,
00354     const Ptr<int> &num_indexes,
00355     const Ptr<int> &num_chars
00356     ) const
00357     {
00358       typedef PrimitiveTypeTraits<Scalar, ConcreteReductObj> PTT;
00359       *num_values = PTT::numPrimitiveObjs();
00360       *num_indexes = PTT::numIndexObjs();
00361       *num_chars = PTT::numCharObjs();
00362     }
00363 
00365   Teuchos::RCP<ReductTarget> reduct_obj_create_impl() const
00366     {
00367       return Teuchos::rcp(
00368         new DefaultReductTarget<ConcreteReductObj>(initReductObjValue()));
00369     }
00370 
00372   virtual void reduce_reduct_objs_impl(
00373     const ReductTarget& in_reduct_obj, const Ptr<ReductTarget>& inout_reduct_obj
00374     ) const
00375     {
00376       const ConcreteReductObj scalar_in_reduct_obj = this->getRawVal(in_reduct_obj);
00377       ConcreteReductObj scalar_inout_reduct_obj = this->getRawVal(*inout_reduct_obj);
00378       reductObjReduction_(scalar_in_reduct_obj, scalar_inout_reduct_obj);
00379       this->setRawVal( scalar_inout_reduct_obj, inout_reduct_obj );
00380     }
00381 
00383   void reduct_obj_reinit_impl( const Ptr<ReductTarget> &reduct_obj ) const
00384     {
00385       setRawVal( initReductObjValue(), reduct_obj );
00386     }
00387 
00389   void extract_reduct_obj_state_impl(
00390     const ReductTarget &reduct_obj,
00391     const ArrayView<primitive_value_type> &value_data,
00392     const ArrayView<index_type> &index_data,
00393     const ArrayView<char_type> &char_data
00394     ) const
00395     {
00396       typedef PrimitiveTypeTraits<Scalar, ConcreteReductObj> PTT;
00397       PTT::extractPrimitiveObjs( getRawVal(reduct_obj),
00398         value_data, index_data, char_data );
00399     }
00400 
00402   void load_reduct_obj_state_impl(
00403     const ArrayView<const primitive_value_type> &value_data,
00404     const ArrayView<const index_type> &index_data,
00405     const ArrayView<const char_type> &char_data,
00406     const Ptr<ReductTarget> &reduct_obj
00407     ) const
00408     {
00409       typedef PrimitiveTypeTraits<Scalar, ConcreteReductObj> PTT;
00410       ConcreteReductObj concrete_reduct_obj;
00411       PTT::loadPrimitiveObjs( value_data, index_data, char_data,
00412         Teuchos::outArg(concrete_reduct_obj) );
00413       this->setRawVal( concrete_reduct_obj, reduct_obj );
00414     }
00415 
00417 
00418 protected:
00419 
00421   STANDARD_MEMBER_COMPOSITION_MEMBERS( ConcreteReductObj, initReductObjValue );
00422 
00423 private:
00424 
00425   ReductObjReduction reductObjReduction_;
00426 
00427 };
00428 
00429 
00430 //
00431 // ROp 1 vector scalar reduction
00432 //
00433 
00434 
00436 template<class Scalar, class ConcreteReductObj, class EleWiseReduction,
00437   class ReductObjReduction = SumScalarReductObjReduction<ConcreteReductObj> >
00438 class ROp_1_ScalarReduction
00439   : public ROpScalarReductionWithOpBase<Scalar, ConcreteReductObj, ReductObjReduction>
00440 {
00441 public:
00442 
00444   typedef ROpScalarReductionWithOpBase<Scalar, ConcreteReductObj, ReductObjReduction> base_t;
00445 
00447   ROp_1_ScalarReduction(
00448     const ConcreteReductObj &initReductObjValue_in = ConcreteReductObj(),
00449     EleWiseReduction eleWiseReduction_in = EleWiseReduction(),
00450     ReductObjReduction reductObjReduction_in = ReductObjReduction()
00451     )
00452     : base_t(initReductObjValue_in, reductObjReduction_in),
00453       eleWiseReduction_(eleWiseReduction_in)
00454     {}
00455 
00458 
00460   void apply_op_impl(
00461     const ArrayView<const ConstSubVectorView<Scalar> > &sub_vecs,
00462     const ArrayView<const SubVectorView<Scalar> > &targ_sub_vecs,
00463     const Ptr<ReductTarget> &reduct_obj_inout
00464     ) const
00465     {
00466       typedef typename Teuchos::ArrayRCP<const Scalar>::iterator const_iter_t;
00467       using Teuchos::dyn_cast;
00468 
00469 #ifdef TEUCHOS_DEBUG
00470       validate_apply_op<Scalar>(*this, 1, 0, true,
00471         sub_vecs, targ_sub_vecs, reduct_obj_inout.getConst());
00472 #endif
00473 
00474       DefaultReductTarget<ConcreteReductObj> &reduct_obj =
00475         dyn_cast<DefaultReductTarget<ConcreteReductObj> >(*reduct_obj_inout); 
00476       ConcreteReductObj reduct = reduct_obj.get();
00477       
00478       const RTOpPack::index_type subDim = sub_vecs[0].subDim();
00479 
00480       const_iter_t v0_val = sub_vecs[0].values().begin();
00481       const ptrdiff_t v0_s = sub_vecs[0].stride();
00482 
00483       if ( v0_s == 1 ) {
00484         for( Teuchos_Ordinal i = 0; i < subDim; ++i )
00485           eleWiseReduction_( *v0_val++, reduct);
00486       }
00487       else {
00488         for( Teuchos_Ordinal i = 0; i < subDim; ++i, v0_val += v0_s )
00489           eleWiseReduction_( *v0_val, reduct);
00490       }
00491       
00492       reduct_obj.set(reduct);
00493       
00494     }
00495   
00497   
00498 private:
00499 
00500   EleWiseReduction eleWiseReduction_;
00501 
00502 };
00503 
00504 
00506 #define RTOP_ROP_1_REDUCT_SCALAR_CUSTOM_DEFAULT( ROP_CLASS_NAME, REDUCT_SCALAR, \
00507   BASIC_REDUCT_TYPE_ENUM, CUSTOM_DEFAULT \
00508   ) \
00509   \
00510   template<class Scalar, class ReductScalar> \
00511   class ROP_CLASS_NAME ## EleWiseReduction \
00512   { \
00513   public: \
00514     inline void operator()( \
00515       const Scalar &v0, \
00516       ReductScalar &reduct \
00517       ) const; \
00518   }; \
00519   \
00520   \
00521   template<class Scalar> \
00522   class ROP_CLASS_NAME  \
00523     : public RTOpPack::ROp_1_ScalarReduction< \
00524         Scalar, \
00525         REDUCT_SCALAR, \
00526         ROP_CLASS_NAME ## EleWiseReduction<Scalar, REDUCT_SCALAR >, \
00527         RTOpPack::BasicReductObjReductionOp<REDUCT_SCALAR, BASIC_REDUCT_TYPE_ENUM> > \
00528   { \
00529     typedef RTOpPack::ROp_1_ScalarReduction< \
00530       Scalar, \
00531       REDUCT_SCALAR, \
00532       ROP_CLASS_NAME ## EleWiseReduction<Scalar, REDUCT_SCALAR >, \
00533       RTOpPack::BasicReductObjReductionOp<REDUCT_SCALAR, BASIC_REDUCT_TYPE_ENUM> > \
00534       base_t; \
00535   public: \
00536     ROP_CLASS_NAME() \
00537       : base_t(CUSTOM_DEFAULT) \
00538       { \
00539         this->setOpNameBase( #ROP_CLASS_NAME ); \
00540       } \
00541   }; \
00542   \
00543   \
00544   template<class Scalar, class ReductScalar> \
00545   void ROP_CLASS_NAME ## EleWiseReduction<Scalar, ReductScalar>::operator()( \
00546     const Scalar &v0, ReductScalar &reduct \
00547     ) const
00548 
00549 
00551 #define RTOP_ROP_1_REDUCT_SCALAR( ROP_CLASS_NAME, REDUCT_SCALAR, \
00552   BASIC_REDUCT_TYPE_ENUM \
00553   ) \
00554   RTOP_ROP_1_REDUCT_SCALAR_CUSTOM_DEFAULT(ROP_CLASS_NAME, REDUCT_SCALAR, \
00555     BASIC_REDUCT_TYPE_ENUM, Teuchos::ScalarTraits<REDUCT_SCALAR >::zero() )
00556 
00557 
00558 //
00559 // ROp 1 coordinate-variant vector scalar reduction
00560 //
00561 
00562 
00565 template<
00566   class Scalar,
00567   class ReductScalar,
00568   class EleWiseReduction,
00569   class ReductObjReduction = SumScalarReductObjReduction<ReductScalar>
00570   >
00571 class ROp_1_CoordVariantScalarReduction
00572   : public ROpScalarReductionWithOpBase<Scalar, ReductScalar, ReductObjReduction>
00573 {
00574 public:
00575 
00578 
00580   typedef ROpScalarReductionWithOpBase<Scalar, ReductScalar, ReductObjReduction> base_t;
00581 
00583   ROp_1_CoordVariantScalarReduction(
00584     const ReductScalar &initReductObjValue_in = ReductScalar(),
00585     EleWiseReduction eleWiseReduction_in = EleWiseReduction(),
00586     ReductObjReduction reductObjReduction_in = ReductObjReduction()
00587     )
00588     : base_t(initReductObjValue_in, reductObjReduction_in),
00589       eleWiseReduction_(eleWiseReduction_in)
00590     {}
00591 
00593   void setEleWiseReduction(EleWiseReduction eleWiseReduction_in)
00594     { eleWiseReduction_ = eleWiseReduction_in; }
00595 
00597   const EleWiseReduction& getEleWiseReduction() const
00598     { return eleWiseReduction_; }
00599   
00601 
00604 
00606   bool coord_invariant_impl() const { return false; }
00607 
00609   void apply_op_impl(
00610     const ArrayView<const ConstSubVectorView<Scalar> > &sub_vecs,
00611     const ArrayView<const SubVectorView<Scalar> > &targ_sub_vecs,
00612     const Ptr<ReductTarget> &reduct_obj_inout
00613     ) const
00614     {
00615       typedef typename Teuchos::ArrayRCP<const Scalar>::iterator const_iter_t;
00616       using Teuchos::dyn_cast;
00617 
00618 #ifdef TEUCHOS_DEBUG
00619       validate_apply_op<Scalar>(*this, 1, 0, true,
00620         sub_vecs, targ_sub_vecs, reduct_obj_inout);
00621 #endif
00622 
00623       DefaultReductTarget<ReductScalar> &reduct_obj =
00624         dyn_cast<DefaultReductTarget<ReductScalar> >(*reduct_obj_inout); 
00625       ReductScalar reduct = reduct_obj.get();
00626       
00627       const RTOpPack::index_type subDim = sub_vecs[0].subDim();
00628 
00629       const_iter_t v0_val = sub_vecs[0].values().begin();
00630       const ptrdiff_t v0_s = sub_vecs[0].stride();
00631 
00632       RTOpPack::index_type global_i = sub_vecs[0].globalOffset();
00633 
00634       if ( v0_s == 1 ) {
00635         for( Teuchos_Ordinal i = 0; i < subDim; ++i, ++global_i )
00636           eleWiseReduction_( global_i, *v0_val++, reduct);
00637       }
00638       else {
00639         for( Teuchos_Ordinal i = 0; i < subDim; ++i, v0_val += v0_s, ++global_i )
00640           eleWiseReduction_( global_i, *v0_val, reduct);
00641       }
00642       
00643       reduct_obj.set(reduct);
00644       
00645     }
00646   
00648   
00649 private:
00650 
00651   EleWiseReduction eleWiseReduction_;
00652 
00653 };
00654 
00655 
00656 //
00657 // ROp 2 vector scalar reduction
00658 //
00659 
00660 
00662 template<
00663   class Scalar,
00664   class ReductScalar,
00665   class EleWiseReduction,
00666   class ReductObjReduction = SumScalarReductObjReduction<ReductScalar>
00667   >
00668 class ROp_2_ScalarReduction
00669   : public ROpScalarReductionWithOpBase<Scalar, ReductScalar, ReductObjReduction>
00670 {
00671 public:
00672 
00674   typedef ROpScalarReductionWithOpBase<Scalar, ReductScalar, ReductObjReduction>
00675     base_t;
00676 
00678   ROp_2_ScalarReduction(
00679     const ReductScalar &initReductObjValue_in = ReductScalar(),
00680     EleWiseReduction eleWiseReduction_in = EleWiseReduction(),
00681     ReductObjReduction reductObjReduction_in = ReductObjReduction()
00682     )
00683     : base_t(initReductObjValue_in, reductObjReduction_in),
00684       eleWiseReduction_(eleWiseReduction_in)
00685     {}
00686 
00689 
00691   void apply_op_impl(
00692     const ArrayView<const ConstSubVectorView<Scalar> > &sub_vecs,
00693     const ArrayView<const SubVectorView<Scalar> > &targ_sub_vecs,
00694     const Ptr<ReductTarget> &reduct_obj_inout
00695     ) const
00696     {
00697       typedef typename Teuchos::ArrayRCP<const Scalar>::iterator const_iter_t;
00698       using Teuchos::dyn_cast;
00699 
00700 #ifdef TEUCHOS_DEBUG
00701       validate_apply_op<Scalar>(*this, 2, 0, true,
00702         sub_vecs, targ_sub_vecs, reduct_obj_inout.getConst());
00703 #endif
00704 
00705       DefaultReductTarget<Scalar> &reduct_obj =
00706         dyn_cast<DefaultReductTarget<Scalar> >(*reduct_obj_inout); 
00707       Scalar reduct = reduct_obj.get();
00708 
00709       const RTOpPack::index_type subDim = sub_vecs[0].subDim();
00710 
00711       const_iter_t v0_val = sub_vecs[0].values().begin();
00712       const ptrdiff_t v0_s = sub_vecs[0].stride();
00713       const_iter_t v1_val = sub_vecs[1].values().begin();
00714       const ptrdiff_t v1_s = sub_vecs[1].stride();
00715 
00716       if( v0_s == 1 && v1_s == 1 ) {
00717         for( Teuchos_Ordinal i = 0; i < subDim; ++i )
00718           eleWiseReduction_( *v0_val++, *v1_val++, reduct);
00719       }
00720       else {
00721         for( Teuchos_Ordinal i = 0; i < subDim; ++i, v0_val += v0_s, v1_val += v1_s )
00722           eleWiseReduction_( *v0_val, *v1_val, reduct);
00723       }
00724 
00725       reduct_obj.set(reduct);
00726 
00727     }
00728 
00730 
00731 private:
00732 
00733   EleWiseReduction eleWiseReduction_;
00734 
00735 };
00736 
00737 
00741 #define RTOP_ROP_2_REDUCT_SCALAR( ROP_CLASS_NAME, REDUCT_SCALAR, \
00742   BASIC_REDUCT_TYPE_ENUM \
00743   ) \
00744   \
00745   template<class Scalar, class ReductScalar> \
00746   class ROP_CLASS_NAME ## EleWiseReduction \
00747   { \
00748   public: \
00749     inline void operator()(const Scalar &v0, \
00750       const Scalar &v1, \
00751       ReductScalar &reduct \
00752       ) const; \
00753   }; \
00754   \
00755   \
00756   template<class Scalar> \
00757   class ROP_CLASS_NAME  \
00758     : public RTOpPack::ROp_2_ScalarReduction< \
00759         Scalar, \
00760         REDUCT_SCALAR, \
00761         ROP_CLASS_NAME ## EleWiseReduction<Scalar, REDUCT_SCALAR >, \
00762         RTOpPack::BasicReductObjReductionOp<REDUCT_SCALAR, BASIC_REDUCT_TYPE_ENUM> > \
00763   { \
00764   public: \
00765     ROP_CLASS_NAME() \
00766       { \
00767         this->setOpNameBase( #ROP_CLASS_NAME ); \
00768         this->initReductObjValue(ScalarTraits<REDUCT_SCALAR >::zero()); \
00769       } \
00770   }; \
00771   \
00772   template<class Scalar, class ReductScalar> \
00773   void ROP_CLASS_NAME ## EleWiseReduction<Scalar, ReductScalar>::operator()( \
00774     const Scalar &v0, const Scalar &v1, ReductScalar &reduct) const
00775 
00776 
00777 //
00778 // TOp 0 to 1 vector transformation
00779 //
00780 
00781 
00783 template<class Scalar, class EleWiseTransformation>
00784 class TOp_0_1_Base : public RTOpT<Scalar>
00785 {
00786 public:
00787 
00789   TOp_0_1_Base(
00790     EleWiseTransformation eleWiseTransformation = EleWiseTransformation()
00791     )
00792     : eleWiseTransformation_(eleWiseTransformation)
00793     {}
00794 
00797 
00799   void apply_op_impl(
00800     const ArrayView<const ConstSubVectorView<Scalar> > &sub_vecs,
00801     const ArrayView<const SubVectorView<Scalar> > &targ_sub_vecs,
00802     const Ptr<ReductTarget> &reduct_obj_inout
00803     ) const
00804     {
00805       typedef typename Teuchos::ArrayRCP<Scalar>::iterator iter_t;
00806 
00807 #ifdef TEUCHOS_DEBUG
00808       validate_apply_op<Scalar>(*this, 0, 1, false,
00809         sub_vecs, targ_sub_vecs, reduct_obj_inout.getConst());
00810 #endif
00811       
00812       const RTOpPack::index_type subDim = targ_sub_vecs[0].subDim();
00813 
00814       iter_t z0_val = targ_sub_vecs[0].values().begin();
00815       const ptrdiff_t z0_s = targ_sub_vecs[0].stride();
00816 
00817       if ( z0_s == 1 ) {
00818         for( Teuchos_Ordinal i = 0; i < subDim; ++i )
00819           eleWiseTransformation_( *z0_val++);
00820       }
00821       else {
00822         for( Teuchos_Ordinal i = 0; i < subDim; ++i, z0_val += z0_s )
00823           eleWiseTransformation_( *z0_val);
00824       }
00825       
00826     }
00827   
00829   
00830 private:
00831 
00832   EleWiseTransformation eleWiseTransformation_;
00833 
00834 };
00835 
00836 
00839 template<class Scalar, class EleWiseTransformation>
00840 class TOp_0_1_CoordVariantBase : public RTOpT<Scalar>
00841 {
00842 public:
00843 
00845   TOp_0_1_CoordVariantBase(
00846     EleWiseTransformation eleWiseTransformation = EleWiseTransformation()
00847     )
00848     : eleWiseTransformation_(eleWiseTransformation)
00849     {}
00850 
00852   void setEleWiseTransformation(EleWiseTransformation eleWiseTransformation)
00853     {
00854       eleWiseTransformation_ = eleWiseTransformation;
00855     }
00856 
00858   const EleWiseTransformation& getEleWiseTransformation() const
00859     {
00860       return eleWiseTransformation_;
00861     }
00862   
00865 
00867   bool coord_invariant_impl() const { return false; }
00868 
00870   void apply_op_impl(
00871     const ArrayView<const ConstSubVectorView<Scalar> > &sub_vecs,
00872     const ArrayView<const SubVectorView<Scalar> > &targ_sub_vecs,
00873     const Ptr<ReductTarget> &reduct_obj_inout
00874     ) const
00875     {
00876       typedef typename Teuchos::ArrayRCP<Scalar>::iterator iter_t;
00877 
00878 #ifdef TEUCHOS_DEBUG
00879       validate_apply_op<Scalar>(*this, 0, 1, false,
00880         sub_vecs, targ_sub_vecs, reduct_obj_inout.getConst());
00881 #endif
00882       
00883       const RTOpPack::index_type subDim = targ_sub_vecs[0].subDim();
00884 
00885       iter_t z0_val = targ_sub_vecs[0].values().begin();
00886       const ptrdiff_t z0_s = targ_sub_vecs[0].stride();
00887 
00888       RTOpPack::index_type global_i = targ_sub_vecs[0].globalOffset();
00889 
00890       if ( z0_s == 1 ) {
00891         for( Teuchos_Ordinal i = 0; i < subDim; ++i, ++global_i )
00892           eleWiseTransformation_(global_i, *z0_val++);
00893       }
00894       else {
00895         for( Teuchos_Ordinal i = 0; i < subDim; ++i, z0_val += z0_s, ++global_i )
00896           eleWiseTransformation_(global_i, *z0_val);
00897       }
00898       
00899     }
00900   
00902   
00903 private:
00904 
00905   EleWiseTransformation eleWiseTransformation_;
00906 
00907 };
00908 
00909 
00910 //
00911 // TOp 1 to 1 vector transformation
00912 //
00913 
00914 
00916 template<class Scalar, class EleWiseTransformation>
00917 class TOp_1_1_Base : public RTOpT<Scalar>
00918 {
00919 public:
00920 
00922   TOp_1_1_Base(
00923     EleWiseTransformation eleWiseTransformation = EleWiseTransformation()
00924     )
00925     : eleWiseTransformation_(eleWiseTransformation)
00926     {}
00927 
00930 
00932   void apply_op_impl(
00933     const ArrayView<const ConstSubVectorView<Scalar> > &sub_vecs,
00934     const ArrayView<const SubVectorView<Scalar> > &targ_sub_vecs,
00935     const Ptr<ReductTarget> &reduct_obj_inout
00936     ) const
00937     {
00938       typedef typename Teuchos::ArrayRCP<const Scalar>::iterator const_iter_t;
00939       typedef typename Teuchos::ArrayRCP<Scalar>::iterator iter_t;
00940 
00941 #ifdef TEUCHOS_DEBUG
00942       validate_apply_op<Scalar>(*this, 1, 1, false,
00943         sub_vecs, targ_sub_vecs, reduct_obj_inout.getConst());
00944 #endif
00945       
00946       const RTOpPack::index_type subDim = sub_vecs[0].subDim();
00947 
00948       const_iter_t v0_val = sub_vecs[0].values().begin();
00949       const ptrdiff_t v0_s = sub_vecs[0].stride();
00950 
00951       iter_t z0_val = targ_sub_vecs[0].values().begin();
00952       const ptrdiff_t z0_s = targ_sub_vecs[0].stride();
00953 
00954       if ( v0_s == 1 && z0_s == 1 ) {
00955         for( Teuchos_Ordinal i = 0; i < subDim; ++i )
00956           eleWiseTransformation_( *v0_val++, *z0_val++);
00957       }
00958       else {
00959         for( Teuchos_Ordinal i = 0; i < subDim; ++i, v0_val += v0_s, z0_val += z0_s )
00960           eleWiseTransformation_( *v0_val, *z0_val);
00961       }
00962       
00963     }
00964   
00966   
00967 private:
00968 
00969   EleWiseTransformation eleWiseTransformation_;
00970 
00971 };
00972 
00973 
00975 #define RTOP_TOP_1_1( TOP_CLASS_NAME ) \
00976   \
00977   template<class Scalar> \
00978   class TOP_CLASS_NAME ## EleWiseTransformation \
00979   { \
00980   public: \
00981     inline void operator()( const Scalar &v0, Scalar &z0 ) const; \
00982   }; \
00983   \
00984   \
00985   template<class Scalar> \
00986   class TOP_CLASS_NAME  \
00987     : public RTOpPack::TOp_1_1_Base< Scalar, \
00988         TOP_CLASS_NAME ## EleWiseTransformation<Scalar> > \
00989   { \
00990   public: \
00991     TOP_CLASS_NAME() \
00992       { \
00993         this->setOpNameBase( #TOP_CLASS_NAME ); \
00994       } \
00995   }; \
00996   \
00997   \
00998   template<class Scalar> \
00999   void TOP_CLASS_NAME ## EleWiseTransformation<Scalar>::operator()( \
01000     const Scalar &v0, Scalar &z0 \
01001     ) const
01002 
01003 
01004 //
01005 // TOp 2 to 1 vector transformation
01006 //
01007 
01008 
01010 template<class Scalar, class EleWiseTransformation>
01011 class TOp_2_1_Base : public RTOpT<Scalar>
01012 {
01013 public:
01014 
01016   TOp_2_1_Base(
01017     EleWiseTransformation eleWiseTransformation = EleWiseTransformation()
01018     )
01019     : eleWiseTransformation_(eleWiseTransformation)
01020     {}
01021 
01024 
01026   void apply_op_impl(
01027     const ArrayView<const ConstSubVectorView<Scalar> > &sub_vecs,
01028     const ArrayView<const SubVectorView<Scalar> > &targ_sub_vecs,
01029     const Ptr<ReductTarget> &reduct_obj_inout
01030     ) const
01031     {
01032       typedef typename Teuchos::ArrayRCP<const Scalar>::iterator const_iter_t;
01033       typedef typename Teuchos::ArrayRCP<Scalar>::iterator iter_t;
01034 
01035 #ifdef TEUCHOS_DEBUG
01036       validate_apply_op<Scalar>(*this, 2, 1, false,
01037         sub_vecs, targ_sub_vecs, reduct_obj_inout);
01038 #endif
01039       
01040       const RTOpPack::index_type subDim = sub_vecs[0].subDim();
01041 
01042       const_iter_t v0_val = sub_vecs[0].values().begin();
01043       const ptrdiff_t v0_s = sub_vecs[0].stride();
01044 
01045       const_iter_t v1_val = sub_vecs[1].values().begin();
01046       const ptrdiff_t v1_s = sub_vecs[1].stride();
01047 
01048       iter_t z0_val = targ_sub_vecs[0].values().begin();
01049       const ptrdiff_t z0_s = targ_sub_vecs[0].stride();
01050 
01051       if ( v0_s == 1 && v1_s == 1 && z0_s == 1 ) {
01052         for( Teuchos_Ordinal i = 0; i < subDim; ++i )
01053           eleWiseTransformation_( *v0_val++, *v1_val++, *z0_val++ );
01054       }
01055       else {
01056         for(
01057           Teuchos_Ordinal i = 0;
01058           i < subDim;
01059           ++i, v0_val += v0_s, v1_val += v1_s, z0_val += z0_s
01060           )
01061         {
01062           eleWiseTransformation_( *v0_val, *v1_val, *z0_val );
01063         }
01064       }
01065       
01066     }
01067   
01069   
01070 private:
01071 
01072   EleWiseTransformation eleWiseTransformation_;
01073 
01074 };
01075 
01076 
01077 } // namespace RTOpPack
01078 
01079 
01080 #endif // RTOPPACK_RTOP_T_HELPERS_DECL_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines