Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

АиПА / include / dalmat

.h
Скачиваний:
7
Добавлен:
07.02.2016
Размер:
16.63 Кб
Скачать
/*-------------------------------------------------------------------------------------*/
/* Библиотека VP/C++, модуль DALMAT.H (линейная алгебра). Версия 2009.08 */
/* Пинчук В.П. Запорожье, vpinchuk@zntu.edu.ua */
/* Печатать Courier New Cyr, Size = 10, Rihgt Margin = 89, Print Margin = 3 */
/*-------------------------------------------------------------------------------------*/
#include <syst.h>

class dvector;
class dmatrix;
class ftable;
typedef dvector (*vfun)(dvector);

/* ---------------------Прототипы внешних перегруженных операций ----------------------*/

dmatrix operator+(const dmatrix& A, const dmatrix& B);
dmatrix operator-(const dmatrix& A, const dmatrix& B);
dmatrix operator*(const dmatrix& A, const dmatrix& B);
dmatrix operator*(double p, const dmatrix& B);
dmatrix operator*(const dmatrix& A, double p);
dvector operator*(const dmatrix& A, const dvector& X);
dmatrix operator/(double e, const dmatrix& D);
dmatrix operator/(const dmatrix& A, const dmatrix& B);
dvector operator+(const dvector& A, const dvector& B);
dvector operator-(const dvector& A, const dvector& B);
double operator*(const dvector& A, const dvector& B);

/*------------------------Прототипы внешних функций и процедур ------------------------*/

double amax(const dmatrix& A);
double amax(const dvector& A);
void gauss(const dmatrix& A, const dvector& B, dvector& X);
double polinom(dvector& a, double x);
dvector interpolinom(dvector& x, dvector& y);
dvector polinappr(ftable F, int p);
int newton(vfun system, double eps, double h, dvector& x);

/*-------------------------------------------------------------------------------------*/

