~ubuntu-branches/ubuntu/utopic/blitz++/utopic

« back to all changes in this revision

Viewing changes to blitz/tinyvec2.h

  • Committer: Package Import Robot
  • Author(s): Christophe Trophime
  • Date: 2012-07-06 09:15:30 UTC
  • mfrom: (11.1.5 sid)
  • Revision ID: package-import@ubuntu.com-20120706091530-vzrb8zf0vpbf8tp9
Tags: 1:0.10-1
* New upstream release
  Closes: #679407
* debian/rules:
  - update for new release
  - add override_dh_auto_test target
  - regenerate configure and Makefile.am
* debian/control:
  - add libtool, automake to BuildDepends
* debian/libblitz-doc.install
  - modify path for html files
* remove uneeded patches
* add examples.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// -*- C++ -*-
 
2
/***************************************************************************
 
3
 * blitz/tinyvec.h      Declaration of the TinyVector<T, N> class
 
4
 *
 
5
 * $Id$
 
6
 *
 
7
 * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org>
 
8
 *
 
9
 * This file is a part of Blitz.
 
10
 *
 
11
 * Blitz is free software: you can redistribute it and/or modify 
 
12
 * it under the terms of the GNU Lesser General Public License
 
13
 * as published by the Free Software Foundation, either version 3
 
14
 * of the License, or (at your option) any later version.
 
15
 *
 
16
 * Blitz is distributed in the hope that it will be useful,
 
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
19
 * GNU Lesser General Public License for more details.
 
20
 *
 
21
 * You should have received a copy of the GNU Lesser General Public 
 
22
 * License along with Blitz.  If not, see <http://www.gnu.org/licenses/>.
 
23
 * 
 
24
 * Suggestions:          blitz-devel@lists.sourceforge.net
 
25
 * Bugs:                 blitz-support@lists.sourceforge.net    
 
26
 *
 
27
 * For more information, please see the Blitz++ Home Page:
 
28
 *    https://sourceforge.net/projects/blitz/
 
29
 *
 
30
 ***************************************************************************/
 
31
 
 
32
#ifndef BZ_TINYVEC_H
 
33
#define BZ_TINYVEC_H
 
34
 
 
35
#include <blitz/blitz.h>
 
36
#include <blitz/listinit.h>
 
37
#include <blitz/et-forward.h>
 
38
#include <blitz/etbase.h>
 
39
#include <blitz/simdtypes.h>
 
40
#include <blitz/array/slice.h>
 
41
 
 
42
#ifdef BZ_HAVE_BOOST_SERIALIZATION
 
43
#include <boost/serialization/serialization.hpp>
 
44
#endif
 
45
#ifdef BZ_HAVE_BOOST_MPI
 
46
#include <boost/mpi/datatype.hpp>
 
47
#endif
 
48
 
 
49
#ifdef BZ_HAVE_CSTRING
 
50
#include <cstring> // For memcpy
 
51
#endif
 
52
 
 
53
BZ_NAMESPACE(blitz)
 
54
 
 
55
/*****************************************************************************
 
56
 * Forward declarations
 
57
 */
 
58
 
 
59
template<typename P_numtype, int N_length>
 
60
class FastTV2Iterator;
 
61
template<typename P_numtype, int N_length>
 
62
class FastTV2CopyIterator;
 
63
 
 
64
 
 
65
/** The TinyVector class is a one-dimensional, fixed length vector
 
66
    that implements the blitz expression template
 
67
    machinery. TinyVector-only expressions are very fast because they
 
68
    usually get reduced to just the unrolled (and vectorized, if
 
69
    enabled) assembly instructions. TinyVectors can also be used in
 
70
    mixed expressions with other ET classes. */
 
71
template<typename P_numtype, int N_length>
 
72
class TinyVector : public ETBase<TinyVector<P_numtype, N_length> >
 
