blitz Version 0.10
blitz/reduce.h
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  * blitz/reduce.h        Reduction operators: sum, mean, min, max,
00004  *                       minIndex, maxIndex, product, count, any, all
00005  *
00006  * $Id: reduce.h,v 1.11 2011/03/25 22:41:16 julianc Exp $
00007  *
00008  * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org>
00009  *
00010  * This file is a part of Blitz.
00011  *
00012  * Blitz is free software: you can redistribute it and/or modify 
00013  * it under the terms of the GNU Lesser General Public License
00014  * as published by the Free Software Foundation, either version 3
00015  * of the License, or (at your option) any later version.
00016  *
00017  * Blitz is distributed in the hope that it will be useful,
00018  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020  * GNU Lesser General Public License for more details.
00021  *
00022  * You should have received a copy of the GNU Lesser General Public 
00023  * License along with Blitz.  If not, see <http://www.gnu.org/licenses/>.
00024  * 
00025  * Suggestions:          blitz-devel@lists.sourceforge.net
00026  * Bugs:                 blitz-support@lists.sourceforge.net    
00027  *
00028  * For more information, please see the Blitz++ Home Page:
00029  *    https://sourceforge.net/projects/blitz/
00030  *
00031  ***************************************************************************/
00032 
00033 #ifndef BZ_REDUCE_H
00034 #define BZ_REDUCE_H
00035 
00036 #ifndef BZ_BLITZ_H
00037  #include <blitz/blitz.h>
00038 #endif
00039 
00040 #ifndef BZ_NUMTRAIT_H
00041  #include <blitz/numtrait.h>
00042 #endif
00043 
00044 #ifndef BZ_NUMINQUIRE_H
00045  #include <blitz/numinquire.h>
00046 #endif
00047 
00048 //  The various reduce classes.
00049 //  The prototype of the reset method is mandated by the class _bz_ReduceReset
00050 //  in file array/reduce.h
00051 
00052 BZ_NAMESPACE(blitz)
00053 
00054 template<typename P_sourcetype, typename P_resulttype = BZ_SUMTYPE(P_sourcetype)>
00055 class ReduceSum {
00056 public:
00057 
00058     typedef P_sourcetype T_sourcetype;
00059     typedef P_resulttype T_resulttype;
00060     typedef T_resulttype T_numtype;
00061 
00062     static const bool needIndex = false, needInit = false;
00063 
00064     ReduceSum() { }
00065 
00066     bool operator()(const T_sourcetype& x,const int=0) const { 
00067         sum_ += x; 
00068         return true;
00069     }
00070 
00071     T_resulttype result(const int) const { return sum_; }
00072 
00073     void reset() const { sum_ = zero(T_resulttype()); }
00074  
00075     static const char* name() { return "sum"; }
00076  
00077 protected:
00078 
00079     mutable T_resulttype sum_;
00080 };
00081 
00082 template<typename P_sourcetype, typename P_resulttype = BZ_FLOATTYPE(P_sourcetype)>
00083 class ReduceMean {
00084 public:
00085 
00086     typedef P_sourcetype T_sourcetype;
00087     typedef P_resulttype T_resulttype;
00088     typedef T_resulttype T_numtype;
00089 
00090     static const bool needIndex = false, needInit = false;
00091 
00092     ReduceMean() { }
00093 
00094     bool operator()(const T_sourcetype& x,const int=0) const { 
00095         sum_ += x; 
00096         return true;
00097     }
00098 
00099     T_resulttype result(const int count) const { return sum_ / count; }
00100 
00101     void reset() const { sum_ = zero(T_resulttype()); }
00102 
00103     static const char* name() { return "mean"; }
00104 
00105 protected:
00106 
00107     mutable T_resulttype sum_;
00108 };
00109 
00110 template<typename P_sourcetype>
00111 class ReduceMin {
00112 public:
00113 
00114     typedef P_sourcetype T_sourcetype;
00115     typedef P_sourcetype T_resulttype;
00116     typedef T_resulttype T_numtype;
00117 
00118     static const bool needIndex = false, needInit = false;
00119 
00120     ReduceMin() { }
00121 
00122     bool operator()(const T_sourcetype& x,const int=0) const {
00123         if (x < min_)
00124             min_ = x;
00125         return true;
00126     }
00127 
00128     T_resulttype result(const int) const { return min_; }
00129 
00130     void reset() const { min_ = huge(P_sourcetype()); }
00131 
00132     static const char* name() { return "min"; }
00133 
00134 protected:
00135 
00136     mutable T_resulttype min_;
00137 };
00138 
00139 template<typename P_sourcetype>
00140 class ReduceMax {
00141 public:
00142 
00143     typedef P_sourcetype T_sourcetype;
00144     typedef P_sourcetype T_resulttype;
00145     typedef T_resulttype T_numtype;
00146 
00147     static const bool needIndex = false, needInit = false;
00148 
00149     ReduceMax() { }
00150 
00151     bool operator()(const T_sourcetype& x,const int=0) const {
00152         if (x > max_)
00153             max_ = x;
00154         return true;
00155     }
00156 
00157     T_resulttype result(const int) const { return max_; }
00158 
00159     void reset() const { max_ = neghuge(P_sourcetype()); }
00160 
00161     static const char* name() { return "max"; }
00162 
00163 protected:
00164 
00165     mutable T_resulttype max_;
00166 };
00167 
00168 template <typename T>
00169 struct MinMaxValue {
00170     void operator=(const T& val) { min = max = val; }
00171     T min;
00172     T max;
00173 };
00174 
00175 template<typename P_sourcetype>
00176 class ReduceMinMax {
00177 public:
00178 
00179     typedef P_sourcetype              T_sourcetype;
00180     typedef MinMaxValue<P_sourcetype> T_resulttype;
00181     typedef T_resulttype              T_numtype;
00182 
00183     static const bool needIndex = false, needInit = true;
00184 
00185     ReduceMinMax() { }
00186 
00187     bool operator()(T_sourcetype x,const int=0) const {
00188         if (x > minmax_.max)
00189             minmax_.max = x;
00190         else if (x < minmax_.min)
00191             minmax_.min = x;
00192         return true;
00193     }
00194 
00195     T_resulttype result(int) { return minmax_; }
00196 
00197     void reset(P_sourcetype initialValue) const { minmax_ = initialValue; }
00198 
00199     static const char* name() { return "minmax"; }
00200 
00201 protected:
00202 
00203     mutable T_resulttype minmax_;
00204 };
00205 
00206 template<typename P_sourcetype>
00207 class ReduceMinIndex {
00208 public:
00209 
00210     typedef P_sourcetype T_sourcetype;
00211     typedef int          T_resulttype;
00212     typedef T_resulttype T_numtype;
00213 
00214     static const bool needIndex = true, needInit = false;
00215 
00216     ReduceMinIndex() { }
00217 
00218     bool operator()(const T_sourcetype& x,const T_resulttype& index) const {
00219         if (x < min_) {
00220             min_ = x;
00221             index_ = index;
00222         }
00223         return true;
00224     }
00225 
00226     T_resulttype result(const int) const { return index_; }
00227 
00228     void reset(const T_resulttype& index) const { 
00229         min_ = huge(T_sourcetype());
00230         index_ = index;        
00231     }
00232 
00233     static const char* name() { return "minIndex"; }
00234 
00235 protected:
00236 
00237     mutable T_sourcetype min_;
00238     mutable T_resulttype index_;
00239 };
00240 
00241 template<typename P_sourcetype, int N>
00242 class ReduceMinIndexVector {
00243 public:
00244 
00245     typedef P_sourcetype T_sourcetype;
00246     typedef TinyVector<int,N> T_resulttype;
00247     typedef T_resulttype T_numtype;
00248 
00249     static const bool needIndex = true, needInit = false;
00250 
00251     ReduceMinIndexVector() { }
00252 
00253     bool operator()(const T_sourcetype& x, const T_resulttype& index) const {
00254         if (x < min_) {
00255             min_ = x;
00256             index_ = index;
00257         }
00258         return true;
00259     }
00260 
00261     T_resulttype result(const int) const { return index_; }
00262 
00263     void reset(const T_resulttype& index) const {
00264         min_ = huge(T_sourcetype());
00265         index_ = index;
00266     }
00267 
00268     static const char* name() { return "minIndexVector"; }
00269 
00270 protected:
00271 
00272     mutable T_sourcetype min_;
00273     mutable T_resulttype index_;
00274 };
00275 
00276 template<typename P_sourcetype>
00277 class ReduceMaxIndex {
00278 public:
00279 
00280     typedef P_sourcetype T_sourcetype;
00281     typedef int          T_resulttype;
00282     typedef T_resulttype T_numtype;
00283 
00284     static const bool needIndex = true, needInit = false;
00285 
00286     ReduceMaxIndex() { }
00287 
00288     bool operator()(const T_sourcetype& x,const T_resulttype& index) const {
00289         if (x > max_) {
00290             max_ = x;
00291             index_ = index;
00292         }
00293         return true;
00294     }
00295 
00296     T_resulttype result(int) const { return index_; }
00297 
00298     void reset(const T_resulttype& index) const {
00299         max_ = neghuge(T_sourcetype());
00300         index_ = index;
00301     }
00302 
00303     static const char* name() { return "maxIndex"; }
00304 
00305 protected:
00306 
00307     mutable T_sourcetype max_;
00308     mutable T_resulttype index_;
00309 };
00310 
00311 template<typename P_sourcetype, int N_rank>
00312 class ReduceMaxIndexVector {
00313 public:
00314 
00315     typedef P_sourcetype T_sourcetype;
00316     typedef TinyVector<int,N_rank> T_resulttype;
00317     typedef T_resulttype T_numtype;
00318 
00319     static const bool needIndex = true, needInit = false;
00320 
00321     ReduceMaxIndexVector() { }
00322 
00323     bool operator()(const T_sourcetype& x, const T_resulttype& index) const {
00324         if (x > max_) {
00325             max_ = x;
00326             index_ = index;
00327         }
00328         return true;
00329     }
00330 
00331     T_resulttype result(const int) const { return index_; }
00332 
00333     void reset(const T_resulttype& index) const {
00334         max_ = neghuge(T_sourcetype());
00335         index_ = index;
00336     }
00337 
00338     static const char* name() { return "maxIndexVector"; }
00339 
00340 protected:
00341 
00342     mutable T_sourcetype max_;
00343     mutable T_resulttype index_;
00344 };
00345 
00346 template<typename P_sourcetype>
00347 class ReduceFirst {
00348 public:
00349 
00350     typedef P_sourcetype T_sourcetype;
00351     typedef int          T_resulttype;
00352     typedef T_resulttype T_numtype;
00353 
00354     static const bool needIndex = false, needInit = false;
00355 
00356     ReduceFirst() { }
00357 
00358     bool operator()(const T_sourcetype& x,const T_resulttype& index) const {
00359         if (x) {
00360             index_ = index;
00361             return false;
00362         } else
00363             return true;
00364     }
00365 
00366     T_resulttype result(const int) const { return index_; }
00367 
00368     void reset() const { index_ = tiny(int()); }
00369 
00370     static const char* name() { return "first"; }
00371 
00372 protected:
00373 
00374     mutable T_resulttype index_;
00375 };
00376 
00377 template<typename P_sourcetype>
00378 class ReduceLast {
00379 public:
00380 
00381     typedef P_sourcetype T_sourcetype;
00382     typedef int          T_resulttype;
00383     typedef T_resulttype T_numtype;
00384 
00385     static const bool needIndex = false, needInit = false;
00386 
00387     ReduceLast() { }
00388 
00389     bool operator()(const T_sourcetype& x,const T_resulttype& index) const {
00390         if (x) {
00391             index_ = index;
00392             return true;
00393         } else
00394             return true;
00395     }
00396 
00397     T_resulttype result(const int) const { return index_; }
00398 
00399     void reset() const { index_ = huge(int()); }
00400 
00401     static const char* name() { return "last"; }
00402 
00403 protected:
00404 
00405     mutable T_resulttype index_;
00406 };
00407 
00408 template<typename P_sourcetype, typename P_resulttype = BZ_SUMTYPE(P_sourcetype)>
00409 class ReduceProduct {
00410 public:
00411 
00412     typedef P_sourcetype T_sourcetype;
00413     typedef P_resulttype T_resulttype;
00414     typedef T_resulttype T_numtype;
00415 
00416     static const bool needIndex = false, needInit = false;
00417 
00418     ReduceProduct() { }
00419 
00420     bool operator()(const T_sourcetype& x,const int=0) const { 
00421         product_ *= x; 
00422         return true;
00423     }
00424 
00425     T_resulttype result(const int) const { return product_; }
00426 
00427     void reset() const { product_ = one(T_resulttype()); }
00428 
00429     static const char* name() { return "product"; }
00430 
00431 protected:
00432 
00433     mutable T_resulttype product_;
00434 };
00435 
00436 template<typename P_sourcetype>
00437 class ReduceCount {
00438 public:
00439 
00440     typedef P_sourcetype T_sourcetype;
00441     typedef int          T_resulttype;
00442     typedef T_resulttype T_numtype;
00443 
00444     static const bool needIndex = false, needInit = false;
00445 
00446     ReduceCount() { }
00447 
00448     bool operator()(const T_sourcetype& x,const int=0) const {
00449         if (bool(x))
00450             ++count_;
00451         return true;
00452     }
00453 
00454     T_resulttype result(const int) const { return count_; }
00455 
00456     void reset() const { count_ = zero(T_resulttype()); }
00457 
00458     static const char* name() { return "count"; }
00459 
00460 protected:
00461 
00462     mutable T_resulttype count_;
00463 };
00464 
00465 template<typename P_sourcetype>
00466 class ReduceAny {
00467 public:
00468 
00469     typedef P_sourcetype T_sourcetype;
00470     typedef bool     T_resulttype;
00471     typedef T_resulttype T_numtype;
00472 
00473     static const bool needIndex = false, needInit = false;
00474 
00475     ReduceAny() { }
00476 
00477     bool operator()(const T_sourcetype& x,const int=0) const {
00478         if (bool(x)) {
00479             any_ = true;
00480             return false;
00481         }
00482 
00483         return true;
00484     }
00485 
00486     T_resulttype result(const int) const { return any_; }
00487 
00488     void reset() const { any_ = false; }
00489 
00490     static const char* name() { return "any"; }
00491 
00492 protected:
00493 
00494     mutable T_resulttype any_;
00495 };
00496 
00497 template<typename P_sourcetype>
00498 class ReduceAll {
00499 public:
00500 
00501     typedef P_sourcetype T_sourcetype;
00502     typedef bool     T_resulttype;
00503     typedef T_resulttype T_numtype;
00504 
00505     static const bool needIndex = false, needInit = false;
00506 
00507     ReduceAll() { }
00508 
00509     bool operator()(const T_sourcetype& x,const int=0) const {
00510         if (!bool(x)) {
00511             all_ = false;
00512             return false;
00513         } else
00514             return true;
00515     }
00516 
00517     T_resulttype result(const int) const { return all_; }
00518 
00519     void reset() const { all_ = true; }
00520 
00521     static const char* name() { return "all"; }
00522 
00523 protected:
00524 
00525     mutable T_resulttype all_;
00526 }; 
00527 
00528 BZ_NAMESPACE_END
00529 
00530 #endif // BZ_REDUCE_H
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines