00001
00002
00003
00004
00005
00006 #ifndef MOR_MINMAXTOOLS_HPP
00007 #define MOR_MINMAXTOOLS_HPP
00008
00009 #include "Teuchos_Assert.hpp"
00010
00011 #include <algorithm>
00012 #include <iterator>
00013
00014 namespace MOR {
00015
00016 template <typename ScalarArrayView>
00017 typename std::iterator_traits<typename ScalarArrayView::const_iterator>::difference_type
00018 indexOfMinimum(const ScalarArrayView &array) {
00019 TEUCHOS_ASSERT(array.size());
00020 return std::distance(array.begin(), std::min_element(array.begin(), array.end()));
00021 }
00022
00023 template <typename First, typename Second>
00024 struct Pair {
00025 First first;
00026 Second second;
00027 };
00028
00029 template <typename First, typename Second>
00030 Pair<First, Second>
00031 makePair(const First &first, const Second &second) {
00032 Pair<First, Second> result;
00033 result.first = first;
00034 result.second = second;
00035 return result;
00036 }
00037
00038 template <typename First, typename Second>
00039 bool operator<(const Pair<First, Second> &a, const Pair<First, Second> &b) {
00040 return (a.first < b.first) || (!(b.first < a.first) && (a.second < b.second));
00041 }
00042
00043 template <typename First, typename Second>
00044 bool operator>(const Pair<First, Second> &a, const Pair<First, Second> &b) {
00045 return (a.first > b.first) || (!(b.first > a.first) && (a.second > b.second));
00046 }
00047
00048 template <typename First, typename Second>
00049 bool operator==(const Pair<First, Second> &a, const Pair<First, Second> &b) {
00050 return (a.first == b.first) && (a.second == b.second);
00051 }
00052
00053 template <typename First, typename Second>
00054 bool operator!=(const Pair<First, Second> &a, const Pair<First, Second> &b) {
00055 return (a.first != b.first) || (a.second != b.second);
00056 }
00057
00058 }
00059
00060 #include <Teuchos_ScalarTraits.hpp>
00061 #include <Teuchos_SerializationTraits.hpp>
00062
00063 namespace Teuchos {
00064
00065 template <typename First, typename Second>
00066 class ScalarTraits<MOR::Pair<First, Second> > {
00067 public:
00068 static const bool isComparable = ScalarTraits<First>::isComparable && ScalarTraits<Second>::isComparable;
00069 };
00070
00071 template <typename Ordinal, typename First, typename Second>
00072 class SerializationTraits<Ordinal, MOR::Pair<First, Second> > :
00073 public DirectSerializationTraits<Ordinal, MOR::Pair<First, Second> >
00074 {};
00075
00076 }
00077
00078 #include <Teuchos_Comm.hpp>
00079 #include <Teuchos_CommHelpers.hpp>
00080
00081 namespace MOR {
00082
00083 template <typename CommOrdinal, typename IdOrdinal, typename Scalar>
00084 Pair<Scalar, IdOrdinal>
00085 computeGlobalMin(const Teuchos::Comm<CommOrdinal> &comm, const Pair<Scalar, IdOrdinal> &in) {
00086 typedef Pair<Scalar, IdOrdinal> P;
00087 P result;
00088 Teuchos::reduceAll(
00089 comm,
00090 Teuchos::MinValueReductionOp<CommOrdinal, P>(),
00091 Teuchos::OrdinalTraits<CommOrdinal>::one(),
00092 &in, &result);
00093 return result;
00094 }
00095
00096 template <typename CommOrdinal, typename IdArrayView, typename CandidateArrayView>
00097 typename IdArrayView::value_type
00098 globalIdOfGlobalMinimum(
00099 const Teuchos::Comm<CommOrdinal> &comm,
00100 const IdArrayView &globalIds,
00101 const CandidateArrayView &candidates) {
00102 typedef typename IdArrayView::size_type LocOrdinal;
00103 const LocOrdinal localMinIndex = indexOfMinimum(candidates);
00104
00105 typedef Pair<typename CandidateArrayView::value_type, typename IdArrayView::value_type> P;
00106 const P localMin = makePair(candidates[localMinIndex], globalIds[localMinIndex]);
00107 const P globalMin = computeGlobalMin(comm, localMin);
00108 return globalMin.second;
00109 }
00110
00111 }
00112
00113 #endif