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