Possible interest in select_by_predicate?
I work in doing programming involving quite a bit of data analysis, and lately I've gotten sick and tired of doing routine searches on vectors and other linear containers to pull out maximum/minimum values. I ended up sitting down and writing a unary function object that retains a value based on any predicate. An example is worth a thousand words: int array[10] = { 5, 4, 6, 3, 9, 0, 7, 2, 8, 1 }; int maximum = std::for_each(&array[0], &array[10], select_by_predicate<int, std::greater>()); int minimum = std::for_each(&array[0], &array[10], select_by_predicate<int, std::less>()); assert(maximum == 9 && minimum == 0); Another example, using select_by_predicate independently: select_by_predicate<int, std::greater> max_error(0); for(loop through data samples) { double error; ... analyze data sample error ... max_error.compare(error); // same as max_error(error) } std::cout << "Maximum error: " << max_error; Is select_by_predicate something that boost users would be interested in? It's been helpful to me in all kinds of contexts. -Jonathan
Jonathan - This sounds like it would make a nice extension to the STLAlogorithmExtension library that Jeremy Siek has suggested and all sorts of boosters have recommended algorithms for. Check out the Wiki page and add it in. http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?STLAlgorithmE... sions Jeff
-----Original Message----- From: Jonathan Brownell [mailto:alphaomega@proaxis.com] Sent: Saturday, February 09, 2002 11:47 PM To: Boost-Users@yahoogroups.com Subject: [Boost-Users] Possible interest in select_by_predicate?
I work in doing programming involving quite a bit of data analysis, and lately I've gotten sick and tired of doing routine searches on vectors and other linear containers to pull out maximum/minimum values. I ended up sitting down and writing a unary function object that retains a value based on any predicate. An example is worth a thousand words:
int array[10] = { 5, 4, 6, 3, 9, 0, 7, 2, 8, 1 };
int maximum = std::for_each(&array[0], &array[10], select_by_predicate<int, std::greater>());
int minimum = std::for_each(&array[0], &array[10], select_by_predicate<int, std::less>());
assert(maximum == 9 && minimum == 0);
Another example, using select_by_predicate independently:
select_by_predicate<int, std::greater> max_error(0);
for(loop through data samples) { double error; ... analyze data sample error ...
max_error.compare(error); // same as max_error(error) }
std::cout << "Maximum error: " << max_error;
Is select_by_predicate something that boost users would be interested in? It's been helpful to me in all kinds of contexts.
-Jonathan
Info: <http://www.boost.org> Wiki: <http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl> Unsubscribe: <mailto:boost-users-unsubscribe@yahoogroups.com>
Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
Hello Dear Jonathan, Could you answer the following 3 questions please? (1) For all cases where an STL predicate "pred" will suffice, e.g. your example using std::greater<>, is there any case where std::max_element(b, e, pred) would not also perform the job? Apart from the issue of code bloat, performance would seem better with std::maximum(), because there would be no function call in the inner loop. (Most if not all std predicates inline cleanly. With Borland compilers at least, function calls do not inline if they contain "if" statements. That is why select_by_predicate<> would result in an inner loop function call.) (2) For those cases where there is no suitable std predicate, you must have a custom predicate. In all such cases, is there any in which the call std::max_element(b,e, custom_pred) would not perform suitably? In this case let us ignore the performance issue. I only want to know if any new functionality has been added by introducing select_by_predicate<>. (3) I suppose your functor select_by_predicate<> has "state" between calls which retains a pointer to the last element which evaluated true. I suppose that pointer is initialized to NULL, and thats how the functor knows which is the first call. When the pointer is not NULL it compares the elements and resets the pointer if true. Below is the code for max_element from my Borland-Rouge Wave STL library. Note that max_element keep a copy of the best iterator, because it has access to the iterators, whereas select_by_predicate<> does not. I said I "suppose" your functor uses a pointer . But I don't know that for certain. That means I have to worry about whether "ForwardIterator::value_type::operator=" might be called. If I am not totally familiar with select_by_predicate<>, that means I either have to avoid any situation where "ForwardIterator::value_type::operator=" would be dangerous, or be prepared to open the doc page to double check. Do you think this is a valid issue? ============================ template <class ForwardIterator, class Compare> ForwardIterator max_element (ForwardIterator first, ForwardIterator last, Compare _RWSTD_COMP) { if (first == last) return first; ForwardIterator result = first; while (++first != last) if (_RWSTD_COMP(*result, *first)) result = first; return result; } ============================= Respecfully Yours Craig Hicks Engineer, KGK, Tokyo Jonathan Brownell wrote:
I work in doing programming involving quite a bit of data analysis, and lately I've gotten sick and tired of doing routine searches on vectors and other linear containers to pull out maximum/minimum values. I ended up sitting down and writing a unary function object that retains a value based on any predicate. An example is worth a thousand words:
int array[10] = { 5, 4, 6, 3, 9, 0, 7, 2, 8, 1 };
int maximum = std::for_each(&array[0], &array[10], select_by_predicate<int, std::greater>());
int minimum = std::for_each(&array[0], &array[10], select_by_predicate<int, std::less>());
assert(maximum == 9 && minimum == 0);
Another example, using select_by_predicate independently:
select_by_predicate<int, std::greater> max_error(0);
for(loop through data samples) { double error; ... analyze data sample error ...
max_error.compare(error); // same as max_error(error) }
std::cout << "Maximum error: " << max_error;
Is select_by_predicate something that boost users would be interested in? It's been helpful to me in all kinds of contexts.
-Jonathan
Info: <http://www.boost.org> Wiki: <http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl> Unsubscribe: <mailto:boost-users-unsubscribe@yahoogroups.com>
Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
(1) For all cases where an STL predicate "pred" will suffice, e.g. your example using std::greater<>, is there any case where std::max_element(b, e, pred) would not also perform the job?
Not that I can see. The max_element/min_element STL functions have somehow slipped my knowledge thus far, and I feel like a complete chump now in duplicating their functionality. Thanks for pointing out the obvious, and I'll go crawl back in my hole. -Jonathan
I must apologize as that was not my intention. Jonathan Brownell wrote:
(1) For all cases where an STL predicate "pred" will suffice, e.g. your example using std::greater<>, is there any case where std::max_element(b, e, pred) would not also perform the job?
Not that I can see. The max_element/min_element STL functions have somehow slipped my knowledge thus far, and I feel like a complete chump now in duplicating their functionality. Thanks for pointing out the obvious, and I'll go crawl back in my hole.
-Jonathan
Info: <http://www.boost.org> Wiki: <http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl> Unsubscribe: <mailto:boost-users-unsubscribe@yahoogroups.com>
Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
[Non-text portions of this message have been removed]
participants (3)
-
hicks
-
Jeff Garland
-
Jonathan Brownell