на тему рефераты
 
Главная | Карта сайта
на тему рефераты
РАЗДЕЛЫ

на тему рефераты
ПАРТНЕРЫ

на тему рефераты
АЛФАВИТ
... А Б В Г Д Е Ж З И К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Э Ю Я

на тему рефераты
ПОИСК
Введите фамилию автора:


Реферат: Организация математических операций в С++


12.        Функция операции ввода friend istream& operator>>(istream&, Matrix&):

Так же как и предыдущая, данная функция не может быть членом класса, а поэтому для доступа к приватным элементам класса объявлена "дружественной" функцией класса. Она так же имеет два параметра: ссылку на поток, который находится слева от знака >>, и ссылку объект, который находится слева от знака операции, в него и будут вводиться данные из потока. Затем следует ввод данных из потока в элементы массива и возвращается поток. Для ввода данных из файла, нужно открыть его присоединением к потоку ifstream.

13.       Функции-члены dim write(ofstream&) и dim read(ifstream&):

Функции предназначены для вывода в файл и ввода из файла матриц в из двоичном представлении. Для этого необходимо передать в них соответствующую ссылку на открытый файл.

14.       Функция void ERROR_MATRIX(dim):

Это функция-член, которая вызывается для фиксации некоторых ошибок при создании матриц и работе с ними, таких как отсутствие памяти, несогласованность размеров матриц при операции умножения, попытки вычислить отрицательную степень матрицы и т.п.

 

Листинг модуля с определением и реализацией класса матриц

// файл tmatr.cpp

#include <stdlib.h>

#include <mem.h>    // для setmem()

#include <fstream.h>

#include <math.h>

typedef unsigned char dim;

template <class VARTYPE> class Matrix {

typedef Matrix Vector;

private:

   VARTYPE *matr;   // указатель на массив матрицы

   dim m,n;                   // размеры матрицы

public:

// конструкторы и деструкторы:

   Matrix() { matr=(VARTYPE*)0; m=n=0; }

   Matrix(dim,dim=1); // Обычный конструктор

   Matrix(const Matrix<VARTYPE>&); // Конструктор копирования

   ~Matrix() { delete [ ]matr; }

// доступ к элементам матрицы

   dim size_row() { return m; }            // число строк

   dim size_col() { return n; }  // число столбцов

   VARTYPE& operator() (dim x) const { return (*this)(x,0); }        // элементу

// перегруженные операции и функции:

   Matrix<VARTYPE>& operator=(const Matrix<VARTYPE>&);

   Matrix<VARTYPE>& operator=(const VARTYPE&);

   Matrix<VARTYPE> operator^(int);   // возведение в степень

   Matrix<VARTYPE> operator!();      // транспонирование

   VARTYPE determ();   // определитель матрицы

   VARTYPE vmodul();   // модуль вектора

   Matrix& Gauss(dim,dim); // преобразование по Гауссу

                                          // (для получ. обратной и единичной матрицы)

                                          // (для получ. верхнетреугольной матрицы)

   Matrix  minor(dim,dim);  // возвращает указ. минор матрицы

   Vector  line(dim i)       // возвращает вектор-строку матрицы

               { return extract(1,n,i,0); }

   Vector  column(dim j)     // возвращает вектор-столбец матрицы

               { return extract(m,1,0,j); }

   VARTYPE& operator() (dim,dim) const;                                       // доступ к

Matrix<VARTYPE>& operator<<=(const Matrix &A) { return newsize(A.m,A.n)=A; }

                                                 // безусловное приравнивание матриц

   Matrix<VARTYPE>& insert(const Matrix&, dim=0, dim=0);       // вставить часть матрицы

   Matrix<VARTYPE> extract(dim, dim, dim=0, dim=0);                // извлечь часть матрицы

   Matrix<VARTYPE>& newsize(dim, dim=1);                                // установить новые размеры

   void swap_line(dim, dim);                                                               //обмен строками матрицы

   void swap_column(dim, dim);                                                         // обмен столбцами матрицы

   friend Matrix<VARTYPE> operator+(const Matrix<VARTYPE>&,const Matrix<VARTYPE>&);      //A-B

   friend Matrix<VARTYPE> operator-(const Matrix<VARTYPE>&,const Matrix<VARTYPE>&);       //A-B

   friend Matrix<VARTYPE> operator*(const Matrix<VARTYPE>&,const Matrix<VARTYPE>&);       //A*B

   friend Matrix operator*(const double&,const Matrix<VARTYPE>&);  //k*A

   friend Matrix operator*(const Matrix<VARTYPE>&, const double&); //A*k

   friend ostream& operator<<(ostream&,Matrix<VARTYPE>&);

                                                 // потоковый вывод матрицы

   friend int operator>>(istream&,Matrix<VARTYPE>&);

                                                 // потоковый ввод существ. матрицы

                                                 // 0 - без. ошибок, 1 - была ошибка

   dim read(ifstream&);           // файловое чтение и запись матрицы

   dim write(ofstream&);         // в ее внутреннем, двоичном представлении.

   friend VARTYPE operator %(const Matrix<VARTYPE>&,const Matrix<VARTYPE>&);

   //Функция ошибок

   void ERROR_MATRIX(dim) const;

};

