*** empty log message ***
This commit is contained in:
parent
e49b73e9e9
commit
d55727cb83
45
matexp.h
45
matexp.h
@ -248,28 +248,43 @@ return r;
|
|||||||
|
|
||||||
//this simple implementation seems not to be numerically stable enough
|
//this simple implementation seems not to be numerically stable enough
|
||||||
//and probably not efficient either
|
//and probably not efficient either
|
||||||
|
//@@@ make more efficient - for nilpotent mat at known power and
|
||||||
|
|
||||||
template<class M, class V>
|
template<class M, class V>
|
||||||
const V exptimesnaive(const M &mat, V vec) //uses just matrix vector multiplication
|
void exptimesdestructive(const M &mat, V &result, V &rhs, bool transpose=false, const double scale=1. ) //uses just matrix vector multiplication
|
||||||
{
|
{
|
||||||
if(mat.nrows()!=mat.ncols()||(unsigned int) mat.nrows() != (unsigned int)vec.size()) laerror("inappropriate sizes in exptimes");
|
if(mat.nrows()!=mat.ncols()||(unsigned int) mat.nrows() != (unsigned int)rhs.size()) laerror("inappropriate sizes in exptimes");
|
||||||
|
|
||||||
int power;
|
int power;
|
||||||
//prepare the polynom of and effectively scale the matrix
|
//prepare the polynom of and effectively scale the matrix
|
||||||
NRVec<typename LA_traits<V>::elementtype> taylor2=exp_aux<M,typename LA_traits<V>::elementtype>(mat,power);
|
NRVec<typename LA_traits<V>::elementtype> taylor2=exp_aux<M,typename LA_traits<V>::elementtype>(mat,power);
|
||||||
|
cerr <<"test power "<<power<<endl;
|
||||||
|
|
||||||
|
V tmp;
|
||||||
|
|
||||||
V result(mat.nrows());
|
|
||||||
for(int i=1; i<=(1<<power); ++i) //unfortunatelly, here we have to repeat it many times, unlike if the matrix is stored explicitly
|
for(int i=1; i<=(1<<power); ++i) //unfortunatelly, here we have to repeat it many times, unlike if the matrix is stored explicitly
|
||||||
{
|
{
|
||||||
if(i>1) vec=result; //apply again to the result of previous application
|
if(i>1) rhs=result; //apply again to the result of previous application
|
||||||
//apply polynom of the matrix to the vector iteratively
|
else result=rhs;
|
||||||
V y=vec;
|
tmp=rhs; //now rhs can be used as scratch
|
||||||
result=y*taylor2[0];
|
result*=taylor2[0];
|
||||||
for(int j=1; j<taylor2.size(); ++j)
|
for(int j=1; j<taylor2.size(); ++j)
|
||||||
{
|
{
|
||||||
y=mat*y;
|
mat.gemv(0.,rhs,transpose?'t':'n',scale,tmp);
|
||||||
result.axpy(taylor2[j],y);
|
tmp=rhs;
|
||||||
|
result.axpy(taylor2[j],tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class M, class V>
|
||||||
|
const V exptimes(const M &mat, V rhs, bool transpose=false, const double scale=1.)
|
||||||
|
{
|
||||||
|
V result;
|
||||||
|
exptimesdestructive(mat,result,rhs,transpose,scale);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,8 +294,7 @@ return result;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef EXPOKIT
|
||||||
|
|
||||||
//this comes from dgexpv from expokit, it had to be translated to C to make a template
|
//this comes from dgexpv from expokit, it had to be translated to C to make a template
|
||||||
// dgexpv.f -- translated by f2c (version 20030320).
|
// dgexpv.f -- translated by f2c (version 20030320).
|
||||||
|
|
||||||
@ -323,13 +337,13 @@ extern "C" void FORNAME(dnchbv)(int *, double *, double *, int *, double *, doub
|
|||||||
|
|
||||||
//partial template specialization leaving still free room for generic matrix type
|
//partial template specialization leaving still free room for generic matrix type
|
||||||
template<class M>
|
template<class M>
|
||||||
extern void exptimes(const M &mat, NRVec<double> &result, const NRVec<double> &rhs, bool transpose=false, const double t=1., int mxkrylov=0, double tol=1e-14, int mxstep=1000, int mxreject=0, int ideg=6)
|
extern void dgexpv(const M &mat, NRVec<double> &result, const NRVec<double> &rhs, bool transpose=false, const double t=1., int mxkrylov=0, double tol=1e-14, int mxstep=1000, int mxreject=0, int ideg=6)
|
||||||
{
|
{
|
||||||
if(mat.nrows()!= mat.ncols()) laerror("non-square matrix in exptimes");
|
if(mat.nrows()!= mat.ncols()) laerror("non-square matrix in exptimes");
|
||||||
int n=mat.nrows();
|
int n=mat.nrows();
|
||||||
int m;
|
int m;
|
||||||
if(mxkrylov) m=mxkrylov; else m= n>100? 100: n-1;
|
if(mxkrylov) m=mxkrylov; else m= n>100? 100: (n>1?n-1:1);
|
||||||
if (m >= n || m <= 0) laerror("illegal mxkrylov");
|
if (m > n || m <= 0) laerror("illegal mxkrylov");
|
||||||
if(result.size()!=n || rhs.size()!=n) laerror("inconsistent vector and matrix size in exptimes");
|
if(result.size()!=n || rhs.size()!=n) laerror("inconsistent vector and matrix size in exptimes");
|
||||||
|
|
||||||
const double *v=rhs;
|
const double *v=rhs;
|
||||||
@ -766,6 +780,9 @@ return;
|
|||||||
#undef FORNAME
|
#undef FORNAME
|
||||||
#undef pow_dd
|
#undef pow_dd
|
||||||
|
|
||||||
|
#endif
|
||||||
|
//EXPOKIT
|
||||||
|
|
||||||
|
|
||||||
//@@@ power series matrix logarithm?
|
//@@@ power series matrix logarithm?
|
||||||
|
|
||||||
|
@ -186,9 +186,9 @@ void cblas_dgemv(const enum CBLAS_ORDER Order,
|
|||||||
const double *X, const int incX, const double beta,
|
const double *X, const int incX, const double beta,
|
||||||
double *Y, const int incY)
|
double *Y, const int incY)
|
||||||
{
|
{
|
||||||
if(Order!=CblasRowMajor) laerror("CblasRowMajor order asserted");
|
if(Order!=CblasRowMajor) FORNAME(dgemv) (TransA==CblasNoTrans?"N":"T", &N, &M, &alpha, A, &lda, X, &incX, &beta, Y, &incY );
|
||||||
//swap n-m and toggle transposition
|
//swap n-m and toggle transposition
|
||||||
FORNAME(dgemv) (TransA==CblasNoTrans?"T":"N", &N, &M, &alpha, A, &lda, X, &incX, &beta, Y, &incY );
|
else FORNAME(dgemv) (TransA==CblasNoTrans?"T":"N", &N, &M, &alpha, A, &lda, X, &incX, &beta, Y, &incY );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
12
t.cc
12
t.cc
@ -675,8 +675,11 @@ int n;
|
|||||||
double f;
|
double f;
|
||||||
cin>>n >>f ;
|
cin>>n >>f ;
|
||||||
NRMat<double> a(n,n);
|
NRMat<double> a(n,n);
|
||||||
for(int i=0;i<n;++i) for(int j=0;j<n;++j)
|
NRVec<double>u(n),v,w;
|
||||||
|
for(int i=0;i<n;++i)
|
||||||
{
|
{
|
||||||
|
u[i]=f*random()/(1.+RAND_MAX);
|
||||||
|
for(int j=0;j<n;++j)
|
||||||
a(i,j)= f*random()/(1.+RAND_MAX);
|
a(i,j)= f*random()/(1.+RAND_MAX);
|
||||||
}
|
}
|
||||||
//cout <<"a matrix \n"<<a;
|
//cout <<"a matrix \n"<<a;
|
||||||
@ -695,6 +698,13 @@ c=exp(a,false);
|
|||||||
cout <<" tricky exp took "<<clock()/((double) (CLOCKS_PER_SEC))-t<<endl;
|
cout <<" tricky exp took "<<clock()/((double) (CLOCKS_PER_SEC))-t<<endl;
|
||||||
cout<<"error2 = "<<(c-b).norm()/b.norm()<<endl;
|
cout<<"error2 = "<<(c-b).norm()/b.norm()<<endl;
|
||||||
|
|
||||||
|
v=b*u;
|
||||||
|
t=clock()/((double) (CLOCKS_PER_SEC));
|
||||||
|
w=exptimes(a,u);
|
||||||
|
cout <<"exptimes took "<<clock()/((double) (CLOCKS_PER_SEC))-t<<endl;
|
||||||
|
cout <<"error of exptimes = "<<(v-w).norm()/v.norm()<<endl;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
6
vec.cc
6
vec.cc
@ -450,6 +450,7 @@ void NRVec<double>::gemv(const double beta, const NRMat<double> &A,
|
|||||||
if ((trans == 'n'?A.ncols():A.nrows()) != x.size())
|
if ((trans == 'n'?A.ncols():A.nrows()) != x.size())
|
||||||
laerror("incompatible sizes in gemv A*x");
|
laerror("incompatible sizes in gemv A*x");
|
||||||
#endif
|
#endif
|
||||||
|
copyonwrite();
|
||||||
cblas_dgemv(CblasRowMajor, (trans=='n' ? CblasNoTrans:CblasTrans),
|
cblas_dgemv(CblasRowMajor, (trans=='n' ? CblasNoTrans:CblasTrans),
|
||||||
A.nrows(), A.ncols(), alpha, A, A.ncols(), x.v, 1, beta, v, 1);
|
A.nrows(), A.ncols(), alpha, A, A.ncols(), x.v, 1, beta, v, 1);
|
||||||
}
|
}
|
||||||
@ -463,6 +464,7 @@ void NRVec< complex<double> >::gemv(const complex<double> beta,
|
|||||||
if ((trans == 'n'?A.ncols():A.nrows()) != x.size())
|
if ((trans == 'n'?A.ncols():A.nrows()) != x.size())
|
||||||
laerror("incompatible sizes in gemv A*x");
|
laerror("incompatible sizes in gemv A*x");
|
||||||
#endif
|
#endif
|
||||||
|
copyonwrite();
|
||||||
cblas_zgemv(CblasRowMajor, (trans=='n' ? CblasNoTrans:CblasTrans),
|
cblas_zgemv(CblasRowMajor, (trans=='n' ? CblasNoTrans:CblasTrans),
|
||||||
A.nrows(), A.ncols(), &alpha, A, A.ncols(),
|
A.nrows(), A.ncols(), &alpha, A, A.ncols(),
|
||||||
x.v, 1, &beta, v, 1);
|
x.v, 1, &beta, v, 1);
|
||||||
@ -476,7 +478,7 @@ void NRVec<double>::gemv(const double beta, const NRSMat<double> &A,
|
|||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (A.ncols()!=x.size()) laerror("incompatible dimension in gemv A*x");
|
if (A.ncols()!=x.size()) laerror("incompatible dimension in gemv A*x");
|
||||||
#endif
|
#endif
|
||||||
NRVec<double> result(nn);
|
copyonwrite();
|
||||||
cblas_dspmv(CblasRowMajor, CblasLower, A.ncols(), alpha, A, x.v, 1, beta, v, 1);
|
cblas_dspmv(CblasRowMajor, CblasLower, A.ncols(), alpha, A, x.v, 1, beta, v, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -489,7 +491,7 @@ void NRVec< complex<double> >::gemv(const complex<double> beta,
|
|||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (A.ncols()!=x.size()) laerror("incompatible dimension in gemv");
|
if (A.ncols()!=x.size()) laerror("incompatible dimension in gemv");
|
||||||
#endif
|
#endif
|
||||||
NRVec< complex<double> > result(nn);
|
copyonwrite();
|
||||||
cblas_zhpmv(CblasRowMajor, CblasLower, A.ncols(), &alpha, A,
|
cblas_zhpmv(CblasRowMajor, CblasLower, A.ncols(), &alpha, A,
|
||||||
x.v, 1, &beta, v, 1);
|
x.v, 1, &beta, v, 1);
|
||||||
}
|
}
|
||||||
|
20
vec.h
20
vec.h
@ -43,6 +43,7 @@ public:
|
|||||||
explicit inline NRVec(const int n) : nn(n), v(new T[n]), count(new int(1)) {};
|
explicit inline NRVec(const int n) : nn(n), v(new T[n]), count(new int(1)) {};
|
||||||
inline NRVec(const T &a, const int n);
|
inline NRVec(const T &a, const int n);
|
||||||
inline NRVec(const T *a, const int n);
|
inline NRVec(const T *a, const int n);
|
||||||
|
inline NRVec(T *a, const int n, bool skeleton);
|
||||||
inline NRVec(const NRVec &rhs);
|
inline NRVec(const NRVec &rhs);
|
||||||
inline explicit NRVec(const NRSMat<T> & S);
|
inline explicit NRVec(const NRSMat<T> & S);
|
||||||
#ifdef MATPTR
|
#ifdef MATPTR
|
||||||
@ -136,12 +137,29 @@ inline NRVec<T>::NRVec(const T& a, const int n) : nn(n), v(new T[n]), count(new
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline NRVec<T>::NRVec(const T *a, const int n) : nn(n), v(new T[n]), count(new int)
|
inline NRVec<T>::NRVec(const T *a, const int n) : nn(n), count(new int)
|
||||||
{
|
{
|
||||||
|
v=new T[n];
|
||||||
*count = 1;
|
*count = 1;
|
||||||
memcpy(v, a, n*sizeof(T));
|
memcpy(v, a, n*sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline NRVec<T>::NRVec(T *a, const int n, bool skeleton) : nn(n), count(new int)
|
||||||
|
{
|
||||||
|
if(!skeleton)
|
||||||
|
{
|
||||||
|
v=new T[n];
|
||||||
|
*count = 1;
|
||||||
|
memcpy(v, a, n*sizeof(T));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*count = 2;
|
||||||
|
v=a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline NRVec<T>::NRVec(const NRVec<T> &rhs)
|
inline NRVec<T>::NRVec(const NRVec<T> &rhs)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user