Vectors




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

linalg/VectStd.H

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.

linalg/VectStd.C

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

linalg/array1d.H

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.
}