~ubuntu-branches/ubuntu/raring/python-scipy/raring-proposed

« back to all changes in this revision

Viewing changes to Lib/weave/blitz/blitz/array/reduce.h

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2007-01-07 14:12:12 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20070107141212-mm0ebkh5b37hcpzn
* Remove build dependency on python-numpy-dev.
* python-scipy: Depend on python-numpy instead of python-numpy-dev.
* Package builds on other archs than i386. Closes: #402783.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// -*- C++ -*-
 
2
/***************************************************************************
 
3
 * blitz/array/reduce.h   Reductions of an array (or array expression) in a 
 
4
 *                        single rank: sum, mean, min, minIndex, max, maxIndex,
 
5
 *                        product, count, any, all
 
6
 *
 
7
 * Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org>
 
8
 *
 
9
 * This program is free software; you can redistribute it and/or
 
10
 * modify it under the terms of the GNU General Public License
 
11
 * as published by the Free Software Foundation; either version 2
 
12
 * of the License, or (at your option) any later version.
 
13
 *
 
14
 * This program is distributed in the hope that it will be useful,
 
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
 * GNU General Public License for more details.
 
18
 *
 
19
 * Suggestions:          blitz-dev@oonumerics.org
 
20
 * Bugs:                 blitz-bugs@oonumerics.org
 
21
 *
 
22
 * For more information, please see the Blitz++ Home Page:
 
23
 *    http://oonumerics.org/blitz/
 
24
 *
 
25
 ****************************************************************************/
 
26
#ifndef BZ_ARRAYREDUCE_H
 
27
#define BZ_ARRAYREDUCE_H
 
28
 
 
29
#ifndef BZ_ARRAYEXPR_H
 
30
 #error <blitz/array/reduce.h> must be included after <blitz/array/expr.h>
 
31
#endif
 
32
 
 
33
#include <blitz/reduce.h>
 
34
 
 
35
BZ_NAMESPACE(blitz)
 
36
 
 
37
template<typename T_expr, int N_index, typename T_reduction>
 
