/*************************************************************************** * blitz/array/reduce.h Reductions of an array (or array expression) in a * single rank: sum, mean, min, minIndex, max, maxIndex, * product, count, any, all * * $Id: reduce.h,v 1.1.1.1 1999-04-09 17:59: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.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_ARRAYREDUCE_H #define BZ_ARRAYREDUCE_H #ifndef BZ_ARRAYEXPR_H #error must be included after #endif #ifndef BZ_REDUCE_H #include #endif BZ_NAMESPACE(blitz) template class _bz_ArrayExprReduce { public: typedef _bz_typename T_reduction::T_numtype T_numtype; typedef T_expr T_ctorArg1; typedef T_reduction T_ctorArg2; enum { numArrayOperands = BZ_ENUM_CAST(T_expr::numArrayOperands), numIndexPlaceholders = BZ_ENUM_CAST(T_expr::numIndexPlaceholders) + 1, rank = BZ_ENUM_CAST(T_expr::rank) - 1 }; _bz_ArrayExprReduce(const _bz_ArrayExprReduce& reduce) : reduce_(reduce.reduce_), iter_(reduce.iter_) { } _bz_ArrayExprReduce(T_expr expr) : iter_(expr) { } _bz_ArrayExprReduce(T_expr expr, T_reduction reduce) : iter_(expr), reduce_(reduce) { } int lbound(int rank) { return iter_.lbound(rank); } int ubound(int rank) { return iter_.ubound(rank); } template T_numtype operator()(const TinyVector& destIndex) { BZPRECHECK(N_destRank == N_index, "Array reduction performed over rank " << N_index << " to produce a rank " << N_destRank << " expression." << endl << "You must reduce over rank " << N_destRank << " instead."); TinyVector index; // This metaprogram copies elements 0..N-1 of destIndex into index _bz_meta_vecAssign::assign(index, destIndex, _bz_update()); int lbound = iter_.lbound(N_index); int ubound = iter_.ubound(N_index); // NEEDS_WORK: replace with tiny(int()) and huge(int()) once // widely available BZPRECHECK((lbound != INT_MIN) && (ubound != INT_MAX), "Array reduction performed over rank " << N_index << " is unbounded." << endl << "There must be an array object in the expression being reduced" << endl << "which provides a bound in rank " << N_index << "."); reduce_.reset(); for (index[N_index] = iter_.lbound(N_index); index[N_index] <= ubound; ++index[N_index]) { if (!reduce_(iter_(index), index[N_index])) break; } return reduce_.result(ubound-lbound+1); } // If you have a precondition failure on this routine, it means // you are trying to use stack iteration mode on an expression // which contains an index placeholder. You must use index // iteration mode instead. int operator*() { BZPRECONDITION(0); return 0; } // See operator*() note void push(int) { BZPRECONDITION(0); } // See operator*() note void pop(int) { BZPRECONDITION(0); } // See operator*() note void advance() { BZPRECONDITION(0); } // See operator*() note void advance(int) { BZPRECONDITION(0); } // See operator*() note void loadStride(int) { BZPRECONDITION(0); } _bz_bool isUnitStride(int rank) const { BZPRECONDITION(0); return false; } void advanceUnitStride() { BZPRECONDITION(0); } _bz_bool canCollapse(int,int) const { BZPRECONDITION(0); return _bz_false; } T_numtype operator[](int) { BZPRECONDITION(0); return T_numtype(); } T_numtype fastRead(int) { BZPRECONDITION(0); return T_numtype(); } int suggestStride(int) const { BZPRECONDITION(0); return 0; } _bz_bool isStride(int,int) const { BZPRECONDITION(0); return _bz_true; } template void moveTo(const TinyVector& i) { BZPRECONDITION(0); return; } void prettyPrint(std::string& str, prettyPrintFormat& format) const { // NEEDS_WORK-- do real formatting for reductions str += "reduce[NEEDS_WORK]("; iter_.prettyPrint(str,format); str += ")"; } template _bz_bool shapeCheck(const T_shape& shape) const { // NEEDS_WORK-- do a real shape check (tricky) return _bz_true; } private: _bz_ArrayExprReduce() { } T_reduction reduce_; T_expr iter_; }; #define BZ_DECL_ARRAY_PARTIAL_REDUCE(fn,reduction) \ template \ inline \ _bz_ArrayExpr<_bz_ArrayExprReduce<_bz_ArrayExpr, N_index, \ reduction<_bz_typename T_expr::T_numtype> > > \ fn(_bz_ArrayExpr expr, const IndexPlaceholder&) \ { \ return _bz_ArrayExprReduce<_bz_ArrayExpr, N_index, \ reduction<_bz_typename T_expr::T_numtype> >(expr); \ } \ \ template \ inline \ _bz_ArrayExpr<_bz_ArrayExprReduce, \ N_index, reduction > > \ fn(const Array& array, \ const IndexPlaceholder&) \ { \ return _bz_ArrayExprReduce, \ N_index, reduction > (array.begin()); \ } BZ_DECL_ARRAY_PARTIAL_REDUCE(sum, ReduceSum) BZ_DECL_ARRAY_PARTIAL_REDUCE(mean, ReduceMean) BZ_DECL_ARRAY_PARTIAL_REDUCE(min, ReduceMin) BZ_DECL_ARRAY_PARTIAL_REDUCE(minIndex, ReduceMinIndex) BZ_DECL_ARRAY_PARTIAL_REDUCE(max, ReduceMax) BZ_DECL_ARRAY_PARTIAL_REDUCE(maxIndex, ReduceMaxIndex) BZ_DECL_ARRAY_PARTIAL_REDUCE(product, ReduceProduct) BZ_DECL_ARRAY_PARTIAL_REDUCE(count, ReduceCount) BZ_DECL_ARRAY_PARTIAL_REDUCE(any, ReduceAny) BZ_DECL_ARRAY_PARTIAL_REDUCE(all, ReduceAll) BZ_DECL_ARRAY_PARTIAL_REDUCE(first, ReduceFirst) /* * Complete reductions */ // Prototype of reduction function template _bz_typename T_reduction::T_resulttype _bz_ArrayExprFullReduce(T_expr expr, T_reduction reduction); #define BZ_DECL_ARRAY_FULL_REDUCE(fn,reduction) \ template \ inline \ _bz_typename reduction<_bz_typename T_expr::T_numtype>::T_resulttype \ fn(_bz_ArrayExpr expr) \ { \ return _bz_ArrayExprFullReduce(expr, \ reduction<_bz_typename T_expr::T_numtype>()); \ } \ \ template \ inline \ _bz_typename reduction::T_resulttype \ fn(const Array& array) \ { \ return _bz_ArrayExprFullReduce(array.begin(), \ reduction()); \ } BZ_DECL_ARRAY_FULL_REDUCE(sum, ReduceSum) BZ_DECL_ARRAY_FULL_REDUCE(mean, ReduceMean) BZ_DECL_ARRAY_FULL_REDUCE(min, ReduceMin) BZ_DECL_ARRAY_FULL_REDUCE(minIndex, ReduceMinIndex) BZ_DECL_ARRAY_FULL_REDUCE(max, ReduceMax) BZ_DECL_ARRAY_FULL_REDUCE(maxIndex, ReduceMaxIndex) BZ_DECL_ARRAY_FULL_REDUCE(product, ReduceProduct) BZ_DECL_ARRAY_FULL_REDUCE(count, ReduceCount) BZ_DECL_ARRAY_FULL_REDUCE(any, ReduceAny) BZ_DECL_ARRAY_FULL_REDUCE(all, ReduceAll) BZ_DECL_ARRAY_FULL_REDUCE(first, ReduceFirst) BZ_NAMESPACE_END #include #endif // BZ_ARRAYREDUCE_H