Новичок
Профиль
Группа: Участник
Сообщений: 9
Регистрация: 23.4.2006
Репутация: нет Всего: нет
|
Вот есть целый класс, тока чето не фурычит мож кто подскажет | Код | // файл 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) { if (M+A.m>m || N+A.n>n) ERROR_MATRIX(6); for(int i=0, j; i<A.m; i++) for(j=0; j<A.n; j++) (*this)(i+M,j+N)=A(i,j); return *this; }
template <class VARTYPE> // извлечение Matrix<VARTYPE> Matrix<VARTYPE>::extract(dim LM, dim LN, dim M, dim N) { if (M+LM>m || N+LN>n) ERROR_MATRIX(7); Matrix<VARTYPE> A(LM,LN); for(int i=0, j; i<LM; i++) for(j=0; j<LN; j++) A(i,j)=(*this)(i+M,j+N); return A; }
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) { if(A.n!=1 || B.n!=1) A.ERROR_MATRIX(9); if(A.m!=B.m) A.ERROR_MATRIX(0); VARTYPE scalarmul = 0; for(int i=0; i<A.m; i++) scalarmul = scalarmul+A(i)*B(i); return scalarmul; }
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; }
|
|