*** 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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user