blitz  Version 0.9
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
vector.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 /***************************************************************************
3  * blitz/vector.h Declaration of the Vector<P_numtype> class
4  *
5  * $Id: vector.h,v 1.10 2005/10/06 23:27:13 julianc Exp $
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 
27 /*
28  * KNOWN BUGS
29  *
30  * 1. operator[](Vector<int>) won't match; compiler complains of no
31  * suitable copy constructor for VectorPick<T>
32  * 2. Vector<T>(_bz_VecExpr<E>) constructor generates warning
33  * 3. operator+=,-=,..etc.(Random<D>) won't match; compiler complains of
34  * no suitable copy constructor for _bz_VecExpr(...).
35  */
36 
37 #ifndef BZ_VECTOR_H
38 #define BZ_VECTOR_H
39 
40 #include <blitz/blitz.h>
41 #include <blitz/memblock.h>
42 #include <blitz/range.h>
43 #include <blitz/listinit.h>
44 
45 BZ_NAMESPACE(blitz)
46 
47 // Forward declarations
48 template<typename P_numtype> class VectorIter;
49 template<typename P_numtype> class VectorIterConst;
50 template<typename P_expr> class _bz_VecExpr;
51 template<typename P_numtype> class VectorPick;
52 template<typename P_numtype> class Random;
53 
54 // Declaration of class Vector<P_numtype>
55 
56 template<typename P_numtype>
57 class Vector : protected MemoryBlockReference<P_numtype> {
58 
59 private:
61  using T_base::data_;
62 
63 public:
65  // Public Types
67 
68  typedef P_numtype T_numtype;
74 
76  // Constructors //
78  // Most of the constructors are inlined so that
79  // the setting of the stride_ data member will
80  // be visible to the optimizer.
81 
83  {
84  length_ = 0;
85  stride_ = 0;
86  }
87 
88  // This constructor is provided inline because it involves
89  // no memory allocation.
91  : MemoryBlockReference<T_numtype>(const_cast<Vector<T_numtype>&>(vec))
92  {
93  length_ = vec.length_;
94  stride_ = vec.stride_;
95  }
96 
97  explicit Vector(int length)
98  : MemoryBlockReference<T_numtype>(length)
99  {
100  length_ = length;
101  stride_ = 1;
102  }
103 
105  : MemoryBlockReference<T_numtype>(const_cast<Vector<T_numtype>&>(vec),
106  r.first() * vec.stride())
107  {
108  BZPRECONDITION((r.first() >= 0) && (r.first() < vec.length()));
109  BZPRECONDITION((r.last(vec.length()-1) >= 0)
110  && (r.last(vec.length()-1) < vec.length()));
111  length_ = (r.last(vec.length()-1) - r.first()) / r.stride() + 1;
112  stride_ = vec.stride() * r.stride();
113  }
114 
115  Vector(int length, T_numtype initValue)
116  : MemoryBlockReference<T_numtype>(length)
117  {
118  length_ = length;
119  stride_ = 1;
120  (*this) = initValue;
121  }
122 
123  Vector(int length, T_numtype firstValue, T_numtype delta)
124  : MemoryBlockReference<T_numtype>(length)
125  {
126  length_ = length;
127  stride_ = 1;
128  for (int i=0; i < length; ++i)
129  data_[i] = firstValue + i * delta;
130  }
131 
132  template<typename P_distribution>
133  Vector(int length, Random<P_distribution>& random)
134  : MemoryBlockReference<T_numtype>(length)
135  {
136  length_ = length;
137  stride_ = 1;
138  (*this) = random;
139  }
140 
141  template<typename P_expr>
142  Vector(_bz_VecExpr<P_expr> expr)
143  : MemoryBlockReference<T_numtype>(expr._bz_suggestLength())
144  {
145  length_ = expr._bz_suggestLength();
146  stride_ = 1;
147  (*this) = expr;
148  }
149 
150  // Create a vector view of an already allocated block of memory.
151  // Note that the memory will not be freed when this vector is
152  // destroyed.
153  Vector(int length, T_numtype* restrict data, int stride = 1)
154  : MemoryBlockReference<T_numtype>(length, data, neverDeleteData)
155  {
156  length_ = length;
157  stride_ = stride;
158  }
159 
160  // Create a vector containing a range of numbers
162  : MemoryBlockReference<T_numtype>(r._bz_suggestLength())
163  {
164  length_ = r._bz_suggestLength();
165  stride_ = 1;
166  (*this) = _bz_VecExpr<Range>(r);
167  }
168 
170  // Member functions
172 
173  // assertUnitStride() is provided as an optimizing trick. When
174  // vectors are constructed outside the function scope, the optimizer
175  // is unaware that they have unit stride. This function sets the
176  // stride to 1 in the local scope so the optimizer can do copy
177  // propagation & dead code elimination. Obviously, you don't
178  // want to use this routine unless you are certain that the
179  // vectors have unit stride.
180  void assertUnitStride()
181  {
182  BZPRECONDITION(stride_ == 1);
183  stride_ = 1;
184  }
185 
186  T_iterator beginFast() { return T_iterator(*this); }
187  T_constIterator beginFast() const { return T_constIterator(*this); }
188 
189  T_vector copy() const;
190 
191  // T_iterator end();
192  // T_constIterator end() const;
193 
194  T_numtype * restrict data()
195  { return data_; }
196 
197  const T_numtype * restrict data() const
198  { return data_; }
199 
200  bool isUnitStride() const
201  { return stride_ == 1; }
202 
203  int length() const
204  { return length_; }
205 
206  void makeUnique();
207 
208  // int storageSize() const;
209 
210  // void storeToBuffer(void* buffer, int bufferLength) const;
211 
212  void reference(T_vector&);
213 
214  void resize(int length);
215 
216  void resizeAndPreserve(int newLength);
217 
218  // int restoreFromBuffer(void* buffer, int bufferLength);
219 
220  T_vector reverse()
221  { return T_vector(*this,Range(length()-1,0,-1)); }
222 
223  int stride() const
224  { return stride_; }
225 
226  operator _bz_VecExpr<VectorIterConst<T_numtype> > () const
227  { return _bz_VecExpr<VectorIterConst<T_numtype> >(beginFast()); }
228 
230  // Library-internal member functions
231  // These are undocumented and may change or
232  // disappear in future releases.
234 
235  int _bz_suggestLength() const
236  { return length_; }
237 
238  bool _bz_hasFastAccess() const
239  { return stride_ == 1; }
240 
241  T_numtype& _bz_fastAccess(int i)
242  { return data_[i]; }
243 
244  T_numtype _bz_fastAccess(int i) const
245  { return data_[i]; }
246 
247  template<typename P_expr, typename P_updater>
248  void _bz_assign(P_expr, P_updater);
249 
250  _bz_VecExpr<T_constIterator> _bz_asVecExpr() const
251  { return _bz_VecExpr<T_constIterator>(beginFast()); }
252 
254  // Subscripting operators
256 
257  // operator()(int) may be used only when the vector has unit
258  // stride. Otherwise, use operator[].
259  T_numtype operator()(int i) const
260  {
261  BZPRECONDITION(i < length_);
262  BZPRECONDITION(stride_ == 1);
263  return data_[i];
264  }
265 
266  // operator()(int) may be used only when the vector has unit
267  // stride. Otherwise, use operator[].
268  T_numtype& restrict operator()(int i)
269  {
270  BZPRECONDITION(i < length_);
271  BZPRECONDITION(stride_ == 1);
272  return data_[i];
273  }
274 
275  T_numtype operator[](int i) const
276  {
277  BZPRECONDITION(i < length_);
278  return data_[i * stride_];
279  }
280 
281  T_numtype& restrict operator[](int i)
282  {
283  BZPRECONDITION(i < length_);
284  return data_[i * stride_];
285  }
286 
287  T_vector operator()(Range r)
288  {
289  return T_vector(*this, r);
290  }
291 
292  T_vector operator[](Range r)
293  {
294  return T_vector(*this, r);
295  }
296 
297  T_pick operator()(T_indexVector i)
298  {
299  return T_pick(*this, i);
300  }
301 
302  T_pick operator[](T_indexVector i)
303  {
304  return T_pick(*this, i);
305  }
306 
307  // T_vector operator()(difference-equation-expression)
308 
310  // Assignment operators
312 
313  // Scalar operand
315  {
317  }
318 
319  T_iterator getInitializationIterator()
320  { return beginFast(); }
321 
322  T_vector& initialize(T_numtype);
323  T_vector& operator+=(T_numtype);
324  T_vector& operator-=(T_numtype);
325  T_vector& operator*=(T_numtype);
326  T_vector& operator/=(T_numtype);
327  T_vector& operator%=(T_numtype);
328  T_vector& operator^=(T_numtype);
329  T_vector& operator&=(T_numtype);
330  T_vector& operator|=(T_numtype);
331  T_vector& operator>>=(int);
332  T_vector& operator<<=(int);
333 
334  // Vector operand
335 
336  template<typename P_numtype2> T_vector& operator=(const Vector<P_numtype2> &);
337 
338  // Specialization uses memcpy instead of element-by-element cast and
339  // copy
340  // NEEDS_WORK -- KCC won't accept this syntax; standard??
341  // template<> T_vector& operator=(const T_vector&);
342 
343  template<typename P_numtype2> T_vector& operator+=(const Vector<P_numtype2> &);
344  template<typename P_numtype2> T_vector& operator-=(const Vector<P_numtype2> &);
345  template<typename P_numtype2> T_vector& operator*=(const Vector<P_numtype2> &);
346  template<typename P_numtype2> T_vector& operator/=(const Vector<P_numtype2> &);
347  template<typename P_numtype2> T_vector& operator%=(const Vector<P_numtype2> &);
348  template<typename P_numtype2> T_vector& operator^=(const Vector<P_numtype2> &);
349  template<typename P_numtype2> T_vector& operator&=(const Vector<P_numtype2> &);
350  template<typename P_numtype2> T_vector& operator|=(const Vector<P_numtype2> &);
351  template<typename P_numtype2> T_vector& operator>>=(const Vector<P_numtype2> &);
352  template<typename P_numtype2> T_vector& operator<<=(const Vector<P_numtype2> &);
353 
354  // Vector expression operand
355  template<typename P_expr> T_vector& operator=(_bz_VecExpr<P_expr>);
356  template<typename P_expr> T_vector& operator+=(_bz_VecExpr<P_expr>);
357  template<typename P_expr> T_vector& operator-=(_bz_VecExpr<P_expr>);
358  template<typename P_expr> T_vector& operator*=(_bz_VecExpr<P_expr>);
359  template<typename P_expr> T_vector& operator/=(_bz_VecExpr<P_expr>);
360  template<typename P_expr> T_vector& operator%=(_bz_VecExpr<P_expr>);
361  template<typename P_expr> T_vector& operator^=(_bz_VecExpr<P_expr>);
362  template<typename P_expr> T_vector& operator&=(_bz_VecExpr<P_expr>);
363  template<typename P_expr> T_vector& operator|=(_bz_VecExpr<P_expr>);
364  template<typename P_expr> T_vector& operator>>=(_bz_VecExpr<P_expr>);
365  template<typename P_expr> T_vector& operator<<=(_bz_VecExpr<P_expr>);
366 
367  // VectorPick operand
368  template<typename P_numtype2>
369  T_vector& operator=(const VectorPick<P_numtype2> &);
370  template<typename P_numtype2>
371  T_vector& operator+=(const VectorPick<P_numtype2> &);
372  template<typename P_numtype2>
373  T_vector& operator-=(const VectorPick<P_numtype2> &);
374  template<typename P_numtype2>
375  T_vector& operator*=(const VectorPick<P_numtype2> &);
376  template<typename P_numtype2>
377  T_vector& operator/=(const VectorPick<P_numtype2> &);
378  template<typename P_numtype2>
379  T_vector& operator%=(const VectorPick<P_numtype2> &);
380  template<typename P_numtype2>
381  T_vector& operator^=(const VectorPick<P_numtype2> &);
382  template<typename P_numtype2>
383  T_vector& operator&=(const VectorPick<P_numtype2> &);
384  template<typename P_numtype2>
385  T_vector& operator|=(const VectorPick<P_numtype2> &);
386  template<typename P_numtype2>
387  T_vector& operator>>=(const VectorPick<P_numtype2> &);
388  template<typename P_numtype2>
389  T_vector& operator<<=(const VectorPick<P_numtype2> &);
390 
391  // Range operand
392  T_vector& operator=(Range);
393  T_vector& operator+=(Range);
394  T_vector& operator-=(Range);
395  T_vector& operator*=(Range);
396  T_vector& operator/=(Range);
397  T_vector& operator%=(Range);
398  T_vector& operator^=(Range);
399  T_vector& operator&=(Range);
400  T_vector& operator|=(Range);
401  T_vector& operator>>=(Range);
402  T_vector& operator<<=(Range);
403 
404  // Random operand
405  template<typename P_distribution>
406  T_vector& operator=(Random<P_distribution>& random);
407  template<typename P_distribution>
408  T_vector& operator+=(Random<P_distribution>& random);
409  template<typename P_distribution>
410  T_vector& operator-=(Random<P_distribution>& random);
411  template<typename P_distribution>
412  T_vector& operator*=(Random<P_distribution>& random);
413  template<typename P_distribution>
414  T_vector& operator/=(Random<P_distribution>& random);
415  template<typename P_distribution>
416  T_vector& operator%=(Random<P_distribution>& random);
417  template<typename P_distribution>
418  T_vector& operator^=(Random<P_distribution>& random);
419  template<typename P_distribution>
420  T_vector& operator&=(Random<P_distribution>& random);
421  template<typename P_distribution>
422  T_vector& operator|=(Random<P_distribution>& random);
423 
425  // Unary operators
427 
428 // T_vector& operator++();
429 // void operator++(int);
430 // T_vector& operator--();
431 // void operator--(int);
432 
433 private:
434  int length_;
435  int stride_;
436 };
437 
438 // Global I/O functions
439 
440 template<typename P_numtype>
441 ostream& operator<<(ostream& os, const Vector<P_numtype>& x);
442 
443 template<typename P_expr>
444 ostream& operator<<(ostream& os, _bz_VecExpr<P_expr> expr);
445 
447 
448 #include <blitz/veciter.h> // Iterators
449 #include <blitz/vecpick.h> // VectorPick
450 #include <blitz/vecexpr.h> // Expression template classes
451 #include <blitz/vecglobs.h> // Global functions
452 #include <blitz/vector.cc> // Member functions
453 #include <blitz/vecio.cc> // IO functions
454 
455 #endif // BZ_VECTOR_H