38
class _bz_ArrayExprReduce {
 
39
 
 
40
public:   
 
41
    typedef _bz_typename T_reduction::T_numtype T_numtype;
 
42
    typedef T_expr      T_ctorArg1;
 
43
    typedef T_reduction T_ctorArg2;
 
44
 
 
45
    static const int 
 
46
        numArrayOperands = T_expr::numArrayOperands,
 
47
        numIndexPlaceholders = T_expr::numIndexPlaceholders + 1,
 
48
        rank = T_expr::rank - 1;
 
49
 
 
50
    _bz_ArrayExprReduce(const _bz_ArrayExprReduce<T_expr,N_index,T_reduction>&
 
51
        reduce)
 
52
        : reduce_(reduce.reduce_), iter_(reduce.iter_), ordering_(reduce.ordering_)
 
53
    {
 
54
    }
 
55
 
 
56
    _bz_ArrayExprReduce(T_expr expr)
 
57
        : iter_(expr)
 
58
    { computeOrdering(); }
 
59
 
 
60
    _bz_ArrayExprReduce(T_expr expr, T_reduction reduce)
 
61
        : iter_(expr), reduce_(reduce)
 
62
    { computeOrdering(); }
 
63
 
 
64
    int ascending(int r)
 
65
    { return iter_.ascending(r); }
 
66
 
 
67
    int ordering(int r)
 
68
    { return ordering_[r]; }
 
69
 
 
70
    int lbound(int r)
 
71
    { return iter_.lbound(r); }
 
72
 
 
73
    int ubound(int r)
 
74
    { return iter_.ubound(r); }
 
75
 
 
76
    template<int N_destRank>
 
77
    T_numtype operator()(const TinyVector<int, N_destRank>& destIndex)
 
78
    {
 
79
        BZPRECHECK(N_destRank == N_index,  
 
80
            "Array reduction performed over rank " << N_index 
 
81
            << " to produce a rank " << N_destRank << " expression." << endl
 
82
            << "You must reduce over rank " << N_destRank << " instead.");
 
83
 
 
84
        TinyVector<int, N_destRank + 1> index;
 
85
 
 
86
        // This metaprogram copies elements 0..N-1 of destIndex into index
 
87
        _bz_meta_vecAssign<N_index, 0>::assign(index, destIndex, 
 
88
            _bz_update<int,int>());
 
89
 
 
90
        int lbound = iter_.lbound(N_index);
 
91
        int ubound = iter_.ubound(N_index);
 
92
 
 
93
        // NEEDS_WORK: replace with tiny(int()) and huge(int()) once
 
94
        // <limits> widely available
 
95
        BZPRECHECK((lbound != INT_MIN) && (ubound != INT_MAX),
 
96
           "Array reduction performed over rank " << N_index
 
97
           << " is unbounded." << endl 
 
98
           << "There must be an array object in the expression being reduced"
 
99
           << endl << "which provides a bound in rank " << N_index << ".");
 
100
 
 
101
        reduce_.reset();
 
102
 
 
103
        for (index[N_index] = iter_.lbound(N_index);
 
104
            index[N_index] <= ubound; ++index[N_index])
 
105
        {
 
106
            if (!reduce_(iter_(index), index[N_index]))
 
107
                break;
 
108
        }
 
109
 
 
110
        return reduce_.result(ubound-lbound+1);
 
111
    }
 
112
 
 
113
    // If you have a precondition failure on this routine, it means
 
114
    // you are trying to use stack iteration mode on an expression
 
115
    // which contains an index placeholder.  You must use index
 
116
    // iteration mode instead.
 
117
    int operator*()
 
118
    {
 
119
        BZPRECONDITION(0);
 
120
        return 0;
 
121
    }
 
122
 
 
123
    // See operator*() note
 
124
    void push(int)
 
125
    {
 
126
        BZPRECONDITION(0);
 
127
    }
 
128
 
 
129
    // See operator*() note
 
130
    void pop(int)
 
131
    {
 
132
        BZPRECONDITION(0);
 
133
    }
 
134
 
 
135
    // See operator*() note
 
136
    void advance()
 
137
    {
 
138
        BZPRECONDITION(0);
 
139
    }
 
140
 
 
141
    // See operator*() note
 
142
    void advance(int)
 
143
    {
 
144
        BZPRECONDITION(0);
 
145
    }
 
146
 
 
147
    // See operator*() note
 
148
    void loadStride(int)
 
149
    {
 
150
        BZPRECONDITION(0);
 
151
    }
 
152
 
 
153
    bool isUnitStride(int) const
 
154
    {
 
155
        BZPRECONDITION(0);
 
156
        return false;
 
157
    }
 
158
 
 
159
    void advanceUnitStride()
 
160
    {
 
161
        BZPRECONDITION(0);
 
162
    }
 
163
 
 
164
    bool canCollapse(int,int) const
 
165
    {   BZPRECONDITION(0); return false; }
 
166
 
 
167
    T_numtype operator[](int)
 
168
    {
 
169
        BZPRECONDITION(0);
 
170
        return T_numtype();
 
171
    }
 
172
 
 
173
    T_numtype fastRead(int)
 
174
    {
 
175
        BZPRECONDITION(0);
 
176
        return T_numtype();
 
177
    }
 
178
 
 
179
    int suggestStride(int) const
 
180
    {
 
181
        BZPRECONDITION(0);
 
182
        return 0;
 
183
    }
 
184
 
 
185
    bool isStride(int,int) const
 
186
    {
 
187
        BZPRECONDITION(0);
 
188
        return true;
 
189
    }
 
190
 
 
191
    template<int N_rank>
 
192
    void moveTo(const TinyVector<int,N_rank>&)
 
193
    {
 
194
        BZPRECONDITION(0);
 
195
        return;
 
196
    }
 
197
 
 
198
    void prettyPrint(BZ_STD_SCOPE(string) &str, 
 
199
        prettyPrintFormat& format) const
 
200
    {
 
201
        // NEEDS_WORK-- do real formatting for reductions
 
202
        str += "reduce[NEEDS_WORK](";
 
203
        iter_.prettyPrint(str,format);
 
204
        str += ")";
 
205
    }
 
206
 
 
207
    template<typename T_shape>
 
208
    bool shapeCheck(const T_shape&) const
 
209
    { 
 
210
        // NEEDS_WORK-- do a real shape check (tricky)
 
211
        return true; 
 
212
    }
 
213
 
 
214
private: 
 
215
    _bz_ArrayExprReduce() { }
 
216
// method for properly initializing the ordering values
 
217
    void computeOrdering()
 
218
    {
 
219
        TinyVector<bool,rank> in_ordering;
 
220
        in_ordering = false;
 
221
 
 
222
        int j = 0;
 
223
        for (int i=0; i<rank; ++i)
 
224
        {
 
225
            int orderingj = iter_.ordering(i);
 
226
            if (orderingj != INT_MIN && orderingj < rank &&
 
227
                !in_ordering(orderingj)) { // unique value in ordering array
 
228
                in_ordering(orderingj) = true;
 
229
                ordering_(j++) = orderingj;
 
230
            }
 
231
 
 
232
        }
 
233
 
 
234
        // It is possible that ordering is not a permutation of 0,...,rank-1.
 
235
        // In that case j will be less than rank. We fill in ordering with
 
236
        // the unused values in decreasing order.
 
237
        for (int i = rank-1; j < rank; ++j) {
 
238
            while (in_ordering(i))
 
239
                --i;
 
240
            ordering_(j) = i--;
 
241
        }
 
242
    }
 
243
 
 
244
    T_reduction reduce_;
 
245
    T_expr iter_;
 
246
    TinyVector<int,rank> ordering_;
 
247
};
 
