Скачиваний:
34
Добавлен:
02.05.2014
Размер:
19.32 Кб
Скачать
#ifndef            MATRIX_CPP
#define            MATRIX_CPP

#include           <assert.h>
#include           <iostream.h>


template<class TYPE>
class TMatrix
{
   friend TMatrix  operator+    (TYPE, TMatrix &); //сложение со скаляром
   friend TMatrix  operator-    (TYPE, TMatrix &); //вычитание со скаляром
   friend TMatrix  operator*    (TYPE, TMatrix &); //умножение на скаляр
   friend istream& operator>>   (istream &, TMatrix &); //ввод матрицы
   friend ostream& operator<<   (ostream &, TMatrix &); //вывод матрицы
public:
   TMatrix                      ();                //конструктор по умолчанию
   TMatrix                      (TMatrix &);       //конструктор копирования
   TMatrix                      (int, int);        //конструктор с заданием
						   //размера
   ~TMatrix                     ();                //деструктор
   void            init         (TYPE c);          //инициализация числом
   void            initStat     (TYPE *p, int, int);//инициализ. статич.
						    //массивом
   void            initDynam    (TYPE **p, int, int);//инициализ. динамич.
						   //массивом
   void            setSize      (int, int);        //установка размера
   int             getSizeRow   ();                //кол-во строк
   int             getSizeCol   ();                //кол-во столбцов
   TYPE &          operator()   (int, int);        //элемент матрицы
   TYPE &          operator[]   (int);             //элемент
						   //матрицы-вектора
   TMatrix &       operator=    (TMatrix &);       //присваивание
   TMatrix         getRow       (int);             //строка
   TMatrix         getCol       (int);             //столбец
   void            setRow       (int, TMatrix &);  //задать строку
   void            setCol       (int, TMatrix &);  //задать столбец
   TMatrix         getPart      (int, int, int, int); //получить часть
   void            setPart      (int, int, TMatrix &); //задать часть
   void            swapRow      (int, int);        //обмен строк
   void            swapCol      (int, int);        //обмен столбцов
   TMatrix         operator+    (TMatrix &);       //сложение матриц
   TMatrix         operator-    (TMatrix &);       //вычитание матриц
   TMatrix         operator*    (TMatrix &);       //умножение матриц
   TMatrix         operator^    (TMatrix &);       //умножение матриц
						   //(перемножение
						   //соответствующих
						   //элементов)
   TMatrix &       operator+=   (TMatrix &);       //присваивания
   TMatrix &       operator-=   (TMatrix &);
   TMatrix &       operator*=   (TMatrix &);
   TMatrix &       operator^=   (TMatrix &);
   TMatrix         getTranspose ();                //транспонирование
   TMatrix &       setSingle    (int n);           //сделать единичной
   TMatrix         operator+    (TYPE);            //операции со скалярами
   TMatrix         operator-    (TYPE);
   TMatrix         operator*    (TYPE);
   TMatrix         operator/    (TYPE);
   TMatrix &       operator+=   (TYPE);
   TMatrix &       operator-=   (TYPE);
   TMatrix &       operator*=   (TYPE);
   TMatrix &       operator/=   (TYPE);
   TMatrix         operator-    ();
   TYPE            operator%    (TMatrix &);       //скалярное умножение для
						   //матриц-векторов
   int             readSize     (istream &);       //чтение размеров
   int             readArray    (istream &);       //чтение массива
   int             writeSize    (ostream &);       //запись размеров
   int             writeArray   (ostream &);       //запись массива
private:
   TYPE **         array;                          //элементы матрицы
   int             sizeRow;                        //кол-во строк
   int             sizeCol;                        //кол-во столбцов
   void            error        (int);             //сообщение об ошибке
};

template<class TYPE>
TMatrix<TYPE>::TMatrix()
{
   array=NULL;
   sizeRow=0;
   sizeCol=0;
}