// Реализация класса матриц

template <class VARTYPE>

Matrix<VARTYPE>::Matrix(dim M, dim N)

 {

    m=M;

    n=N;

    matr=new VARTYPE[m*n];

    if(!matr) ERROR_MATRIX(1);

    setmem(matr,sizeof(VARTYPE)*m*n,0);

 }

template <class VARTYPE>

Matrix<VARTYPE>::Matrix(const Matrix<VARTYPE> &M_Obj)  //Конструктор копирования

 {

   m=M_Obj.m;

   n=M_Obj.n;

   matr=new VARTYPE[m*n];

   if(!matr) ERROR_MATRIX(1);

   movmem(M_Obj.matr, matr, sizeof(VARTYPE)*m*n);

 }

template <class VARTYPE>

Matrix<VARTYPE>& Matrix<VARTYPE>::operator=(const Matrix<VARTYPE> &M_Obj)

 {

   m=M_Obj.m;

   n=M_Obj.n;

   matr=new VARTYPE[m*n];

   if(!matr) ERROR_MATRIX(1);

   movmem(M_Obj.matr,matr,sizeof(VARTYPE)*m*n);

   return *this;

 }

//Диагональ?

template <class VARTYPE>

Matrix<VARTYPE>& Matrix<VARTYPE>::operator=(const VARTYPE &f)

 {

   for(int i=0,j;i<m;i++) for(j=0;j<n;j++)

      if(i==j) (*this)(i,j)=f;

      else (*this)(i,j)=0;

   return *this;

 }

template <class VARTYPE>

Matrix<VARTYPE> Matrix<VARTYPE>::operator^(int q) // Степень

 {

   if (q>0)

      {

             for(Matrix M=*this; q>1; q--)

               M=M*(*this);

             return M;

      }

   if (q!=-1) ERROR_MATRIX(3);

   // вычисление обратной метoдом преобразований Гаусса

   if (n!=m)  ERROR_MATRIX(4);

   Matrix M(m,2*n);

   M.insert(*this);

   for(int i=0;i<M.m;i++)

      M(i,i+M.m)=1;

   for(i=0;i<M.m;i++)

      M.Gauss(i,i);

   return M.extract(M.m,M.m,0,M.m);

 }

template <class VARTYPE>

Matrix<VARTYPE> Matrix<VARTYPE>::operator!()  // Транспозиция

 { Matrix<VARTYPE> A(n,m);

   for(int i=0, j; i<m; i++)

     for(j=0; j<n; j++)

       A(j,i)=(*this)(i,j);

   return A;

 }

template <class VARTYPE>

VARTYPE Matrix<VARTYPE>::determ() // рекурсивно находит определитель матрицы

 {

   if (n!=m) ERROR_MATRIX(4);

   if (n==1)

      return (*this)(0,0);

   for(int i=0; i<m; i++)

     if ((*this)(i,0))

       {

             static Matrix<VARTYPE> M;

             M <<= *this;

             VARTYPE d=M(i,0)*(i%2?-1:1);

             return d*M.Gauss(i,0).minor(i,0).determ();

            }

   return 0.0;

 }

