blitz Version 0.10
|
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