template<class TYPE>
TMatrix<TYPE>::TMatrix(TMatrix<TYPE> &m)
{
   array=NULL;
   sizeRow=0;
   sizeCol=0;

   if(m.sizeRow>0 && m.sizeCol>0)
   {
      sizeRow=m.sizeRow;
      sizeCol=m.sizeCol;

      array=new TYPE*[sizeRow];
      assert(array!=NULL);

      for(int i=0; i<sizeRow; i++)
      {
	 array[i]=new TYPE[sizeCol];
	 assert(array[i]!=NULL);
      }

      for(i=0; i<sizeRow; i++)
      {
	 for(int j=0; j<sizeCol; j++)
	 {
	    array[i][j]=m.array[i][j];
	 }
      }
   }
   else
   {
      error(1);
   }
}


template<class TYPE>
TMatrix<TYPE>::TMatrix(int row, int col)
{
   array=NULL;
   sizeRow=0;
   sizeCol=0;

   if(row>0 && col>0)
   {
      sizeRow=row;
      sizeCol=col;

      array=new TYPE*[sizeRow];
      assert(array!=NULL);

      for(int i=0; i<sizeRow; i++)
      {
	 array[i]=new TYPE[sizeCol];
	 assert(array[i]!=NULL);
      }
   }
   else
   {
      error(2);
   }
}


template<class TYPE>
TMatrix<TYPE>::~TMatrix()
{
   if(array!=NULL)
   {
      for(int i=0; i<sizeRow; i++)
      {
	 if(array[i]!=NULL)
	 {
	    delete [] array[i];
	 }
      }

      delete [] array;
   }
}


template<class TYPE>
TMatrix<TYPE> &TMatrix<TYPE>::operator=(TMatrix<TYPE> &m)
{
   if(this!=&m)
   {
      if(sizeRow==0 && sizeCol==0)
      {
	 sizeRow=m.sizeRow;
	 sizeCol=m.sizeCol;

	 array=new TYPE*[sizeRow];
	 assert(array!=NULL);

	 for(int i=0; i<sizeRow; i++)
	 {
	    array[i]=new TYPE[sizeCol];
	    assert(array[i]!=NULL);
	 }
      }

      if(sizeRow==m.sizeRow && sizeCol==m.sizeCol)
      {
	 for(int i=0; i<sizeRow; i++)
	 {
	    for(int j=0; j<sizeCol; j++)
	    {
	       array[i][j]=m.array[i][j];
	    }
	 }
      }
      else
      {
	 error(3);
      }
   }

   return *this;
}


template<class TYPE>
TYPE & TMatrix<TYPE>::operator()(int row, int col)
{
   if(row>0 && row<=sizeRow && col>0 && col<=sizeCol)
   {
      return array[row-1][col-1];
   }
   else
   {
      error(4);
      return array[0][0];
   }
}


template<class TYPE>
TYPE & TMatrix<TYPE>::operator[](int k)
{
   if(sizeRow==1 && k>0 && k<=sizeCol)
   {
      return array[0][k-1];
   }
   else
   {
      if(sizeCol==1 && k>0 && k<=sizeRow)
      {
	  return array[k-1][0];
      }
      else
      {
	 error(5);
	 return array[0][0];
      }
   }
}


template<class TYPE>
int TMatrix<TYPE>::getSizeRow()
{
   return sizeRow;
}


template<class TYPE>
int TMatrix<TYPE>::getSizeCol()
{
   return sizeCol;
}


template<class TYPE>
void TMatrix<TYPE>::setSize(int row, int col)
{
   if(row==0 && col==0)
   {
      if(array!=NULL)
      {
	 for(int i=0; i<sizeRow; i++)
	 {
	    if(array[i]!=NULL)
	    {
	       delete [] array[i];
	    }
	 }

	 delete [] array;
	 array=NULL;
      }

      sizeRow=0;
      sizeCol=0;

      return;
   }

   if(row>0 && col>0)
   {
      if(array!=NULL)
      {
	 for(int i=0; i<sizeRow; i++)
	 {
	    if(array[i]!=NULL)
	    {
	       delete [] array[i];
	    }
	 }

	 delete [] array;
      }

      sizeRow=row;
      sizeCol=col;

      array=new TYPE*[sizeRow];
      assert(array!=NULL);

      for(int i=0; i<sizeRow; i++)
      {
	 array[i]=new TYPE[sizeCol];
	 assert(array[i]!=NULL);
      }
   }
   else
   {
      error(6);
   }
}


