/***************************************************************************
* File: ArgMinMax.hh
* Author: Keith Schwarz (htiek@cs.stanford.edu)
*
* Implementation of two algorithms, ArgMin and ArgMax, which take as inputs
* a range of iterators and a function to call, then return iterators to the
* elements in the range for which the function obtains its minimum (maximum)
* value. These functions are similar to the STL min_element and max_element
* functions, but are significantly easier to use when a simple function is
* being applied. For example, compare:
*
* double Haversine(double x) {
* return (1.0 - cos(x)) / 2.0;
* }
*
* bool CompareByHaversines(double x, double y) {
* return Haversine(x) < Haversine(y);
* }
*
* iterator itr = max_element(begin, end, CompareByHaversines);
*
* To
*
* double Haversine(double x) {
* return (1.0 - cos(x)) / 2.0;
* }
*
* iterator itr = ArgMax(begin, end, Haversine);
*/
#ifndef ArgMinMax_Included
#define ArgMinMax_Included
/**
* ForwardIterator ArgMax(ForwardIterator begin, ForwardIterator end,
* UnaryFunction function)
* Usage: ForwardIterator itr = ArgMax(begin, end, Haversine);
* -------------------------------------------------------------------------
* Given a range of iterators [begin, end), returns an iterator to an element
* in the range for which function attains a maximum value.
*/
template <typename ForwardIterator, typename UnaryFunction>
ForwardIterator ArgMax(ForwardIterator begin, ForwardIterator end,
UnaryFunction function);
/**
* ForwardIterator ArgMin(ForwardIterator begin, ForwardIterator end,
* UnaryFunction function)
* Usage: ForwardIterator itr = ArgMin(begin, end, Haversine);
* -------------------------------------------------------------------------
* Given a range of iterators [begin, end), returns an iterator to an element
* in the range for which function attains a minimum value.
*/
template <typename ForwardIterator, typename UnaryFunction>
ForwardIterator ArgMin(ForwardIterator begin, ForwardIterator end,
UnaryFunction function);
/* * * * * Implementation Below This Point * * * * */
template <typename ForwardIterator, typename UnaryFunction>
ForwardIterator ArgMax(ForwardIterator begin, ForwardIterator end,
UnaryFunction function) {
/* Initially, our guess is that the first argument is the max element. */
ForwardIterator result = begin;
/* Scan across the values, updating our guess at each point. */
for (; begin != end; ++begin)
if (function(*result) < function(*begin))
result = begin;
return result;
}
template <typename ForwardIterator, typename UnaryFunction>
ForwardIterator ArgMin(ForwardIterator begin, ForwardIterator end,
UnaryFunction function) {
/* Initially, our guess is that the first argument is the min element. */
ForwardIterator result = begin;
/* Scan across the values, updating our guess at each point. */
for (; begin != end; ++begin)
if (function(*begin) < function(*result))
result = begin;
return result;
}
#endif