lib_ex_pour_HZpp/Partie_2/algebre_lineaire/MV++/mv/include/mvvtp.h

1 line
No EOL
14 KiB
C
Executable file

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* */
/* */
/* 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
#ifndef _MV_VECTOR_TPL_H_
#define _MV_VECTOR_TPL_H_
#include <iostream.h> // for formatted printing of vecteur : GR
#include <stdlib.h>
#ifdef MV_VECTOR_BOUNDS_CHECK
# include <assert.h>
#endif
#include "mvvind.h"
#include "mvvrf.h"
template <class TYPE>
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<TYPE>&);
~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<TYPE> operator()(const MV_VecIndex &I) ;
inline MV_Vector<TYPE> operator()(void);
inline const MV_Vector<TYPE> operator()(void) const;
inline const MV_Vector<TYPE> 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<TYPE> & newsize(unsigned int );
/*::::::::::::::*/
/* Assignment */
/*::::::::::::::*/
MV_Vector<TYPE> & operator=(const MV_Vector<TYPE>&);
MV_Vector<TYPE> & operator=(const TYPE&);
};
template <class TYPE>
ostream& operator<<(ostream& s, const MV_Vector<TYPE>& V)
{
int N = V.size();
for (int j=0; j<N; j++)
s << V(j) << " " ;
s << endl;
return s;
}
template <class TYPE>
MV_Vector<TYPE>::MV_Vector() : p_(NULL), dim_(0) , ref_(0){}
template <class TYPE>
MV_Vector<TYPE>::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 <class TYPE>
MV_Vector<TYPE>::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<n; i++)
p_[i] = v;
}
// operators and member functions
//
template <class TYPE>
MV_Vector<TYPE>& MV_Vector<TYPE>::operator=(const TYPE & m)
{
#ifdef TRACE_VEC
cout << "> MV_Vector<TYPE>::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<Nminus4; )
{
p_[i++] = m;
p_[i++] = m;
p_[i++] = m;
p_[i++] = m;
}
for (; i<N; p_[i++] = m); // finish off last piece...
#ifdef TRACE_VEC
cout << "< MV_Vector<TYPE>::operator=(const TYPE & m) " << endl;
#endif
return *this;
}
template <class TYPE>
MV_Vector<TYPE>& MV_Vector<TYPE>::newsize(unsigned int n)
{
#ifdef TRACE_VEC
cout << "> MV_Vector<TYPE>::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<TYPE>::newsize(unsigned int n) " << endl;
#endif
return *this;
}
template <class TYPE>
MV_Vector<TYPE>& MV_Vector<TYPE>::operator=(const MV_Vector<TYPE> & 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<N; i++)
p_[i] = m.p_[i];
}
}
else
{
newsize(N);
// no need to test for overlap, since this region is new
for (i =0; i< N; i++) // careful not to use bcopy()
p_[i] = m.p_[i]; // here, but TYPE::operator= TYPE.
}
return *this;
}
template <class TYPE>
MV_Vector<TYPE>::MV_Vector(const MV_Vector<TYPE> & 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<N; i++)
p_[i] = m.p_[i];
}
// note that ref() is initalized with i rather than 1.
// this is so compilers will not generate a warning that i was
// not used in the construction. (MV_Vector::ref_type is an enum that
// can *only* have the value of 1.
//
template <class TYPE>
MV_Vector<TYPE>::MV_Vector(TYPE* d, unsigned int n, MV_Vector_::ref_type i) :
p_(d), dim_(n) , ref_(i) {}
template <class TYPE>
MV_Vector<TYPE>::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<n; i++)
p_[i] = d[i];
}
template <class TYPE>
MV_Vector<TYPE>::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<n; i++)
p_[i] = d[i];
}
template <class TYPE>
MV_Vector<TYPE> MV_Vector<TYPE>::operator()(void)
{
return MV_Vector<TYPE>(p_, dim_, MV_Vector_::ref);
}
template <class TYPE>
const MV_Vector<TYPE> MV_Vector<TYPE>::operator()(void) const
{
return MV_Vector<TYPE>(p_, dim_, MV_Vector_::ref);
}
template <class TYPE>
MV_Vector<TYPE> MV_Vector<TYPE>::operator()(const MV_VecIndex &I)
{
// default parameters
if (I.all())
return MV_Vector<TYPE>(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<TYPE>(p_+ I.start(), I.end() - I.start() + 1,
MV_Vector_::ref);
}
}
template <class TYPE>
const MV_Vector<TYPE> MV_Vector<TYPE>::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<TYPE>(p_+ I.start(), I.end() - I.start() + 1,
MV_Vector_::ref);
}
template <class TYPE>
MV_Vector<TYPE>::~MV_Vector()
{
if (p_ && !ref_ ) delete [] p_;
}
template <class TYPE>
class FMV_Vector : public MV_Vector<TYPE>
{
public:
FMV_Vector(unsigned int n) : MV_Vector<TYPE>(n) {}
FMV_Vector<TYPE>& operator=(const FMV_Vector<TYPE>& m);
FMV_Vector<TYPE>& operator=(const TYPE& m);
};
template <class TYPE>
FMV_Vector<TYPE>& FMV_Vector<TYPE>::operator=( const FMV_Vector<TYPE>& m)
{
#ifdef TRACE_VEC
cout << "> FMV_Vector<TYPE>::operator=( const FMV_Vector<TYPE>& 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<TYPE>::operator=( const FMV_Vector<TYPE>& m)" << endl;
#endif
return *this;
}
template <class TYPE>
FMV_Vector<TYPE>& FMV_Vector<TYPE>::operator=(const TYPE & m)
{
#ifdef TRACE_VEC
cout << "> FMV_Vector<TYPE>::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<Nminus4; )
{
p_[i++] = m;
p_[i++] = m;
p_[i++] = m;
p_[i++] = m;
}
for (; i<N; p_[i++] = m); // finish off last piece...
#ifdef TRACE_VEC
cout << "< FMV_Vector<TYPE>::operator=(const TYPE & m) " << endl;
#endif
return *this;
}
#include "mvblas.h"
#endif
// _MV_VECTOR_TPL_H_