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.5 2005/05/07 04:17:56 julianc Exp $
00007  *
00008  * Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org>
00009  *
00010  * This program is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU General Public License
00012  * as published by the Free Software Foundation; either version 2
00013  * of the License, or (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * Suggestions:          blitz-dev@oonumerics.org
00021  * Bugs:                 blitz-bugs@oonumerics.org
00022  *
00023  * For more information, please see the Blitz++ Home Page:
00024  *    http://oonumerics.org/blitz/
00025  *
00026  ***************************************************************************/
00027 
00028 #ifndef BZ_REDUCE_H
00029 #define BZ_REDUCE_H
00030 
00031 #ifndef BZ_BLITZ_H
00032  #include <blitz/blitz.h>
00033 #endif
00034 
00035 #ifndef BZ_NUMTRAIT_H
00036  #include <blitz/numtrait.h>
00037 #endif
00038 
00039 #ifndef BZ_NUMINQUIRE_H
00040  #include <blitz/numinquire.h>
00041 #endif
00042 
00043 BZ_NAMESPACE(blitz)
00044 
00045 template<typename P_sourcetype, typename P_resulttype = BZ_SUMTYPE(P_sourcetype)>
00046 class ReduceSum {
00047 
00048 public:
00049     typedef P_sourcetype T_sourcetype;
00050     typedef P_resulttype T_resulttype;
00051     typedef T_resulttype T_numtype;
00052 
00053     static const bool needIndex = false, canProvideInitialValue = true;
00054 
00055     ReduceSum()
00056     { reset(); }
00057 
00058     ReduceSum(T_resulttype initialValue)
00059     { sum_ = initialValue; }
00060 
00061     bool operator()(T_sourcetype x)
00062     { 
00063         sum_ += x; 
00064         return true;
00065     }
00066 
00067     bool operator()(T_sourcetype x, int)
00068     { 
00069         sum_ += x; 
00070         return true;
00071     }
00072 
00073     T_resulttype result(int)
00074     { return sum_; }
00075 
00076     void reset()
00077     { sum_ = zero(T_resulttype()); }
00078 
00079     void reset(T_resulttype initialValue)
00080     { sum_ = initialValue; }
00081  
00082     static const char* name()
00083     { return "sum"; }
00084  
00085 protected:
00086     T_resulttype sum_;
00087 };
00088 
00089 template<typename P_sourcetype, typename P_resulttype = BZ_FLOATTYPE(P_sourcetype)>
00090 class ReduceMean {
00091 
00092 public:
00093     typedef P_sourcetype T_sourcetype;
00094     typedef P_resulttype T_resulttype;
00095     typedef T_resulttype T_numtype;
00096 
00097     static const bool needIndex = false, canProvideInitialValue = false;
00098 
00099     ReduceMean()
00100     { reset(); }
00101 
00102     ReduceMean(T_resulttype)
00103     { 
00104         BZPRECHECK(0, "Provided an initial value for ReduceMean");
00105         reset();
00106     }
00107 
00108     bool operator()(T_sourcetype x)
00109     { 
00110         sum_ += x; 
00111         return true;
00112     }
00113 
00114     bool operator()(T_sourcetype x, int)
00115     { 
00116         sum_ += x; 
00117         return true;
00118     }
00119 
00120     T_resulttype result(int count)
00121     { return sum_ / count; }
00122 
00123     void reset()
00124     { sum_ = zero(T_resulttype()); }
00125 
00126     void reset(T_resulttype)
00127     { 
00128         BZPRECHECK(0, "Provided an initial value for ReduceMean");
00129         reset();
00130     }
00131 
00132     static const char* name() 
00133     { return "mean"; }
00134 
00135 protected:
00136     T_resulttype sum_;
00137 };
00138 
00139 template<typename P_sourcetype>
00140 class ReduceMin {
00141 
00142 public:
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, canProvideInitialValue = false;
00148 
00149     ReduceMin()
00150     { reset(); }
00151 
00152     ReduceMin(T_resulttype min)
00153     {
00154         min_ = min;
00155     }
00156 
00157     bool operator()(T_sourcetype x)
00158     { 
00159         if (x < min_)
00160             min_ = x;
00161         return true;
00162     }
00163 
00164     bool operator()(T_sourcetype x, int)
00165     {
00166         if (x < min_)
00167             min_ = x;
00168         return true;
00169     }
00170 
00171     T_resulttype result(int)
00172     { return min_; }
00173 
00174     void reset()
00175     { min_ = huge(P_sourcetype()); }
00176 
00177     void reset(T_resulttype initialValue)
00178     { min_ = initialValue; }
00179 
00180     static const char* name()
00181     { return "min"; }
00182 
00183 protected:
00184     T_resulttype min_;
00185 };
00186 
00187 template<typename P_sourcetype>
00188 class ReduceMax {
00189 
00190 public:
00191     typedef P_sourcetype T_sourcetype;
00192     typedef P_sourcetype T_resulttype;
00193     typedef T_resulttype T_numtype;
00194 
00195     static const bool needIndex = false, canProvideInitialValue = true;
00196 
00197     ReduceMax()
00198     { reset(); }
00199 
00200     ReduceMax(T_resulttype max)
00201     {
00202         max_ = max;
00203     }
00204 
00205     bool operator()(T_sourcetype x)
00206     {
00207         if (x > max_)
00208             max_ = x;
00209         return true;
00210     }
00211 
00212     bool operator()(T_sourcetype x, int)
00213     {
00214         if (x > max_)
00215             max_ = x;
00216         return true;
00217     }
00218 
00219     T_resulttype result(int)
00220     { return max_; }
00221 
00222     void reset()
00223     { max_ = neghuge(P_sourcetype()); }
00224 
00225     void reset(T_resulttype initialValue)
00226     { max_ = initialValue; }
00227 
00228     static const char* name()
00229     { return "max"; }
00230 
00231 protected:
00232     T_resulttype max_;
00233 };
00234 
00235 template<typename P_sourcetype>
00236 class ReduceMinIndex {
00237 
00238 public:
00239     typedef P_sourcetype T_sourcetype;
00240     typedef int          T_resulttype;
00241     typedef T_resulttype T_numtype;
00242 
00243     static const bool needIndex = true, canProvideInitialValue = false;
00244 
00245     ReduceMinIndex()
00246     { reset(); }
00247 
00248     ReduceMinIndex(T_resulttype min)
00249     {
00250         reset(min);
00251     }
00252 
00253     bool operator()(T_sourcetype x)
00254     {
00255         BZPRECONDITION(0);
00256         return false;
00257     }
00258 
00259     bool operator()(T_sourcetype x, int index)
00260     {
00261         if (x < min_)
00262         {
00263             min_ = x;
00264             index_ = index;
00265         }
00266         return true;
00267     }
00268 
00269     T_resulttype result(int)
00270     { return index_; }
00271 
00272     void reset()
00273     { 
00274         min_ = huge(T_sourcetype());
00275         index_ = tiny(int());        
00276     }
00277 
00278     void reset(T_resulttype)
00279     { 
00280         BZPRECHECK(0, "Provided initial value for ReduceMinIndex");
00281         reset();
00282     }
00283 
00284     static const char* name()
00285     { return "minIndex"; }
00286 
00287 protected:
00288     T_sourcetype min_;
00289     int index_;
00290 };
00291 
00292 template<typename P_sourcetype, int N>
00293 class ReduceMinIndexVector {
00294 
00295 public:
00296     typedef P_sourcetype T_sourcetype;
00297     typedef TinyVector<int,N> T_resulttype;
00298     typedef T_resulttype T_numtype;
00299 
00300     static const bool canProvideInitialValue = false;
00301 
00302     ReduceMinIndexVector()
00303     { reset(); }
00304 
00305     ReduceMinIndexVector(T_resulttype min)
00306     {
00307         reset(min);
00308     }
00309 
00310     bool operator()(T_sourcetype x)
00311     {
00312         BZPRECONDITION(0);
00313         return false;
00314     }
00315 
00316     bool operator()(T_sourcetype, int)
00317     {
00318         BZPRECONDITION(0);
00319         return false;
00320     }
00321    
00322     bool operator()(T_sourcetype x, const TinyVector<int,N>& index)
00323     {
00324         if (x < min_)
00325         {
00326             min_ = x;
00327             index_ = index;
00328         }
00329         return true;
00330     }
00331 
00332     T_resulttype result(int)
00333     { return index_; }
00334 
00335     void reset()
00336     {
00337         min_ = huge(T_sourcetype());
00338         index_ = tiny(int());
00339     }
00340 
00341     void reset(T_resulttype)
00342     {
00343         BZPRECHECK(0, "Provided initial value for ReduceMinIndex");
00344         reset();
00345     }
00346 
00347     static const char* name()
00348     { return "minIndex"; }
00349 
00350 protected:
00351     T_sourcetype min_;
00352     TinyVector<int,N> index_;
00353 };
00354 
00355 template<typename P_sourcetype>
00356 class ReduceMaxIndex {
00357 
00358 public:
00359     typedef P_sourcetype T_sourcetype;
00360     typedef int          T_resulttype;
00361     typedef T_resulttype T_numtype;
00362 
00363     static const bool needIndex = true, canProvideInitialValue = false;
00364 
00365     ReduceMaxIndex()
00366     { reset(); }
00367 
00368     ReduceMaxIndex(T_resulttype max)
00369     {
00370         reset(max);
00371     }
00372 
00373     bool operator()(T_sourcetype x)
00374     {
00375         BZPRECONDITION(0);
00376         return false;
00377     }
00378 
00379     bool operator()(T_sourcetype x, int index)
00380     {
00381         if (x > max_)
00382         {
00383             max_ = x;
00384             index_ = index;
00385         }
00386         return true;
00387     }
00388 
00389     T_resulttype result(int)
00390     { return index_; }
00391 
00392     void reset()
00393     {
00394         max_ = neghuge(T_sourcetype());
00395         index_ = tiny(int());
00396     }
00397 
00398     void reset(T_resulttype)
00399     {
00400         BZPRECHECK(0, "Provided initial value for ReduceMaxIndex");
00401         reset();
00402     }
00403 
00404     static const char* name()
00405     { return "maxIndex"; }
00406 
00407 protected:
00408     T_sourcetype max_;
00409     int index_;
00410 };
00411 
00412 template<typename P_sourcetype, int N_rank>
00413 class ReduceMaxIndexVector {
00414 
00415 public:
00416     typedef P_sourcetype T_sourcetype;
00417     typedef TinyVector<int,N_rank> T_resulttype;
00418     typedef T_resulttype T_numtype;
00419 
00420     static const bool canProvideInitialValue = false;
00421 
00422     ReduceMaxIndexVector()
00423     { reset(); }
00424 
00425     ReduceMaxIndexVector(T_resulttype max)
00426     {
00427         reset(max);
00428     }
00429 
00430     bool operator()(T_sourcetype x)
00431     {
00432         BZPRECONDITION(0);
00433         return false;
00434     }
00435 
00436     bool operator()(T_sourcetype x, const TinyVector<int,N_rank>& index)
00437     {
00438         if (x > max_)
00439         {
00440             max_ = x;
00441             index_ = index;
00442         }
00443         return true;
00444     }
00445 
00446     T_resulttype result(int)
00447     { return index_; }
00448 
00449     void reset()
00450     {
00451         max_ = neghuge(T_sourcetype());
00452         index_ = tiny(int());
00453     }
00454 
00455     void reset(T_resulttype)
00456     {
00457         BZPRECHECK(0, "Provided initial value for ReduceMaxIndex");
00458         reset();
00459     }
00460 
00461     static const char* name()
00462     { return "maxIndex"; }
00463 
00464 protected:
00465     T_sourcetype max_;
00466     TinyVector<int,N_rank> index_;
00467 };
00468 
00469 template<typename P_sourcetype>
00470 class ReduceFirst {
00471 
00472 public:
00473     typedef P_sourcetype T_sourcetype;
00474     typedef int          T_resulttype;
00475     typedef T_resulttype T_numtype;
00476 
00477     static const bool needIndex = true, canProvideInitialValue = false;
00478 
00479     ReduceFirst()
00480     { reset(); }
00481 
00482     ReduceFirst(T_resulttype)
00483     {
00484         BZPRECONDITION(0);
00485     }
00486 
00487     bool operator()(T_sourcetype x)
00488     {
00489         BZPRECONDITION(0);
00490         return false;
00491     }
00492 
00493     bool operator()(T_sourcetype x, int index)
00494     {
00495         if (x)
00496         {
00497             index_ = index;
00498             return false;
00499         }
00500         else
00501             return true;
00502     }
00503 
00504     T_resulttype result(int)
00505     { return index_; }
00506 
00507     void reset()
00508     {
00509         index_ = tiny(int());
00510     }
00511 
00512     void reset(T_resulttype)
00513     {
00514         BZPRECHECK(0, "Provided initial value for ReduceFirst");
00515         reset();
00516     }
00517 
00518     static const char* name()
00519     { return "first"; }
00520 
00521 protected:
00522     int index_;
00523 };
00524 
00525 template<typename P_sourcetype>
00526 class ReduceLast {
00527 
00528 public:
00529     typedef P_sourcetype T_sourcetype;
00530     typedef int          T_resulttype;
00531     typedef T_resulttype T_numtype;
00532 
00533     static const bool needIndex = true, canProvideInitialValue = false;
00534 
00535     ReduceLast()
00536     { reset(); }
00537 
00538     ReduceLast(T_resulttype)
00539     {
00540         BZPRECONDITION(0);
00541     }
00542 
00543     bool operator()(T_sourcetype x)
00544     {
00545         BZPRECONDITION(0);
00546         return false;
00547     }
00548 
00549     bool operator()(T_sourcetype x, int index)
00550     {
00551         if (x)
00552         {
00553             index_ = index;
00554             return true;
00555         }
00556         else
00557             return true;
00558     }
00559 
00560     T_resulttype result(int)
00561     { return index_; }
00562 
00563     void reset()
00564     {
00565         index_ = huge(int());
00566     }
00567 
00568     void reset(T_resulttype)
00569     {
00570         BZPRECHECK(0, "Provided initial value for ReduceFirst");
00571         reset();
00572     }
00573 
00574     static const char* name()
00575     { return "last"; }
00576 
00577 protected:
00578     int index_;
00579 };
00580 
00581 template<typename P_sourcetype, typename P_resulttype = BZ_SUMTYPE(P_sourcetype)>
00582 class ReduceProduct {
00583 
00584 public:
00585     typedef P_sourcetype T_sourcetype;
00586     typedef P_resulttype T_resulttype;
00587     typedef T_resulttype T_numtype;
00588 
00589     static const bool needIndex = false, canProvideInitialValue = true;
00590 
00591     ReduceProduct()
00592     { product_ = one(T_resulttype()); }
00593 
00594     ReduceProduct(T_resulttype initialValue)
00595     { product_ = initialValue; }
00596 
00597     bool operator()(T_sourcetype x)
00598     { 
00599         product_ *= x; 
00600         return true;
00601     }
00602 
00603     bool operator()(T_sourcetype x, int)
00604     { 
00605         product_ *= x; 
00606         return true;
00607     }
00608 
00609     T_resulttype result(int)
00610     { return product_; }
00611 
00612     void reset()
00613     { product_ = one(T_resulttype()); }
00614 
00615     void reset(T_resulttype initialValue)
00616     { product_ = initialValue; }
00617 
00618     static const char* name()
00619     { return "product"; }
00620 
00621 protected:
00622     T_resulttype product_;
00623 };
00624 
00625 template<typename P_sourcetype>
00626 class ReduceCount {
00627 
00628 public:
00629     typedef P_sourcetype T_sourcetype;
00630     typedef int          T_resulttype;
00631     typedef T_resulttype T_numtype;
00632 
00633     static const bool needIndex = false, canProvideInitialValue = true;
00634 
00635     ReduceCount()
00636     { reset(); }
00637 
00638     ReduceCount(T_resulttype count)
00639     {
00640         count_ = count;
00641     }
00642 
00643     bool operator()(T_sourcetype x)
00644     {
00645         if (x)
00646             ++count_;
00647         return true;
00648     }
00649 
00650     bool operator()(T_sourcetype x, int)
00651     {
00652         if (x)
00653             ++count_;
00654         return true;
00655     }
00656 
00657     T_resulttype result(int)
00658     { return count_; }
00659 
00660     void reset()
00661     { count_ = zero(T_resulttype()); }
00662 
00663     void reset(T_resulttype initialValue)
00664     { count_ = initialValue; }
00665 
00666     static const char* name()
00667     { return "count"; }
00668 
00669 protected:
00670     T_resulttype count_;
00671 };
00672 
00673 template<typename P_sourcetype>
00674 class ReduceAny {
00675 
00676 public:
00677     typedef P_sourcetype T_sourcetype;
00678     typedef bool     T_resulttype;
00679     typedef T_resulttype T_numtype;
00680 
00681     static const bool needIndex = false, canProvideInitialValue = false;
00682 
00683     ReduceAny()
00684     { reset(); }
00685 
00686     ReduceAny(T_resulttype initialValue)
00687     {
00688         reset(initialValue);
00689     }
00690 
00691     bool operator()(T_sourcetype x)
00692     {
00693         if (x)
00694         {
00695             any_ = true;
00696             return false;
00697         }
00698 
00699         return true;
00700     }
00701 
00702     bool operator()(T_sourcetype x, int)
00703     {
00704         if (x)
00705         {
00706             any_ = true;
00707             return false;
00708         }
00709 
00710         return true;
00711     }
00712 
00713     T_resulttype result(int)
00714     { return any_; }
00715 
00716     void reset()
00717     { any_ = false; }
00718 
00719     void reset(T_resulttype)
00720     { 
00721         BZPRECHECK(0, "Provided initial value for ReduceAny");
00722         reset();
00723     }
00724 
00725     static const char* name()
00726     { return "any"; }
00727 
00728 protected:
00729     T_resulttype any_;
00730 };
00731 
00732 template<typename P_sourcetype>
00733 class ReduceAll {
00734 
00735 public:
00736     typedef P_sourcetype T_sourcetype;
00737     typedef bool     T_resulttype;
00738     typedef T_resulttype T_numtype;
00739 
00740     static const bool needIndex = false, canProvideInitialValue = false;
00741 
00742     ReduceAll()
00743     { reset(); }
00744 
00745     ReduceAll(T_resulttype initialValue)
00746     {
00747         reset(initialValue);
00748     }
00749 
00750     bool operator()(T_sourcetype x)
00751     {
00752         if (!bool(x))
00753         {
00754             all_ = false;
00755             return false;
00756         }
00757         else
00758             return true;
00759     }
00760 
00761     bool operator()(T_sourcetype x, int)
00762     {
00763         if (!bool(x))
00764         {
00765             all_ = false;
00766             return false;
00767         }
00768         else
00769             return true;
00770     }
00771 
00772     T_resulttype result(int)
00773     { return all_; }
00774 
00775     void reset()
00776     { all_ = true; }
00777 
00778     void reset(T_resulttype)
00779     {
00780         BZPRECHECK(0, "Provided initial value for ReduceAll");
00781         reset();
00782     }
00783 
00784     static const char* name()
00785     { return "all"; }
00786 
00787 protected:
00788     T_resulttype all_;
00789 }; 
00790 
00791 BZ_NAMESPACE_END
00792 
00793 #endif // BZ_REDUCE_H

Generated on Wed Oct 17 17:20:04 2007 for blitz by  doxygen 1.5.2