template <class VARTYPE>

VARTYPE Matrix<VARTYPE>::vmodul()      // Модуль вектора

 {

   VARTYPE d=0;

   if (n!=1) ERROR_MATRIX(9);

   static Matrix<VARTYPE> M;

   M <<= *this;

   for(int i=0; i<m; i++)

      d=d+M(i,0)*M(i,0);

   return sqrt(d);

 }

template <class VARTYPE>

Matrix<VARTYPE>& Matrix<VARTYPE>::Gauss(dim M, dim N)

 {

   Matrix<VARTYPE>& A=*this;

   if (!A(M,N))  ERROR_MATRIX(5);

   for(int i=0,j;i<m;i++)

      for(j=0;j<n;j++)

            if (i!=M && j!=N)

              A(i,j)-=A(M,j)*A(i,N)/A(M,N);

   for(j=0;j<n;j++)

     if (j!=N)

              A(M,j)/=A(M,N);

   for(i=0;i<m;i++)

              A(i,N)=0;

   A(M,N)=1;

   return *this;

 }

template <class VARTYPE>

Matrix<VARTYPE> Matrix<VARTYPE>::minor(dim M, dim N)  // возвращ. матрицу без

 {                                                                                                         // строки y и столбца x

    Matrix<VARTYPE> A(m-1,n-1);

    for(int i=0,in=0,j,jn;i<m;i++)

      if (i!=M)

            {

               for(j=0,jn=0;j<n;j++)

                 if (j!=N)

                   A(in,jn++)=(*this)(i,j);

               in++;

            }

   return A;

 }

template <class VARTYPE>   // вставка

Matrix<VARTYPE>& Matrix<VARTYPE>::insert(const Matrix<VARTYPE> &A, dim M, dim N)

 

template <class VARTYPE>   // извлечение

Matrix<VARTYPE> Matrix<VARTYPE>::extract(dim LM, dim LN, dim M, dim N)

 

template <class VARTYPE>

VARTYPE& Matrix<VARTYPE>::operator() (dim M, dim N) const

 { return *(matr+n*M+N); }

template <class VARTYPE>

Matrix<VARTYPE> operator+(const Matrix<VARTYPE> &A, const Matrix<VARTYPE>&B)

 {

   Matrix<VARTYPE> C=A;

   for(int i=0,j; i<A.m; i++)

      for(j=0; j<A.n; j++)

             C(i,j)+=B(i,j);

   return C;

 }

template <class VARTYPE>

Matrix<VARTYPE> operator-(const Matrix<VARTYPE> &A, const Matrix<VARTYPE> &B)

 {

   Matrix<VARTYPE> C=A;

   for(int i=0, j; i<A.m; i++)

     for(j=0;j<A.n;j++)

       C(i,j)-=B(i,j);

   return C;

 }

template <class VARTYPE>

Matrix<VARTYPE> operator*(const Matrix<VARTYPE> &A,const Matrix<VARTYPE> &B)

{

  Matrix<VARTYPE> C(A.m,B.n);

  if (A.n!=B.m)

  {

    if(A.m==3 && A.n==1 && B.m==3 && B.n==1)

    {

      C(0)=A(1)*B(2)-A(2)*B(1);

      C(1)=A(2)*B(0)-A(0)*B(2);

      C(2)=A(0)*B(1)-A(1)*B(0);

    }

    else

      A.ERROR_MATRIX(2);

  }

  else

  {

    for(int i=0,j,k;i<C.m;i++)

      for(j=0;j<C.n;j++)

            for(k=0;k<A.n;k++)

              C(i,j)+=A(i,k)*B(k,j);

  }

  return C;

}

template <class VARTYPE>//умножение числа на матрицу

Matrix<VARTYPE> operator*(const double &f,const Matrix<VARTYPE> &A)

 {

   Matrix<VARTYPE> B=A;

   for(int i=0,j;i<A.m;i++)

     for(j=0;j<A.n;j++)

       B(i,j)*=f;

   return B;

 }

template <class VARTYPE>// умножение матрицы на число

