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     const int lcl_throw_exception = (throw_exception_test) ? Teuchos::rank(comm)+1 : 0; \
00072     int gbl_throw; \
00073     Teuchos::reduceAll(comm,Teuchos::REDUCE_MAX,lcl_throw_exception,&gbl_throw); \
00074     TEST_FOR_EXCEPTION(gbl_throw,Exception,  \
00075                        msg << " Failure on node " << gbl_throw-1 << "." << std::endl); \
00076 }
00077 
00078 // if TEUCHOS_DEBUG is defined, then it calls SHARED_TEST_FOR_EXCEPTION
00079 // otherwise, it calls TEST_FOR_EXCEPTION
00080 #ifdef HAVE_TEUCHOS_DEBUG
00081 #define SWITCHED_TEST_FOR_EXCEPTION(throw_exception_test,Exception,msg,comm) \
00082 { \
00083     SHARED_TEST_FOR_EXCEPTION(throw_exception_test,Exception,msg,comm); \
00084 }
00085 #else 
00086 #define SWITCHED_TEST_FOR_EXCEPTION(throw_exception_test,Exception,msg,comm) \
00087 { \
00088     TEST_FOR_EXCEPTION(throw_exception_test,Exception,msg); \
00089 }
00090 #endif
00091 
00092 namespace Tpetra {
00093 
00116   // efficientAddOrUpdate is taken from Scott Meyers' "Effective STL", Item 24.
00117   // if m already contains an entry with key k, use operator [].
00118   // if it doesn't, insert is used.
00119   template<typename MapType, typename KeyArgType, typename ValueArgType>
00120   typename MapType::iterator efficientAddOrUpdate(MapType& m, 
00121                           const KeyArgType & k, 
00122                           const ValueArgType & v) 
00123   {
00124     typename MapType::iterator lb = m.lower_bound(k);
00125     if(lb != m.end() && !(m.key_comp()(k, lb->first))) {
00126       lb->second = v;
00127       return(lb);
00128     }
00129     else {
00130       typedef typename MapType::value_type MVT;
00131       return(m.insert(lb, MVT(k, v)));
00132     }
00133   }
00134 
00135 
00136   // sort function for multiple arrays
00137   // The values in sortVals will be sorted in ascending order.
00138   // The same permutation required to sort sortVals will be applied
00139   // to otherVals.
00140 
00141   // for two arrays
00142   template<class IT1, class IT2>
00143   void sort2(const IT1 &first1, const IT1 &last1, const IT2 &first2) {
00144     typedef typename std::iterator_traits<IT1>::value_type KT;
00145     typedef typename std::iterator_traits<IT2>::value_type VT;
00146     // copy values into a multimap
00147     // (using a multimap instead of a map because values may be duplicated)
00148     std::multimap<KT,VT> tempMap;
00149     IT1 keyIter = first1;
00150     IT2 valueIter = first2;
00151     for (; keyIter != last1; ++keyIter, ++valueIter) {
00152       tempMap.insert(std::pair<KT,VT>(*keyIter, *valueIter));
00153     }
00154     // multimap will automatically sort them, we just need to pull them out in order
00155     // and write them back to the original arrays
00156     keyIter   = first1;
00157     valueIter = first2;
00158     for(typename std::multimap<KT,VT>::iterator i = tempMap.begin(); 
00159                                                 i != tempMap.end(); 
00160                                                 ++i, ++keyIter, ++valueIter) 
00161     {
00162       *keyIter   = i->first;
00163       *valueIter = i->second;
00164     }
00165   }
00166 
00167   // for three arrays
00168   template<class IT1, class IT2, class IT3>
00169   void sort3(const IT1 &first1, const IT1 &last1, const IT2 &first2, const IT3 &first3)
00170   {
00171     typedef typename std::iterator_traits<IT1>::value_type KT;
00172     typedef typename std::iterator_traits<IT2>::value_type VT1;
00173     typedef typename std::iterator_traits<IT3>::value_type VT2;
00174     // copy values into a multimap
00175     // (using a multimap instead of a map because values may be duplicated)
00176     typedef typename std::pair<VT1,VT2> ValuePair;
00177     std::multimap<KT,ValuePair> tempMap;
00178     IT1 keyIter    = first1;
00179     IT2 valueIter1 = first2;
00180     IT3 valueIter2 = first3;
00181     for(; keyIter != last1; ++keyIter, ++valueIter1, ++valueIter2) {
00182       tempMap.insert(std::pair<KT,ValuePair>(*keyIter,ValuePair(*valueIter1,*valueIter2)));
00183     }
00184     // multimap will automatically sort them, we just need to pull them out in order
00185     // and write them back to the original arrays
00186     keyIter    = first1;
00187     valueIter1 = first2;
00188     valueIter2 = first3;
00189     for(typename std::multimap<KT,ValuePair>::iterator i = tempMap.begin(); 
00190                                                        i != tempMap.end(); 
00191                                                        i++, keyIter++, valueIter1++, valueIter2++) 
00192     {
00193       *keyIter    = i->first;
00194       *valueIter1 = i->second.first;
00195       *valueIter2 = i->second.second;
00196     }
00197   }
00198 
00199 } // namespace Tpetra
00200 
00201 
00202 #endif // TPETRA_UTIL_HPP

Generated on Wed May 12 21:40:14 2010 for Tpetra Matrix/Vector Services by  doxygen 1.4.7