/*------------------------------------ Класс dmatrix ----------------------------------*/
class dmatrix
{ public:
int n,m;
double** r;
dmatrix() { n=m=0; r=0; }
dmatrix(int);
dmatrix(int,int);
dmatrix(double**, int, int);
dmatrix(const dmatrix&);
~dmatrix();
dmatrix& operator=(const dmatrix&);
dmatrix& operator=(double);
double* operator[](int);
dmatrix operator~();
dmatrix& operator>>(FILE*);
dmatrix& operator<<(FILE*);
double det();
void rand(double, double);
};
/*-------------------------------- Функции класса dmatrix -----------------------------*/
dmatrix::dmatrix(int N)
{ int i,j;
n=N; m=N;
r= new double*[n];
for (i=0;i<n;i++) r[i]= new double[m];
for (i=0;i<n;i++) for (j=0;j<m;j++) r[i][j]=0.0;
}
dmatrix::dmatrix(int N, int M)
{ int i,j;
n=N; m=M;
r= new double*[n];
for (i=0;i<n;i++) r[i]= new double[m];
for (i=0;i<n;i++) for (j=0;j<m;j++) r[i][j]=0.0;
}
dmatrix::dmatrix(double** A, int N, int M = 0)
{ int i,j;
n=N;
if (M==0) m=N; else m=M;
r= new double*[n];
for (i=0;i<n;i++) r[i]= new double[m];
for (i=0;i<n;i++) for (j=0;j<m;j++) r[i][j]=A[i][j];
}
dmatrix::dmatrix(const dmatrix& B)
{ int i,j;
n=B.n; m=B.m;
r= new double*[n];
for (i=0;i<n;i++) r[i]= new double[m];
for (i=0;i<n;i++) for (j=0;j<m;j++) r[i][j]=B.r[i][j];
}
dmatrix::~dmatrix()
{ for (int i=0;i<n;i++) delete[] r[i];
delete[] r;
}
dmatrix& dmatrix::operator=(const dmatrix& B)
{ if (this==&B) return *this;
int i,j;
if (n) { for (i=0;i<n;i++) delete[] r[i];
delete[] r;
}
if (B.n) { n=B.n; m=B.m;
r= new double*[n];
for (i=0;i<n;i++) r[i]= new double[m];
for (i=0;i<n;i++) for (j=0;j<m;j++) r[i][j]=B.r[i][j];
}
else { n=m=0; r=0; }
return *this;
}
dmatrix dmatrix::operator~()
{ dmatrix R(m,n);
int i,j;
for (i=0;i<n;i++) for (j=0;j<m;j++) R.r[j][i]=r[i][j];
return R;
}
dmatrix& dmatrix::operator=(double u)
{ if (n!=m) throw "dmatrix::operator=(double) : matrix must be square!";
int i,j;
for (i=0;i<n;i++)
for (j=0;j<n;j++) { if (i==j) r[i][j]= u;
else r[i][j]= 0.0;
}
return *this;
}
double* dmatrix::operator[](int i)
{ if (i<0 || i>=n) throw "function dmatrix::operator[](int) : illegal index";
return r[i];
}
dmatrix& dmatrix::operator>>(FILE* f)
{ fprintf(f,"%4d %4d \n",n,m);
int i,j;
for (i=0;i<n;i++)
{ for (j=0;j<m;j++) fprintf(f,"%15.8e ",r[i][j]);
fprintf(f,"\n");
}
return *this;
}
dmatrix& dmatrix::operator<<(FILE* f)
{ int i,j;
if (n) { for (i=0;i<n;i++) delete[] r[i];
delete[] r;
}
fscanf(f,"%d %d",&n,&m);
if (n) { r= new double*[n];
for (i=0;i<n;i++) r[i]= new double[m];
for (i=0;i<n;i++)
for (j=0;j<m;j++) fscanf(f,"%lf",&r[i][j]);
}
else { n=m=0; r=0; }
return *this;
}
void dmatrix::rand(double a, double b)
{ int i,j;
for (i=0;i<n;i++) for (j=0;j<m;j++) r[i][j]=frand(a,b);
}
FILE* operator<<(FILE* f, const dmatrix& B)
{ fprintf(f,"%4d %4d \n",B.n,B.m);
int i,j;
for (i=0;i<B.n;i++)
{ for (j=0;j<B.m;j++) fprintf(f,"%g ",B.r[i][j]);
fprintf(f,"\n");
}
return f;
}
double dmatrix::det()
{ if (n!=m) throw "dmatrix::det(): Not a square matrix in expression!";
int i,j,k,l;
double Q, D=1.0;
double** A= new double*[n];
for (i=0;i<n;i++) A[i]= new double[n];
for (i=0;i<n;i++) for (j=0;j<n;j++) A[i][j]=r[i][j];
for (k=0;k<n-1;k++)
{ l=k;
for (i=k+1;i<n;i++) if (abs(A[i][k]) >= abs(A[l][k])) l=i;
if (l==k && A[k][k]==0.0) return 0.0;
if (l!=k) { D=-D; swp(A[k],A[l]); }
if (A[k][k]==0.0) return 0.0;
for (i=k+1;i<n;i++)
{ Q=A[i][k]/A[k][k];
for (j=k+1;j<n;j++) A[i][j]-=Q*A[k][j]; }
}
for (i=0;i<n;i++) D*=A[i][i];
for (i=0;i<n;i++) delete[] A[i];
delete[] A;
return D;
}
/*-------------------------------------- Класс dvector --------------------------------*/
class dvector
{ public:
int m;
double* r;
dvector() { m=0; r=0; }
dvector(int);
dvector(int,double*);
dvector(const dvector&);
~dvector() { delete[] r; }
dvector& operator=(const dvector&);
dvector operator-();
double& operator[](int);
dvector& operator>>(FILE*);
dvector& operator<<(FILE*);
double length();
dvector& rand(double, double);
};
/*-------------------------------- Функции класса dvector -----------------------------*/
dvector::dvector(int N)
{ m=N;
r= new double[m];
for (int i=0;i<m;i++) r[i]=0.0;
}
dvector::dvector(int N, double* A)
{ m=N;
r= new double[m];
for (int i=0;i<m;i++) r[i]=A[i];
}
dvector::dvector(const dvector& B)
{ m=B.m;
r= new double[m];
for (int i=0;i<m;i++) r[i]=B.r[i];
}
dvector& dvector::operator=(const dvector& B)
{ if (this==&B) return *this;
int i;
if (m) delete[] r;
if (B.m) { m=B.m;
r= new double[m];
for (i=0;i<m;i++) r[i]=B.r[i];
}
else { m=0; r=0; }
return *this;
}
dvector dvector::operator-()
{ dvector A(*this);
for (int i=0;i<m;i++) A.r[i]= -A.r[i];
return A;
}
double& dvector::operator[](int k)
{ if (k<0 || k>=m) throw "dvector::operator[](int) : invalid index";
return r[k];
}
dvector& dvector::operator>>(FILE* f)
{ fprintf(f,"%4d \n",m);
for (int i=0;i<m;i++) fprintf(f,"%6.3f ",r[i]);
fprintf(f,"\n");
return *this;
}
dvector& dvector::operator<<(FILE* f)
{ if (m) delete[] r;
fscanf(f,"%d",&m);
if (m) { r= new double[m];
for (int i=0;i<m;i++) fscanf(f,"%lf",&r[i]);
}
else { m=0; r=0; }
return *this;
}
double dvector::length()
{ double L=0;
for (int i=0;i<m;i++) L+=sqr(r[i]);
L=sqrt(L);
return L;
}
dvector& dvector::rand(double a, double b)
{ int i;
for (i=0;i<m;i++) r[i]=frand(a,b);
return *this;
}