248
 
 
249
#define BZ_DECL_ARRAY_PARTIAL_REDUCE(fn,reduction)                      \
 
250
template<typename T_expr, int N_index>                                  \
 
251
inline                                                                  \
 
252
_bz_ArrayExpr<_bz_ArrayExprReduce<_bz_ArrayExpr<T_expr>, N_index,       \
 
253
    reduction<_bz_typename T_expr::T_numtype> > >                       \
 
254
fn(_bz_ArrayExpr<T_expr> expr, const IndexPlaceholder<N_index>&)        \
 
255
{                                                                       \
 
256
    return _bz_ArrayExprReduce<_bz_ArrayExpr<T_expr>, N_index,          \
 
257
        reduction<_bz_typename T_expr::T_numtype> >(expr);              \
 
258
}                                                                       \
 
259
                                                                        \
 
260
template<typename T_numtype, int N_rank, int N_index>                   \
 
261
inline                                                                  \
 
262
_bz_ArrayExpr<_bz_ArrayExprReduce<FastArrayIterator<T_numtype,N_rank>,  \
 
263
    N_index, reduction<T_numtype> > >                                   \
 
264
fn(const Array<T_numtype, N_rank>& array,                               \
 
265
    const IndexPlaceholder<N_index>&)                                   \
 
266
{                                                                       \
 
267
    return _bz_ArrayExprReduce<FastArrayIterator<T_numtype,N_rank>,     \
 
268
        N_index, reduction<T_numtype> > (array.beginFast());            \
 
269
}                        
 
270
 
 
271
BZ_DECL_ARRAY_PARTIAL_REDUCE(sum,      ReduceSum)
 
272
BZ_DECL_ARRAY_PARTIAL_REDUCE(mean,     ReduceMean)
 
273
BZ_DECL_ARRAY_PARTIAL_REDUCE(min,      ReduceMin)
 
274
BZ_DECL_ARRAY_PARTIAL_REDUCE(minIndex, ReduceMinIndex)
 
275
BZ_DECL_ARRAY_PARTIAL_REDUCE(max,      ReduceMax)
 
276
BZ_DECL_ARRAY_PARTIAL_REDUCE(maxIndex, ReduceMaxIndex)
 
277
BZ_DECL_ARRAY_PARTIAL_REDUCE(product,  ReduceProduct)
 
278
BZ_DECL_ARRAY_PARTIAL_REDUCE(count,    ReduceCount)
 
279
BZ_DECL_ARRAY_PARTIAL_REDUCE(any,      ReduceAny)
 
280
BZ_DECL_ARRAY_PARTIAL_REDUCE(all,      ReduceAll)
 
281
BZ_DECL_ARRAY_PARTIAL_REDUCE(first,    ReduceFirst)
 
282
BZ_DECL_ARRAY_PARTIAL_REDUCE(last,     ReduceLast)
 
