blitz Version 0.10
blitz/vector.h
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  * blitz/vector.h      Declaration of the Vector<P_numtype> class
00004  *
00005  * $Id: vector.h,v 1.13 2011/03/25 22:41:16 julianc Exp $
00006  *
00007  * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org>
00008  *
00009  * This file is a part of Blitz.
00010  *
00011  * Blitz is free software: you can redistribute it and/or modify 
00012  * it under the terms of the GNU Lesser General Public License
00013  * as published by the Free Software Foundation, either version 3
00014  * of the License, or (at your option) any later version.
00015  *
00016  * Blitz is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU Lesser General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU Lesser General Public 
00022  * License along with Blitz.  If not, see <http://www.gnu.org/licenses/>.
00023  * 
00024  * Suggestions:          blitz-devel@lists.sourceforge.net
00025  * Bugs:                 blitz-support@lists.sourceforge.net    
00026  *
00027  * For more information, please see the Blitz++ Home Page:
00028  *    https://sourceforge.net/projects/blitz/
00029  *
00030  ****************************************************************************/
00031 
00032 /*
00033  * KNOWN BUGS
00034  *
00035  * 1. operator[](Vector<int>) won't match; compiler complains of no
00036  *       suitable copy constructor for VectorPick<T>
00037  * 2. Vector<T>(_bz_VecExpr<E>) constructor generates warning
00038  * 3. operator+=,-=,..etc.(Random<D>) won't match; compiler complains of
00039  *       no suitable copy constructor for _bz_VecExpr(...).
00040  */
00041 
00042 #ifndef BZ_VECTOR_H
00043 #define BZ_VECTOR_H
00044 
00045 #include <blitz/blitz.h>
00046 #include <blitz/memblock.h>
00047 #include <blitz/range.h>
00048 #include <blitz/listinit.h>
00049 
00050 BZ_NAMESPACE(blitz)
00051 
00052 // Forward declarations
00053 template<typename P_numtype> class VectorIter;
00054 template<typename P_numtype> class VectorIterConst;
00055 template<typename P_expr>    class _bz_VecExpr;       
00056 template<typename P_numtype> class VectorPick;
00057 template<typename P_numtype> class Random;
00058 
00059 // Declaration of class Vector<P_numtype>
00060 
00061 template<typename P_numtype>
00062 class Vector : protected MemoryBlockReference<P_numtype> {
00063   
00064 private:
00065     typedef MemoryBlockReference<P_numtype> T_base;
00066     using T_base::data_;
00067 
00068 public:
00070     // Public Types
00072 
00073     typedef P_numtype                  T_numtype;
00074     typedef Vector<T_numtype>          T_vector;
00075     typedef VectorIter<T_numtype>      T_iterator;
00076     typedef VectorIterConst<T_numtype> T_constIterator;
00077     typedef VectorPick<T_numtype>      T_pick;
00078     typedef Vector<int>                T_indexVector;
00079 
00081     // Constructors                             //
00083     // Most of the constructors are inlined so that
00084     // the setting of the stride_ data member will
00085     // be visible to the optimizer.
00086 
00087     Vector()
00088     { 
00089         length_ = 0;
00090         stride_ = 0;
00091     }
00092 
00093     // This constructor is provided inline because it involves
00094     // no memory allocation.
00095     Vector(const Vector<T_numtype>& vec)
00096         : MemoryBlockReference<T_numtype>(const_cast<Vector<T_numtype>&>(vec))
00097     {
00098         length_ = vec.length_;
00099         stride_ = vec.stride_;
00100     }
00101 
00102     explicit Vector(int length)
00103         : MemoryBlockReference<T_numtype>(length)
00104     {
00105         length_ = length;
00106         stride_ = 1;
00107     }
00108 
00109     Vector(const Vector<T_numtype>& vec, Range r)
00110         : MemoryBlockReference<T_numtype>(const_cast<Vector<T_numtype>&>(vec),
00111                                           r.first() * vec.stride())
00112     {
00113         BZPRECONDITION((r.first() >= 0) && (r.first() < vec.length()));
00114         BZPRECONDITION((r.last(vec.length()-1) >= 0) 
00115             && (r.last(vec.length()-1) < vec.length()));
00116         length_ = (r.last(vec.length()-1) - r.first()) / r.stride() + 1;
00117         stride_ = vec.stride() * r.stride();
00118     }
00119 
00120     Vector(int length, T_numtype initValue)
00121         : MemoryBlockReference<T_numtype>(length)
00122     {
00123         length_ = length;
00124         stride_ = 1;
00125         (*this) = initValue;
00126     }
00127 
00128     Vector(int length, T_numtype firstValue, T_numtype delta)
00129         : MemoryBlockReference<T_numtype>(length)
00130     {
00131         length_ = length;
00132         stride_ = 1;
00133         for (int i=0; i < length; ++i)
00134             data_[i] = firstValue + i * delta;
00135     }
00136 
00137     template<typename P_distribution>
00138     Vector(int length, Random<P_distribution>& random)
00139         : MemoryBlockReference<T_numtype>(length)
00140     {
00141         length_ = length;
00142         stride_ = 1;
00143         (*this) = random;
00144     }
00145 
00146     template<typename P_expr>
00147     Vector(_bz_VecExpr<P_expr> expr)
00148         : MemoryBlockReference<T_numtype>(expr._bz_suggestLength())
00149     {
00150         length_ = expr._bz_suggestLength();
00151         stride_ = 1;
00152         (*this) = expr;
00153     }
00154 
00155     // Create a vector view of an already allocated block of memory.
00156     // Note that the memory will not be freed when this vector is
00157     // destroyed.
00158     Vector(int length, T_numtype* restrict data, int stride = 1)
00159         : MemoryBlockReference<T_numtype>(length, data, neverDeleteData)
00160     {
00161         length_ = length;
00162         stride_ = stride;
00163     }
00164 
00165     // Create a vector containing a range of numbers
00166     Vector(Range r)
00167         : MemoryBlockReference<T_numtype>(r._bz_suggestLength())
00168     {
00169         length_ = r._bz_suggestLength();
00170         stride_ = 1;
00171         (*this) = _bz_VecExpr<Range>(r);
00172     }
00173     
00175     // Member functions
00177 
00178     // assertUnitStride() is provided as an optimizing trick.  When
00179     // vectors are constructed outside the function scope, the optimizer
00180     // is unaware that they have unit stride.  This function sets the
00181     // stride to 1 in the local scope so the optimizer can do copy
00182     // propagation & dead code elimination.  Obviously, you don't
00183     // want to use this routine unless you are certain that the
00184     // vectors have unit stride.
00185     void            assertUnitStride()
00186     {
00187         BZPRECONDITION(stride_ == 1);
00188         stride_ = 1;
00189     }
00190 
00191     T_iterator      beginFast()        { return T_iterator(*this);      }
00192     T_constIterator beginFast()  const { return T_constIterator(*this); }
00193 
00194     T_vector        copy()   const;
00195 
00196     // T_iterator      end();
00197     // T_constIterator end()    const;
00198 
00199     T_numtype * restrict data()  
00200     { return data_; }
00201 
00202     const T_numtype * restrict data() const
00203     { return data_; }
00204 
00205     bool        isUnitStride() const
00206     { return stride_ == 1; }
00207 
00208     int        length() const
00209     { return length_; }
00210 
00211     void            makeUnique();
00212 
00213     // int        storageSize() const;
00214 
00215     // void            storeToBuffer(void* buffer, int bufferLength) const;
00216 
00217     void            reference(T_vector&);
00218 
00219     void            resize(int length);
00220 
00221     void            resizeAndPreserve(int newLength);
00222 
00223     // int             restoreFromBuffer(void* buffer, int bufferLength);
00224 
00225     T_vector        reverse()
00226     { return T_vector(*this,Range(length()-1,0,-1)); }
00227 
00228     int             stride() const
00229     { return stride_; }
00230 
00231     operator _bz_VecExpr<VectorIterConst<T_numtype> > () const
00232     { return _bz_VecExpr<VectorIterConst<T_numtype> >(beginFast()); }
00233 
00235     // Library-internal member functions
00236     // These are undocumented and may change or
00237     // disappear in future releases.
00239 
00240     int        _bz_suggestLength() const
00241     { return length_; }
00242 
00243     bool        _bz_hasFastAccess() const
00244     { return stride_ == 1; }
00245 
00246     T_numtype&      _bz_fastAccess(int i)
00247     { return data_[i]; }
00248 
00249     T_numtype       _bz_fastAccess(int i) const
00250     { return data_[i]; }
00251 
00252     template<typename P_expr, typename P_updater>
00253     void            _bz_assign(P_expr, P_updater);
00254 
00255     _bz_VecExpr<T_constIterator> _bz_asVecExpr() const
00256     { return _bz_VecExpr<T_constIterator>(beginFast()); }
00257 
00259     // Subscripting operators
00261 
00262     // operator()(int) may be used only when the vector has unit
00263     // stride.  Otherwise, use operator[].
00264     T_numtype        operator()(int i) const
00265     {
00266         BZPRECONDITION(i < length_);
00267         BZPRECONDITION(stride_ == 1);
00268         return data_[i];
00269     }
00270 
00271     // operator()(int) may be used only when the vector has unit
00272     // stride.  Otherwise, use operator[].
00273     T_numtype& restrict operator()(int i) 
00274     {
00275         BZPRECONDITION(i < length_);
00276         BZPRECONDITION(stride_ == 1);
00277         return data_[i];
00278     }
00279 
00280     T_numtype        operator[](int i) const
00281     {
00282         BZPRECONDITION(i < length_);
00283         return data_[i * stride_];
00284     }
00285 
00286     T_numtype& restrict operator[](int i)
00287     {
00288         BZPRECONDITION(i < length_);
00289         return data_[i * stride_];
00290     }
00291 
00292     T_vector      operator()(Range r)
00293     {
00294         return T_vector(*this, r);
00295     }
00296 
00297     T_vector      operator[](Range r)
00298     {
00299         return T_vector(*this, r);
00300     }
00301 
00302     T_pick        operator()(T_indexVector i)
00303     {
00304         return T_pick(*this, i);
00305     }
00306 
00307     T_pick        operator[](T_indexVector i)
00308     {
00309         return T_pick(*this, i);
00310     }
00311 
00312     // T_vector      operator()(difference-equation-expression)
00313 
00315     // Assignment operators
00317 
00318     // Scalar operand
00319     ListInitializationSwitch<T_vector,T_iterator> operator=(T_numtype x)
00320     {
00321         return ListInitializationSwitch<T_vector,T_iterator>(*this, x);
00322     }
00323 
00324     T_iterator getInitializationIterator()
00325     { return beginFast(); }
00326 
00327     T_vector& initialize(T_numtype);
00328     T_vector& operator+=(T_numtype);
00329     T_vector& operator-=(T_numtype);
00330     T_vector& operator*=(T_numtype);
00331     T_vector& operator/=(T_numtype);
00332     T_vector& operator%=(T_numtype);
00333     T_vector& operator^=(T_numtype);
00334     T_vector& operator&=(T_numtype);
00335     T_vector& operator|=(T_numtype);
00336     T_vector& operator>>=(int);
00337     T_vector& operator<<=(int); 
00338 
00339     // Vector operand
00340    
00341     template<typename P_numtype2> T_vector& operator=(const Vector<P_numtype2> &);
00342 
00343     // Specialization uses memcpy instead of element-by-element cast and
00344     // copy
00345     // NEEDS_WORK -- KCC won't accept this syntax; standard??
00346     // template<> T_vector& operator=(const T_vector&);
00347 
00348     template<typename P_numtype2> T_vector& operator+=(const Vector<P_numtype2> &);
00349     template<typename P_numtype2> T_vector& operator-=(const Vector<P_numtype2> &);
00350     template<typename P_numtype2> T_vector& operator*=(const Vector<P_numtype2> &);
00351     template<typename P_numtype2> T_vector& operator/=(const Vector<P_numtype2> &);
00352     template<typename P_numtype2> T_vector& operator%=(const Vector<P_numtype2> &);
00353     template<typename P_numtype2> T_vector& operator^=(const Vector<P_numtype2> &);
00354     template<typename P_numtype2> T_vector& operator&=(const Vector<P_numtype2> &);
00355     template<typename P_numtype2> T_vector& operator|=(const Vector<P_numtype2> &);
00356     template<typename P_numtype2> T_vector& operator>>=(const Vector<P_numtype2> &);
00357     template<typename P_numtype2> T_vector& operator<<=(const Vector<P_numtype2> &);
00358 
00359     // Vector expression operand
00360     template<typename P_expr> T_vector& operator=(_bz_VecExpr<P_expr>);
00361     template<typename P_expr> T_vector& operator+=(_bz_VecExpr<P_expr>); 
00362     template<typename P_expr> T_vector& operator-=(_bz_VecExpr<P_expr>);
00363     template<typename P_expr> T_vector& operator*=(_bz_VecExpr<P_expr>);
00364     template<typename P_expr> T_vector& operator/=(_bz_VecExpr<P_expr>);
00365     template<typename P_expr> T_vector& operator%=(_bz_VecExpr<P_expr>);
00366     template<typename P_expr> T_vector& operator^=(_bz_VecExpr<P_expr>);
00367     template<typename P_expr> T_vector& operator&=(_bz_VecExpr<P_expr>);
00368     template<typename P_expr> T_vector& operator|=(_bz_VecExpr<P_expr>);
00369     template<typename P_expr> T_vector& operator>>=(_bz_VecExpr<P_expr>);
00370     template<typename P_expr> T_vector& operator<<=(_bz_VecExpr<P_expr>);
00371     
00372     // VectorPick operand
00373     template<typename P_numtype2> 
00374     T_vector& operator=(const VectorPick<P_numtype2> &);
00375     template<typename P_numtype2> 
00376     T_vector& operator+=(const VectorPick<P_numtype2> &);
00377     template<typename P_numtype2> 
00378     T_vector& operator-=(const VectorPick<P_numtype2> &);
00379     template<typename P_numtype2> 
00380     T_vector& operator*=(const VectorPick<P_numtype2> &);
00381     template<typename P_numtype2> 
00382     T_vector& operator/=(const VectorPick<P_numtype2> &);
00383     template<typename P_numtype2>
00384     T_vector& operator%=(const VectorPick<P_numtype2> &);
00385     template<typename P_numtype2>
00386     T_vector& operator^=(const VectorPick<P_numtype2> &);
00387     template<typename P_numtype2>
00388     T_vector& operator&=(const VectorPick<P_numtype2> &);
00389     template<typename P_numtype2>
00390     T_vector& operator|=(const VectorPick<P_numtype2> &);
00391     template<typename P_numtype2>
00392     T_vector& operator>>=(const VectorPick<P_numtype2> &);
00393     template<typename P_numtype2>
00394     T_vector& operator<<=(const VectorPick<P_numtype2> &);
00395 
00396     // Range operand
00397     T_vector& operator=(Range);
00398     T_vector& operator+=(Range);
00399     T_vector& operator-=(Range);
00400     T_vector& operator*=(Range);
00401     T_vector& operator/=(Range);
00402     T_vector& operator%=(Range);
00403     T_vector& operator^=(Range);
00404     T_vector& operator&=(Range);
00405     T_vector& operator|=(Range);
00406     T_vector& operator>>=(Range);
00407     T_vector& operator<<=(Range);
00408 
00409     // Random operand
00410     template<typename P_distribution>
00411     T_vector& operator=(Random<P_distribution>& random);
00412     template<typename P_distribution>
00413     T_vector& operator+=(Random<P_distribution>& random);
00414     template<typename P_distribution>
00415     T_vector& operator-=(Random<P_distribution>& random);
00416     template<typename P_distribution>
00417     T_vector& operator*=(Random<P_distribution>& random);
00418     template<typename P_distribution>
00419     T_vector& operator/=(Random<P_distribution>& random);
00420     template<typename P_distribution>
00421     T_vector& operator%=(Random<P_distribution>& random);
00422     template<typename P_distribution>
00423     T_vector& operator^=(Random<P_distribution>& random);
00424     template<typename P_distribution>
00425     T_vector& operator&=(Random<P_distribution>& random);
00426     template<typename P_distribution>
00427     T_vector& operator|=(Random<P_distribution>& random);
00428 
00430     // Unary operators
00432 
00433 //    T_vector& operator++();
00434 //    void operator++(int);
00435 //    T_vector& operator--();
00436 //    void operator--(int);
00437     
00438 private:
00439     int      length_;
00440     int      stride_;
00441 };
00442 
00443 // Global I/O functions
00444 
00445 template<typename P_numtype>
00446 ostream& operator<<(ostream& os, const Vector<P_numtype>& x);
00447 
00448 template<typename P_expr>
00449 ostream& operator<<(ostream& os, _bz_VecExpr<P_expr> expr);
00450 
00451 template<typename P_numtype>
00452 istream& operator>>(istream& is, Vector<P_numtype>& x);
00453 
00454 BZ_NAMESPACE_END
00455 
00456 #include <blitz/veciter.h>          // Iterators
00457 #include <blitz/vecpick.h>          // VectorPick
00458 #include <blitz/vecexpr.h>          // Expression template classes
00459 #include <blitz/vecwhere.h>         // Vector where function
00460 #include <blitz/vecglobs.h>         // Global functions
00461 #include <blitz/vector.cc>          // Member functions
00462 #include <blitz/vecio.cc>           // IO functions
00463 
00464 #endif // BZ_VECTOR_H
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines