/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ /* */ /* */ /* MV++ Numerical Matrix/Vector C++ Library */ /* MV++ Version 1.5 */ /* */ /* R. Pozo */ /* National Institute of Standards and Technology */ /* */ /* NOTICE */ /* */ /* Permission to use, copy, modify, and distribute this software and */ /* its documentation for any purpose and without fee is hereby granted */ /* provided that this permission notice appear in all copies and */ /* supporting documentation. */ /* */ /* Neither the Institution (National Institute of Standards and Technology) */ /* nor the author makes any representations about the suitability of this */ /* software for any purpose. This software is provided ``as is''without */ /* expressed or implied warranty. */ /* */ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ // // mvvtp.h Basic templated vector class // #ifndef _MV_VECTOR_TPL_H_ #define _MV_VECTOR_TPL_H_ #include #ifdef MV_VECTOR_BOUNDS_CHECK # include #endif #include "mvvind.h" #include "mvvrf.h" template class MV_Vector { protected: TYPE *p_; unsigned int dim_; int ref_; // 0 or 1; does this own its own memory space? public: /*::::::::::::::::::::::::::*/ /* Constructors/Destructors */ /*::::::::::::::::::::::::::*/ MV_Vector(); MV_Vector(unsigned int); MV_Vector(unsigned int, const TYPE&); MV_Vector(TYPE*, unsigned int); MV_Vector(const TYPE*, unsigned int); // reference of an exisiting data structure // MV_Vector(TYPE*, unsigned int, MV_Vector_::ref_type i); MV_Vector(const MV_Vector&); ~MV_Vector(); /*::::::::::::::::::::::::::::::::*/ /* Indices and access operations */ /*::::::::::::::::::::::::::::::::*/ inline TYPE& operator()(unsigned int i) { # ifdef MV_VECTOR_BOUNDS_CHECK assert(i < dim_); # endif return p_[i]; } inline const TYPE& operator()(unsigned int i) const { # ifdef MV_VECTOR_BOUNDS_CHECK assert(i < dim_); # endif return p_[i]; } inline TYPE& operator[](unsigned int i) { # ifdef MV_VECTOR_BOUNDS_CHECK assert(i < dim_); # endif return p_[i]; } inline const TYPE& operator[](unsigned int i) const { # ifdef MV_VECTOR_BOUNDS_CHECK assert(i < dim_); # endif return p_[i]; } inline MV_Vector operator()(const MV_VecIndex &I) ; inline MV_Vector operator()(void); inline const MV_Vector operator()(void) const; inline const MV_Vector operator()(const MV_VecIndex &I) const; inline unsigned int size() const { return dim_;} inline int ref() const { return ref_;} inline int null() const {return dim_== 0;} // // Create a new *uninitalized* vector of size N MV_Vector & newsize(unsigned int ); /*::::::::::::::*/ /* Assignment */ /*::::::::::::::*/ MV_Vector & operator=(const MV_Vector&); MV_Vector & operator=(const TYPE&); }; template MV_Vector::MV_Vector() : p_(0), dim_(0) , ref_(0){}; template MV_Vector::MV_Vector(unsigned int n) : p_(new TYPE[n]), dim_(n), ref_(0) { if (p_ == NULL) { cerr << "Error: NULL pointer in MV_Vector(int) constructor " << endl; cerr << " Most likely out of memory... " << endl; exit(1); } } template MV_Vector::MV_Vector(unsigned int n, const TYPE& v) : p_(new TYPE[n]), dim_(n), ref_(0) { if (p_ == NULL) { cerr << "Error: NULL pointer in MV_Vector(int) constructor " << endl; cerr << " Most likely out of memory... " << endl; exit(1); } for (int i=0; i MV_Vector& MV_Vector::operator=(const TYPE & m) { #ifdef TRACE_VEC cout << "> MV_Vector::operator=(const TYPE & m) " << endl; #endif // unroll loops to depth of length 4 int N = size(); int Nminus4 = N-4; int i; for (i=0; i::operator=(const TYPE & m) " << endl; #endif return *this; } template MV_Vector& MV_Vector::newsize(unsigned int n) { #ifdef TRACE_VEC cout << "> MV_Vector::newsize(unsigned int n) " << endl; #endif if (ref_ ) // is this structure just a pointer? { { cerr << "MV_Vector::newsize can't operator on references.\n"; exit(1); } } else if (dim_ != n ) // only delete and new if { // the size of memory is really if (p_) delete [] p_; // changing, otherwise just p_ = new TYPE[n]; // copy in place. if (p_ == NULL) { cerr << "Error : NULL pointer in operator= " << endl; exit(1); } dim_ = n; } #ifdef TRACE_VEC cout << "< MV_Vector::newsize(unsigned int n) " << endl; #endif return *this; } template MV_Vector& MV_Vector::operator=(const MV_Vector & m) { int N = m.dim_; int i; if (ref_ ) // is this structure just a pointer? { if (dim_ != m.dim_) // check conformance, { cerr << "MV_VectorRef::operator= non-conformant assignment.\n"; exit(1); } // handle overlapping matrix references if ((m.p_ + m.dim_) >= p_) { // overlap case, copy backwards to avoid overwriting results for (i= N-1; i>=0; i--) p_[i] = m.p_[i]; } else { for (i=0; i MV_Vector::MV_Vector(const MV_Vector & m) : p_(new TYPE[m.dim_]), dim_(m.dim_) , ref_(0) { if (p_ == NULL) { cerr << "Error: Null pointer in MV_Vector(const MV_Vector&); " << endl; exit(1); } int N = m.dim_; for (int i=0; i MV_Vector::MV_Vector(TYPE* d, unsigned int n, MV_Vector_::ref_type i) : p_(d), dim_(n) , ref_(i) {} template MV_Vector::MV_Vector(TYPE* d, unsigned int n) : p_(new TYPE[n]), dim_(n) , ref_(0) { if (p_ == NULL) { cerr << "Error: Null pointer in MV_Vector(TYPE*, int) " << endl; exit(1); } for (int i=0; i MV_Vector::MV_Vector(const TYPE* d, unsigned int n) : p_(new TYPE[n]), dim_(n) , ref_(0) { if (p_ == NULL) { cerr << "Error: Null pointer in MV_Vector(TYPE*, int) " << endl; exit(1); } for (int i=0; i MV_Vector MV_Vector::operator()(void) { return MV_Vector(p_, dim_, MV_Vector_::ref); } template const MV_Vector MV_Vector::operator()(void) const { return MV_Vector(p_, dim_, MV_Vector_::ref); } template MV_Vector MV_Vector::operator()(const MV_VecIndex &I) { // default parameters if (I.all()) return MV_Vector(p_, dim_, MV_Vector_::ref); else { // check that index is not out of bounds // if ( I.end() >= dim_) { cerr << "MV_VecIndex: (" << I.start() << ":" << I.end() << ") too big for matrix (0:" << dim_ - 1 << ") " << endl; exit(1); } return MV_Vector(p_+ I.start(), I.end() - I.start() + 1, MV_Vector_::ref); } } template const MV_Vector MV_Vector::operator()(const MV_VecIndex &I) const { // check that index is not out of bounds // if ( I.end() >= dim_) { cerr << "MV_VecIndex: (" << I.start() << ":" << I.end() << ") too big for matrix (0:" << dim_ - 1 << ") " << endl; exit(1); } return MV_Vector(p_+ I.start(), I.end() - I.start() + 1, MV_Vector_::ref); } template MV_Vector::~MV_Vector() { if (p_ && !ref_ ) delete [] p_; } template class FMV_Vector : public MV_Vector { public: FMV_Vector(unsigned int n) : MV_Vector(n) {} FMV_Vector& operator=(const FMV_Vector& m); FMV_Vector& operator=(const TYPE& m); }; template FMV_Vector& FMV_Vector::operator=( const FMV_Vector& m) { #ifdef TRACE_VEC cout << "> FMV_Vector::operator=( const FMV_Vector& m)" << endl; #endif int N = m.dim_; if (ref_ ) // is this structure just a pointer? { if (dim_ != m.dim_) // check conformance, { cerr << "MV_VectorRef::operator= non-conformant assignment.\n"; exit(1); } } else if ( dim_ != m.dim_ ) // resize only if necessary newsize(N); memmove(p_, m.p_, N * sizeof(TYPE)); #ifdef TRACE_VEC cout << "< FMV_Vector::operator=( const FMV_Vector& m)" << endl; #endif return *this; } template FMV_Vector& FMV_Vector::operator=(const TYPE & m) { #ifdef TRACE_VEC cout << "> FMV_Vector::operator=(const TYPE & m) " << endl; #endif // unroll loops to depth of length 4 int N = size(); int Nminus4 = N-4; int i; for (i=0; i::operator=(const TYPE & m) " << endl; #endif return *this; } #include "mvblas.h" #endif // _MV_VECTOR_TPL_H_