283
 
 
284
/*
 
285
 * Complete reductions
 
286
 */
 
287
 
 
288
// Prototype of reduction function
 
289
template<typename T_expr, typename T_reduction>
 
290
_bz_typename T_reduction::T_resulttype
 
291
_bz_ArrayExprFullReduce(T_expr expr, T_reduction reduction);
 
292
 
 
293
#define BZ_DECL_ARRAY_FULL_REDUCE(fn,reduction)                         \
 
294
template<typename T_expr>                                               \
 
295
inline                                                                  \
 
296
_bz_typename reduction<_bz_typename T_expr::T_numtype>::T_resulttype    \
 
297
fn(_bz_ArrayExpr<T_expr> expr)                                          \
 
298
{                                                                       \
 
299
    return _bz_ArrayExprFullReduce(expr,                                \
 
300
        reduction<_bz_typename T_expr::T_numtype>());                   \
 
301
}                                                                       \
 
302
                                                                        \
 
303
template<typename T_numtype, int N_rank>                                \
 
304
inline                                                                  \
 
305
_bz_typename reduction<T_numtype>::T_resulttype                         \
 
306
fn(const Array<T_numtype, N_rank>& array)                               \
 
307
{                                                                       \
 
308
    return _bz_ArrayExprFullReduce(array.beginFast(),                   \
 
309
        reduction<T_numtype>());                                        \
 
310
}                                                                     
 
311
 
 
312
BZ_DECL_ARRAY_FULL_REDUCE(sum,      ReduceSum)
 
313
BZ_DECL_ARRAY_FULL_REDUCE(mean,     ReduceMean)
 
314
BZ_DECL_ARRAY_FULL_REDUCE(min,      ReduceMin)
 
315
BZ_DECL_ARRAY_FULL_REDUCE(max,      ReduceMax)
 
316
BZ_DECL_ARRAY_FULL_REDUCE(product,  ReduceProduct)
 
317
BZ_DECL_ARRAY_FULL_REDUCE(count,    ReduceCount)
 
318
BZ_DECL_ARRAY_FULL_REDUCE(any,      ReduceAny)
 
319
BZ_DECL_ARRAY_FULL_REDUCE(all,      ReduceAll)
 
320
BZ_DECL_ARRAY_FULL_REDUCE(first,    ReduceFirst)
 
321
BZ_DECL_ARRAY_FULL_REDUCE(last,     ReduceLast)
 
322
 
 
323
// Special versions of complete reductions: minIndex and
 
324
// maxIndex
 
325
 
 
326
#define BZ_DECL_ARRAY_FULL_REDUCE_INDEXVECTOR(fn,reduction)             \
 
327
template<typename T_expr>                                               \
 
328
inline                                                                  \
 
329
_bz_typename reduction<_bz_typename T_expr::T_numtype,                  \
 
330
    T_expr::rank>::T_resulttype                                         \
 
331
fn(_bz_ArrayExpr<T_expr> expr)                                          \
 
332
{                                                                       \
 
333
    return _bz_reduceWithIndexVectorTraversal(expr,                     \
 
334
        reduction<_bz_typename T_expr::T_numtype, T_expr::rank>());     \
 
335
}                                                                       \
 
336
                                                                        \
 
337
template<typename T_numtype, int N_rank>                                \
 
338
inline                                                                  \
 
339
_bz_typename reduction<T_numtype,N_rank>::T_resulttype                  \
 
340
fn(const Array<T_numtype, N_rank>& array)                               \
 
341
{                                                                       \
 
342
    return _bz_reduceWithIndexVectorTraversal( array.beginFast(),       \
 
343
        reduction<T_numtype,N_rank>());                                 \
 
344
}
 
345
 
 
346
BZ_DECL_ARRAY_FULL_REDUCE_INDEXVECTOR(minIndex, ReduceMinIndexVector)
 
347
BZ_DECL_ARRAY_FULL_REDUCE_INDEXVECTOR(maxIndex, ReduceMaxIndexVector)
 
348
 
 
349
BZ_NAMESPACE_END
 
350
 
 
351
#include <blitz/array/reduce.cc>
 
352
 
 
353
#endif // BZ_ARRAYREDUCE_H