template<class TYPE>
TMatrix<TYPE> TMatrix<TYPE>::operator+(TMatrix<TYPE> &m)
{
   TMatrix t_m(sizeRow, sizeCol);

   if(sizeRow==m.sizeRow&&sizeCol==m.sizeCol)
   {
      for(int i=0; i<sizeRow; i++)
      {
	 for(int j=0; j<sizeCol; j++)
	 {
	    t_m.array[i][j]=array[i][j]+m.array[i][j];
	 }
      }
   }
   else
   {
      error(7);
   }

   return t_m;
}


template<class TYPE>
TMatrix<TYPE> TMatrix<TYPE>::operator-(TMatrix<TYPE> &m)
{
   TMatrix t_m(sizeRow, sizeCol);

   if(sizeRow==m.sizeRow&&sizeCol==m.sizeCol)
   {
      for(int i=0; i<sizeRow; i++)
      {
	 for(int j=0; j<sizeCol; j++)
	 {
	    t_m.array[i][j]=array[i][j]-m.array[i][j];
	 }
      }
   }
   else
   {
      error(8);
   }

   return t_m;
}


template<class TYPE>
TMatrix<TYPE> TMatrix<TYPE>::operator*(TMatrix<TYPE> &m)
{
   TMatrix t_m(sizeRow, m.sizeCol);

   if(sizeCol==m.sizeRow)
   {
      for(int i=0; i<t_m.sizeRow; i++)
      {
	 for(int j=0; j<t_m.sizeCol; j++)
	 {
	    TYPE sum=0;

	    for(int k=0; k<sizeCol; k++)
	    {
	       sum+=array[i][k]*m.array[k][j];
	    }

	    t_m.array[i][j]=sum;
	 }
      }
   }
   else
   {
      error(9);
   }

   return t_m;
}


template<class TYPE>
TMatrix<TYPE> TMatrix<TYPE>::operator^(TMatrix<TYPE> &m)
{
   TMatrix t_m(sizeRow, sizeCol);

   if(sizeRow==m.sizeRow&&sizeCol==m.sizeCol)
   {
      for(int i=0; i<sizeRow; i++)
      {
	 for(int j=0; j<sizeCol; j++)
	 {
	    t_m.array[i][j]=array[i][j]*m.array[i][j];
	 }
      }
   }
   else
   {
      error(10);
   }

   return t_m;
}


template<class TYPE>
TMatrix<TYPE> &TMatrix<TYPE>::operator+=(TMatrix<TYPE> &m)
{
   if(sizeRow==m.sizeRow&&sizeCol==m.sizeCol)
   {
      for(int i=0; i<sizeRow; i++)
      {
	 for(int j=0; j<sizeCol; j++)
	 {
	    array[i][j]+=m.array[i][j];
	 }
      }
   }
   else
   {
      error(11);
   }

   return *this;
}


template<class TYPE>
TMatrix<TYPE> &TMatrix<TYPE>::operator-=(TMatrix<TYPE> &m)
{
   if(sizeRow==m.sizeRow&&sizeCol==m.sizeCol)
   {
      for(int i=0; i<sizeRow; i++)
      {
	 for(int j=0; j<sizeCol; j++)
	 {
	    array[i][j]-=m.array[i][j];
	 }
      }
   }
   else
   {
      error(12);
   }

   return *this;
}


template<class TYPE>
TMatrix<TYPE> & TMatrix<TYPE>::operator*=(TMatrix<TYPE> &m)
{
   TMatrix t_m(sizeRow, m.sizeCol);

   if(sizeCol==m.sizeRow)
   {
      for(int i=0; i<t_m.sizeRow; i++)
      {
	 for(int j=0; j<t_m.sizeCol; j++)
	 {
	    TYPE sum=0;

	    for(int k=0; k<sizeCol; k++)
	    {
	       sum+=array[i][k]*m.array[k][j];
	    }

	    t_m.array[i][j]=sum;
	 }
      }

      *this=t_m;
   }
   else
   {
      error(29);
   }

   return *this;
}


