La largeur de bande, bdth, d'une matrice a de taille size x size
est la plus grande valeur de |i-j| telle que
.
Il est facile de voir que la correspondance entre a(i,j) et cc[size*(i-j + bdth) + j]
est bi-univoque. Ainsi en redéfinissant l'opération d'accès a(i,j) on n'épargne
le fastidieux et obscur travail d'appel à a.cc[size*(i-j + bdth) + j]. En plus
le type des éléments a(i,j) pourra être reel, complexe ou même matriciel.
Dans ce dernier cas l'opération de multiplication matrice vecteur impliquera aussi une opération
de multiplication matrice vecteur au niveau des élements. Il y a donc 2 types indéterminés,
celui des éléments de la matrice, T, et celui, R, des éléments des vecteurs qui multiplieront
ces éléments.
template <class T, class R> class Bandmatrix { public:
int bdth,size,csize; // bandwidth, matrix size and array size
T* cc;
Bandmatrix(int n,int bdth1)
{ size=n; bdth = bdth1; csize = size*(2*bdth +1);
if (csize > 0) cc = new T[csize]; else cc = NULL;
}
Bandmatrix(Bandmatrix& b)
{ size=b.size; bdth = b.bdth; csize = size*(2*bdth +1);
if (csize > 0 )
{ cc = new T[csize]; for(int i=0;i<csize;i++)cc[i]=b.cc[i];}
else cc = NULL;
}
~Bandmatrix(){ delete [] cc; }
T& operator()( int i, int j) const // access function
{ int k = size*(i-j + bdth) + j;
assert(cc && (k>=0)&&(k<csize));
return cc[k];
}
Vector<R> operator * (const Vector<R>& ); // matrix vector multiplication
};
Les fonctions P1 sont déterminées par leurs valeurs aux sommets de la triangulation. Un tableau suffit donc pour les représenter. Par ailleurs les opérations sur les fonctions sont les mêmes que sur les vecteurs. D'ou la classe suivante, ou le type T de f(x) est laissé indéterminé:
template <class T> class Vector{ public:
T *cc;
int size;
Vector(int csize = 0)
{ size = csize;
if (size > 0 )
{ cc = new T[size]; for(int i=0;i<size;i++) cc[i] = 0; }
else cc = NULL;
}
~Vector() { delete [] cc; size = 0; }
Vector (const Vector& v );
const Vector& operator = (const T& r);
const Vector& operator = ( const Vector& v);
Vector& operator += (const Vector& v1);
Vector operator + (const Vector& v1);
Vector& operator -= (const Vector& v1);
Vector operator - (const Vector& v1);
Vector operator * (const T& a);
Vector operator / (const T& a);
T& operator [] (int i) const
{assert ( cc &&(i >= 0)&&(i < size) ); return cc[i];}
};