/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ /* */ /* */ /* 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 // // modif gérard Rio : // - introduction de la surcharge d'écriture dans la classe MVvecteur // - modification de l'indice du type unsigned int au type int et vérification // du nombre négatif // - modification de la surcharge d'écriture (ajout de l'écriture de la taille) // et ajout de la surcharge de lecture en cohérence avec l'écriture déjà existante // - introduction de la possibilité de créer un vecteur à la place d'un autre // en donnant la référence à l'autre vecteur et un indicateur de non construction // - dans le cas ou les tailles à alouer sont nulles, on met en place une procédure spé #ifndef _MV_VECTOR_TPL_H_ #define _MV_VECTOR_TPL_H_ #include // for formatted printing of vecteur : GR #include #ifdef MV_VECTOR_BOUNDS_CHECK # include #endif #include "Sortie.h" //#ifdef SYSTEM_MAC_OS_X // #include // a priori ce n'est pas portable //#el #if defined SYSTEM_MAC_OS_CARBON #include // a priori ce n'est pas portable #else #include // pour le flot en memoire centrale #endif #include #include "mvvind_GR.h" #include "mvvrf_GR.h" using namespace std; template class MV_Vector { protected: TYPE *p_; // unsigned int dim_; int dim_; // modif GR int ref_; // 0 or 1; does this own its own memory space? public: // les informations sont le type puis la taille puis les datas friend istream & operator >> (istream & entree, MV_Vector& vec) { // vérification du type string type; entree >> type; if (type != "MV_Vector<>") {Sortie (1); return entree; } // passage de la chaine donnant la taille puis lecture de la taille int taille; entree >> type >> taille; // vérification de la taille sinon changement if (vec.size() != taille) vec.newsize(taille); // lecture des données for (int i = 0; i< taille; i++) entree >> vec.p_[i]; return entree; }; // surcharge de l'operator d'ecriture non formatée // les informations sont le type puis la taille puis les datas séparées par // un espace friend ostream& operator<<(ostream& s, const MV_Vector& V) { int N = V.size(); s << "\n MV_Vector<> taille= " << V.size(); for (int j=0; j&); // construction conditionnelle en fonction de l'indicateur // cette construction est moins rapide que la précédente s'il y a vraiment // définition d'un nouveau tableau de data (appel de new moin bon) MV_Vector(MV_Vector&,MV_Vector_::ref_type i); // destructeur ~MV_Vector(); /*::::::::::::::::::::::::::::::::*/ /* Indices and access operations */ /*::::::::::::::::::::::::::::::::*/ // inline TYPE& operator()(unsigned int i) inline TYPE& operator()(int i) // modif GR { # ifdef MV_VECTOR_BOUNDS_CHECK // assert(i < dim_); assert((i < dim_)||(i>=0)); // modif GR # endif return p_[i]; } // inline const TYPE& operator()(unsigned int i) const inline const TYPE& operator()( int i) const // modif GR { # ifdef MV_VECTOR_BOUNDS_CHECK // assert(i < dim_); assert((i < dim_)||(i>=0)); // modif GR # endif return p_[i]; } // inline TYPE& operator[](unsigned int i) inline TYPE& operator[](int i) // modif GR { # ifdef MV_VECTOR_BOUNDS_CHECK // assert(i < dim_); assert((i < dim_)||(i>=0)); // modif GR # endif return p_[i]; } // inline const TYPE& operator[](unsigned int i) const inline const TYPE& operator[]( int i) const // modif GR { # ifdef MV_VECTOR_BOUNDS_CHECK // assert(i < dim_); assert((i < dim_)||(i>=0)); // modif GR # 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 size() const { return dim_;} // modif GR inline int ref() const { return ref_;} inline int null() const {return dim_== 0;} // // Create a new *uninitalized* vector of size N MV_Vector & newsize( int ); /*::::::::::::::*/ /* Assignment */ /*::::::::::::::*/ MV_Vector & operator=(const MV_Vector&); MV_Vector & operator=(const TYPE&); }; template ostream& operator<<(ostream& s, const MV_Vector& V) { int N = V.size(); s << "\n MV_Vector<> taille= " << V.size(); for (int j=0; j istream & operator >> (istream & entree, MV_Vector& vec) { // vérification du type string type; entree >> type; if (type != "MV_Vector<>") {Sortie (1); return entree; } // passage de la chaine donnant la taille puis lecture de la taille int taille; entree >> type >> taille; // vérification de la taille sinon changement if (vec.size() != taille) vec.newsize(taille); // lecture des données for (int i = 0; i< vec.taille; i++) entree >> vec.p_[i]; return entree; }; template MV_Vector::MV_Vector() : p_(NULL), dim_(0) , ref_(0){} template //MV_Vector::MV_Vector(unsigned int n) : p_(new TYPE[n]), dim_(n), // a priori si n est négatif new ramènera une erreur //MV_Vector::MV_Vector( int n) : p_(new TYPE[n]), dim_(n), // modif 1 GR MV_Vector::MV_Vector( int n) : dim_(n), // modif 2 GR ref_(0) { if (n!= 0) {p_ = new TYPE[n]; if (p_ == NULL) { cerr << "Error: NULL pointer in MV_Vector(int) constructor " << endl; cerr << " Most likely out of memory... " << endl; Sortie(1); } } else p_=NULL; // ajout car new ne fait pas bien son boulot !! } template //MV_Vector::MV_Vector(unsigned int n, const TYPE& v) : MV_Vector::MV_Vector( int n, const TYPE& v) : // modif 1 GR // p_(new TYPE[n]), dim_(n), ref_(0) dim_(n), ref_(0) // modif 2 GR { if (n!= 0) { p_ = new TYPE[n]; if (p_ == NULL) { cerr << "Error: NULL pointer in MV_Vector(int) constructor " << endl; cerr << " Most likely out of memory... " << endl; Sortie(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 = this->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) MV_Vector& MV_Vector::newsize( int n) // modif GR { #ifdef TRACE_VEC // cout << "> MV_Vector::newsize(unsigned int n) " << endl; cout << "> MV_Vector::newsize( int n) " << endl; #endif if (ref_ ) // is this structure just a pointer? { { cerr << "MV_Vector::newsize can't operator on references.\n"; Sortie(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; Sortie(1); } dim_ = n; } #ifdef TRACE_VEC // cout << "< MV_Vector::newsize(unsigned int n) " << endl; cout << "< MV_Vector::newsize( 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"; Sortie(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_]), MV_Vector::MV_Vector(const MV_Vector & m) : // modif 2 GR dim_(m.dim_) , ref_(0) , p_(NULL) // gerard: ajout de p_(NULL) { if (m.dim_ != 0) {p_ = new TYPE[m.dim_]; if (p_ == NULL) { cerr << "Error: Null pointer in MV_Vector(const MV_Vector&); " << endl; Sortie(1); } int N = m.dim_; for (int i=0; i //MV_Vector::MV_Vector(TYPE* d, unsigned int n, MV_Vector_::ref_type i) : MV_Vector::MV_Vector(TYPE* d, int n, MV_Vector_::ref_type i) : // modif GR p_(d), dim_(n) , ref_(i) { # ifdef MV_VECTOR_BOUNDS_CHECK assert(n < 0); // modif GR # endif } template //MV_Vector::MV_Vector(TYPE* d, unsigned int n) : p_(new TYPE[n]), //MV_Vector::MV_Vector(TYPE* d, int n) : p_(new TYPE[n]), // modif 1 GR MV_Vector::MV_Vector(TYPE* d, int n) : // modif 2 GR // a priori si n est négatif l'opérateur new renvera une erreur dim_(n) , ref_(0) { if (n != 0) {p_ = new TYPE[n]; if (p_ == NULL) { cerr << "Error: Null pointer in MV_Vector(TYPE*, int) " << endl; Sortie(1); } for (int i=0; i MV_Vector::MV_Vector(MV_Vector& B ,MV_Vector_::ref_type i) : p_(B.p_),dim_(B.dim_) , ref_(i) { // le vecteur est construit en fonction du cas donné par ref_ if (ref_ != 1) // cas avec construction { p_ = new TYPE[dim_]; for (int i=0; i //MV_Vector::MV_Vector(const TYPE* d, unsigned int n) : p_(new TYPE[n]), //MV_Vector::MV_Vector(const TYPE* d, int n) : p_(new TYPE[n]), // modif 1 GR MV_Vector::MV_Vector(const TYPE* d, int n) : // modif 2 GR // a priori si n est négatif l'opérateur new renvera une erreur dim_(n) , ref_(0) {if (n != 0) {p_=new TYPE[n]; if (p_ == NULL) { cerr << "Error: Null pointer in MV_Vector(TYPE*, int) " << endl; Sortie(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; Sortie(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; Sortie(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( 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 (this->ref_ ) // is this structure just a pointer? { if (this->dim_ != m.dim_) // check conformance, { cerr << "MV_VectorRef::operator= non-conformant assignment.\n"; Sortie(1); } } else if ( this->dim_ != m.dim_ ) // resize only if necessary this->newsize(N); memmove(this->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 = this->size(); int Nminus4 = N-4; int i; for (i=0; ip_[i++] = m; this->p_[i++] = m; this->p_[i++] = m; this->p_[i++] = m; } for (; ip_[i++] = m); // finish off last piece... #ifdef TRACE_VEC cout << "< FMV_Vector::operator=(const TYPE & m) " << endl; #endif return *this; } #include "mvblas_GR.h" #endif // _MV_VECTOR_TPL_H_