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

АиПА / include / dalmat

.h
Скачиваний:
8
Добавлен:
07.02.2016
Размер:
17 Кб
Скачать
/*-------------------------------------------------------------------------------------*/
/* Библиотека 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