blitz Version 0.10
|
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