/*-------------------------------------- Класс ftable ---------------------------------*/
class ftable
{ public:
int n;
double *x, *y;
ftable() { n=0; x=y=NULL; }
ftable(int, double*, double*);
ftable(dvector&, dvector&);
ftable(const ftable&);
~ftable() { delete[] x, delete[] y; }
ftable& operator=(const ftable&);
ftable& operator>>(FILE*);
ftable& operator<<(FILE*);
};
/*--------------------------------- Функции класса ftable -----------------------------*/
ftable::ftable(int N, double* X, double* Y)
{ n=N;
x= new double[n]; y= new double[n];
for (int i=0;i<n;i++) { x[i]=X[i]; y[i]=Y[i]; }
}
ftable::ftable(dvector& X, dvector& Y)
{ if (X.m!=Y.m) throw "ftable: Invalid Parameters";
n=X.m;
x= new double[n]; y= new double[n];
for (int i=0;i<n;i++) { x[i]=X[i]; y[i]=Y[i]; }
}
ftable::ftable(const ftable& T)
{ n=T.n;
x= new double[n]; y= new double[n];
for (int i=0;i<n;i++) { x[i]=T.x[i]; y[i]=T.y[i]; }
}
ftable& ftable::operator=(const ftable& T)
{ if (this==&T) return *this;
delete[] x; delete[] y;
n=T.n;
x= new double[n]; y= new double[n];
for (int i=0;i<n;i++) { x[i]=T.x[i]; y[i]=T.y[i]; }
return *this;
}
ftable& ftable::operator>>(FILE* f)
{ fprintf(f,"%3d\n",n);
for (int i=0;i<n;i++) fprintf(f,"%19.12le %19.12le\n",x[i],y[i]);
return *this;
}
ftable& ftable::operator<<(FILE* f)
{ delete[] x; delete[] y;
fscanf(f,"%d",&n);
x= new double[n]; y= new double[n];
for (int i=0;i<n;i++) fscanf(f,"%le %le",&x[i],&y[i]);
return *this;
}

/* ----------------------------- Внешние перегруженные операции -----------------------*/

