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