Matrix<VARTYPE> operator*(const Matrix<VARTYPE> &A, const double &f)

 {

   Matrix<VARTYPE> B=A;

   for(int i=0,j;i<A.m;i++)

     for(j=0;j<A.n;j++)

       B(i,j)*=f;

   return B;

 }

template <class VARTYPE>

Matrix<VARTYPE>& Matrix<VARTYPE>::newsize(dim M, dim N)

 { delete [] matr;

   m=M;

   n=N;

   if (N && M) { matr=new VARTYPE[m*n];

   if (!matr) ERROR_MATRIX(1);

             setmem(matr,sizeof(VARTYPE)*m*n,0); }

    else { m=n=0; matr=(VARTYPE*)0; }

   return *this;

 }

template <class VARTYPE>

ostream& operator<<(ostream &out,Matrix<VARTYPE> &A)

 { for(int i=0,j;i<A.size_row();i++)

      { for(j=0;j<A.size_col();j++)

            out << A(i,j)<< "  ";

            out<<endl;

      }

   return out;

 }

template <class VARTYPE>

int operator>>(istream &inp,Matrix<VARTYPE> &A)

 { for(int i=0,j;i<A.size_row();i++)

      for(j=0;j<A.size_col();j++) if( !(inp>>A(i,j)) ) return 1;

   return 0;

 }

template <class VARTYPE>

void Matrix<VARTYPE>::swap_line(dim L1, dim L2)

 {

   if (L1==L2)

     return;

   double b;

   for(int j=0;j<n;j++)

     {

       b=(*this)(L1,j);

       (*this)(L1,j)=(*this)(L2,j);

       (*this)(L2,j)=b;

     }

 }

template <class VARTYPE>

void Matrix<VARTYPE>::swap_column(dim C1, dim C2)

 {

   if (C1==C2)

     return;

   double b;

   for(int i=0;i<m;i++)

    {

      b=(*this)(i,C1);

      (*this)(i,C1)=(*this)(i,C2);

      (*this)(i,C2)=b;

    }

 }

template <class VARTYPE>

dim Matrix<VARTYPE>::read(ifstream &finp)

 { (finp.get(m)).get(n); delete []matr; matr=new VARTYPE[m*n];

      if(!matr) ERROR_MATRIX(1);

   setmem(matr,sizeof(VARTYPE)*m*n,0);

   finp.read((char *)matr,sizeof(VARTYPE)*m*n); return finp.fail();

 }

template <class VARTYPE>

dim Matrix<VARTYPE>::write(ofstream &fout)

 { (fout.put(m)).put(n);

   (fout.write((char *)matr,sizeof(VARTYPE)*m*n))<<flush; return fout.fail();

 }

template <class VARTYPE>

VARTYPE operator%(const Matrix<VARTYPE> &A, const Matrix<VARTYPE>&B)

 

template <class VARTYPE>

void Matrix<VARTYPE>::ERROR_MATRIX(dim E) const

 { static char *message[] = {

             "Матрицы должны иметь одинаковую размерность",                 //0

             "Не выделена память!",                                                                   //1

             "Матрицы не согласованы для умножения",                                //2

             "Степень должна быть больше нуля или -1",                                //3

             "Матрица должна быть квадратной",                                            //4

             "Нулевой ведущий элемент в преобразовании Гаусса",             //5

             "Вставка невозможна из-за перекрытия базовой матрицы",      //6

             "Извлекаемая матрица выходит за границы базовой",                //7

             "Выход за границы. Попытка доступа к несущ. элементу",       //8

             "Это не вектор!"};                                                                            //9

   cerr<<"ERROR: "<< message[E] << endl; exit(1);

 }


Демонстративно - тестирующая программа:

#include <conio.h>

#include <iostream.h>

#include <fstream.h>

#include "tmatr.cpp"

int main()