73
{
 
74
public:
 
75
 
 
76
    //////////////////////////////////////////////
 
77
    // Public Types
 
78
    //////////////////////////////////////////////
 
79
 
 
80
    typedef P_numtype                                    T_numtype;
 
81
    typedef TinyVector<T_numtype,N_length>               T_vector;
 
82
    typedef FastTV2Iterator<T_numtype,N_length>         T_iterator;
 
83
    typedef T_numtype*                                   iterator;
 
84
    typedef const T_numtype*                             const_iterator;
 
85
  typedef FastTV2CopyIterator<P_numtype, N_length> T_range_result;
 
86
 
 
87
    static const int 
 
88
    //numArrayOperands = 1, 
 
89
    //numIndexPlaceholders = 0,
 
90
        rank_ = 1;
 
91
 
 
92
    TinyVector()  { }
 
93
    ~TinyVector() { }
 
94
 
 
95
  TinyVector(const TinyVector<T_numtype,N_length>& x);
 
96
 
 
97
    template <typename T_numtype2>
 
98
    TinyVector(const TinyVector<T_numtype2,N_length>& x);
 
99
 
 
100
  /** This constructor creates a TinyVector from another ETBase
 
101
      object. It needs to be explicit to avoid all kinds of
 
102
      ambiguities. */
 
103
    template <typename T_expr>
 
104
    inline explicit TinyVector(const ETBase<T_expr>& expr) {
 
105
      *this = expr; }
 
106
 
 
107
  /** This constructor creates a TinyVector specifically from an
 
108
      expression. This one we do NOT want to be explicit because that
 
109
      breaks simple construction assignments like "TinyVector<double,
 
110
      1> v = a+b;", forcing the user to explicitly write it like a
 
111
      construction. */
 
112
    template <typename T_expr>
 
113
    inline TinyVector(const _bz_ArrayExpr<T_expr>& expr) {
 
114
      *this = expr; }
 
115
 
 
116
    inline TinyVector(const T_numtype initValue);
 
117
 
 
118
    inline TinyVector(const T_numtype x[]) {
 
119
        memcpy(data_,x,N_length*sizeof(T_numtype));
 
120
    }
 
121
 
 
122
  
 
123
    TinyVector(T_numtype x0, T_numtype x1)
 
124
    {
 
125
        data_[0] = x0;
 
126
        data_[1] = x1;
 
127
    }
 
128
 
 
129
    TinyVector(T_numtype x0, T_numtype x1, T_numtype x2)
 
130
    {
 
131
        data_[0] = x0;
 
132
        data_[1] = x1;
 
133
        data_[2] = x2;
 
134
    }
 
135
 
 
136
    TinyVector(T_numtype x0, T_numtype x1, T_numtype x2,
 
137
        T_numtype x3)
 
138
    {
 
139
        data_[0] = x0;
 
140
        data_[1] = x1;
 
141
        data_[2] = x2;
 
142
        data_[3] = x3;
 
143
    }
 
144
 
 
145
    TinyVector(T_numtype x0, T_numtype x1, T_numtype x2,
 
146
        T_numtype x3, T_numtype x4)
 
147
    {
 
148
        data_[0] = x0;
 
149
        data_[1] = x1;
 
150
        data_[2] = x2;
 
151
        data_[3] = x3;
 
152
        data_[4] = x4;
 
153
    }
 
154
 
 
155
    TinyVector(T_numtype x0, T_numtype x1, T_numtype x2,
 
156
        T_numtype x3, T_numtype x4, T_numtype x5)
 
157
    {
 
158
        data_[0] = x0;
 
159
        data_[1] = x1;
 
160
        data_[2] = x2;
 
161
        data_[3] = x3;
 
162
        data_[4] = x4;
 
163
        data_[5] = x5;
 
164
    }
 
165
 
 
166
    TinyVector(T_numtype x0, T_numtype x1, T_numtype x2,
 
167
        T_numtype x3, T_numtype x4, T_numtype x5, T_numtype x6)
 
168
    {
 
169
        data_[0] = x0;
 
170
        data_[1] = x1;
 
171
        data_[2] = x2;
 
172
        data_[3] = x3;
 
173
        data_[4] = x4;
 
174
        data_[5] = x5;
 
175
        data_[6] = x6;
 
176
    }
 
177
 
 
178
    TinyVector(T_numtype x0, T_numtype x1, T_numtype x2,
 
179
        T_numtype x3, T_numtype x4, T_numtype x5, T_numtype x6,
 
180
        T_numtype x7)
 
181
    {
 
182
        data_[0] = x0;
 
183
        data_[1] = x1;
 
184
        data_[2] = x2;
 
185
        data_[3] = x3;
 
186
        data_[4] = x4;
 
187
        data_[5] = x5;
 
188
        data_[6] = x6;
 
189
        data_[7] = x7;
 
190
    }
 
191
 
 
192
    TinyVector(T_numtype x0, T_numtype x1, T_numtype x2,
 
193
        T_numtype x3, T_numtype x4, T_numtype x5, T_numtype x6,
 
194
        T_numtype x7, T_numtype x8)
 
195
    {
 
196
        data_[0] = x0;
 
197
        data_[1] = x1;
 
198
        data_[2] = x2;
 
199
        data_[3] = x3;
 
200
        data_[4] = x4;
 
201
        data_[5] = x5;
 
202
        data_[6] = x6;
 
203
        data_[7] = x7;
 
204
        data_[8] = x8;
 
205
    }
 
206
 
 
207
    TinyVector(T_numtype x0, T_numtype x1, T_numtype x2,
 
208
        T_numtype x3, T_numtype x4, T_numtype x5, T_numtype x6,
 
209
        T_numtype x7, T_numtype x8, T_numtype x9)
 
210
    {
 
211
        data_[0] = x0;
 
212
        data_[1] = x1;
 
213
        data_[2] = x2;
 
214
        data_[3] = x3;
 
215
        data_[4] = x4;
 
216
        data_[5] = x5;
 
217
        data_[6] = x6;
 
218
        data_[7] = x7;
 
219
        data_[8] = x8;
 
220
        data_[9] = x9;
 
221
    }
 
222
 
 
223
    TinyVector(T_numtype x0, T_numtype x1, T_numtype x2,
 
224
        T_numtype x3, T_numtype x4, T_numtype x5, T_numtype x6,
 
225
        T_numtype x7, T_numtype x8, T_numtype x9, T_numtype x10)
 
226
    {
 
227
        data_[0] = x0;
 
228
        data_[1] = x1;
 
229
        data_[2] = x2;
 
230
        data_[3] = x3;
 
231
        data_[4] = x4;
 
232
        data_[5] = x5;
 
233
        data_[6] = x6;
 
234
        data_[7] = x7;
 
235
        data_[8] = x8;
 
236
        data_[9] = x9;
 
237
        data_[10] = x10;
 
238
    }
 
239
 
 
240
  static int base() 
 
241
  { return 0; }
 
242
 
 
243
  static int                               base(int rank) 
 
244
  { BZPRECONDITION(rank==0); return 0; }
 
245
 
 
246
 
 
247
    T_iterator      beginFast() const       { return T_iterator(*this);      }
 
248
 
 
249
    iterator       begin()       { return data_; }
 
250
    const_iterator begin() const { return data_; }
 
251
 
 
252
  static int                               dimensions()
 
253
    { return 1; }
 
254
 
 
255
    iterator       end()       { return data_ + N_length; }
 
256
    const_iterator end() const { return data_ + N_length; }
 
257
 
 
258
    T_numtype * restrict data()
 
259
    { return data_; }
 
260
 
 
261
    const T_numtype * restrict data() const
 
262
    { return data_; }
 
263
 
 
264
    T_numtype * restrict dataFirst()
 
265
    { return data_; }
 
266
 
 
267
    const T_numtype * restrict dataFirst() const
 
268
    { return data_; }
 
269
 
 
270
    const TinyVector<int, rank_>    shape() const
 
271
    { return N_length; }
 
272
 
 
273
  static int                               lbound(int rank) 
 
274
  { BZPRECONDITION(rank==0); return 0; }
 
275
  static int            lbound() 
 
276
  { return 0; }
 
277
 
 
278
  static int                               length(int rank) 
 
279
  { BZPRECONDITION(rank==0); return N_length; }
 
280
  static int    length() 
 
281
  { return N_length; }
 
282
 
 
283
  static int                               extent(int rank)
 
284
  { BZPRECONDITION(rank==0); return N_length; }
 
285
 
 
286
  static int                               ordering(int storageRankIndex) 
 
287
  { return 0; }
 
288
 
 
289
  static int    ordering() 
 
290
  { return 0; }
 
291
 
 
292
  static  int                               rank()
 
293
    { return rank_; }
 
294
 
 
295
    static sizeType                               numElements() 
 
296
  { return length(); }
 
297
 
 
298
    static diffType    stride() 
 
299
    { return 1; }
 
300
 
 
301
  static diffType                               stride(int rank) 
 
302
    { BZPRECONDITION(rank==0); return 1; }
 
303
 
 
304
  static int                               ubound(int rank) 
 
305
  { BZPRECONDITION(rank==0); return length()-1; }
 
306
 
 
307
  static int           ubound() 
 
308
  { return length()-1; }
 
309
 
 
310
     template<typename P_expr, typename P_updater>
 
311
     void _bz_assign(P_expr, P_updater);
 
312
 
 
313
    T_numtype operator*() const
 
314
    { return *data_; }
 
315
 
 
316
    //////////////////////////////////////////////
 
317
    // Subscripting operators
 
318
    //////////////////////////////////////////////
 
319
 
 
320
    T_vector& noConst() const
 
321
    { return const_cast<T_vector&>(*this); }
 
322
 
 
323
  static bool lengthCheck(unsigned i) 
 
324
    {
 
325
        BZPRECHECK(i < N_length, 
 
326
            "TinyVector<" << BZ_DEBUG_TEMPLATE_AS_STRING_LITERAL(T_numtype) 
 
327
            << "," << N_length << "> index out of bounds: " << i);
 
328
        return true;
 
329
    }
 
330
 
 
331
    const T_numtype& operator()(unsigned i) const
 
332
    {
 
333
        BZPRECONDITION(lengthCheck(i));
 
334
        return data_[i];
 
335
    }
 
336
 
 
337
    T_numtype& restrict operator()(unsigned i)
 
338
    { 
 
339
        BZPRECONDITION(lengthCheck(i));
 
340
        return data_[i];
 
341
    }
 
342
 
 
343
  T_numtype operator()(TinyVector<int,1> i) const
 
344
    {
 
345
        BZPRECONDITION(lengthCheck(i[0]));
 
346
        return data_[i[0]];
 
347
    }
 
348
 
 
349
    template<int N0>
 
350
    _bz_ArrayExpr<ArrayIndexMapping<typename asExpr<T_vector>::T_expr, N0> >
 
351
    operator()(IndexPlaceholder<N0>) const;
 
352
 
 
353
    const T_numtype& operator[](unsigned i) const
 
354
    {
 
355
        BZPRECONDITION(lengthCheck(i));
 
356
        return data_[i];
 
357
    }
 
358
 
 
359
    T_numtype& restrict operator[](unsigned i)
 
360
    {
 
361
        BZPRECONDITION(lengthCheck(i));
 
362
        return data_[i];
 
363
    }
 
364
 
 
365
  // must return reference so the iterator can turn it into an
 
366
  // iterator for the contained in case we have a multicomponent.
 
367
  const T_numtype& fastRead(diffType i) const
 
368
    { return data_[i]; }
 
369
 
 
370
  /** Since data_ is simd aligned by construction, we just have
 
371
      to check the offest. */
 
372
  bool isVectorAligned(diffType offset) const 
 
373
  { return (offset%simdTypes<T_numtype>::vecWidth)==0; }
 
374
 
 
375
  bool canCollapse(int outerLoopRank, int innerLoopRank) const
 
376
  {
 
377
    BZPRECONDITION(outerLoopRank==0);
 
378
    BZPRECONDITION(innerLoopRank==0);
 
379
    return true;
 
380
  }
 
381
 
 
382
    //////////////////////////////////////////////
 
383
    // Assignment operators
 
384
    //////////////////////////////////////////////
 
385
 
 
386
    // Scalar operand
 
387
    ListInitializationSwitch<T_vector,T_numtype*> operator=(T_numtype x)
 
388
    {
 
389
        return ListInitializationSwitch<T_vector,T_numtype*>(*this, x);
 
390
    }
 
391
 
 
392
  T_vector& initialize(T_numtype);
 
393
 
 
394
    template<typename T_expr>
 
395
    T_vector& operator=(const ETBase<T_expr>&);
 
396
 
 
397
    template<typename T> T_vector& operator+=(const T&);
 
398
    template<typename T> T_vector& operator-=(const T&);
 
399
    template<typename T> T_vector& operator*=(const T&);
 
400
    template<typename T> T_vector& operator/=(const T&);
 
401
    template<typename T> T_vector& operator%=(const T&);
 
402
    template<typename T> T_vector& operator^=(const T&);
 
403
    template<typename T> T_vector& operator&=(const T&);
 
404
    template<typename T> T_vector& operator|=(const T&);
 
405
    template<typename T> T_vector& operator>>=(const T&);
 
406
    template<typename T> T_vector& operator<<=(const T&);
 
407
 
 
408
    T_numtype* restrict getInitializationIterator()
 
409
    { return dataFirst(); }
 
410
 
 
411
  // // vectors can't be sliced
 
412
  // template<typename T1, typename T2 = nilArraySection, 
 
413
  //       class T3 = nilArraySection, typename T4 = nilArraySection, 
 
414
  //       class T5 = nilArraySection, typename T6 = nilArraySection, 
 
415
  //       class T7 = nilArraySection, typename T8 = nilArraySection, 
 
416
  //       class T9 = nilArraySection, typename T10 = nilArraySection, 
 
417
  //       class T11 = nilArraySection>
 
418
  // class SliceInfo {
 
419
  // public:    
 
420
  //   typedef void T_slice;
 
421
  // };
 
422
 
 
423
private:
 
424
  template<typename T_expr, typename T_update>
 
425
  void _tv_evaluate(const T_expr& expr, T_update);
 
426
 
 
427
#ifdef BZ_HAVE_BOOST_SERIALIZATION
 
428
  friend class boost::serialization::access;
 
429
  
 
430
  template<class T_arch>
 
431
  void serialize(T_arch& ar, const unsigned int version) {
 
432
    ar & data_;
 
433
  };
 
434
#endif
 
435
 
 
436
 
 
437
  BZ_ALIGN_VARIABLE(T_numtype, data_[N_length], BZ_SIMD_WIDTH)
 
438
};
 
439
 
 
440
// Specialization for N = 0: KCC is giving some
 
441
// peculiar errors, perhaps this will fix.
 
442
 
 
443
template<typename T>
 
444
class TinyVector<T,0> {
 
445
};
 
446
 
 
447
BZ_NAMESPACE_END
 
448
 
 
449
#ifdef BZ_HAVE_BOOST_SERIALIZATION
 
450
namespace boost {
 
451
  namespace mpi {
 
452
    template<typename T> struct is_mpi_datatype;
 
453
    template <typename T, int N>
 
454
    struct is_mpi_datatype<blitz::TinyVector<T, N> > 
 
455
      : public is_mpi_datatype<T> { };
 
456
  } };
 
457
#endif
 
458
 
 
459
 
 
460
#endif // BZ_TINYVEC_H
 
461