*** empty log message ***
This commit is contained in:
parent
a235d4cb98
commit
6e2727f595
14
conjgrad.h
Normal file
14
conjgrad.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#include "vec.h"
|
||||||
|
#include "smat.h"
|
||||||
|
#include "mat.h"
|
||||||
|
#include "sparsemat.h"
|
||||||
|
#include "nonclass.h"
|
||||||
|
|
||||||
|
//conjugate gradient solution of a linear system
|
||||||
|
|
||||||
|
//matrix can be any class which has nrows(), ncols(), diagonalof() and NRVec::gemv() available
|
||||||
|
//does not even have to be explicitly stored
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T, typename Matrix>
|
||||||
|
extern void conjgrad(const Matrix &bigmat, const NRVec<T> &b, NRVec<T> &x, const bool doguess, const double tol, const int itmax, const bool verbose, bool issquare,const bool precondition);
|
2
gmres.h
2
gmres.h
@ -10,4 +10,4 @@
|
|||||||
//does not even have to be explicitly stored
|
//does not even have to be explicitly stored
|
||||||
|
|
||||||
template<typename T, typename Matrix>
|
template<typename T, typename Matrix>
|
||||||
extern void gmres(const Matrix &bigmat, const NRVec<T> &b, NRVec<T> &x, const bool doguess=1, const double eps=1e-7, const int MAXIT=50, int neustart=0, const bool verbose=1, bool square=1,const bool precondition=1);
|
extern void gmres(const Matrix &bigmat, const NRVec<T> &b, NRVec<T> &x, const bool doguess=1, const double eps=1e-7, const int MAXIT=50, const bool verbose=1, bool square=1,const bool precondition=1, int neustart=0);
|
||||||
|
16
laerror.cc
Normal file
16
laerror.cc
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// LA errorr handler
|
||||||
|
#include <iostream>
|
||||||
|
#include "laerror.h"
|
||||||
|
void laerror(const char *s1)
|
||||||
|
{
|
||||||
|
std::cerr << "LA:ERROR - ";
|
||||||
|
if(!s1)
|
||||||
|
std::cerr << "udefined.\n";
|
||||||
|
else {
|
||||||
|
if(s1) std::cerr << s1;
|
||||||
|
std::cerr << "\n";
|
||||||
|
}
|
||||||
|
throw LAerror(s1);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
14
laerror.h
Normal file
14
laerror.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef _LAERROR_H_
|
||||||
|
#define _LAERROR_H_
|
||||||
|
|
||||||
|
//exception class for laerror
|
||||||
|
class LAerror
|
||||||
|
{
|
||||||
|
const char *msg;
|
||||||
|
public:
|
||||||
|
LAerror(const char *s) {msg=s;};
|
||||||
|
};
|
||||||
|
|
||||||
|
extern void laerror(const char *);
|
||||||
|
|
||||||
|
#endif
|
20
mat.cc
20
mat.cc
@ -743,28 +743,38 @@ const complex<double> NRMat< complex<double> >::trace() const
|
|||||||
|
|
||||||
//get diagonal; for compatibility with large matrices do not return newly created object
|
//get diagonal; for compatibility with large matrices do not return newly created object
|
||||||
//for non-square get diagonal of A^TA, will be used as preconditioner
|
//for non-square get diagonal of A^TA, will be used as preconditioner
|
||||||
void NRMat<double>::diagonalof(NRVec<double> &r) const
|
void NRMat<double>::diagonalof(NRVec<double> &r, const bool divide) const
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (r.size() != nn) laerror("diagonalof() incompatible vector");
|
if (r.size() != nn) laerror("diagonalof() incompatible vector");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
double a;
|
||||||
|
|
||||||
|
r.copyonwrite();
|
||||||
|
|
||||||
if(nn==mm)
|
if(nn==mm)
|
||||||
{
|
{
|
||||||
#ifdef MATPTR
|
#ifdef MATPTR
|
||||||
for (int i=0; i< nn; i++) r[i] = v[i][i];
|
if(divide) for (int i=0; i< nn; i++) if((a=v[i][i])) r[i]/=a;
|
||||||
|
else for (int i=0; i< nn; i++) r[i] = v[i][i];
|
||||||
#else
|
#else
|
||||||
{int i,j; for (i=j=0; j< nn; ++j, i+=nn+1) r[j] = v[i];}
|
if(divide) {int i,j; for (i=j=0; j< nn; ++j, i+=nn+1) if((a=v[i])) r[j] /=a;}
|
||||||
|
else {int i,j; for (i=j=0; j< nn; ++j, i+=nn+1) r[j] = v[i];}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else //non-square
|
else //non-square
|
||||||
{
|
{
|
||||||
for (int i=0; i< mm; i++)
|
for (int i=0; i< mm; i++)
|
||||||
|
{
|
||||||
#ifdef MATPTR
|
#ifdef MATPTR
|
||||||
r[i] = cblas_ddot(nn,v[0]+i,mm,v[0]+i,mm);
|
a= cblas_ddot(nn,v[0]+i,mm,v[0]+i,mm);
|
||||||
#else
|
#else
|
||||||
r[i] = cblas_ddot(nn,v+i,mm,v+i,mm);
|
a=cblas_ddot(nn,v+i,mm,v+i,mm);
|
||||||
#endif
|
#endif
|
||||||
|
if(divide) {if(a) r[i]/=a;}
|
||||||
|
else r[i] = a;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
2
mat.h
2
mat.h
@ -58,7 +58,7 @@ public:
|
|||||||
const NRVec<T> operator*(const NRVec<T> &rhs) const; // Mat * Vec
|
const NRVec<T> operator*(const NRVec<T> &rhs) const; // Mat * Vec
|
||||||
const NRVec<T> rsum() const; //sum of rows
|
const NRVec<T> rsum() const; //sum of rows
|
||||||
const NRVec<T> csum() const; //sum of columns
|
const NRVec<T> csum() const; //sum of columns
|
||||||
void diagonalof(NRVec<T> &) const; //get diagonal
|
void diagonalof(NRVec<T> &, const bool divide=0) const; //get diagonal
|
||||||
inline T* operator[](const int i); //subscripting: pointer to row i
|
inline T* operator[](const int i); //subscripting: pointer to row i
|
||||||
inline const T* operator[](const int i) const;
|
inline const T* operator[](const int i) const;
|
||||||
inline T& operator()(const int i, const int j); // (i,j) subscripts
|
inline T& operator()(const int i, const int j); // (i,j) subscripts
|
||||||
|
17
nonclass.cc
17
nonclass.cc
@ -98,23 +98,6 @@ void lawritemat(FILE *file,const T *a,int r,int c,const char *form0,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// LA errorr handler
|
|
||||||
void laerror(const char *s1, const char *s2, const char *s3, const char *s4)
|
|
||||||
{
|
|
||||||
std::cerr << "LA:ERROR - ";
|
|
||||||
if(!s1)
|
|
||||||
std::cerr << "udefined.";
|
|
||||||
else {
|
|
||||||
if(s1) std::cerr << s1;
|
|
||||||
if(s2) std::cerr << s2;
|
|
||||||
if(s3) std::cerr << s3;
|
|
||||||
if(s4) std::cerr << s4;
|
|
||||||
}
|
|
||||||
std::cerr << endl;
|
|
||||||
//@@@throw
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////
|
//////////////////////
|
||||||
// LAPACK interface //
|
// LAPACK interface //
|
||||||
//////////////////////
|
//////////////////////
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "smat.h"
|
#include "smat.h"
|
||||||
#include "mat.h"
|
#include "mat.h"
|
||||||
|
|
||||||
|
|
||||||
//MISC
|
//MISC
|
||||||
export template <class T>
|
export template <class T>
|
||||||
const NRMat<T> diagonalmatrix(const NRVec<T> &x)
|
const NRMat<T> diagonalmatrix(const NRVec<T> &x)
|
||||||
@ -51,6 +52,8 @@ extern T trace2(const NRMat<T> &a, const NRMat<T> &b, bool trb=0); \
|
|||||||
extern T trace2(const NRSMat<T> &a, const NRSMat<T> &b, const bool diagscaled=0);\
|
extern T trace2(const NRSMat<T> &a, const NRSMat<T> &b, const bool diagscaled=0);\
|
||||||
extern void linear_solve(NRMat<T> &a, NRMat<T> *b, double *det=0); \
|
extern void linear_solve(NRMat<T> &a, NRMat<T> *b, double *det=0); \
|
||||||
extern void linear_solve(NRSMat<T> &a, NRMat<T> *b, double *det=0); \
|
extern void linear_solve(NRSMat<T> &a, NRMat<T> *b, double *det=0); \
|
||||||
|
extern void linear_solve(NRMat<T> &a, NRVec<T> &b, double *det=0); \
|
||||||
|
extern void linear_solve(NRSMat<T> &a, NRVec<T> &b, double *det=0); \
|
||||||
extern void diagonalize(NRMat<T> &a, NRVec<T> &w, const bool eivec=1, const bool corder=1, int n=0); \
|
extern void diagonalize(NRMat<T> &a, NRVec<T> &w, const bool eivec=1, const bool corder=1, int n=0); \
|
||||||
extern void diagonalize(NRSMat<T> &a, NRVec<T> &w, NRMat<T> *v, const bool corder=1);\
|
extern void diagonalize(NRSMat<T> &a, NRVec<T> &w, NRMat<T> *v, const bool corder=1);\
|
||||||
extern void singular_decomposition(NRMat<T> &a, NRMat<T> *u, NRVec<T> &s,\
|
extern void singular_decomposition(NRMat<T> &a, NRMat<T> *u, NRVec<T> &s,\
|
||||||
|
8
smat.cc
8
smat.cc
@ -45,11 +45,17 @@ NRSMat<T> & NRSMat<T>::operator=(const T &a)
|
|||||||
|
|
||||||
//get diagonal
|
//get diagonal
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void NRSMat<T>::diagonalof(NRVec<T> &r) const
|
void NRSMat<T>::diagonalof(NRVec<T> &r, const bool divide) const
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if(r.size()!=nn) laerror("incompatible vector in diagonalof()");
|
if(r.size()!=nn) laerror("incompatible vector in diagonalof()");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
r.copyonwrite();
|
||||||
|
|
||||||
|
if (divide)
|
||||||
|
for (int i=0; i<nn; i++) {T a =v[i*(i+1)/2+i]; if(a!=0.) r[i] /= a;}
|
||||||
|
else
|
||||||
for (int i=0; i<nn; i++) r[i] = v[i*(i+1)/2+i];
|
for (int i=0; i<nn; i++) r[i] = v[i*(i+1)/2+i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
smat.h
2
smat.h
@ -43,7 +43,7 @@ public:
|
|||||||
const NRMat<T> operator*(const NRMat<T> &rhs) const; // SMat*Mat
|
const NRMat<T> operator*(const NRMat<T> &rhs) const; // SMat*Mat
|
||||||
const T dot(const NRSMat &rhs) const; // Smat.Smat
|
const T dot(const NRSMat &rhs) const; // Smat.Smat
|
||||||
const NRVec<T> operator*(const NRVec<T> &rhs) const;
|
const NRVec<T> operator*(const NRVec<T> &rhs) const;
|
||||||
void diagonalof(NRVec<T> &) const; //get diagonal
|
void diagonalof(NRVec<T> &, const bool divide=0) const; //get diagonal
|
||||||
inline const T& operator[](const int ij) const;
|
inline const T& operator[](const int ij) const;
|
||||||
inline T& operator[](const int ij);
|
inline T& operator[](const int ij);
|
||||||
inline const T& operator()(const int i, const int j) const;
|
inline const T& operator()(const int i, const int j) const;
|
||||||
|
18
sparsemat.cc
18
sparsemat.cc
@ -486,26 +486,36 @@ for(i=0;i<nn;++i)
|
|||||||
|
|
||||||
|
|
||||||
//get diagonal, do not construct a new object, but store in existing one, important for huge CI matrices
|
//get diagonal, do not construct a new object, but store in existing one, important for huge CI matrices
|
||||||
|
// with the divide option is used as a preconditioner, another choice of preconditioner is possible
|
||||||
template <class T>
|
template <class T>
|
||||||
void SparseMat<T>::diagonalof(NRVec<T> &r) const
|
void SparseMat<T>::diagonalof(NRVec<T> &r, const bool divide) const
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if((int)mm!=r.size()) laerror("incompatible vector size in diagonalof()");
|
if((int)mm!=r.size()) laerror("incompatible vector size in diagonalof()");
|
||||||
#endif
|
#endif
|
||||||
matel<T> *l=list;
|
matel<T> *l=list;
|
||||||
r=(T)0;
|
NRVec<T> *rr;
|
||||||
|
|
||||||
|
r.copyonwrite();
|
||||||
|
if(divide) {rr=new NRVec<T>(mm); *rr=(T)0;}
|
||||||
|
else {r=(T)0; rr=&r;}
|
||||||
if(nn==mm) //square
|
if(nn==mm) //square
|
||||||
while(l)
|
while(l)
|
||||||
{
|
{
|
||||||
if(l->row == l->col) r[l->row]+= l->elem;
|
if(l->row == l->col) (*rr)[l->row]+= l->elem;
|
||||||
l= l->next;
|
l= l->next;
|
||||||
}
|
}
|
||||||
else //diagonal of A^TA, assuming it has been simplified (only one entry per position), will be used as preconditioner only anyway
|
else //diagonal of A^TA, assuming it has been simplified (only one entry per position), will be used as preconditioner only anyway
|
||||||
while(l)
|
while(l)
|
||||||
{
|
{
|
||||||
r[l->col] += l->elem*l->elem *(l->col!=l->row && symmetric?2.:1.);
|
(*rr)[l->col] += l->elem*l->elem *(l->col!=l->row && symmetric?2.:1.);
|
||||||
l= l->next;
|
l= l->next;
|
||||||
}
|
}
|
||||||
|
if(divide)
|
||||||
|
{
|
||||||
|
for(unsigned int i=0; i<mm; ++i) if((*rr)[i]!=0.) r[i]/=(*rr)[i];
|
||||||
|
delete rr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ public:
|
|||||||
inline const SparseMat operator-(const SparseMat &rhs) const {return SparseMat(*this) -= rhs;} //must not be symmetric+general
|
inline const SparseMat operator-(const SparseMat &rhs) const {return SparseMat(*this) -= rhs;} //must not be symmetric+general
|
||||||
const NRVec<T> multiplyvector(const NRVec<T> &rhs, const bool transp=0) const; //sparse matrix * dense vector optionally transposed
|
const NRVec<T> multiplyvector(const NRVec<T> &rhs, const bool transp=0) const; //sparse matrix * dense vector optionally transposed
|
||||||
inline const NRVec<T> operator*(const NRVec<T> &rhs) const {return multiplyvector(rhs);} //sparse matrix * dense vector
|
inline const NRVec<T> operator*(const NRVec<T> &rhs) const {return multiplyvector(rhs);} //sparse matrix * dense vector
|
||||||
void diagonalof(NRVec<T> &) const; //get diagonal
|
void diagonalof(NRVec<T> &, const bool divide=0) const; //get diagonal
|
||||||
const SparseMat operator*(const SparseMat &rhs) const;
|
const SparseMat operator*(const SparseMat &rhs) const;
|
||||||
void gemm(const T beta, const SparseMat &a, const char transa, const SparseMat &b, const char transb, const T alpha);//this := alpha*op( A )*op( B ) + beta*this, if this is symemtric, only half will be added onto it
|
void gemm(const T beta, const SparseMat &a, const char transa, const SparseMat &b, const char transb, const T alpha);//this := alpha*op( A )*op( B ) + beta*this, if this is symemtric, only half will be added onto it
|
||||||
const T dot(const SparseMat &rhs) const; //supervector dot product
|
const T dot(const SparseMat &rhs) const; //supervector dot product
|
||||||
|
69
t.cc
69
t.cc
@ -7,6 +7,8 @@
|
|||||||
#include "matexp.h"
|
#include "matexp.h"
|
||||||
#include "fourindex.h"
|
#include "fourindex.h"
|
||||||
#include "davidson.h"
|
#include "davidson.h"
|
||||||
|
#include "gmres.h"
|
||||||
|
#include "conjgrad.h"
|
||||||
|
|
||||||
|
|
||||||
extern void test(const NRVec<double> &x);
|
extern void test(const NRVec<double> &x);
|
||||||
@ -42,6 +44,10 @@ NRVec<double> x(1.,10);
|
|||||||
NRVec<double> y(2.,10);
|
NRVec<double> y(2.,10);
|
||||||
NRVec<double> z(-2.,10);
|
NRVec<double> z(-2.,10);
|
||||||
|
|
||||||
|
cout.setf(ios::fixed);
|
||||||
|
cout.precision(12);
|
||||||
|
|
||||||
|
|
||||||
if(0) test(x);
|
if(0) test(x);
|
||||||
|
|
||||||
y.axpy(3,x);
|
y.axpy(3,x);
|
||||||
@ -785,7 +791,7 @@ cout <<v;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(1)
|
if(0)
|
||||||
{
|
{
|
||||||
int n,m;
|
int n,m;
|
||||||
cin>>n >>m;
|
cin>>n >>m;
|
||||||
@ -800,16 +806,65 @@ for(int i=0;i<n;++i) for(int j=0;j<=i;++j)
|
|||||||
}
|
}
|
||||||
|
|
||||||
NRMat<double> aa=a;
|
NRMat<double> aa=a;
|
||||||
cout <<aa;
|
|
||||||
diagonalize(aa,rr);
|
diagonalize(aa,rr);
|
||||||
cout <<aa;
|
|
||||||
cout <<rr;
|
|
||||||
|
|
||||||
NRVec<double> r(m);
|
NRVec<double> r(m);
|
||||||
NRVec<double> *eivecs = new NRVec<double>[m];
|
NRVec<double> *eivecs = new NRVec<double>[m];
|
||||||
davidson(a,eivecs,r,m);
|
davidson(a,r,eivecs,m,1);
|
||||||
|
|
||||||
|
cout <<"Davidson energies " <<r;
|
||||||
|
cout <<"Exact energies " ;
|
||||||
|
for(int i=0; i<m; ++i) cout <<rr[i]<<" ";
|
||||||
|
cout <<endl;
|
||||||
|
|
||||||
|
cout <<"Eigenvectors compare:\n";
|
||||||
|
for(int i=0; i<m; ++i)
|
||||||
|
{
|
||||||
|
cout <<eivecs[i];
|
||||||
|
for(int j=0; j<n;++j) cout <<aa[j][i]<<" ";
|
||||||
|
cout <<endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(1)
|
||||||
|
{
|
||||||
|
int n,m;
|
||||||
|
cin>>n >>m;
|
||||||
|
NRMat<double> a(n,m);
|
||||||
|
NRVec<double> b(n);
|
||||||
|
NRVec<double> x(m);
|
||||||
|
|
||||||
|
for(int i=0;i<n;++i) for(int j=0;j<m;++j)
|
||||||
|
{
|
||||||
|
//a(j,i)= 2*i*i*i-5*j+ +9*8*7*6*5*4*3*2/(i+j+1.)+3*(i*i+2*j*j*j);
|
||||||
|
a(i,j)= random()/(1.+RAND_MAX);
|
||||||
|
if(i==j) a(i,i)+= .5*(i-n);
|
||||||
|
}
|
||||||
|
for(int i=0;i<n;++i) b[i] = i;
|
||||||
|
|
||||||
|
NRVec<double> bb=b;
|
||||||
|
//cout <<a;
|
||||||
|
//cout <<b;
|
||||||
|
NRMat<double>aa=a;
|
||||||
|
linear_solve(aa,bb);
|
||||||
|
//cout <<bb;
|
||||||
|
//gmres (a,b,x,1,1e-10,100,1,0,1,0);
|
||||||
|
conjgrad(a,b,x,1,1e-10,200,1,0,1);
|
||||||
|
|
||||||
|
cout <<"\nsolution compare:\n";
|
||||||
|
for(int i=0; i<m; ++i)
|
||||||
|
{
|
||||||
|
cout <<"iterative solver: ";
|
||||||
|
cout <<x[i];
|
||||||
|
cout <<" direct solver:";
|
||||||
|
cout <<bb[i];
|
||||||
|
cout <<endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
cout <<r;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
3
vec.h
3
vec.h
@ -1,7 +1,7 @@
|
|||||||
#ifndef _LA_VEC_H_
|
#ifndef _LA_VEC_H_
|
||||||
#define _LA_VEC_H_
|
#define _LA_VEC_H_
|
||||||
|
|
||||||
|
#include "laerror.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "cblas.h"
|
#include "cblas.h"
|
||||||
@ -20,7 +20,6 @@ template <typename T> class SparseMat;
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
void laerror(const char *s1=0, const char *s2=0, const char *s3=0, const char *s4=0);
|
|
||||||
template <typename T> void lawritemat(FILE *file,const T *a,int r,int c,
|
template <typename T> void lawritemat(FILE *file,const T *a,int r,int c,
|
||||||
const char *form0,int nodim,int modulo, int issym);
|
const char *form0,int nodim,int modulo, int issym);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user