{

  clrscr();

  Matrix<double> A(3,3), B(3,3), C(3,3);

  Matrix<double> V(3),X(3),H(3),U(3);

  double d;

  A(0,0)=1.1; A(0,1)=2.2; A(0,2)=3.3;

  A(1,0)=2.4; A(1,1)=1.1; A(1,2)=4.4;

  A(2,0)=1.3; A(2,1)=2.1; A(2,2)=4.1;

  B(0,0)=2; B(0,1)=7; B(0,2)=2;

  B(1,0)=4; B(1,1)=8; B(1,2)=1;

  B(2,0)=6; B(2,1)=4; B(2,2)=1;

  V(0)=2.1; V(1)=3.31; V(2)=1.4;

  H(0)=1.1; H(1)=2.1; H(2)=3.1;

//******************************

  C=A+B;

  cout<<"A:\n"<<A<<endl;

  cout<<"B:\n"<<B<<endl;

  cout<<"C=A+B:\n"<<C<<endl;

  cout<<"Press any key...\n";

  getch();

  clrscr();

//******************************

  C=A-B;

  cout<<"A:\n"<<A<<endl;

  cout<<"B:\n"<<B<<endl;

  cout<<"C=A-B:\n"<<C<<endl;

  cout<<"Press any key...\n";

  getch();

  clrscr();

//******************************

//******************************

  X=V+H;

  cout<<"V:\n"<<V<<endl;

  cout<<"H:\n"<<H<<endl;

  cout<<"X=V+H:\n"<<X<<endl;

  cout<<"Press any key...\n";

  getch();

  clrscr();

//******************************

  X=V-H;

  cout<<"V:\n"<<V<<endl;

  cout<<"H:\n"<<H<<endl;

  cout<<"X=V-H:\n"<<X<<endl;

  cout<<"Press any key...\n";

  getch();

  clrscr();

  C=A*V;

  cout<<"A:\n"<<A<<endl;

  cout<<"V:\n"<<V<<endl;

  cout<<"C=A*V:\n"<<C<<endl;

  cout<<"Press any key...\n";

  getch();

  clrscr();

//******************************

  Matrix<int> D(3,3), E(3,3);

  D(0,0)=1; D(0,1)=2; D(0,2)=3;

  D(1,0)=2; D(1,1)=5; D(1,2)=6;

  D(2,0)=7; D(2,1)=3; D(2,2)=9;

  ofstream fout("test.mtr");

  if(!fout)

    {

      cout<<"file not open\n";

      return 1;

    }

  D.write(fout);

  fout.close();

  ifstream fin("test.mtr");

  if(!fin)

    {

      cout<<"file not open\n";

      return 1;

    }

  E.read(fin);  //é ñó«¿t¡«¼ ó¿ñÑ

  cout<<"D:\n";

  cout<<D;

  cout<<"E:\n";

  cout<<E;

  fin.close();

  cout<<"Press any key...\n";

  getch();

  clrscr();

  //************************************

  C=A^-1;

  cout<<"A:\n"<<A<<endl;

  cout<<"C=A^-1:\n"<<C<<endl;

  cout<<"Press any key...\n";

  getch();

  clrscr();

 //****************************

 // A*X=V   X=(A^-1)*V

  X=(A^-1)*V;

  cout<<"A^-1:\n"<<(A^-1)<<endl;

  cout<<"V:\n"<<V<<endl;

  cout<<"X:\n"<<X<<endl;

  cout<<"Press any key...\n";

  getch();

  clrscr();

//************************************

  d=A.determ();

  cout<<"determinant of A = "<<d<< endl;

  d=V.vmodul();

  cout<<"modul of V = "<<d<< endl;

  cout<<"Press any key...\n";

  getch();

  clrscr();

//************************************

  V(0)=4; V(1)=3; V(2)=2;

  U(0)=1; U(1)=2; U(2)=3;

  d=V%U;

  cout<<"scalar product V*U= "<< d<<endl;

  cout<<"Press any key...\n";

  getch();

  clrscr();

//************************************

  C=!A;

  cout<<"A:\n"<<A<<endl;

  cout<<"C=!A:\n"<<C<<endl;

  cout<<"Press any key...\n";

  getch();

  clrscr();

  C=5*A;

  B=A*2;

  cout<<"A:\n"<<A<<endl;

  cout<<"C=5*A:\n"<<C<<endl;

  cout<<"B=A*2:\n"<<B<<endl;

  cout<<"Press any key...\n";

  getch();

  clrscr();

//************************************

//************************************

return 0;

Результаты тестирования класса Matrix

Сложение матриц A и B:

     A:                                                 B:                                            C=A+B:

1.1     2.2     3.3                        2        7        2                           3.1     9.2     5.3

2.4     1.1     4.4                        4        8        1                           6.4     9.1     5.4

1.3     2.1     4.1                        6        4        1                           7.3     6.1     5.1

Вычитание матриц A и B:

     A:                                                 B:                                            C=A-B:

1.1     2.2     3.3                        2        7        2                           -0.9   -4.8   1.3

2.4     1.1     4.4                        4        8        1                           -1.6   -6.9   3.4

1.3     2.1     4.1                        6        4        1                           -4.7   -1.9   3.1

Сложение матриц A и B:

     A:                                                 B:                                            C=A*B:

1.1     2.2     3.3                        2        7        2                           30.8   38.5   7.7

2.4     1.1     4.4                        4        8        1                           35.6   43.2   10.3

1.3     2.1     4.1                        6        4        1                           35.6   42.3   8.8

Сложение векторов

V:

2.1

3.31

1.4

H:

1.1

2.1

3.1

X=V+H

3.2

5.41

4.5

Вычитание векторов

V:

2.1

3.31

1.4

H:

1.1

2.1

3.1

X=V-H:

1

1.21

-1.7

Умножение матрицы на вектор

A:

1.1  2.2  3.3

2.4  1.1  4.4

1.3  2.1  4.1

V:

2.1

3.31

1.4

C=A*V:

14.212

14.841

15.421

Запись матрицы в файл

D:

1  2  3

2  5  6

7  3  9

Считывание матрицы из файла

E:

1  2  3

2  5  6

7  3  9

Вычисление обратной матрицы

A:

1.1  2.2  3.3

2.4  1.1  4.4

1.3  2.1  4.1

C=A^-1:

2.009346  0.88785  -2.570093

1.750212  -0.093458  -1.308411

-1.53356  -0.233645  1.728972

Решение алгебраического уравнения

A^-1:

2.009346  0.88785  -2.570093

1.750212  -0.093458  -1.308411

-1.53356  -0.233645  1.728972

V:

2.1

3.31

1.4

X:

3.56028

1.534325

-1.57328

Определение детерминанта матрицы

determinant of A = -2.354

Определение длины (модуля) вектора

modul of V = 4.162463

Вычисление скалярного произведения векторов

scalar product V*U= 16


ВЫВОД

В результате выполнения курсового проекта были разработаны два класса функций для решения простейших задач линейной алгебры. Число этих функций сравнительно невелико, однако можно легко добавить в эти классы более сложные функции, построенные на базе уже имеющихся. Классы позволяют работать с матрицами и векторами, элементы которых могут быть любого типа, однако на практике чаще всего используется целый тип и тип чисел с плавающей запятой.

Классы написаны на языке С++, однако могут быть легко переписаны на любом из современных языков программирования, так как приведены довольно простые алгоритмы всех компонентных функций. Были максимально предусмотрены все возможные ошибки, которые могут возникнуть при использовании функций данных классов. Особое внимание уделялось разумному выделению памяти под объекты во время выполнения программы, поэтому все функции были тщательно отлажены.

Классы Matrix и Vector могут быть эффекивно применены на практике в задачах, требующих операций с матрицами и векторами, а также связанных с решением систем линейных алгебраических уравнений.


Список использованной литературы

1.   Дискретная математика, конспект лекций. В. Г. Засовенко. Запорожье, 1998 г.

2.   Начальный курс С и С++. Б. И. Березин. Москва: "ДИАЛОГ-МИФИ", 1999 г.

3.   Язык программирования С++. Б. Страуструп. Киев:"ДиаСофт", 1993 г.


Страницы: 1, 2


на тему рефераты
НОВОСТИ на тему рефераты
на тему рефераты
ВХОД на тему рефераты
Логин:
Пароль:
регистрация
забыли пароль?

на тему рефераты    
на тему рефераты
ТЕГИ на тему рефераты

Рефераты бесплатно, реферат бесплатно, курсовые работы, реферат, доклады, рефераты, рефераты скачать, рефераты на тему, сочинения, курсовые, дипломы, научные работы и многое другое.


Copyright © 2012 г.
При использовании материалов - ссылка на сайт обязательна.