Tpetra_Util.hpp

Go to the documentation of this file.
00001 // HAVE_@HEADER
00002 // ***********************************************************************
00003 // 
00004 //          Tpetra: Templated Linear Algebra Services Package
00005 //                 Copyright (2008) 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 TPETRA_UTIL_HPP
00030 #define TPETRA_UTIL_HPP
00031 
00032 #include "Tpetra_ConfigDefs.hpp" // for map, vector, string, and iostream 
00033 #include <iterator>
00034 #include <Teuchos_Utils.hpp>
00035 #include <Teuchos_TestForException.hpp>
00036 
00037 // handle an efficiency warning, according to HAVE_TPETRA_THROW_EFFICIENCY_WARNINGS and HAVE_TPETRA_PRINT_EFFICIENCY_WARNINGS
00038 #if defined(HAVE_TPETRA_THROW_EFFICIENCY_WARNINGS) || defined(HAVE_TPETRA_PRINT_EFFICIENCY_WARNINGS)
00039 #define TPETRA_EFFICIENCY_WARNING(throw_exception_test,Exception,msg)                                 \
00040 {                                                                                                     \
00041   std::string err = Teuchos::typeName(*this) + msg;                                                   \
00042   if (TPETRA_PRINTS_EFFICIENCY_WARNINGS && (throw_exception_test)) {                                  \
00043     std::cerr << err << std::endl;                                                                    \
00044   }                                                                                                   \
00045   TEST_FOR_EXCEPTION(TPETRA_THROWS_EFFICIENCY_WARNINGS && (throw_exception_test), Exception, err);    \
00046 }
00047 #else
00048 #define TPETRA_EFFICIENCY_WARNING(throw_exception_test,Exception,msg)
00049 #endif
00050 
00051 // handle an abuse warning, according to HAVE_TPETRA_THROW_ABUSE_WARNINGS and HAVE_TPETRA_PRINT_ABUSE_WARNINGS
00052 #if defined(HAVE_TPETRA_THROW_ABUSE_WARNINGS) || defined(HAVE_TPETRA_PRINT_ABUSE_WARNINGS)
00053 #define TPETRA_ABUSE_WARNING(throw_exception_test,Exception,msg)                               \
00054 {                                                                                              \
00055   std::string err = Teuchos::typeName(*this) + msg;                                            \
00056   if (TPETRA_PRINTS_ABUSE_WARNINGS && (throw_exception_test)) {                                \
00057     std::cerr << err << std::endl;                                                             \
00058   }                                                                                            \
00059   TEST_FOR_EXCEPTION(TPETRA_THROWS_ABUSE_WARNINGS && (throw_exception_test), Exception, err);  \
00060 }
00061 #else
00062 #define TPETRA_ABUSE_WARNING(throw_exception_test,Exception,msg)
00063 #endif
00064 
00065 
00066 // shared test for exception
00067 // just like Teuchos TEST_FOR_EXCEPTION, but with the assurance 
00068 // that all nodes test and throw the exception together
00069 #define SHARED_TEST_FOR_EXCEPTION(throw_exception_test,Exception,msg,comm) \
00070 { \
00071     using Teuchos::outArg; \
00072     const int lcl_throw_exception = (throw_exception_test) ? Teuchos::rank(comm)+1 : 0; \
00073     int gbl_throw; \
00074     Teuchos::reduceAll(comm,Teuchos::REDUCE_MAX,lcl_throw_exception,outArg(gbl_throw)); \
00075     TEST_FOR_EXCEPTION(gbl_throw,Exception,  \
00076                        msg << " Failure on node " << gbl_throw-1 << "." << std::endl); \
00077 }
00078 
00079 // if TEUCHOS_DEBUG is defined, then it calls SHARED_TEST_FOR_EXCEPTION
00080 // otherwise, it calls TEST_FOR_EXCEPTION
00081 #ifdef HAVE_TEUCHOS_DEBUG
00082 #define SWITCHED_TEST_FOR_EXCEPTION(throw_exception_test,Exception,msg,comm) \
00083 { \
00084     SHARED_TEST_FOR_EXCEPTION(throw_exception_test,Exception,msg,comm); \
00085 }
00086 #else 
00087 #define SWITCHED_TEST_FOR_EXCEPTION(throw_exception_test,Exception,msg,comm) \
00088 { \
00089     TEST_FOR_EXCEPTION(throw_exception_test,Exception,msg); \
00090 }
00091 #endif
00092 
00093 namespace Tpetra {
00094 
00117   // efficientAddOrUpdate is taken from Scott Meyers' "Effective STL", Item 24.
00118   // if m already contains an entry with key k, use operator [].
00119   // if it doesn't, insert is used.
00120   template<typename MapType, typename KeyArgType, typename ValueArgType>
00121   typename MapType::iterator efficientAddOrUpdate(MapType& m, 
00122                           const KeyArgType & k, 
00123                           const ValueArgType & v) 
00124   {
00125     typename MapType::iterator lb = m.lower_bound(k);
00126     if(lb != m.end() && !(m.key_comp()(k, lb->first))) {
00127       lb->second = v;
00128       return(lb);
00129     }
00130     else {
00131       typedef typename MapType::value_type MVT;
00132       return(m.insert(lb, MVT(k, v)));
00133     }
00134   }
00135 
00136 
00137   // sort function for multiple arrays
00138   // The values in sortVals will be sorted in ascending order.
00139   // The same permutation required to sort sortVals will be applied
00140   // to otherVals.
00141 
00142   // for two arrays
00143   template<class IT1, class IT2>
00144   void sort2(const IT1 &first1, const IT1 &last1, const IT2 &first2) {
00145     typedef typename std::iterator_traits<IT1>::value_type KT;
00146     typedef typename std::iterator_traits<IT2>::value_type VT;
00147     // copy values into a multimap
00148     // (using a multimap instead of a map because values may be duplicated)
00149     std::multimap<KT,VT> tempMap;
00150     IT1 keyIter = first1;
00151     IT2 valueIter = first2;
00152     for (; keyIter != last1; ++keyIter, ++valueIter) {
00153       tempMap.insert(std::pair<KT,VT>(*keyIter, *valueIter));
00154     }
00155     // multimap will automatically sort them, we just need to pull them out in order
00156     // and write them back to the original arrays
00157     keyIter   = first1;
00158     valueIter = first2;
00159     for(typename std::multimap<KT,VT>::iterator i = tempMap.begin(); 
00160                                                 i != tempMap.end(); 
00161                                                 ++i, ++keyIter, ++valueIter) 
00162     {
00163       *keyIter   = i->first;
00164       *valueIter = i->second;
00165     }
00166   }
00167 
00168   // for three arrays
00169   template<class IT1, class IT2, class IT3>
00170   void sort3(const IT1 &first1, const IT1 &last1, const IT2 &first2, const IT3 &first3)
00171   {
00172     typedef typename std::iterator_traits<IT1>::value_type KT;
00173     typedef typename std::iterator_traits<IT2>::value_type VT1;
00174     typedef typename std::iterator_traits<IT3>::value_type VT2;
00175     // copy values into a multimap
00176     // (using a multimap instead of a map because values may be duplicated)
00177     typedef typename std::pair<VT1,VT2> ValuePair;
00178     std::multimap<KT,ValuePair> tempMap;
00179     IT1 keyIter    = first1;
00180     IT2 valueIter1 = first2;
00181     IT3 valueIter2 = first3;
00182     for(; keyIter != last1; ++keyIter, ++valueIter1, ++valueIter2) {
00183       tempMap.insert(std::pair<KT,ValuePair>(*keyIter,ValuePair(*valueIter1,*valueIter2)));
00184     }
00185     // multimap will automatically sort them, we just need to pull them out in order
00186     // and write them back to the original arrays
00187     keyIter    = first1;
00188     valueIter1 = first2;
00189     valueIter2 = first3;
00190     for(typename std::multimap<KT,ValuePair>::iterator i = tempMap.begin(); 
00191                                                        i != tempMap.end(); 
00192                                                        i++, keyIter++, valueIter1++, valueIter2++) 
00193     {
00194       *keyIter    = i->first;
00195       *valueIter1 = i->second.first;
00196       *valueIter2 = i->second.second;
00197     }
00198   }
00199 
00200 } // namespace Tpetra
00201 
00202 
00203 #endif // TPETRA_UTIL_HPP

Generated on Tue Jul 13 09:39:07 2010 for Tpetra Matrix/Vector Services by  doxygen 1.4.7