/*************************************************************************** * blitz/reduce.h Reduction operators: sum, mean, min, max, * minIndex, maxIndex, product, count, any, all * * $Id: reduce.h,v 1.1.1.1 1999-11-26 16:37:04 ansari Exp $ * * Copyright (C) 1997,1998 Todd Veldhuizen * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * Suggestions: blitz-suggest@cybervision.com * Bugs: blitz-bugs@cybervision.com * * For more information, please see the Blitz++ Home Page: * http://seurat.uwaterloo.ca/blitz/ * *************************************************************************** * $Log: not supported by cvs2svn $ * Revision 1.1.1.1 1999/04/09 17:59:02 ansari * Creation module DPC/Blitz (blitz 0.4) Reza 09/04/99 * * Revision 1.2 1998/03/14 00:04:47 tveldhui * 0.2-alpha-05 * * Revision 1.1 1997/07/16 14:51:20 tveldhui * Update: Alpha release 0.2 (Arrays) * */ #ifndef BZ_REDUCE_H #define BZ_REDUCE_H #ifndef BZ_BLITZ_H #include #endif #ifndef BZ_NUMTRAIT_H #include #endif #ifdef BZ_HAVE_NUMERIC_LIMITS #ifndef BZ_NUMINQUIRE_H #include #endif #endif BZ_NAMESPACE(blitz) template class ReduceSum { public: typedef P_sourcetype T_sourcetype; typedef P_resulttype T_resulttype; typedef T_resulttype T_numtype; enum { needIndex = 0, canProvideInitialValue = 1 }; ReduceSum() { reset(); } ReduceSum(T_resulttype initialValue) { sum_ = initialValue; } bool operator()(T_sourcetype x) { sum_ += x; return true; } bool operator()(T_sourcetype x, int) { sum_ += x; return true; } T_resulttype result(int) { return sum_; } #ifdef BZ_HAVE_NUMERIC_LIMITS void reset() { sum_ = zero(T_resulttype()); } #else void reset() { sum_ = 0; } #endif void reset(T_resulttype initialValue) { sum_ = initialValue; } static const char* name() { return "sum"; } protected: T_resulttype sum_; }; template class ReduceMean { public: typedef P_sourcetype T_sourcetype; typedef P_resulttype T_resulttype; typedef T_resulttype T_numtype; enum { needIndex = 0, canProvideInitialValue = 0 }; ReduceMean() { reset(); } ReduceMean(T_resulttype) { BZPRECHECK(0, "Provided an initial value for ReduceMean"); reset(); } bool operator()(T_sourcetype x) { sum_ += x; return true; } bool operator()(T_sourcetype x, int) { sum_ += x; return true; } T_resulttype result(int count) { return sum_ / count; } #ifdef BZ_HAVE_NUMERIC_LIMITS void reset() { sum_ = zero(T_resulttype()); } #else void reset() { sum_ = 0; } #endif void reset(T_resulttype) { BZPRECHECK(0, "Provided an initial value for ReduceMean"); reset(); } static const char* name() { return "mean"; } protected: T_resulttype sum_; }; template class ReduceMin { public: typedef P_sourcetype T_sourcetype; typedef P_sourcetype T_resulttype; typedef T_resulttype T_numtype; enum { needIndex = 0, canProvideInitialValue = 1 }; ReduceMin() { reset(); } ReduceMin(T_resulttype min) { min_ = min; } bool operator()(T_sourcetype x) { if (x < min_) min_ = x; return true; } bool operator()(T_sourcetype x, int) { if (x < min_) min_ = x; return true; } T_resulttype result(int) { return min_; } #ifdef BZ_HAVE_NUMERIC_LIMITS void reset() { min_ = huge(P_sourcetype()); } #else void reset() { BZPRECHECK(0, "ReduceMin requires from the ISO/ANSI C++ standard"); } #endif void reset(T_resulttype initialValue) { min_ = initialValue; } static const char* name() { return "min"; } protected: T_resulttype min_; }; template class ReduceMax { public: typedef P_sourcetype T_sourcetype; typedef P_sourcetype T_resulttype; typedef T_resulttype T_numtype; enum { needIndex = 0, canProvideInitialValue = 1 }; ReduceMax() { reset(); } ReduceMax(T_resulttype max) { max_ = max; } bool operator()(T_sourcetype x) { if (x > max_) max_ = x; return true; } bool operator()(T_sourcetype x, int) { if (x > max_) max_ = x; return true; } T_resulttype result(int) { return max_; } #ifdef BZ_HAVE_NUMERIC_LIMITS void reset() { max_ = tiny(P_sourcetype()); } #else void reset() { BZPRECHECK(0, "ReduceMax requires from the ISO/ANSI C++ standard"); } #endif void reset(T_resulttype initialValue) { max_ = initialValue; } static const char* name() { return "max"; } protected: T_resulttype max_; }; template class ReduceMinIndex { public: typedef P_sourcetype T_sourcetype; typedef int T_resulttype; typedef T_resulttype T_numtype; enum { needIndex = 1, canProvideInitialValue = 0 }; ReduceMinIndex() { reset(); } ReduceMinIndex(T_resulttype min) { reset(min); } bool operator()(T_sourcetype x) { BZPRECONDITION(0); return false; } bool operator()(T_sourcetype x, int index) { if (x < min_) { min_ = x; index_ = index; } return true; } T_resulttype result(int) { return index_; } #ifdef BZ_HAVE_NUMERIC_LIMITS void reset() { min_ = huge(T_sourcetype()); index_ = tiny(int()); } #else void reset() { BZPRECHECK(0, "ReduceMinIndex requires from the ISO/ANSI C++ standard"); } #endif void reset(T_resulttype) { BZPRECHECK(0, "Provided initial value for ReduceMinIndex"); reset(); } static const char* name() { return "minIndex"; } protected: T_sourcetype min_; int index_; }; template class ReduceMaxIndex { public: typedef P_sourcetype T_sourcetype; typedef int T_resulttype; typedef T_resulttype T_numtype; enum { needIndex = 1, canProvideInitialValue = 0 }; ReduceMaxIndex() { reset(); } ReduceMaxIndex(T_resulttype max) { reset(max); } bool operator()(T_sourcetype x) { BZPRECONDITION(0); return false; } bool operator()(T_sourcetype x, int index) { if (x > max_) { max_ = x; index_ = index; } return true; } T_resulttype result(int) { return index_; } #ifdef BZ_HAVE_NUMERIC_LIMITS void reset() { max_ = tiny(T_sourcetype()); index_ = tiny(int()); } #else void reset() { BZPRECHECK(0, "ReduceMaxIndex requires from the ISO/ANSI C++ standard"); } #endif void reset(T_resulttype) { BZPRECHECK(0, "Provided initial value for ReduceMaxIndex"); reset(); } static const char* name() { return "maxIndex"; } protected: T_sourcetype max_; int index_; }; template class ReduceFirst { public: typedef P_sourcetype T_sourcetype; typedef int T_resulttype; typedef T_resulttype T_numtype; enum { needIndex = 1, canProvideInitialValue = 0 }; ReduceFirst() { reset(); } ReduceFirst(T_resulttype) { BZPRECONDITION(0); } bool operator()(T_sourcetype x) { BZPRECONDITION(0); return false; } bool operator()(T_sourcetype x, int index) { if (x) { index_ = index; return false; } else return true; } T_resulttype result(int) { return index_; } #ifdef BZ_HAVE_NUMERIC_LIMITS void reset() { index_ = tiny(int()); } #else void reset() { index_ = INT_MIN; } #endif void reset(T_resulttype) { BZPRECHECK(0, "Provided initial value for ReduceFirst"); reset(); } static const char* name() { return "first"; } protected: int index_; }; template class ReduceProduct { public: typedef P_sourcetype T_sourcetype; typedef P_resulttype T_resulttype; typedef T_resulttype T_numtype; enum { needIndex = 0, canProvideInitialValue = 1 }; #ifdef BZ_HAVE_NUMERIC_LIMITS ReduceProduct() { product_ = one(T_resulttype()); } #else ReduceProduct() { product_ = 1; } #endif ReduceProduct(T_resulttype initialValue) { product_ = initialValue; } bool operator()(T_sourcetype x) { product_ *= x; return true; } bool operator()(T_sourcetype x, int) { product_ *= x; return true; } T_resulttype result(int) { return product_; } #ifdef BZ_HAVE_NUMERIC_LIMITS void reset() { product_ = one(T_resulttype()); } #else void reset() { product_ = T_resulttype(1.0); } #endif void reset(T_resulttype initialValue) { product_ = initialValue; } static const char* name() { return "product"; } protected: T_resulttype product_; }; template class ReduceCount { public: typedef P_sourcetype T_sourcetype; typedef int T_resulttype; typedef T_resulttype T_numtype; enum { needIndex = 0, canProvideInitialValue = 1 }; ReduceCount() { reset(); } ReduceCount(T_resulttype count) { count_ = count; } bool operator()(T_sourcetype x) { if (x) ++count_; return true; } bool operator()(T_sourcetype x, int) { if (x) ++count_; return true; } T_resulttype result(int) { return count_; } #ifdef BZ_HAVE_NUMERIC_LIMITS void reset() { count_ = zero(T_resulttype()); } #else void reset() { count_ = 0; } #endif void reset(T_resulttype initialValue) { count_ = initialValue; } static const char* name() { return "count"; } protected: T_resulttype count_; }; template class ReduceAny { public: typedef P_sourcetype T_sourcetype; typedef _bz_bool T_resulttype; typedef T_resulttype T_numtype; enum { needIndex = 0, canProvideInitialValue = 0 }; ReduceAny() { reset(); } ReduceAny(T_resulttype initialValue) { reset(initialValue); } bool operator()(T_sourcetype x) { if (x) { any_ = _bz_true; return false; } return true; } bool operator()(T_sourcetype x, int) { if (x) { any_ = _bz_true; return false; } return true; } T_resulttype result(int) { return any_; } void reset() { any_ = _bz_false; } void reset(T_resulttype) { BZPRECHECK(0, "Provided initial value for ReduceAny"); reset(); } static const char* name() { return "any"; } protected: T_resulttype any_; }; template class ReduceAll { public: typedef P_sourcetype T_sourcetype; typedef _bz_bool T_resulttype; typedef T_resulttype T_numtype; enum { needIndex = 0, canProvideInitialValue = 0 }; ReduceAll() { reset(); } ReduceAll(T_resulttype initialValue) { reset(initialValue); } bool operator()(T_sourcetype x) { if (!_bz_bool(x)) { all_ = _bz_false; return false; } else return true; } bool operator()(T_sourcetype x, int) { if (!_bz_bool(x)) { all_ = _bz_false; return false; } else return true; } T_resulttype result(int) { return all_; } void reset() { all_ = _bz_true; } void reset(T_resulttype) { BZPRECHECK(0, "Provided initial value for ReduceAll"); reset(); } static const char* name() { return "all"; } protected: T_resulttype all_; }; BZ_NAMESPACE_END #endif // BZ_REDUCE_H