1 Introduction
Vectors are one-dimensional arrays in which
all the coefficients are stored (even if they are zero).
They provide classical arithmetic operations such
as addition, substraction, multiplication by scalars.
...
2 Implementation
template < class R> struct VectStd
The standard class of vectors.
{
R rep;
typedef typename R::size_type size_type;
typedef typename R::value_type value_type;
typedef typename R::iterator iterator_t;
// typedef typename R::reverse_iterator iterator_r;
typedef R rep_type;
typedef VectStd self_t;
VectStd(): rep() {}
VectStd(const R & r):rep(r){}
VectStd(size_type s): rep(s){}
VectStd(size_type s, value_type* t): rep(t,t+s){}
VectStd(iterator_t b,iterator_t e): rep(b,e){}
VectStd(size_type m, const char * str);
// Copy constructor
VectStd(const self_t & r): rep(r.rep) {}
template
VectStd(const VectStd & P) {assign(*this,P);}
template
VectStd(const VAL & P) {assign(*this,P.rep);}
iterator_t begin() {return rep.begin();}
iterator_t begin() const {return rep.begin();}
iterator_t end() {return rep.end();}
iterator_t end() const {return rep.end();}
// iterator_r rbegin() {return rep.rbegin();}
// iterator_r rbegin() const {return rep.rbegin();}
// iterator_r rend() {return rep.rend();}
// iterator_r rend() const {return rep.rend();}
// Assignement
self_t & operator =(const self_t & V){rep=V.rep; return *this;}
template
self_t & operator=(const VectStd & V) {assign(*this,V); return *this;}
template
self_t & operator=(const VAL & V) {assign(*this,V.rep); return *this;}
self_t & operator+=(const self_t & v);
self_t & operator-=(const self_t & v);
self_t & operator*=(const value_type & c);
self_t & operator/=(const value_type & c);
value_type & operator[] (size_type i) {return rep[i];}
value_type operator[] (size_type i) const {return rep[i];}
VectStd > operator[](const Range & I);
size_type size() const {return rep.size();}
};
The value_type is the type of the coefficients. The size_type is the type
of the indices used to access the elements of the vectors.
The iterator_t is the type of the forward iterators on the vectors.
The internal representation type R is rep_type.
template < class R>
inline VAL< OP< '+',VectStd< R> ,VectStd< R> > >
operator+(const VectStd< R> & a, const VectStd< R> & b)
Addition operator.
template < class R>
inline VAL< OP< '-',VectStd< R> ,VectStd< R> > >
operator-(const VectStd< R> & a, const VectStd< R> & b)
Substraction operator.
template < class R>
inline VAL< OP< '-',VectStd< R> ,VectStd< R> > >
operator-(const VectStd< R> & a)
Unary substraction operator.
template < class R> inline
VAL< OP< '.',VectStd< R> ,typename VectStd< R> ::value_type> >
operator*(const VectStd< R> & a, const typename VectStd< R> ::value_type & c)
Scalar multiplication on the right.
template < class R> inline
VAL< OP< '.',VectStd< R> ,typename VectStd< R> ::value_type> >
operator*(const typename VectStd< R> ::value_type & c,const VectStd< R> & a)
Scalar multiplication on the left.
template < class R,class C> inline
VAL< OP< '/',VectStd< R> ,C> >
operator/(const VectStd< R> & a, const C & b)
Scalar division on the right.
template< class R>
ostream & operator< < (ostream & os, const VectStd< R> & V)
Output operator.
template< class R> inline
istream & operator> > (istream & is, VectStd< R> & V)
Input operator for standard matrices. The input format is of the form
s c0 c1 ... where s is the number of elements.
template < class R>
VectStd< R> ::VectStd(size_type m, const char * str): rep(m)
Constructor for a size m and a string containing the elements.
Example: VectStd(3,"1 2 3").
3 Containers for Vectors
The container type R should provide the following signature:
typedef size_type; // type of the index.
typedef value_type; // type of the coefficients.
typedef iterator; // type of the iterator.
R(size_type n);
R(size_type n, value_type* t);
R(iterator b,iterator e);
R& R::operator=(const R &)
size_type R::size()
value_type & R::operator[] (size_type i);
value_type R::operator[] (size_type i) const;
void R::reserve(size_type);
The constructor R(size_type i) allocate the memory but nothing is
supposed to be known about the allocated values.
The constructor R(iterator_t b, iterator_t e) allocates the memory
and fill it with the values from the iterator from b to e.
The constructor R(size_type n, const char* str) build the array
of size n from the string str.
The function void R::reserve(size_type s) reallocate the memory if
necessary and copies the elements of this,
or use the current memory space if s is less that the
actual space.
4 An example of containor
template < class C> struct array1d
Unidimensional array of coefficients with a size.
{
typedef C value_type;
typedef unsigned int size_type;
typedef C* iterator;
typedef C* const_iterator;
size_type size_;
C * tab_;
array1d() : size_(0), tab_(0) {}
array1d(const array1d & v);
array1d(size_type i);
array1d(size_type i, C* t);
array1d(C* b, C* e);
array1d(size_type, const char * nm);
void reserve(size_type i);
array1d & operator=(const array1d & v);
array1d & operator=(array1d * v);
size_type size() const {return size_;}
iterator begin() { return iterator(tab_); }
const_iterator begin() const { return const_iterator(tab_); }
iterator end() { return iterator(tab_+size_); }
const_iterator end() const { return const_iterator(tab_+size_); }
inline C & operator[] (size_type i)
{return tab_[i];}
inline const C & operator[] (size_type i) const
{return tab_[i];}
// No test {if(i
5 How to use them
#include "linalg.H"
// General header file for linear algebra
typedef VectStd<array1d<double> > VECT;
// Vector definition based on array1d container, with double coefficients.
int main(int argc, char** argv) {
VECT U(4,"0 2 1 3"), V(4,"1 2 3 4"), W;
cout<<"U="<<U<<", V ="<<V<<endl;
U=[0, 2, 1, 3], V =[1, 2, 3, 4]
cout<<V*2 << ", " << V/4<<endl;
([1, 2, 3, 4]).(2), ([1, 2, 3, 4])/(4)
// Yes, the operations are performed only when the result is assigned
// to a variable.
V *= 2; cout<<V<<endl;
[2, 4, 6, 8]
V /= 4; cout<<V<<endl;
[0.5, 1, 1.5, 2]
V += V; cout<<V<<endl;
[1, 2, 3, 4]
U-=(V+V); cout<<U<<endl;
[-2, -2, -5, -5]
W=U+V; cout<<W<<endl;
[-1, 0, -2, -1]
W=V*2; cout<<W<<endl;
[2, 4, 6, 8]
W=W*2-3*U; cout<<W<<endl;
[10, 14, 27, 31]
W = V; V[2]= -1; cout<<W << ", " << V<<endl;
[1, 2, 3, 4], [1, 2, -1, 4]
W= V[Range(1,2)]; cout<<W<<endl;
[2, -1]
// The indexes are starting from 0.
}