template<class TYPE>
TMatrix<TYPE> &TMatrix<TYPE>::operator^=(TMatrix<TYPE> &m)
{
   if(sizeRow==m.sizeRow&&sizeCol==m.sizeCol)
   {
      for(int i=0; i<sizeRow; i++)
      {
	 for(int j=0; j<sizeCol; j++)
	 {
	    array[i][j]*=m.array[i][j];
	 }
      }
   }
   else
   {
      error(13);
   }

   return *this;
}


template<class TYPE>
TMatrix<TYPE> TMatrix<TYPE>::getTranspose()
{
   TMatrix<TYPE> new_m(sizeCol, sizeRow);

   for(int i=0; i<sizeRow; i++)
   {
      for(int j=0; j<sizeCol; j++)
      {
	 new_m.array[j][i]=array[i][j];
      }
   }

   return new_m;
}


template<class TYPE>
TMatrix<TYPE> TMatrix<TYPE>::operator+(TYPE c)
{
   TMatrix<TYPE> t_m(*this);

   if(sizeRow==sizeCol)
   {
      for(int i=0; i<sizeRow; i++)
      {
	 t_m.array[i][i]+=c;
      }
   }
   else
   {
      error(14);
   }

   return t_m;
}


template<class TYPE>
TMatrix<TYPE> TMatrix<TYPE>::operator-(TYPE c)
{
   TMatrix<TYPE> t_m(*this);

   if(sizeRow==sizeCol)
   {
      for(int i=0; i<sizeRow; i++)
      {
	 t_m.array[i][i]-=c;
      }
   }
   else
   {
      error(15);
   }

   return t_m;
}


template<class TYPE>
TMatrix<TYPE> TMatrix<TYPE>::operator*(TYPE c)
{
   TMatrix<TYPE> t_m(sizeRow, sizeCol);

   for(int i=0; i<sizeRow; i++)
   {
      for(int j=0; j<sizeCol; j++)
      {
	 t_m.array[i][j]=array[i][j]*c;
      }
   }

   return t_m;
}


template<class TYPE>
TMatrix<TYPE> TMatrix<TYPE>::operator/(TYPE c)
{
   TMatrix<TYPE> t_m(sizeRow, sizeCol);

   for(int i=0; i<sizeRow; i++)
   {
      for(int j=0; j<sizeCol; j++)
      {
	 t_m.array[i][j]=array[i][j]/c;
      }
   }

   return t_m;
}


template<class TYPE>
TMatrix<TYPE> &TMatrix<TYPE>::operator+=(TYPE c)
{
   if(sizeRow==sizeCol)
   {
      for(int i=0; i<sizeRow; i++)
      {
	 array[i][i]+=c;
      }
   }
   else
   {
      error(16);
   }

   return *this;
}


template<class TYPE>
TMatrix<TYPE> &TMatrix<TYPE>::operator-=(TYPE c)
{
   if(sizeRow==sizeCol)
   {
      for(int i=0; i<sizeRow; i++)
      {
	 array[i][i]-=c;
      }
   }
   else
   {
      error(17);
   }

   return *this;
}


template<class TYPE>
TMatrix<TYPE> &TMatrix<TYPE>::operator*=(TYPE c)
{
   for(int i=0; i<sizeRow; i++)
   {
      for(int j=0; j<sizeCol; j++)
      {
	 array[i][j]*=c;
      }
   }

   return *this;
}


template<class TYPE>
TMatrix<TYPE> &TMatrix<TYPE>::operator/=(TYPE c)
{
   for(int i=0; i<sizeRow; i++)
   {
      for(int j=0; j<sizeCol; j++)
      {
	 array[i][j]/=c;
      }
   }

   return *this;
}


template<class TYPE>
TMatrix<TYPE> TMatrix<TYPE>::getRow(int row)
{
   TMatrix<TYPE> t_m(1, sizeCol);

   if(row>0 && row<=sizeRow)
   {
      for(int i=0; i<sizeCol; i++)
      {
	 t_m.array[0][i]=array[row-1][i];
      }
   }
   else
   {
      error(18);
   }

   return t_m;
}


