#include #include #include #include #ifdef USEVECSTL #include #endif using namespace std; // class MyException : public exception class MyException { public: MyException(const char * msg) { _msg = msg; } // virtual ~MyException() { } string Msg() { return(_msg); } private: string _msg; }; template class Matrix { T* data; int siz_x, siz_y, offset, step_x, step_y; int size; public: Matrix (int sx, int sy, int step=0, int offset=0, bool fg=false); ~Matrix (); inline T operator [] (int k) const { return data[k]; } inline T& operator [] (int k) { return data[k]; } inline T operator () (int ix, int iy) const { return data[ix+iy*siz_x]; } inline T& operator () (int ix, int iy) { return data[ix+iy*siz_x]; } inline T elem (int ix, int iy) const { return data[offset+ix*step_x+iy*step_y]; } inline T& elem (int ix, int iy) { return data[offset+ix*step_x+iy*step_y]; } inline T elemCk (int ix, int iy) const { if ((ix < 0) || (ix >= siz_x) || (iy < 0) || (iy >= siz_y)) throw MyException("Matrix Out of bound"); return data[offset+ix*step_x+iy*step_y]; } inline T& elemCk (int ix, int iy) { if ((ix < 0) || (ix >= siz_x) || (iy < 0) || (iy >= siz_y)) throw MyException("Matrix Out of bound"); return data[offset+ix*step_x+iy*step_y]; } inline int getSize () const { return size; } inline int getSizeX () const { return siz_x; } inline int getSizeY () const { return siz_y; } // Addition et multiplication en utilisant elem() Matrix * Add(Matrix & v1, Matrix & v2); Matrix * Mult(Matrix & v1, Matrix & v2); // Addition et multiplication en utilisant elemCk() Matrix * AddCk(Matrix & v1, Matrix & v2); Matrix * MultCk(Matrix & v1, Matrix & v2); // Addition et multiplication en utilisant l'operateur [] Matrix * AddO1(Matrix & v1, Matrix & v2); Matrix * MultO1(Matrix & v1, Matrix & v2); // Addition et multiplication en utilisant l'operateur () Matrix * AddO2(Matrix & v1, Matrix & v2); Matrix * MultO2(Matrix & v1, Matrix & v2); }; template Matrix::Matrix (int sx, int sy, int step, int off, bool fg) { int k; int s = offset+sx*sy*step; if (s < 1) s = 1; size = s; siz_x = sx; siz_y = sy; offset = off; step_x = step; step_y = step*siz_x; data = new T[size]; if (!fg) return; T * p = data; for(k=0; k Matrix::~Matrix() { delete[] data; } template Matrix * Matrix::Add(Matrix &v1, Matrix &v2) { int i,j; for (i = 0; i < siz_x; i++) for (j = 0; j < siz_y; j++) elem(i,j) = v1.elem(i,j)+v2.elem(i,j); return (this); } template Matrix * Matrix::Mult(Matrix &v1, Matrix &v2) { int i,j; for (i = 0; i < siz_x; i++) for (j = 0; j < siz_y; j++) elem(i,j) = v1.elem(i,j)*v2.elem(i,j); return (this); } template Matrix * Matrix::AddCk(Matrix &v1, Matrix &v2) { int i,j; for (i = 0; i < siz_x; i++) for (j = 0; j < siz_y; j++) elem(i,j) = v1.elemCk(i,j)+v2.elemCk(i,j); return (this); } template Matrix * Matrix::MultCk(Matrix &v1, Matrix &v2) { int i,j; for (i = 0; i < siz_x; i++) for (j = 0; j < siz_y; j++) elem(i,j) = v1.elemCk(i,j)*v2.elemCk(i,j); return (this); } template Matrix * Matrix::AddO1(Matrix &v1, Matrix &v2) { int i; for (i = 0; i < size; i++) (*this)[i] = v1[i] + v2[i]; return (this); } template Matrix * Matrix::MultO1(Matrix &v1, Matrix &v2) { int i; for (i = 0; i < size; i++) (*this)[i] = v1[i] * v2[i]; return (this); } template Matrix * Matrix::AddO2(Matrix &v1, Matrix &v2) { int i,j; for (i = 0; i < siz_x; i++) for (j = 0; j < siz_y; j++) (*this)(i,j) = v1(i,j) + v2(i,j); return (this); } template Matrix * Matrix::MultO2(Matrix &v1, Matrix &v2) { int i,j; for (i = 0; i < siz_x; i++) for (j = 0; j < siz_y; j++) (*this)(i,j) = v1(i,j) * v2(i,j); return (this); } extern "C" void InitTim(); extern "C" void PrtTim(const char *Comm); /* --------------------------------------------------------------------- */ /* --------------------------- Main Program ---------------------------- */ /* --------------------------------------------------------------------- */ int main (int narg, char *arg[]) { int pos, N, M, Mx, My, Off, Step, OPT, OPE, i; if (narg < 2) { printf("\n Usage: matrix Type(=1,2,3 Int,Float,Double) Ope(=1...10) [N [Mx,My,...] ] \n"); printf("Ope: 1=Create/Delete 2=1+FillVect \n"); printf("Ope: 3=AddO1 4=MultO1 (Using operator [k]) \n"); printf("Ope: 5=AddO2 6=MultO2 (Using operator (i,j)) \n"); printf("Ope: 7=Add 8=Mult (Using elem()) \n"); printf("Ope: 9=AddCk 10=MultCk (Using elemCk() - with bound checking) \n"); printf("N: Number of operations (def= 100) \n"); printf("Mx,My,Step,Offset: Matrix size (def= 300,200,1,0) \n\n"); exit(0); } InitTim(); OPT = 1; OPE = 1; if (narg > 1) OPT = atoi(arg[1]); if ( (OPT < 1) || (OPT > 3) ) OPT = 1; if (narg > 2) OPE = atoi(arg[2]); if ( (OPE < 1) || (OPE > 10) ) OPE = 1; N = 100; if (narg > 3) N = atoi(arg[3]); if (N < 1) N = 1; if (N > 100000) N = 100000; Mx = 300; My = 200; Off = 0; Step = 1; if (narg > 4) sscanf(arg[4], "%d,%d,%d,%d", &Mx, &My, &Step, &Off); if (Mx < 100) Mx = 100; if (My < 100) My = 100; if (Mx > 10000) Mx = 10000; if (My > 10000) My = 10000; if (Step < 1) Step = 1; if (Step > 5) Step = 5; if (Off < 0) Off = 0; if (Off > 1000) Off = 1000; M = Mx*My*Step; printf(" MatrixC++ TestSpeed Typ=%d Ope=%d N=%d MSz=%d\n", OPT, OPE, N,M); printf(" Matrix Size X= %d Y = %d Step= %d Offset= %d \n", Mx, My, Step, Off); if (OPE < 3) { /* Test creation / destruction */ int fg = OPE-1; bool fgf = (fg != 0) ? true : false; printf("\n\n Test new/delete Matrix - fg= %d ( <> 0 ---> FillVec) \n", fg); switch (OPT) { case 1 : { Matrix * v; printf("Test %d new/delete Matrix[%d] \n",N,M); for(i=0; i(Mx, My, Step, Off, fgf); delete v; } } break; case 2 : { Matrix * v; printf("Test %d new/delete Matrix[%d] \n",N,M); for(i=0; i(Mx, My, Step, Off, fgf); delete v; } } break; case 3 : { Matrix * v; printf("Test %d new/delete Matrix[%d] \n",N,M); for(i=0; i(Mx, My, Step, Off, fgf); delete v; } } break; } PrtTim("Fin New/Delete "); printf(" .......... Fin de MatrixC++ ........... \n"); return (0); } // ---------- Test Addition, Multiplication ------------- switch (OPT) { case 1 : { printf("\n\n Test %d operations Matrix[%d] \n",N,M); Matrix *v1,*v2,*v3; v1 = new Matrix(Mx, My, Step, Off); v2 = new Matrix(Mx, My, Step, Off); v3 = new Matrix(Mx, My, Step, Off); PrtTim("Fin_Creation "); for(pos=0; posAddO1(*v1, *v2); PrtTim("Fin Addition AddO1 operator [k]"); } else if (OPE == 4) { for(pos=0; posMultO1(*v1, *v2); PrtTim("Fin Multiplication MultO1 operator [k]"); } else if (OPE == 5) { for(pos=0; posAddO2(*v1, *v2); PrtTim("Fin Addition AddO2 operator (i,j)"); } else if (OPE == 6) { for(pos=0; posMultO2(*v1, *v2); PrtTim("Fin Multiplication MultO2 operator (i,j)"); } else if (OPE == 7) { for(pos=0; posAdd(*v1, *v2); PrtTim("Fin Addition Add"); } else if (OPE == 8) { for(pos=0; posMult(*v1, *v2); PrtTim("Fin Multiplication Mult"); } else if (OPE == 9) { for(pos=0; posAddCk(*v1, *v2); PrtTim("Fin Addition AddCk"); } else if (OPE == 10) { for(pos=0; posMultCk(*v1, *v2); PrtTim("Fin Multiplication MultCk"); } printf("Result[1.2] I1= %d %d I2= %d %d I3= %d %d \n", v1->elem(1,0),v1->elem(2,0), v2->elem(1,0),v2->elem(2,0), v3->elem(1,0),v3->elem(2,0)); printf("ResAdd[991-2] I1= %d %d I2= %d %d I3= %d %d \n", v1->elem(991,0),v1->elem(992,0), v2->elem(991,0),v2->elem(992,0), v3->elem(991,0),v3->elem(992,0)); } break; case 2 : { printf("\n\n Test %d operations Matrix[%d] \n",N,M); Matrix *v1,*v2,*v3; v1 = new Matrix(Mx, My, Step, Off); v2 = new Matrix(Mx, My, Step, Off); v3 = new Matrix(Mx, My, Step, Off); PrtTim("Fin_Creation "); for(pos=0; posAddO1(*v1, *v2); PrtTim("Fin Addition AddO1 operator [k]"); } else if (OPE == 4) { for(pos=0; posMultO1(*v1, *v2); PrtTim("Fin Multiplication MultO1 operator [k]"); } else if (OPE == 5) { for(pos=0; posAddO2(*v1, *v2); PrtTim("Fin Addition AddO2 operator (i,j)"); } else if (OPE == 6) { for(pos=0; posMultO2(*v1, *v2); PrtTim("Fin Multiplication MultO2 operator (i,j)"); } else if (OPE == 7) { for(pos=0; posAdd(*v1, *v2); PrtTim("Fin Addition Add"); } else if (OPE == 8) { for(pos=0; posMult(*v1, *v2); PrtTim("Fin Multiplication Mult"); } else if (OPE == 9) { for(pos=0; posAddCk(*v1, *v2); PrtTim("Fin Addition AddCk"); } else if (OPE == 10) { for(pos=0; posMultCk(*v1, *v2); PrtTim("Fin Multiplication MultCk"); } printf("Result[1.2] F1= %g %g F2= %g %g F3= %g %g \n", v1->elem(1,0),v1->elem(2,0), v2->elem(1,0),v2->elem(2,0), v3->elem(1,0),v3->elem(2,0)); printf("Result[991-2] F1= %g %g F2= %g %g F3= %g %g \n", v1->elem(991,0),v1->elem(992,0), v2->elem(991,0),v2->elem(992,0), v3->elem(991,0),v3->elem(992,0)); } break; case 3 : { printf("\n\n Test %d operations Matrix[%d] \n",N,M); Matrix *v1,*v2,*v3; v1 = new Matrix(Mx, My, Step, Off); v2 = new Matrix(Mx, My, Step, Off); v3 = new Matrix(Mx, My, Step, Off); PrtTim("Fin_Creation "); if (OPE == 3) { for(pos=0; posAddO1(*v1, *v2); PrtTim("Fin Addition AddO1 operator [k]"); } else if (OPE == 4) { for(pos=0; posMultO1(*v1, *v2); PrtTim("Fin Multiplication MultO1 operator [k]"); } else if (OPE == 5) { for(pos=0; posAddO2(*v1, *v2); PrtTim("Fin Addition AddO2 operator (i,j)"); } else if (OPE == 6) { for(pos=0; posMultO2(*v1, *v2); PrtTim("Fin Multiplication MultO2 operator (i,j)"); } else if (OPE == 7) { for(pos=0; posAdd(*v1, *v2); PrtTim("Fin Addition Add"); } else if (OPE == 8) { for(pos=0; posMult(*v1, *v2); PrtTim("Fin Multiplication Mult"); } else if (OPE == 9) { for(pos=0; posAddCk(*v1, *v2); PrtTim("Fin Addition AddCk"); } else if (OPE == 10) { for(pos=0; posMultCk(*v1, *v2); PrtTim("Fin Multiplication MultCk"); } printf("Result[1.2] D1= %g %g D2= %g %g D3= %g %g \n", v1->elem(1,0),v1->elem(2,0), v2->elem(1,0),v2->elem(2,0), v3->elem(1,0),v3->elem(2,0)); printf("Result[991-2] D1= %g %g D2= %g %g D3= %g %g \n", v1->elem(991,0),v1->elem(992,0), v2->elem(991,0),v2->elem(992,0), v3->elem(991,0),v3->elem(992,0)); } break; default: puts("Erreur d'option !"); break; } PrtTim("Fin de Matrix/C++ "); printf(" .......... Fin de MatrixC++ ........... \n"); return (0); } /* #ifdef DECCXX #pragma define_template Matrix #pragma define_template Matrix #pragma define_template Matrix #endif #if defined(GNUGCC) || defined (HPaCC) template class Matrix; template class Matrix; template class Matrix; #endif */