dmatrix operator+(const dmatrix& A, const dmatrix& B)
{ if (A.n != B.n || A.m != B.m) throw "operator+(dmatrix,dmatrix) : invalid operand!";
dmatrix C(A.n,A.m);
int i,j;
for (i=0;i<C.n;i++) for (j=0;j<C.m;j++) C.r[i][j]=A.r[i][j]+B.r[i][j];
return C;
}
dmatrix operator-(const dmatrix& A, const dmatrix& B)
{ if (A.n != B.n || A.m != B.m) throw "operator-(dmatrix,dmatrix) : invalid operand!";
dmatrix C(A.n,A.m);
int i,j;
for (i=0;i<C.n;i++) for (j=0;j<C.m;j++) C.r[i][j]=A.r[i][j]-B.r[i][j];
return C;
}
dmatrix operator*(const dmatrix& A, const dmatrix& B)
{ if (A.m != B.n) throw "operator*(dmatrix,dmatrix): invalid operand!";
dmatrix C(A.n,B.m);
int i,j,k;
for (i=0;i<C.n;i++)
for (k=0;k<C.m;k++) for (j=0;j<A.m;j++) C.r[i][k]+=A.r[i][j]*B.r[j][k];
return C;
}
dmatrix operator*(double p, const dmatrix& B)
{ dmatrix C(B.n,B.m);
int i,k;
for (i=0;i<C.n;i++)
for (k=0;k<C.m;k++) C.r[i][k]=p*B.r[i][k];
return C;
}
dmatrix operator*(const dmatrix& A, double p)
{ dmatrix C(A.n,A.m);
int i,k;
for (i=0;i<C.n;i++)
for (k=0;k<C.m;k++) C.r[i][k]=A.r[i][k]*p;
return C;
}
dvector operator*(const dmatrix& A, const dvector& X)
{ if (A.m != X.m) throw "operator*(dmatrix,dvector): invalid operand!";
dvector Y(A.n);
int i,j;
for (i=0;i<Y.m;i++) for (j=0;j<A.m;j++) Y.r[i]+=A.r[i][j]*X.r[j];
return Y;
}
dmatrix operator/(double e, const dmatrix& D)
{ if ( D.n!=D.m) throw "operator/(int,dmatrix): matrix is not square!";
char* mes = "operator/(int,dmatrix): Determinant of matrix = 0!";
int i,j,k,l, n=D.n; double R,m,aa;
dmatrix A(D), B(n,n);
for (i=0;i<n;i++) B.r[i][i]=1.0;
for (k=0;k<n-1;k++)
{ m=0.0;
for (i=k;i<n;i++) { aa=abs(A.r[i][k]);
if (m<aa) { m=aa; l=i; }
}
if (m==0.0) throw mes;
if (k!=l) { swp(A.r[k],A.r[l]); swp(B.r[k],B.r[l]); }
R=A.r[k][k];
for (j=k+1;j<n;j++) A.r[k][j]/=R;
for (j=0; j<n;j++) B.r[k][j]/=R;
for (i=k+1;i<n;i++)
{ R=A.r[i][k];
if (R!=0.0) { for (j=k+1;j<n;j++) A.r[i][j]-=A.r[k][j]*R;
for (j=0; j<n;j++) B.r[i][j]-=B.r[k][j]*R;
}
}
}
if (A.r[n-1][n-1]==0.0) throw mes;
for (j=0;j<n;j++) B.r[n-1][j]/=A.r[n-1][n-1];
for (k=n-1;k>0;k--)
for (i=k-1;;i--) { R=A.r[i][k];
if (R!=0.0) for (j=0;j<n;j++) B.r[i][j]-=B.r[k][j]*R;
if (i==0) break;
}
if (e!=1.0) for (i=0;i<n;i++) for (j=0;j<n;j++) B.r[i][j]*=e;
return B;
}
dmatrix operator/(const dmatrix& A, const dmatrix& B)
{ return A*(1/B);
}
dvector operator+(const dvector& A, const dvector& B)
{ if (A.m!=B.m) throw "operator+(dvector,dvector): invalid operands!";
int i, m=A.m;
dvector C(m);
for (i=0;i<m;i++) C.r[i]=A.r[i]+B.r[i];
return C;
}
dvector operator-(const dvector& A, const dvector& B)
{ if (A.m!=B.m) throw "operator+(dvector,dvector): invalid operands!";
int i, m=A.m;
dvector C(m);
for (i=0;i<m;i++) C.r[i]=A.r[i]-B.r[i];
return C;
}
double operator*(const dvector& A, const dvector& B)
{ if (A.m!=B.m) throw "operator*(dvector,dvector): invalid operands!";
int i, m=A.m;
double R=0.0;
for (i=0;i<m;i++) R+=A.r[i]*B.r[i];
return R;
}

/*------------------------------------- Внешние функции -------------------------------*/