template<class TYPE>
TMatrix<TYPE> TMatrix<TYPE>::getCol(int col)
{
   TMatrix<TYPE> t_m(sizeRow, 1);

   if(col>0 && col<=sizeCol)
   {
      for(int i=0; i<sizeRow; i++)
      {
	 t_m.array[i][0]=array[i][col-1];
      }
   }
   else
   {
      error(19);
   }

   return t_m;
}


template<class TYPE>
TMatrix<TYPE> TMatrix<TYPE>::getPart(int i1, int j1, int m, int n)
{
   TMatrix<TYPE> res(m,n);

   if(i1>0 && i1<=sizeRow && j1>0 && j1<=sizeCol &&
      m>0 && i1+m<=sizeRow+1 && n>0 && j1+n<=sizeCol+1)
   {
      for(int i=0, i2=i1-1; i<m; i++, i2++)
      {
	 for(int j=0, j2=j1-1; j<n; j++, j2++)
	 {
	    res.array[i][j]=array[i2][j2];
	 }
      }
   }
   else
   {
      error(20);
   }

   return res;
}


template<class TYPE>
void TMatrix<TYPE>::setPart(int i1, int j1, TMatrix<TYPE> &t)
{
   int m=t.getSizeRow(), n=t.getSizeCol();

   if(i1>0 && i1<=sizeRow && j1>0 && j1<=sizeCol &&
      m>0 && i1+m<=sizeRow+1 && n>0 && j1+n<=sizeCol+1)
   {
      for(int i=0, i2=i1-1; i<m; i++, i2++)
      {
	 for(int j=0, j2=j1-1; j<n; j++, j2++)
	 {
	    array[i2][j2]=t.array[i][j];
	 }
      }
   }
   else
   {
      error(21);
   }
}


template<class TYPE>
void TMatrix<TYPE>::swapRow(int i1, int i2)
{
   if(i1>0 && i1<=sizeRow && i2>0 && i2<=sizeRow)
   {
      for(int j=0; j<sizeCol; j++)
      {
	 TYPE t=array[i1-1][j];
	 array[i1-1][j]=array[i2-1][j];
	 array[i2-1][j]=t;
      }
   }
   else
   {
      error(22);
   }
}


template<class TYPE>
void TMatrix<TYPE>::swapCol(int j1, int j2)
{
   if(j1>0 && j1<=sizeCol && j2>0 && j2<=sizeCol)
   {
      for(int i=0; i<sizeRow; i++)
      {
	 TYPE t=array[i][j1-1];
	 array[i][j1-1]=array[i][j2-1];
	 array[i][j2-1]=t;
      }
   }
   else
   {
      error(23);
   }
}


template<class TYPE>
TMatrix<TYPE> operator+(TYPE c, TMatrix<TYPE> &m)
{
   return m+c;
}


template<class TYPE>
TMatrix<TYPE> operator-(TYPE c, TMatrix<TYPE> &m)
{
   return m*(-1)+c;
}


template<class TYPE>
TMatrix<TYPE> operator*(TYPE c, TMatrix<TYPE> &m)
{
   return m*c;
}


template<class TYPE>
void TMatrix<TYPE>::setRow(int row_index, TMatrix<TYPE> &m)
{

   if(m.sizeRow==1 && sizeCol==m.sizeCol &&
      row_index>0 && row_index<=sizeRow)
   {
      for(int i=0; i<sizeCol; i++)
      {
	 array[row_index-1][i]=m.array[0][i];
      }
   }
   else
   {
      error(24);
   }
}


template<class TYPE>
void TMatrix<TYPE>::setCol(int col_index, TMatrix<TYPE> &m)
{
   if(sizeRow==m.sizeRow && m.sizeCol==1 &&
      col_index>0 && col_index<=sizeCol)
   {
      for(int i=0; i<sizeRow; i++)
      {
	 array[i][col_index-1]=m.array[i][0];
      }
   }
   else
   {
      error(25);
   }
}


