continueing on permutations
This commit is contained in:
		
							parent
							
								
									83b9463334
								
							
						
					
					
						commit
						78c94f1e17
					
				
							
								
								
									
										245
									
								
								mat.cc
									
									
									
									
									
								
							
							
						
						
									
										245
									
								
								mat.cc
									
									
									
									
									
								
							| @ -27,6 +27,7 @@ | |||||||
| #include <fcntl.h> | #include <fcntl.h> | ||||||
| #include <errno.h> | #include <errno.h> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
|  | #include <math.h> | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| namespace LA { | namespace LA { | ||||||
| @ -2754,6 +2755,7 @@ NRMat<T>& NRMat<T>::swap_rows(){ | |||||||
|         return *this; |         return *this; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| /***************************************************************************//**
 | /***************************************************************************//**
 | ||||||
|  * interchange the order of the columns of the current (real) matrix |  * interchange the order of the columns of the current (real) matrix | ||||||
|  * @return reference to the modified matrix |  * @return reference to the modified matrix | ||||||
| @ -2925,6 +2927,61 @@ NRMat<T>& NRMat<T>::swap_rows(const int a, const int b){ | |||||||
|         return *this; |         return *this; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | /*rotate rows or columns of a matrix - general implementation, more efficient version could be done with BLAS scal and axpy operations
 | ||||||
|  |  *  but it would require allocation of temporary storage | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | template<typename T> | ||||||
|  | NRMat<T>& NRMat<T>::rotate_rows(const int a, const int b, const T phi){ | ||||||
|  |         T tmp1,tmp2; | ||||||
|  |         copyonwrite(); | ||||||
|  | 	T c=cos(phi); | ||||||
|  | 	T s=sin(phi); | ||||||
|  | #ifdef CUDALA | ||||||
|  |         if(location == cpu){ | ||||||
|  | #endif | ||||||
|  |                         for(register int j=0;j<mm;j++){ | ||||||
|  |                                 tmp1 = (*this)(a,j); | ||||||
|  |                                 tmp2 = (*this)(b,j); | ||||||
|  |                                 (*this)(a,j) = c*tmp1 + s*tmp2; | ||||||
|  |                                 (*this)(b,j) = c*tmp2 - s*tmp1; | ||||||
|  |                         } | ||||||
|  | #ifdef CUDALA | ||||||
|  |         }else{ | ||||||
|  | 		laerror("rotate_rows not implemented on gpu"); | ||||||
|  |         } | ||||||
|  | #endif | ||||||
|  |         return *this; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | template<typename T> | ||||||
|  | NRMat<T>& NRMat<T>::rotate_cols(const int a, const int b, const T phi){ | ||||||
|  |         T tmp1,tmp2; | ||||||
|  |         copyonwrite(); | ||||||
|  |         T c=cos(phi); | ||||||
|  |         T s=sin(phi); | ||||||
|  | #ifdef CUDALA | ||||||
|  |         if(location == cpu){ | ||||||
|  | #endif | ||||||
|  |                         for(register int j=0;j<nn;j++){ | ||||||
|  |                                 tmp1 = (*this)(j,a); | ||||||
|  |                                 tmp2 = (*this)(j,b); | ||||||
|  |                                 (*this)(j,a) = c*tmp1 + s*tmp2; | ||||||
|  |                                 (*this)(j,b) = c*tmp2 - s*tmp1; | ||||||
|  |                         } | ||||||
|  | #ifdef CUDALA | ||||||
|  |         }else{ | ||||||
|  |                 laerror("rotate_rows not implemented on gpu"); | ||||||
|  |         } | ||||||
|  | #endif | ||||||
|  |         return *this; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| /***************************************************************************//**
 | /***************************************************************************//**
 | ||||||
|  * interchange the order of the rows and columns of the current |  * interchange the order of the rows and columns of the current | ||||||
|  * real matrix \f$A\f$ of type T, i.e. perform the operation |  * real matrix \f$A\f$ of type T, i.e. perform the operation | ||||||
| @ -3075,9 +3132,23 @@ NRMat<T>& NRMat<T>::swap_rows_cols(){ | |||||||
|         return *this; |         return *this; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | //permutation matrix
 | ||||||
|  | template<typename T> | ||||||
|  | NRMat<T>::NRMat(const NRPerm<int> &p, const bool direction) | ||||||
|  | { | ||||||
|  | int n=p.size(); | ||||||
|  | resize(n,n); | ||||||
|  | clear(); | ||||||
|  | for(int i=0; i<n; ++i) | ||||||
|  | 	{ | ||||||
|  | 	if(direction) (*this)(i,p[i+1]-1)=1; | ||||||
|  | 	else (*this)(p[i+1]-1,i)=1; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| //apply permutations
 | //apply permutations
 | ||||||
| template<typename T> | template<typename T> | ||||||
| const NRMat<T> NRMat<T>::permute_rows(const NRPerm<int> &p) const | const NRMat<T> NRMat<T>::permuted_rows(const NRPerm<int> &p, const bool inverse) const | ||||||
| { | { | ||||||
| #ifdef DEBUG | #ifdef DEBUG | ||||||
| if(!p.is_valid()) laerror("invalid permutation of matrix"); | if(!p.is_valid()) laerror("invalid permutation of matrix"); | ||||||
| @ -3088,12 +3159,13 @@ if(n!=nn) laerror("incompatible permutation and matrix"); | |||||||
|         if(this->getlocation() != cpu || p.getlocation() != cpu ) laerror("permutations can be done only in CPU memory"); |         if(this->getlocation() != cpu || p.getlocation() != cpu ) laerror("permutations can be done only in CPU memory"); | ||||||
| #endif | #endif | ||||||
| NRMat<T> r(nn,mm); | NRMat<T> r(nn,mm); | ||||||
| for(int i=1; i<=n; ++i) {int pi=p[i]-1; for(int j=0; j<mm; ++j)  r(i-1,j) = (*this)(pi,j);} | if(inverse) for(int i=1; i<=n; ++i) {int pi=p[i]-1; for(int j=0; j<mm; ++j)  r(i-1,j) = (*this)(pi,j);} | ||||||
|  | else for(int i=1; i<=n; ++i) {int pi=p[i]-1; for(int j=0; j<mm; ++j)  r(pi,j) = (*this)(i-1,j);} | ||||||
| return r; | return r; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template<typename T> | template<typename T> | ||||||
| const NRMat<T> NRMat<T>::permute_cols(const NRPerm<int> &p) const | const NRMat<T> NRMat<T>::permuted_cols(const NRPerm<int> &p, const bool inverse) const | ||||||
| { | { | ||||||
| #ifdef DEBUG | #ifdef DEBUG | ||||||
| if(!p.is_valid()) laerror("invalid permutation of matrix"); | if(!p.is_valid()) laerror("invalid permutation of matrix"); | ||||||
| @ -3104,12 +3176,13 @@ if(n!=mm) laerror("incompatible permutation and matrix"); | |||||||
|         if(this->getlocation() != cpu || p.getlocation() != cpu ) laerror("permutations can be done only in CPU memory"); |         if(this->getlocation() != cpu || p.getlocation() != cpu ) laerror("permutations can be done only in CPU memory"); | ||||||
| #endif | #endif | ||||||
| NRMat<T> r(nn,mm); | NRMat<T> r(nn,mm); | ||||||
| for(int i=1; i<=n; ++i) {int pi=p[i]-1; for(int j=0; j<nn; ++j)  r(j,i-1) = (*this)(j,pi);} | if(inverse) for(int i=1; i<=n; ++i) {int pi=p[i]-1; for(int j=0; j<nn; ++j)  r(j,i-1) = (*this)(j,pi);} | ||||||
|  | else for(int i=1; i<=n; ++i) {int pi=p[i]-1; for(int j=0; j<nn; ++j)  r(j,pi) = (*this)(j,i-1);} | ||||||
| return r; | return r; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template<typename T> | template<typename T> | ||||||
| const NRMat<T> NRMat<T>::permute_both(const NRPerm<int> &p, const NRPerm<int> &q) const | const NRMat<T> NRMat<T>::permuted_both(const NRPerm<int> &p, const NRPerm<int> &q, const bool inverse) const | ||||||
| { | { | ||||||
| #ifdef DEBUG | #ifdef DEBUG | ||||||
| if(!p.is_valid() || !q.is_valid() ) laerror("invalid permutation of matrix"); | if(!p.is_valid() || !q.is_valid() ) laerror("invalid permutation of matrix"); | ||||||
| @ -3121,11 +3194,171 @@ if(n!=nn ||m!=mm) laerror("incompatible permutation and matrix"); | |||||||
|         if(this->getlocation() != cpu || p.getlocation() != cpu ) laerror("permutations can be done only in CPU memory"); |         if(this->getlocation() != cpu || p.getlocation() != cpu ) laerror("permutations can be done only in CPU memory"); | ||||||
| #endif | #endif | ||||||
| NRMat<T> r(nn,mm); | NRMat<T> r(nn,mm); | ||||||
| for(int i=1; i<=n; ++i) {int pi=p[i]-1; for(int j=1; j<=m; ++j)  r(i-1,j-1) = (*this)(pi,q[j]-1);} | if(inverse) for(int i=1; i<=n; ++i) {int pi=p[i]-1; for(int j=1; j<=m; ++j)  r(i-1,j-1) = (*this)(pi,q[j]-1);} | ||||||
|  | else for(int i=1; i<=n; ++i) {int pi=p[i]-1; for(int j=1; j<=m; ++j)  r(pi,q[j]-1) = (*this)(i-1,j-1);} | ||||||
| return r; | return r; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | template<typename T> | ||||||
|  | void NRMat<T>::permuteme_rows(const CyclePerm<int> &p) | ||||||
|  | { | ||||||
|  | #ifdef DEBUG | ||||||
|  | if(!p.is_valid()) laerror("invalid permutation of matrix"); | ||||||
|  | #endif | ||||||
|  | if(p.max()>nn) laerror("incompatible permutation and matrix"); | ||||||
|  | #ifdef CUDALA | ||||||
|  |         if(this->getlocation() != cpu || p.getlocation() != cpu ) laerror("permutations can be done only in CPU memory"); | ||||||
|  | #endif | ||||||
|  | copyonwrite(); | ||||||
|  | T *tmp = new T[mm]; | ||||||
|  | for(int cycle=1; cycle<=p.size(); ++cycle) | ||||||
|  |         { | ||||||
|  |         int length= p[cycle].size(); | ||||||
|  |         if(length<=1) continue; //trivial cycle
 | ||||||
|  |         for(int j=0; j<mm; ++j) tmp[j] = (*this)(p[cycle][length]-1,j); | ||||||
|  |         for(int i=length; i>1; --i)  | ||||||
|  | 		for(int j=0; j<mm; ++j) (*this)(p[cycle][i]-1,j)=(*this)(p[cycle][i-1]-1,j); | ||||||
|  | 	for(int j=0; j<mm; ++j) (*this)(p[cycle][1]-1,j)=tmp[j]; | ||||||
|  |         } | ||||||
|  | delete[] tmp; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | template<typename T> | ||||||
|  | void NRMat<T>::permuteme_cols(const CyclePerm<int> &p) | ||||||
|  | { | ||||||
|  | #ifdef DEBUG | ||||||
|  | if(!p.is_valid()) laerror("invalid permutation of matrix"); | ||||||
|  | #endif | ||||||
|  | if(p.max()>mm) laerror("incompatible permutation and matrix"); | ||||||
|  | #ifdef CUDALA | ||||||
|  |         if(this->getlocation() != cpu || p.getlocation() != cpu ) laerror("permutations can be done only in CPU memory"); | ||||||
|  | #endif | ||||||
|  | copyonwrite(); | ||||||
|  | T *tmp = new T[nn]; | ||||||
|  | for(int cycle=1; cycle<=p.size(); ++cycle) | ||||||
|  |         { | ||||||
|  |         int length= p[cycle].size(); | ||||||
|  |         if(length<=1) continue; //trivial cycle
 | ||||||
|  |         for(int j=0; j<nn; ++j) tmp[j] = (*this)(j,p[cycle][length]-1); | ||||||
|  |         for(int i=length; i>1; --i)  | ||||||
|  |                 for(int j=0; j<nn; ++j) (*this)(j,p[cycle][i]-1)=(*this)(j,p[cycle][i-1]-1); | ||||||
|  |         for(int j=0; j<nn; ++j) (*this)(j,p[cycle][1]-1)=tmp[j]; | ||||||
|  |         } | ||||||
|  | delete[] tmp; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //double and complex specialization
 | ||||||
|  | template<> | ||||||
|  | void NRMat<double>::scale_row(const int i, const double f) | ||||||
|  | { | ||||||
|  | #ifdef DEBUG | ||||||
|  | if(i<0||i>=nn) laerror("index out of range in scale_row"); | ||||||
|  | #endif | ||||||
|  | copyonwrite(); | ||||||
|  | #ifdef CUDALA | ||||||
|  |         if(location == cpu) { | ||||||
|  | #endif | ||||||
|  |                 cblas_dscal(mm, f, &(*this)(i,0), 1); | ||||||
|  | #ifdef CUDALA | ||||||
|  |         }else{ | ||||||
|  |                 cublasDscal(mm, f, v+i*mm, 1); | ||||||
|  |                 TEST_CUBLAS("cublasDscal"); | ||||||
|  |         } | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | template<> | ||||||
|  | void NRMat<double>::scale_col(const int i, const double f) | ||||||
|  | { | ||||||
|  | #ifdef DEBUG | ||||||
|  | if(i<0||i>=mm) laerror("index out of range in scale_col"); | ||||||
|  | #endif | ||||||
|  | copyonwrite(); | ||||||
|  | #ifdef CUDALA | ||||||
|  |         if(location == cpu) { | ||||||
|  | #endif | ||||||
|  |                 cblas_dscal(nn, f, &(*this)(0,i), mm); | ||||||
|  | #ifdef CUDALA | ||||||
|  |         }else{ | ||||||
|  |                 cublasDscal(nn, f, v+i, mm); | ||||||
|  |                 TEST_CUBLAS("cublasDscal"); | ||||||
|  |         } | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | template<> | ||||||
|  | void NRMat<std::complex<double> >::scale_row(const int i, const std::complex<double> f) | ||||||
|  | { | ||||||
|  | #ifdef DEBUG | ||||||
|  | if(i<0||i>=nn) laerror("index out of range in scale_row"); | ||||||
|  | #endif | ||||||
|  | copyonwrite(); | ||||||
|  | #ifdef CUDALA | ||||||
|  |         if(location == cpu) { | ||||||
|  | #endif | ||||||
|  |                 cblas_zscal(mm, &f, &(*this)(i,0), 1); | ||||||
|  | #ifdef CUDALA | ||||||
|  |         }else{ | ||||||
|  | 		const cuDoubleComplex fac = *(reinterpret_cast<const cuDoubleComplex*> (&f)); | ||||||
|  |                 cublasZscal(mm, &fac, v+i*mm, 1); | ||||||
|  |                 TEST_CUBLAS("cublasDscal"); | ||||||
|  |         } | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | template<> | ||||||
|  | void NRMat<std::complex<double> >::scale_col(const int i, const std::complex<double> f) | ||||||
|  | { | ||||||
|  | #ifdef DEBUG | ||||||
|  | if(i<0||i>=mm) laerror("index out of range in scale_col"); | ||||||
|  | #endif | ||||||
|  | copyonwrite(); | ||||||
|  | #ifdef CUDALA | ||||||
|  |         if(location == cpu) { | ||||||
|  | #endif | ||||||
|  |                 cblas_zscal(nn, &f, &(*this)(0,i), mm); | ||||||
|  | #ifdef CUDALA | ||||||
|  |         }else{ | ||||||
|  | 		const cuDoubleComplex fac = *(reinterpret_cast<const cuDoubleComplex*> (&f)); | ||||||
|  |                 cublasZscal(nn, &fac, v+i, mm); | ||||||
|  |                 TEST_CUBLAS("cublasDscal"); | ||||||
|  |         } | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //general version
 | ||||||
|  | template<typename T> | ||||||
|  | void NRMat<T>::scale_row(const int i, const T f) | ||||||
|  | { | ||||||
|  | #ifdef DEBUG | ||||||
|  | if(i<0||i>=nn) laerror("index out of range in scale_row"); | ||||||
|  | #endif | ||||||
|  | copyonwrite(); | ||||||
|  | for(int j=0; j<mm; ++j) (*this)(i,j) *= f; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | template<typename T> | ||||||
|  | void NRMat<T>::scale_col(const int i, const T f) | ||||||
|  | { | ||||||
|  | #ifdef DEBUG | ||||||
|  | if(i<0||i>=mm) laerror("index out of range in scale_col"); | ||||||
|  | #endif | ||||||
|  | copyonwrite(); | ||||||
|  | for(int j=0; j<nn; ++j) (*this)(j,i) *= f; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /***************************************************************************//**
 | /***************************************************************************//**
 | ||||||
|  | |||||||
							
								
								
									
										16
									
								
								mat.h
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								mat.h
									
									
									
									
									
								
							| @ -117,9 +117,14 @@ public: | |||||||
| 	void copyonwrite(bool detachonly=false); | 	void copyonwrite(bool detachonly=false); | ||||||
| 
 | 
 | ||||||
| 	//! permute matrix elements
 | 	//! permute matrix elements
 | ||||||
|         const NRMat permute_rows(const NRPerm<int> &p) const; |         const NRMat permuted_rows(const NRPerm<int> &p, const bool inverse=false) const; | ||||||
|         const NRMat permute_cols(const NRPerm<int> &p) const; |         const NRMat permuted_cols(const NRPerm<int> &p, const bool inverse=false) const; | ||||||
|         const NRMat permute_both(const NRPerm<int> &p, const NRPerm<int> &q) const; |         const NRMat permuted_both(const NRPerm<int> &p, const NRPerm<int> &q, const bool inverse=false) const; | ||||||
|  | 	void permuteme_rows(const CyclePerm<int> &p); //in place
 | ||||||
|  | 	void permuteme_cols(const CyclePerm<int> &p); //in place
 | ||||||
|  | 	void scale_row(const int i, const T f); //in place
 | ||||||
|  | 	void scale_col(const int i, const T f); //in place
 | ||||||
|  | 	explicit NRMat(const NRPerm<int> &p, const bool direction); //permutation matrix
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	/***************************************************************************//**
 | 	/***************************************************************************//**
 | ||||||
| @ -349,6 +354,11 @@ public: | |||||||
| 	// LV - swapping of rows i and j
 | 	// LV - swapping of rows i and j
 | ||||||
| 	NRMat & swap_rows(const int i, const int j); | 	NRMat & swap_rows(const int i, const int j); | ||||||
| 
 | 
 | ||||||
|  | 	//rotate rows or columns through an angle
 | ||||||
|  | 	NRMat & rotate_cols(const int i, const int j, const T phi); | ||||||
|  |         NRMat & rotate_rows(const int i, const int j, const T phi); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| 	//! multiply by sparse matrix
 | 	//! multiply by sparse matrix
 | ||||||
| 	SparseSMat<T> operator*(const SparseSMat<T> &rhs) const; | 	SparseSMat<T> operator*(const SparseSMat<T> &rhs) const; | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										153
									
								
								permutation.cc
									
									
									
									
									
								
							
							
						
						
									
										153
									
								
								permutation.cc
									
									
									
									
									
								
							| @ -17,6 +17,10 @@ | |||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| #include "permutation.h" | #include "permutation.h" | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <string.h> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| namespace LA { | namespace LA { | ||||||
| 
 | 
 | ||||||
| template <typename T> | template <typename T> | ||||||
| @ -27,6 +31,7 @@ T n=this->size(); | |||||||
|         if(n<0) laerror("invalid permutation size"); |         if(n<0) laerror("invalid permutation size"); | ||||||
| #endif | #endif | ||||||
| if(n==0) return; | if(n==0) return; | ||||||
|  | this->copyonwrite(); | ||||||
| for(T i=1; i<=n; ++i) (*this)[i]=i; | for(T i=1; i<=n; ++i) (*this)[i]=i; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -118,12 +123,14 @@ return (count&1)? -1:1; | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template <typename T> | template <typename T> | ||||||
| NRPerm<T>::NRPerm(const CyclePerm<T> &rhs, int n) | NRPerm<T>::NRPerm(const CyclePerm<T> &rhs, const int n) | ||||||
| : NRVec_from1<T>(n) |  | ||||||
| { | { | ||||||
| #ifdef DEBUG | #ifdef DEBUG | ||||||
|         if(!rhs.is_valid()) laerror("invalid cycle permutation"); |         if(!rhs.is_valid()) laerror("invalid cycle permutation"); | ||||||
| #endif | #endif | ||||||
|  | int m; | ||||||
|  | if(n) m=n; else m=rhs.max(); | ||||||
|  | this->resize(m); | ||||||
| 
 | 
 | ||||||
| identity(); | identity(); | ||||||
| T ncycles=rhs.size(); | T ncycles=rhs.size(); | ||||||
| @ -137,6 +144,22 @@ if(!is_valid()) laerror("internal error in NRPerm constructor from CyclePerm"); | |||||||
| #endif | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | template <typename T> | ||||||
|  | void NRPerm<T>::randomize(void) | ||||||
|  | { | ||||||
|  | int n=this->size(); | ||||||
|  | if(n<=0) laerror("cannot randomize empty permutation"); | ||||||
|  | this->copyonwrite(); | ||||||
|  | this->identity(); | ||||||
|  | for(int i=n-1; i>=1; --i) | ||||||
|  | 	{ | ||||||
|  | 	int j= random()%(i+1); | ||||||
|  | 	T tmp = (*this)[i+1]; | ||||||
|  | 	(*this)[i+1]=(*this)[j+1]; | ||||||
|  | 	(*this)[j+1]=tmp; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| ////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////
 | ||||||
| 
 | 
 | ||||||
| @ -150,7 +173,7 @@ T n=p.size(); | |||||||
| NRVec_from1<T> used(0,n),tmp(n); | NRVec_from1<T> used(0,n),tmp(n); | ||||||
| T firstunused=1; | T firstunused=1; | ||||||
| T currentcycle=0; | T currentcycle=0; | ||||||
| std::list<NRVec<T> > cyclelist={}; | std::list<NRVec_from1<T> > cyclelist={}; | ||||||
| do | do | ||||||
|         { |         { | ||||||
|         //find a cycle starting with first unused element
 |         //find a cycle starting with first unused element
 | ||||||
| @ -196,7 +219,7 @@ for(T i=1; i<=this->size(); ++i) | |||||||
| 		for(T ii=i; ii<=this->size(); ++ii) | 		for(T ii=i; ii<=this->size(); ++ii) | ||||||
| 			{ | 			{ | ||||||
| 			T nn=(*this)[ii].size(); | 			T nn=(*this)[ii].size(); | ||||||
| 			for(T jj=1; jj<=nn; ++jj) | 			for(T jj=(ii==i?j+1:1); jj<=nn; ++jj) | ||||||
| 				{ | 				{ | ||||||
| 				T xx=(*this)[ii][jj]; | 				T xx=(*this)[ii][jj]; | ||||||
| 				if(x==xx) return false; | 				if(x==xx) return false; | ||||||
| @ -233,11 +256,24 @@ for(T i=1; i<=ncycles; ++i) | |||||||
| 	{ | 	{ | ||||||
| 	T length=(*this)[i].size(); | 	T length=(*this)[i].size(); | ||||||
| 	r[i].resize(length); | 	r[i].resize(length); | ||||||
|  | 	//reverse order in cycles (does not matter in cycle lengths 1 and 2 anyway)
 | ||||||
| 	for(T j=1; j<=length; ++j) r[i][j] = (*this)[i][length-j+1]; | 	for(T j=1; j<=length; ++j) r[i][j] = (*this)[i][length-j+1]; | ||||||
| 	} | 	} | ||||||
| return r; | return r; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | //multiplication via NRPerm - could there be a more efficient direct algorithm?
 | ||||||
|  | template <typename T> | ||||||
|  | CyclePerm<T> CyclePerm<T>::operator*(const CyclePerm q) const | ||||||
|  | { | ||||||
|  | int m=this->max(); | ||||||
|  | int mm=q.max(); | ||||||
|  | if(mm>m) mm=m; | ||||||
|  | NRPerm<T> qq(q,m); | ||||||
|  | NRPerm<T> pp(*this,m); | ||||||
|  | NRPerm<T> rr=pp*qq; | ||||||
|  | return CyclePerm<T>(rr); | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| template <typename T> | template <typename T> | ||||||
| int CyclePerm<T>::parity() const | int CyclePerm<T>::parity() const | ||||||
| @ -271,12 +307,105 @@ for(T i=1; i<=ncycles; ++i) | |||||||
| 	r[length]++; | 	r[length]++; | ||||||
| 	} | 	} | ||||||
| //fill in trivial cycles of length one
 | //fill in trivial cycles of length one
 | ||||||
| r[1] = n - r.sum(); | r[1] += n - r.sum(); | ||||||
| if(r[1]<0) laerror("inconsistent cycle lengths in CyclePerm::cycles"); | if(r[1]<0) laerror("inconsistent cycle lengths in CyclePerm::cycles"); | ||||||
| return r; | return r; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | //auxiliary function for input of a permutation in cycle format
 | ||||||
|  | //returns pointer after closing bracket or NULL if no cycle found
 | ||||||
|  | //or input error
 | ||||||
|  | template <typename T> | ||||||
|  | const char *read1cycle(NRVec_from1<T> &c, const char *p) | ||||||
|  | { | ||||||
|  | if(*p==0) return NULL; | ||||||
|  | const char *openbracket = strchr(p,'('); | ||||||
|  | if(!openbracket) return NULL; | ||||||
|  | const char *closebracket = strchr(openbracket+1,')'); | ||||||
|  | if(!closebracket) return NULL; | ||||||
|  | const char *s = openbracket+1; | ||||||
|  | int r; | ||||||
|  | int length=0; | ||||||
|  | std::list<T> cycle; | ||||||
|  | do      { | ||||||
|  | 	long int tmp; | ||||||
|  |         int nchar; | ||||||
|  |         if(*s==',') ++s; | ||||||
|  |         r = sscanf(s,"%ld%n",&tmp,&nchar); | ||||||
|  |         if(r==1) | ||||||
|  |                 { | ||||||
|  |                 ++length; | ||||||
|  |                 s += nchar; | ||||||
|  | 		cycle.push_back((T)tmp); | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  |         while(r==1 && s<closebracket); | ||||||
|  | 
 | ||||||
|  | //make vector from list
 | ||||||
|  | c.resize(length); | ||||||
|  | int i=0; | ||||||
|  | for(auto l=cycle.begin(); l!=cycle.end(); ++l) c[++i] = *l; | ||||||
|  | 
 | ||||||
|  | return closebracket+1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | template <typename T> | ||||||
|  | void CyclePerm<T>::readfrom(const std::string &line) | ||||||
|  | { | ||||||
|  | const char *p=line.c_str(); | ||||||
|  | std::list<NRVec<T> > cyclelist={}; | ||||||
|  | int ncycles=0; | ||||||
|  | int count=0; | ||||||
|  | NRVec_from1<T> c; | ||||||
|  | while(p=read1cycle(c,p)) | ||||||
|  |         { | ||||||
|  |         //printf("cycle %d of length %d read\n",count,c.size());
 | ||||||
|  |         if(c.size()!=0) //store a nonempty cycle
 | ||||||
|  |                 { | ||||||
|  |                 ++count; | ||||||
|  | 		cyclelist.push_back(c); | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //convert list to vector
 | ||||||
|  | this->resize(count); | ||||||
|  | T i=0; | ||||||
|  | for(auto l=cyclelist.begin(); l!=cyclelist.end(); ++l) (*this)[++i] = *l; | ||||||
|  | #ifdef DEBUG | ||||||
|  | if(!this->is_valid()) laerror("readfrom received input of invalid CyclePerm"); | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | template <typename T> | ||||||
|  | std::istream & operator>>(std::istream &s, CyclePerm<T> &x) | ||||||
|  | { | ||||||
|  | std::string l; | ||||||
|  | getline(s,l); | ||||||
|  | x.readfrom(l); | ||||||
|  | return s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | template <typename T> | ||||||
|  | std::ostream & operator<<(std::ostream &s, const CyclePerm<T> &x) | ||||||
|  | { | ||||||
|  | for(int i=1; i<=x.size(); ++i) | ||||||
|  | 	{ | ||||||
|  | 	s<<"("; | ||||||
|  | 	for(int j=1; j<=x[i].size(); ++j) | ||||||
|  | 		{ | ||||||
|  | 		s<<x[i][j]; | ||||||
|  | 		if(j<x[i].size()) s<<" "; | ||||||
|  | 		} | ||||||
|  | 	s<<")"; | ||||||
|  | 	} | ||||||
|  | return s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| ///////////////////////////////////////////////////////
 | ///////////////////////////////////////////////////////
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -286,4 +415,16 @@ return r; | |||||||
| template class NRPerm<int>; | template class NRPerm<int>; | ||||||
| template class CyclePerm<int>; | template class CyclePerm<int>; | ||||||
| template class Partition<int>; | template class Partition<int>; | ||||||
| } | 
 | ||||||
|  | #define INSTANTIZE(T) \ | ||||||
|  | template std::istream & operator>>(std::istream &s, CyclePerm<T> &x); \ | ||||||
|  | template std::ostream & operator<<(std::ostream &s, const CyclePerm<T> &x); \ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | INSTANTIZE(int) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | }//namespace
 | ||||||
|  | |||||||
| @ -41,7 +41,7 @@ public: | |||||||
| 	NRPerm(const NRVec_from1<T> &rhs): NRVec_from1<T>(rhs) {}; | 	NRPerm(const NRVec_from1<T> &rhs): NRVec_from1<T>(rhs) {}; | ||||||
| 	NRPerm(const T &a, const int n): NRVec_from1<T>(a, n) {}; | 	NRPerm(const T &a, const int n): NRVec_from1<T>(a, n) {}; | ||||||
|         NRPerm(const T *a, const int n): NRVec_from1<T>(a, n) {}; |         NRPerm(const T *a, const int n): NRVec_from1<T>(a, n) {}; | ||||||
| 	NRPerm(const CyclePerm<T> &rhs, int n);  | 	explicit NRPerm(const CyclePerm<T> &rhs, const int n=0);  | ||||||
| 
 | 
 | ||||||
| 	//specific operations
 | 	//specific operations
 | ||||||
| 	void identity(); | 	void identity(); | ||||||
| @ -51,10 +51,10 @@ public: | |||||||
| 	NRPerm operator*(const NRPerm q) const; //q is rhs and applied first, this applied second
 | 	NRPerm operator*(const NRPerm q) const; //q is rhs and applied first, this applied second
 | ||||||
| 	NRPerm conjugate_by(const NRPerm q) const; //q^-1 p q
 | 	NRPerm conjugate_by(const NRPerm q) const; //q^-1 p q
 | ||||||
| 	int parity() const; | 	int parity() const; | ||||||
|  | 	void randomize(void); //uniformly random by Fisher-Yates shuffle
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	//TODO:
 | 	//TODO:
 | ||||||
| 	//@@@permutation matrix
 |  | ||||||
| 	//@@@permgener
 | 	//@@@permgener
 | ||||||
| 	//@@@next permutation
 | 	//@@@next permutation
 | ||||||
| 	//@@@lex rank
 | 	//@@@lex rank
 | ||||||
| @ -67,19 +67,27 @@ template <typename T> | |||||||
| class CyclePerm : public NRVec_from1<NRVec_from1<T> > { | class CyclePerm : public NRVec_from1<NRVec_from1<T> > { | ||||||
| public: | public: | ||||||
| 	CyclePerm() :  NRVec_from1<NRVec_from1<T> >() {}; | 	CyclePerm() :  NRVec_from1<NRVec_from1<T> >() {}; | ||||||
| 	CyclePerm(const NRPerm<T> &rhs); | 	explicit CyclePerm(const NRPerm<T> &rhs); | ||||||
| 
 | 
 | ||||||
| 	bool is_valid() const; //is it really a permutation
 | 	bool is_valid() const; //is it really a permutation
 | ||||||
| 	bool is_identity() const; //no cycles of length > 1
 | 	bool is_identity() const; //no cycles of length > 1
 | ||||||
| 	CyclePerm inverse() const; //reverse all cycles
 | 	CyclePerm inverse() const; //reverse all cycles
 | ||||||
| 	int parity() const; //negative if having odd number of even-length cycles
 | 	int parity() const; //negative if having odd number of even-length cycles
 | ||||||
|  | 	T max() const {T m=0; for(int i=1; i<=this->size(); ++i) {T mm= (*this)[i].max(); if(mm>m) m=mm;} return m;} | ||||||
| 	Partition<T> cycles(const T n) const; | 	Partition<T> cycles(const T n) const; | ||||||
| 	//@@@efficient algorithm for multiplication?
 | 	void readfrom(const std::string &line); | ||||||
| 	//@@@operator >> and <<
 | 	CyclePerm operator*(const CyclePerm q) const; //q is rhs and applied first, this applied second
 | ||||||
| 	//@@@operation in place on matrix and vector
 |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | template <typename T> | ||||||
|  | std::istream & operator>>(std::istream &s, CyclePerm<T> &x); | ||||||
|  | 
 | ||||||
|  | template <typename T> | ||||||
|  | std::ostream & operator<<(std::ostream &s, const CyclePerm<T> &x); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| //partitions stored as #of 1s, #of 2s, etc.
 | //partitions stored as #of 1s, #of 2s, etc.
 | ||||||
| template <typename T> | template <typename T> | ||||||
| class Partition : public NRVec_from1<T> { | class Partition : public NRVec_from1<T> { | ||||||
| @ -94,8 +102,8 @@ public: | |||||||
| //@@@generate all partitions, 
 | //@@@generate all partitions, 
 | ||||||
| //@@@enumerator of partitions of n to r parts and total
 | //@@@enumerator of partitions of n to r parts and total
 | ||||||
| //@@@adjoint partition, 
 | //@@@adjoint partition, 
 | ||||||
| //@@@ output as in the group character table
 | //@@@output formatted as in the group character table
 | ||||||
| //@@@Sn character table
 | //@@@Sn character table computation
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										5
									
								
								smat.cc
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								smat.cc
									
									
									
									
									
								
							| @ -305,7 +305,7 @@ void NRSMat<T>::fscanf(FILE *f, const char *format) { | |||||||
| 
 | 
 | ||||||
| //apply permutation
 | //apply permutation
 | ||||||
| template <typename T> | template <typename T> | ||||||
| const NRSMat<T> NRSMat<T>::permute(const NRPerm<int> &p) const | const NRSMat<T> NRSMat<T>::permuted(const NRPerm<int> &p, const bool inverse) const | ||||||
| { | { | ||||||
| #ifdef DEBUG | #ifdef DEBUG | ||||||
| if(!p.is_valid()) laerror("invalid permutation of smatrix"); | if(!p.is_valid()) laerror("invalid permutation of smatrix"); | ||||||
| @ -316,7 +316,8 @@ if(n!=(*this).size()) laerror("incompatible permutation and smatrix"); | |||||||
|         if(this->getlocation() != cpu || p.getlocation() != cpu ) laerror("permutations can be done only in CPU memory"); |         if(this->getlocation() != cpu || p.getlocation() != cpu ) laerror("permutations can be done only in CPU memory"); | ||||||
| #endif | #endif | ||||||
| NRSMat<T> r(n); | NRSMat<T> r(n); | ||||||
| for(int i=1; i<=n; ++i) {int pi = p[i]-1; r(i-1,i-1) = (*this)(pi,pi);} | if(inverse) for(int i=1; i<=n; ++i) {int pi = p[i]-1; r(i-1,i-1) = (*this)(pi,pi);} | ||||||
|  | else for(int i=1; i<=n; ++i) {int pi = p[i]-1; r(pi,pi) = (*this)(i-1,i-1);} | ||||||
| return r; | return r; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								smat.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								smat.h
									
									
									
									
									
								
							| @ -93,7 +93,7 @@ public: | |||||||
| 	NRSMat & operator=(const T &a); | 	NRSMat & operator=(const T &a); | ||||||
| 
 | 
 | ||||||
| 	//! permute matrix elements
 | 	//! permute matrix elements
 | ||||||
|         const NRSMat permute(const NRPerm<int> &p) const; |         const NRSMat permuted(const NRPerm<int> &p, const bool inverse=false) const; | ||||||
| 
 | 
 | ||||||
| 	inline int getcount() const {return count?*count:0;} | 	inline int getcount() const {return count?*count:0;} | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										63
									
								
								t.cc
									
									
									
									
									
								
							
							
						
						
									
										63
									
								
								t.cc
									
									
									
									
									
								
							| @ -1989,7 +1989,7 @@ c=a+b; | |||||||
| cout<<c; | cout<<c; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| if(1) | if(0) | ||||||
| { | { | ||||||
| NRPerm<int> p; | NRPerm<int> p; | ||||||
| cin >>p; | cin >>p; | ||||||
| @ -1997,8 +1997,67 @@ int n=p.size(); | |||||||
| NRVec_from1<double> v(n); | NRVec_from1<double> v(n); | ||||||
| int i; | int i; | ||||||
| for(i=1; i<=n; ++i) v[i]=10.*i; | for(i=1; i<=n; ++i) v[i]=10.*i; | ||||||
| cout <<v.permute(p); | cout <<v.permuted(p); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | if(0) | ||||||
|  | { | ||||||
|  | CyclePerm<int> c; | ||||||
|  | cin>>c; | ||||||
|  | cout<<c<<endl; | ||||||
|  | NRPerm<int> p(c); | ||||||
|  | cout <<p; | ||||||
|  | CyclePerm<int> cc(p); | ||||||
|  | cout <<cc<<endl; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | if(0) | ||||||
|  | { | ||||||
|  | int seed; | ||||||
|  | int f=open("/dev/random",O_RDONLY); | ||||||
|  | if(sizeof(int)!=read(f,&seed,sizeof(int))) laerror("cannot read /dev/random"); | ||||||
|  | close(f); | ||||||
|  | srand(seed); | ||||||
|  | int n; | ||||||
|  | cin >>n; | ||||||
|  | NRPerm<int> p(n); | ||||||
|  | p.randomize(); | ||||||
|  | cout <<p; | ||||||
|  | CyclePerm<int> cc(p); | ||||||
|  | cout <<cc<<endl; | ||||||
|  | NRPerm<int> pp(cc,n); | ||||||
|  | cout <<pp; | ||||||
|  | if(pp!=p) laerror("inconsistency"); | ||||||
|  | NRVec<double> v(n); | ||||||
|  | for(int i=0; i<n; ++i) v[i]=10.*(i+1); | ||||||
|  | NRVec<double> vv(v); | ||||||
|  | v.permuteme(cc); | ||||||
|  | cout <<v; | ||||||
|  | NRVec<double>  vvv= vv.permuted(pp); | ||||||
|  | cout<<vvv; | ||||||
|  | cout<<"error "<<(v-vvv).norm()<<endl; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | if(1) | ||||||
|  | { | ||||||
|  | int seed; | ||||||
|  | int f=open("/dev/random",O_RDONLY); | ||||||
|  | if(sizeof(int)!=read(f,&seed,sizeof(int))) laerror("cannot read /dev/random"); | ||||||
|  | close(f); | ||||||
|  | srand(seed); | ||||||
|  | int n; | ||||||
|  | cin >>n; | ||||||
|  | NRVec<double> v(n); | ||||||
|  | v.randomize(1.); | ||||||
|  | NRVec<double> vv(v); | ||||||
|  | NRPerm<int> p(n); | ||||||
|  | vv.sort(0,p); | ||||||
|  | NRVec<double> vvv=v.permuted(p,true); | ||||||
|  | NRVec<double> v4=vv.permuted(p,false); | ||||||
|  | cout<<v<<vv; | ||||||
|  | cout<<vvv<<v4<<p; | ||||||
|  | cout <<"error "<<(vv-vvv).norm() <<" "<<(v-v4).norm()<<endl; | ||||||
|  | 
 | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										69
									
								
								vec.cc
									
									
									
									
									
								
							
							
						
						
									
										69
									
								
								vec.cc
									
									
									
									
									
								
							| @ -815,6 +815,15 @@ int NRVec<T>::sort(int direction, int from, int to, int *perm) { | |||||||
| 	else return memqsort<0, NRVec<T>, int, int>(*this, perm, from, to); | 	else return memqsort<0, NRVec<T>, int, int>(*this, perm, from, to); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | template<typename T> | ||||||
|  | int NRVec<T>::sort(int direction, NRPerm<int> &perm) | ||||||
|  | { | ||||||
|  | if(nn!=perm.size()) laerror("incompatible vector and permutation"); | ||||||
|  | perm.identity(); | ||||||
|  | int r=sort(direction,0,nn-1,&perm[1]); | ||||||
|  | return r; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| template<> | template<> | ||||||
| NRVec<std::complex<double> > complexify(const NRVec<double> &rhs) { | NRVec<std::complex<double> > complexify(const NRVec<double> &rhs) { | ||||||
| 	NRVec<std::complex<double> > r(rhs.size(), rhs.getlocation()); | 	NRVec<std::complex<double> > r(rhs.size(), rhs.getlocation()); | ||||||
| @ -834,7 +843,7 @@ NRVec<std::complex<double> > complexify(const NRVec<double> &rhs) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template<typename T> | template<typename T> | ||||||
| const NRVec<T> NRVec<T>::permute(const NRPerm<int> &p) const | const NRVec<T> NRVec<T>::permuted(const NRPerm<int> &p, const bool inverse) const | ||||||
| { | { | ||||||
| #ifdef DEBUG | #ifdef DEBUG | ||||||
| if(!p.is_valid()) laerror("invalid permutation of vector"); | if(!p.is_valid()) laerror("invalid permutation of vector"); | ||||||
| @ -845,10 +854,34 @@ if(n!=(*this).size()) laerror("incompatible permutation and vector"); | |||||||
|         if(this->getlocation() != cpu || p.getlocation() != cpu ) laerror("permutations can be done only in CPU memory"); |         if(this->getlocation() != cpu || p.getlocation() != cpu ) laerror("permutations can be done only in CPU memory"); | ||||||
| #endif | #endif | ||||||
| NRVec<T> r(n); | NRVec<T> r(n); | ||||||
| for(int i=1; i<=n; ++i) r[i-1] = v[p[i]-1]; | if(inverse) for(int i=1; i<=n; ++i) r[i-1] = v[p[i]-1]; | ||||||
|  | else for(int i=1; i<=n; ++i) r[p[i]-1] = v[i-1]; | ||||||
| return r; | return r; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | template<typename T> | ||||||
|  | void NRVec<T>::permuteme(const CyclePerm<int> &p) | ||||||
|  | { | ||||||
|  | #ifdef DEBUG | ||||||
|  | if(!p.is_valid()) laerror("invalid permutation of vector"); | ||||||
|  | #endif | ||||||
|  | if(p.max()>nn) laerror("incompatible permutation and vector"); | ||||||
|  | #ifdef CUDALA | ||||||
|  |         if(this->getlocation() != cpu || p.getlocation() != cpu ) laerror("permutations can be done only in CPU memory"); | ||||||
|  | #endif | ||||||
|  | copyonwrite(); | ||||||
|  | for(int cycle=1; cycle<=p.size(); ++cycle) | ||||||
|  | 	{ | ||||||
|  | 	int length= p[cycle].size(); | ||||||
|  | 	if(length<=1) continue; //trivial cycle
 | ||||||
|  | 	T tmp = v[p[cycle][length]-1]; | ||||||
|  | 	for(int i=length; i>1; --i) v[p[cycle][i]-1] = v[p[cycle][i-1]-1]; | ||||||
|  | 	v[p[cycle][1]-1] = tmp; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| /***************************************************************************//**
 | /***************************************************************************//**
 | ||||||
|  * forced instantization in the corespoding object file |  * forced instantization in the corespoding object file | ||||||
|  ******************************************************************************/ |  ******************************************************************************/ | ||||||
| @ -911,6 +944,38 @@ INSTANTIZE_DUMMY(std::complex<unsigned long long>) | |||||||
| INSTANTIZE_DUMMY(std::complex<std::complex<double> >) | INSTANTIZE_DUMMY(std::complex<std::complex<double> >) | ||||||
| INSTANTIZE_DUMMY(std::complex<std::complex<float> >) | INSTANTIZE_DUMMY(std::complex<std::complex<float> >) | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //also not supported on gpu
 | ||||||
|  | #define INSTANTIZE_NONCOMPLEX(T) \ | ||||||
|  | template<>\ | ||||||
|  | const T NRVec<T>::max() const\ | ||||||
|  | {\ | ||||||
|  | if(nn==0) return 0;\ | ||||||
|  | T m=v[0];\ | ||||||
|  | for(int i=1; i<nn; ++i) if(v[i]>m) m=v[i];\ | ||||||
|  | return m;\ | ||||||
|  | }\ | ||||||
|  | \ | ||||||
|  | template<>\ | ||||||
|  | const T NRVec<T>::min() const\ | ||||||
|  | {\ | ||||||
|  | if(nn==0) return 0;\ | ||||||
|  | T m=v[0];\ | ||||||
|  | for(int i=1; i<nn; ++i) if(v[i]<m) m=v[i];\ | ||||||
|  | return m;\ | ||||||
|  | }\ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | INSTANTIZE_NONCOMPLEX(char) | ||||||
|  | INSTANTIZE_NONCOMPLEX(short) | ||||||
|  | INSTANTIZE_NONCOMPLEX(int) | ||||||
|  | INSTANTIZE_NONCOMPLEX(long) | ||||||
|  | INSTANTIZE_NONCOMPLEX(long long) | ||||||
|  | INSTANTIZE_NONCOMPLEX(float) | ||||||
|  | INSTANTIZE_NONCOMPLEX(double) | ||||||
|  | 
 | ||||||
| template class NRVec<double>; | template class NRVec<double>; | ||||||
| template class NRVec<std::complex<double> >; | template class NRVec<std::complex<double> >; | ||||||
| template class NRVec<char>; | template class NRVec<char>; | ||||||
|  | |||||||
							
								
								
									
										12
									
								
								vec.h
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								vec.h
									
									
									
									
									
								
							| @ -271,7 +271,8 @@ public: | |||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
| 	//! permute vector elements
 | 	//! permute vector elements
 | ||||||
| 	const NRVec permute(const NRPerm<int> &p) const; | 	const NRVec permuted(const NRPerm<int> &p, const bool inverse=false) const; | ||||||
|  | 	void permuteme(const CyclePerm<int> &p); //in place
 | ||||||
| 
 | 
 | ||||||
| 	//! compute the sum of the absolute values of the elements of this vector 
 | 	//! compute the sum of the absolute values of the elements of this vector 
 | ||||||
| 	inline const typename LA_traits<T>::normtype asum() const; | 	inline const typename LA_traits<T>::normtype asum() const; | ||||||
| @ -318,6 +319,12 @@ public: | |||||||
| 	//! determine the minimal element (in the absolute value) of this vector 
 | 	//! determine the minimal element (in the absolute value) of this vector 
 | ||||||
| 	inline const T amin() const; | 	inline const T amin() const; | ||||||
| 
 | 
 | ||||||
|  |         //! determine the maximal element of this vector
 | ||||||
|  |         const T max() const; | ||||||
|  |         //! determine the minimal element of this vector
 | ||||||
|  |         const T min() const; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| 	//! routine for formatted output 
 | 	//! routine for formatted output 
 | ||||||
| 	void fprintf(FILE *f, const char *format, const int modulo) const; | 	void fprintf(FILE *f, const char *format, const int modulo) const; | ||||||
| 	//! routine for unformatted output 
 | 	//! routine for unformatted output 
 | ||||||
| @ -355,6 +362,7 @@ public: | |||||||
| 
 | 
 | ||||||
| 	//! sort by default in ascending order and return the parity of corresponding permutation resulting to this order
 | 	//! sort by default in ascending order and return the parity of corresponding permutation resulting to this order
 | ||||||
| 	int sort(int direction = 0, int from = 0, int to = -1, int *perm = NULL); | 	int sort(int direction = 0, int from = 0, int to = -1, int *perm = NULL); | ||||||
|  | 	int sort(int direction, NRPerm<int> &perm); | ||||||
| 
 | 
 | ||||||
| 	//! apply given function to each element
 | 	//! apply given function to each element
 | ||||||
| 	NRVec& call_on_me(T (*_F)(const T &) ){ | 	NRVec& call_on_me(T (*_F)(const T &) ){ | ||||||
| @ -1082,6 +1090,8 @@ void NRVec<T>::moveto(const GPUID dest) { | |||||||
| } | } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| /***************************************************************************//**
 | /***************************************************************************//**
 | ||||||
|  * adds a real scalar value \f$\alpha\f$ to all elements of this real vector \f$\vec{x}\f$ |  * adds a real scalar value \f$\alpha\f$ to all elements of this real vector \f$\vec{x}\f$ | ||||||
|  * \f[\vec{x}_i\leftarrow\vec{x}_i+\alpha\f] |  * \f[\vec{x}_i\leftarrow\vec{x}_i+\alpha\f] | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user