Будем жить, Маэстро...
Сообщения: 6694
Благодарности: 1393
|
Профиль
|
Сайт
|
Отправить PM
| Цитировать
Ещё один код решения Матрицы (Расскрыть код)
читать дальше »
Код: 
// файл tmatr.cpp
#include <iostream.h>
//#include // для setmem()
//#include
//#include
typedef unsigned char dim;
template 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&); // Конструктор копирования
~Matrix() { delete [ ]matr; }
// доступ к элементам матрицы
dim size_row() { return m; } // число строк
dim size_col() { return n; } // число столбцов
VARTYPE& operator() (dim x) const { return (*this)(x,0); } // элементу
// перегруженные операции и функции:
Matrix& operator=(const Matrix&);
Matrix& operator=(const VARTYPE&);
Matrix operator^(int); // возведение в степень
Matrix 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& operator<<=(const Matrix &A) { return newsize(A.m,A.n)=A;
}
// безусловное приравнивание матриц
Matrix& insert(const Matrix&, dim=0, dim=0); // вставить частьматрицы
Matrix extract(dim, dim, dim=0, dim=0); // извлечьчасть матрицы
Matrix& newsize(dim, dim=1); // установитьновые размеры
void swap_line(dim, dim); //обмен строкамиматрицы
void swap_column(dim, dim); // обмен столбцамиматрицы
friend Matrix operator+(const Matrix&,const Matrix&); //A-B
friend Matrix operator-(const Matrix&,const Matrix&); //A-B
friend Matrix operator*(const Matrix&,const Matrix&); //A*B
friend Matrix operator*(const double&,const Matrix&); //k*A
friend Matrix operator*(const Matrix&, const double&); //A*k
friend ostream& operator<<(ostream&,Matrix&);
// потоковый вывод матрицы
friend int operator>>(istream&,Matrix&);
// потоковый ввод существ. матрицы
// 0 - без. ошибок, 1 - была ошибка
dim read(ifstream&); // файловое чтение и запись матрицы
dim write(ofstream&); // в ее внутреннем, двоичном представлении.
friend VARTYPE operator %(const Matrix&,const Matrix&);
//Функция ошибок
void ERROR_MATRIX(dim) const;
};
// Реализация класса матриц
template
Matrix::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
Matrix::Matrix(const Matrix &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
Matrix& Matrix::operator=(const Matrix &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
Matrix& Matrix::operator=(const VARTYPE &f)
{
for(int i=0,j;i
Matrix Matrix::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
Matrix Matrix::operator!() // Транспозиция
{ Matrix A(n,m);
for(int i=0, j; i
VARTYPE Matrix::determ() // рекурсивно находит определитель матрицы
{
if (n!=m) ERROR_MATRIX(4);
if (n==1)
return (*this)(0,0);
for(int i=0; i 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
VARTYPE Matrix::vmodul() // Модуль вектора
{
VARTYPE d=0;
if (n!=1) ERROR_MATRIX(9);
static Matrix M;
M <<= *this;
for(int i=0; i
Matrix& Matrix::Gauss(dim M, dim N)
{
Matrix& A=*this;
if (!A(M,N)) ERROR_MATRIX(5);
for(int i=0,j;i
Matrix Matrix::minor(dim M, dim N) // возвращ. матрицу без
{ // строки y и столбца x
Matrix A(m-1,n-1);
for(int i=0,in=0,j,jn;i // вставка
Matrix& Matrix::insert(const Matrix &A, dim M, dim N)
{
if (M+A.m>m || N+A.n>n) ERROR_MATRIX(6);
for(int i=0, j; i // извлечение
Matrix Matrix::extract(dim LM, dim LN, dim M, dim N)
{
if (M+LM>m || N+LN>n) ERROR_MATRIX(7);
Matrix A(LM,LN);
for(int i=0, j; i
VARTYPE& Matrix::operator() (dim M, dim N) const
{ return *(matr+n*M+N); }
template
Matrix operator+(const Matrix &A, const
Matrix&B)
{
Matrix C=A;
for(int i=0,j; i
Matrix operator-(const Matrix &A, const Matrix &B)
{
Matrix C=A;
for(int i=0, j; i
Matrix operator*(const Matrix &A,const Matrix &B)
{
Matrix 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//умножение числа на матрицу
Matrix operator*(const double &f,const Matrix &A)
{
Matrix B=A;
for(int i=0,j;i// умножение матрицы на число
Matrix operator*(const Matrix &A, const double &f)
{
Matrix B=A;
for(int i=0,j;i
Matrix& Matrix::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
ostream& operator<<(ostream &out,Matrix &A)
{ for(int i=0,j;i
int operator>>(istream &inp,Matrix &A)
{ for(int i=0,j;i>A(i,j)) ) return 1;
return 0;
}
template
void Matrix::swap_line(dim L1, dim L2)
{
if (L1==L2)
return;
double b;
for(int j=0;j
void Matrix::swap_column(dim C1, dim C2)
{
if (C1==C2)
return;
double b;
for(int i=0;i
dim Matrix::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
dim Matrix::write(ofstream &fout)
{ (fout.put(m)).put(n);
(fout.write((char *)matr,sizeof(VARTYPE)*m*n))<
VARTYPE operator%(const Matrix &A, const Matrix&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
void Matrix::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 <iostream.h>
//#include
//#include
//#include "tmatr.cpp"
int main()
{
int z;
clrscr();
Matrix A(3,3), B(3,3), C(3,3);
Matrix 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"< 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<<"Finish!";
cin>>z;
//-------------------------------------------------------------------------
|