template<class TYPE>
TYPE TMatrix<TYPE>::operator%(TMatrix<TYPE> &m)
{
   TYPE sum=0;

   if(sizeRow==m.sizeRow && sizeCol==m.sizeCol)
   {
      if(sizeRow==1)
      {
	 for(int i=0; i<sizeCol; i++)
	 {
	    sum+=array[0][i]*m.array[0][i];
	 }
      }
      else
      {
	 if(sizeCol==1)
	 {
	    for(int i=0; i<sizeRow; i++)
	    {
	       sum+=array[i][0]*m.array[i][0];
	    }
	 }
	 else
	 {
	    error(26);
	 }
      }
   }
   else
   {
      if(sizeRow==m.sizeCol && sizeCol==m.sizeRow)
      {
	 if(sizeRow==1)
	 {
	    for(int i=0; i<sizeCol; i++)
	    {
	       sum+=array[0][i]*m.array[i][0];
	    }
	 }
	 else
	 {
	    if(sizeCol==1)
	    {
	       for(int i=0; i<sizeRow; i++)
	       {
		  sum+=array[i][0]*m.array[0][i];
	       }
	    }
	    else
	    {
	       error(27);
	    }
	 }
      }
   }

   return sum;
}


template<class TYPE>
TMatrix<TYPE> TMatrix<TYPE>::operator-()
{
   return (*this)*(-1);
}


template<class TYPE>
TMatrix<TYPE> & TMatrix<TYPE>::setSingle(int n)
{
   if(n>0)
   {
      setSize(n,n);
      init(0);
      for(int i=0; i<n; i++)
      {
	 array[i][i]=1;
      }
   }
   else
   {
      error(28);
   }

   return *this;
}


template<class TYPE>
istream & operator>>(istream &in, TMatrix<TYPE> &m)
{
   m.readSize(in);
   m.readArray(in);

   return in;
}


template<class TYPE>
ostream & operator<<(ostream &out, TMatrix<TYPE> &m)
{
   m.writeSize(out);
   m.writeArray(out);

   return out;
}


template<class TYPE>
void TMatrix<TYPE>::init(TYPE c)
{
   for(int i=0; i<sizeRow; i++)
   {
      for(int j=0; j<sizeCol; j++)
      {
	 array[i][j]=c;
      }
   }
}


template<class TYPE>
void TMatrix<TYPE>::initStat(TYPE *p, int size_r, int size_c)
{
   this->setSize(size_r,size_c);

   for(int i=0; i<sizeRow; i++)
   {
      for(int j=0; j<sizeCol; j++)
      {
	 array[i][j]=p[i*size_c+j];
      }
   }
}


template<class TYPE>
void TMatrix<TYPE>::initDynam(TYPE **p, int size_r, int size_c)
{
   this->setSize(size_r,size_c);

   for(int i=0; i<sizeRow; i++)
   {
      for(int j=0; j<sizeCol; j++)
      {
	 array[i][j]=p[i][j];
      }
   }
}


template<class TYPE>
int TMatrix<TYPE>::readSize(istream &in)
{
   if(!in)
   {
      return 0;
   }

   int size1, size2;

   in>>size1>>size2;
   setSize(size1, size2);

   return 1;
}


template<class TYPE>
int TMatrix<TYPE>::readArray(istream &in)
{
   if(!in)
   {
      return 0;
   }

   for(int i=0; i<sizeRow; i++)
   {
      for(int j=0; j<sizeCol; j++)
      {
	 in>>array[i][j];
      }
   }

   return 1;
}


template<class TYPE>
int TMatrix<TYPE>::writeSize(ostream &out)
{
   if(!out)
   {
      return 0;
   }

   out<<sizeRow<<' '<<sizeCol<<endl;

   return 1;
}


template<class TYPE>
int TMatrix<TYPE>::writeArray(ostream &out)
{
   if(!out)
   {
      return 0;
   }

   for(int i=0; i<sizeRow; i++)
   {
      for(int j=0; j<sizeCol; j++)
      {
	 out.width(14);
	 out<<array[i][j];
      }
      out<<endl;
   }

   return 1;
}


template<class TYPE>
void TMatrix<TYPE>::error(int error_id)
{
   cout<<"TMatrix ERROR: #"<<error_id<<endl;
}


#endif