double amax(const dmatrix& A)
{ int i,j;
double x, max=abs(A.r[0][0]);
for (i=1;i<A.n;i++) for (j=0;j<A.m;j++) { x=abs(A.r[i][j]); if (max<x) max=x; }
return max;
}
/*-------------------------------------------------------------------------------------*/
double amax(const dvector& A)
{ double x, max=abs(A.r[0]);
for (int i=1;i<A.m;i++) { x=abs(A.r[i]); if (max<x) max=x; }
return max;
}
/*-------------------------------------------------------------------------------------*/
void gauss(const dmatrix& A, const dvector& B, dvector& X)
{ if (A.n!=A.m || X.m!=B.m || X.m!=A.m)
throw "gauss(dmatrix,dvector,dvector): invalid dimensions of arrays!";
char* mes= "gauss(dmatrix,dvector,dvector): Determinant = 0!";
int i,j,k,l, n=X.m;
dmatrix R(n,n+1);
for (i=0;i<n;i++) for (j=0;j<n;j++) R.r[i][j]=A.r[i][j];
for (i=0;i<n;i++) R.r[i][n]=B.r[i];
double Q;
for (k=0;k<n-1;k++)
{ l=k;
for (i=k+1;i<n;i++) if (abs(R.r[i][k])>=abs(R.r[l][k])) l=i;
if (l==k && R.r[k][k]==0.0) throw mes;
if (l!=k) swp(R.r[k],R.r[l]);
if (R.r[k][k]==0.0) throw mes;
for (i=k+1;i<n;i++)
{ Q=R.r[i][k]/R.r[k][k];
for (j=k+1;j<=n;j++) R.r[i][j]-=Q*R.r[k][j];
}
}
if (R.r[n-1][n-1]==0.0) throw mes;
X.r[n-1]=R.r[n-1][n]/R.r[n-1][n-1];
for (k=n-2;;k--)
{ Q=0;
for (j=k+1;j<n;j++) Q+=X.r[j]*R.r[k][j];
X.r[k]=(R.r[k][n]-Q)/R.r[k][k];
if (k==0) break;
}
}
/*-------------------------------------------------------------------------------------*/
double polinom(dvector& a, double x)
{ int k, n=a.m;
double R= a[n-1];
for (k=n-2;k>=0;k--) R=R*x+a[k];
return R;
}
/*-------------------------------------------------------------------------------------*/
dvector interpolinom(dvector& x, dvector& y)
{ if (x.m!=y.m) throw "polincoef: invalid parameters";
int i,j, n= x.m;
dmatrix a(n,n);
dvector c(n);
for (i=0;i<n;i++) for (j=0;j<n;j++) a.r[i][j]=pow(x[i],j);
gauss(a,y,c);
return c;
}
/*-------------------------------------------------------------------------------------*/
dvector polinappr(ftable F, int p)
{ int i,j,k, n=F.n, m=p+1;
dvector a(m), b(m);
dmatrix g(m,m);
double S;
for (i=0;i<m;i++)
for (j=0;j<m;j++)
{ S=0.0;
for (k=0;k<n;k++) S+= pow(F.x[k],i+j);
g.r[i][j]=S;
}
for (i=0;i<m;i++)
{ S=0.0;
for (k=0;k<n;k++) S+= F.y[k]*pow(F.x[k],i);
b[i]=S;
}
gauss(g,b,a);
return a;
}
/*-------------------------------------------------------------------------------------*/
int newton(vfun system, double eps, double h, dvector& x)
{ const int Nitmax= 1000;
dvector B(x.m),F0(x.m),F1(x.m),dx(x.m);
dmatrix P(x.m);
double hh,dxm,xo;
int i,j, N=x.m, Nit=0;
hh=2*h;
do { B=system(x); B=-B;
for (j=0;j<N;j++) { xo=x[j];
x[j]=xo-h;
F0=system(x);
x[j]=xo+h;
F1=system(x);
x[j]=xo;
for (i=0;i<N;i++) P.r[i][j]=(F1[i]-F0[i])/hh;
}
gauss(P,B,dx);
dxm=abs(dx.r[0]); for (i=1;i<N;i++) if (dxm<abs(dx.r[i])) dxm=abs(dx.r[i]);
x=x+dx;
Nit++; errhalt(Nit>Nitmax,"Process is not approximate");
}
while (dxm>eps);
return Nit;
}
/*-------------------------------------------------------------------------------------*/

Соседние файлы в папке include