mv.h
来自「C++ source code for book-C++ and Object 」· C头文件 代码 · 共 1,506 行 · 第 1/4 页
H
1,506 行
/******************** mv.h ***************************
*
* written by Daoqi Yang
* last modified September 28, 1998.
**********************************************************/
#ifndef MATVEC_H
#define MATVEC_H
#include <cstdlib>
#include <cmath>
#include <iostream.h>
#include <complex>
#include <algorithm>
//using namespace std;
template<class T> class Vcr; // forward declaration
template<class T> class Vcr< complex<T> >; // forward declaration
template<class T> class AbsMtx { // base matrix
protected:
int nrows; // number of rows
virtual Vcr<T> preconding(const Vcr<T>& r,int i=0) const=0;
// Solve P z = r with preconditiner P and vector r.
// It returns z. Here i = 0 if no preconditioning,
// i = 1 if diag prec, i = 2 if SSOR prec
public:
virtual Vcr<T> operator*(const Vcr<T> &) const = 0;
// matrix vector multiply
int CG(Vcr<T>& x, const Vcr<T>& b, double& eps,
int& iter, int pcn);
// Preconditioned conjugate gradient method for Ax = b
// It returns 0 for sucessful return and 1 if breakdown
// A: Hermitian positive definite coefficient matrix
// x: on entry: initial guess;
// on return: approximate solution
// b: right side vector
// eps: on entry: stopping criterion, epsilon
// on return: absolute residual in two-norm for
// approximate solution
// iter: on entry: max number of iterations allowed
// on return: actual number of iterations taken
// pcn: = 0 if no preconditioner, = 1 if diag precond
// = 2 if SSOR preconditioner
int GMRES(Vcr<T>& x, const Vcr<T>& b, double& eps,
int& iter, int pcn, int m);
// Restarted GMRES for solving Ax = b
// Returns 0 for sucessful return and 1 for breakdowns
// It outputs the approximate solution, residual, and
// number of iterations used.
//
// A: any nonsingular matrix, may not be symmetric
// x: on entry: initial guess
// on return: approximate solution
// b: right side vector
// eps: on input, stopping criterion,
// on return, absolute two-norm residual
// iter: on input, max number of iterations allowed
// on return, actual number of iterations taken.
// pcn: = 0 if no preconditioner, = 1 if diag precond,
// = 2 if SSOR precond
// m: number of iterations for restarting GMRES
};
template<class T> class FullMtx: public AbsMtx<T> {
private:
int ncols; // number of columns in matrix
T** mx; // entries of the matrix
Vcr<T> preconding(const Vcr<T>&, int i = 0) const;
// i = 0: no preconditioner, i = 1: diag precondr,
// i = 2: SSOR precondr
public:
FullMtx(int n,int m,T**); // n:# of rows, m:# of columns
FullMtx(int n,int m,T t=0); // all entries are set to t
FullMtx(const FullMtx &); // copy constructor
~FullMtx(){ // destructor
for (int i = 0; i< nrows; i++) delete[] mx[i];
delete[] mx;
}
FullMtx& operator=(const FullMtx&); // overload =
FullMtx& operator+=(const FullMtx&); // overload +=
FullMtx& operator-=(const FullMtx&); // overload -=
FullMtx& operator+(); // unary +, m1 = +m2;
FullMtx& operator-(); // unary -, m1 = -m2;
FullMtx operator+(const FullMtx&); // binary +, m =m1+m2
FullMtx operator-(const FullMtx&); // binary -, m =m1-m2
Vcr<T> operator*(const Vcr<T>&) const;
// matrix-vector multiply
T* operator[](int i) const { return mx[i]; } // subscript
void GaussElim(Vcr<T>&) const; // Gauss elimination
void GaussElimPP(Vcr<T>&) const;
// Gauss Elim with partial pivoting, no interchanging rows
void GaussElimPP2(Vcr<T>&) const;
// Gauss Elim with partial pivoting, interchange rows
void FullMtx<T>::GaussElimCP(Vcr<T>& bb) const;
// Gauss Elim with complete pivoting
};
template<class T> // sparse matrix
class SparseMtx: public AbsMtx<T> {
private: // compressed sparse row format
int lenth; // # of nonzero entries of original matrix
T *sra; // array for storing the non-zero entries
int *clm; // column indexes of entries stored in sra
int *fnz; // 1st nonzero entry of each row in sra
Vcr<T> preconding(const Vcr<T>&, int i = 0) const;
// i = 0: no preconditioner, i = 1: diag precondr,
// i = 2: SSOR precondr
public:
SparseMtx(int n, int m, T* t, int* c, int* f);
// n: number of rows (and columns) of original matrix
// m: length of array sra for nonzero entries
// t: nonzero entries of the original matrix
// c: colunm indexes of entries stored in sra
// f: index in sra of first nonzero entry in each row
SparseMtx(int n, int m); // initialize all entries to 0
// n: number of rows (and columns)
// m: number of nonzero entries.
SparseMtx(const SparseMtx &); // copy constructor
~SparseMtx(){ delete[] sra; delete[] fnz; delete[] clm; }
SparseMtx& operator=(const SparseMtx &); // overload =
Vcr<T> operator*(const Vcr<T>&) const;
// matrix vector multiply
T& operator[](int i) const { return sra[i]; } // subscript
int& getfnz(int i) const { return fnz[i]; }
// first nonzero entry of each row
int& getclm(int i) const { return clm[i]; }
// column index of entries in sra
};
template<class T>
class BandMtx: public AbsMtx<T> { // band matrix
private:
int bwleft; // left bandwidth
int bwrit; // right bandwidth
T** bdmx; // entries within band
Vcr<T> preconding(const Vcr<T> &, int = 0) const;
public:
BandMtx(int n, int p, int r, T** t);
// n: # of rows = # of columns, p: left bandwidth,
// r: right bandwidth, t: entries within the band
BandMtx(int n, int p, int r, T t = 0); // constructor
BandMtx(int n, int p, int r, const FullMtx<T>& m);
BandMtx(const BandMtx &); // copy constructor
~BandMtx(){
for (int i = 0; i < nrows; i++)
delete[] (bdmx[i] -= bwleft);
delete[] bdmx;
}
BandMtx& operator=(const BandMtx&); // overload =
T* operator[](int i) const { return bdmx[i]; } // row i
Vcr<T> operator*(const Vcr<T>&) const;
// matrix vector multiply
void GaussElim(Vcr<T>& b) const; // Gauss elimination
void GaussElimPP(Vcr<T>& b) const;
// Gauss elim, partial pivoting
};
template<class T> class Vcr {
int lenth; // number of entries
T* vr; // entries of the vector
public:
Vcr(int n, const T* const t); // constructor from t
explicit Vcr(int n, T t = 0); // all entries =t
Vcr(const Vcr&); // copy constructor
~Vcr(){ delete[] vr; } // destructor
int size() const { return lenth; } // size of vector
void reset(T = 0); // reset all enties to a value
T& operator[](int i) const { return vr[i]; } // v[i]=10;
Vcr& operator=(const Vcr&); // overload =, v = v2
Vcr& operator+=(const Vcr&); // v += v2
Vcr& operator-=(const Vcr&); // v -= v2
T maxnorm() const; // maximum norm
T twonorm() const; // L-2 norm
};
template<class T> // unary operator, v = + v2
Vcr<T> operator+(const Vcr<T>&);
template<class T> // unary operator, v = - v2
Vcr<T> operator-(const Vcr<T>&);
template<class T> // binary operator, v = u + w
Vcr<T> operator+(const Vcr<T>&, const Vcr<T>&);
template<class T> // binary operator, v = u - w
Vcr<T> operator-(const Vcr<T>&, const Vcr<T>&);
template<class T> // dot product
T dot(const Vcr<T>&, const Vcr<T>&);
template<class T> // vec-scalar multiply
Vcr<T> operator*(T, const Vcr<T>&);
template<class T> // vec-scalar multiply
Vcr<T> operator*(const Vcr<T>&, T);
template<class T> // component-wise multiply
Vcr<T> operator*(const Vcr<T>&, const Vcr<T>&);
template<class T> // vec-scalar division
Vcr<T> operator/(const Vcr<T>&, T);
template<class T> // output operator
ostream& operator<<(ostream&, const Vcr<T>&);
template<class T> T dot(T* a, T* b, int n);
template<class T> class Vcr< complex<T> > {
int lenth; // number of entries
complex<T>* vr; // entries of the vector
public:
Vcr(int n, const complex<T>* const t); // constructor
explicit Vcr(int n, complex<T> t = 0); // constructor
Vcr(const Vcr&); // copy constructor
~Vcr(){ delete[] vr; } // destructor
int size() const { return lenth; } // size of vector
void reset(complex<T> = 0); // reset all entries to a value
complex<T>& operator[](int i) const { return vr[i]; }
// subscript, v[i] = 10;
Vcr& operator=(const Vcr&); // overload =, v = v2
Vcr& operator+=(const Vcr&); // v += v2
Vcr& operator-=(const Vcr&); // v -= v2
T maxnorm() const; // maximum norm
T twonorm() const; // L-2 norm
};
template<class T> // unary operator, v = + v2
Vcr< complex<T> >
operator+(const Vcr< complex<T> >&);
template<class T> // unary operator, v = - v2
Vcr< complex<T> >
operator-(const Vcr< complex<T> >&);
template<class T> // v= v1 + v2
Vcr< complex<T> > operator+
(const Vcr< complex<T> >&, const Vcr< complex<T> >&);
template<class T> // v= v1 - v2
Vcr< complex<T> > operator-
(const Vcr< complex<T> >&, const Vcr< complex<T> >&);
template<class T> // dot product
complex<T> dot(const Vcr< complex<T> >&, const Vcr< complex<T> >&);
template<class T> // vec-scalar multiply
Vcr< complex<T> > operator*
(complex<T>, const Vcr< complex<T> >&);
template<class T> // vec-scalar multiply
Vcr< complex<T> > operator*
(const Vcr< complex<T> >&, complex<T>);
template<class T> // component-wise multiply
Vcr< complex<T> > operator*
(const Vcr< complex<T> >&, const Vcr< complex<T> >&);
template<class T> // vec-scalar division
Vcr< complex<T> > operator/
(const Vcr< complex<T> >&, complex<T>);
template<class T> // output operator
ostream& operator<<
(ostream&, const Vcr< complex<T> >&);
template<class T>
complex<T> dot (complex<T>* a, complex<T>* b, int n);
/*
class Vcr< complex<double> > { // a complete specialization
int lenth; // number of entries in vector
complex<double>* vr; // entries of the vector
public:
Vcr(int, complex<double> *cp); // constructor
explicit Vcr(int, complex<double> c = 0); // constructor
Vcr(const Vcr&); // copy constructor
~Vcr(){ delete[] vr;} // destructor
int size() const { return lenth; } // size of vector
void reset(complex<double> t = 0); // reset all enties to t
complex<double> & operator[](int i) const { return vr[i]; }
Vcr& operator=(const Vcr&); // overload =
Vcr& operator+=(const Vcr&); // v += v2
Vcr& operator-=(const Vcr&); // v -= v2
double maxnorm() const; // maximum norm
double twonorm() const; // L-2 norm
friend Vcr operator+<complex<double> >(const Vcr&);
// unary +, v = + v2
friend Vcr operator-<complex<double> >(const Vcr&);
// unary -, v = - v2
friend Vcr operator+<complex<double> >
(const Vcr&, const Vcr&); // v= v1+v2
friend Vcr operator-<complex<double> >
(const Vcr&, const Vcr&); // v= v1-v2
friend complex<double> dot<complex<double> >
(const Vcr&, const Vcr&); // dot product
friend Vcr operator*<complex<double> >
(complex<double>, const Vcr&); // vec-scalar x
friend Vcr operator*<complex<double> >
(const Vcr&, complex<double>); // vec-scalar x
friend Vcr operator*<complex<double> >
(const Vcr&, const Vcr&); // component-wise x
friend Vcr operator/<complex<double> >
(const Vcr&, complex<double>); // vec-scalar /
friend ostream& operator<<<complex<double> >
(ostream&, const Vcr&);
};
*/
//***** some usefull small functions and parameters *******
//*** report error and exit with return value 1.
template<class T> void error(const T& t) {
//template<class T> void error(const T& t, ostream& s = cout) {
cout << t << ". program exited." << "\n";
exit(1);
}
//const double SMALL = numeric_limits<double>::epsilon();
const double SMALL = 1.0e-15;
// *** definitions for members of class FullMtx
template<class T>
FullMtx<T>::FullMtx(int n, int m, T** dbp) {
nrows = n;
ncols = m;
mx = new T* [nrows];
for (int i = 0; i< nrows; i++) {
mx[i] = new T [ncols];
for (int j = 0; j < ncols; j++) mx[i][j] = dbp[i][j];
}
}
template<class T>
FullMtx<T>::FullMtx(int n, int m, T a) {
nrows = n;
ncols = m;
mx = new T* [nrows];
for (int i = 0; i< nrows; i++) {
mx[i] = new T [ncols];
for (int j = 0; j < ncols; j++) mx[i][j] = a;
}
}
template<class T>
FullMtx<T>::FullMtx(const FullMtx& mat) {
nrows = mat.nrows;
ncols = mat.ncols;
mx = new T* [nrows];
for (int i = 0; i< nrows; i++) {
mx[i] = new T [ncols];
for (int j = 0; j < ncols; j++) mx[i][j] = mat[i][j];
}
}
template<class T>
FullMtx<T> & FullMtx<T>::operator=(const FullMtx & mat) {
if (this != &mat) {
if (nrows !=mat.nrows || ncols !=mat.ncols)
error("bad matrix sizes in FullMtx::operator=()");
for (int i = 0; i < nrows; i++)
for (int j = 0; j < ncols; j++)
mx[i][j] = mat.mx[i][j];
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?