progressing on partitions
This commit is contained in:
		
							parent
							
								
									4be6df3317
								
							
						
					
					
						commit
						88628fb306
					
				
							
								
								
									
										125
									
								
								permutation.cc
									
									
									
									
									
								
							
							
						
						
									
										125
									
								
								permutation.cc
									
									
									
									
									
								
							@ -603,12 +603,12 @@ return (n_even_cycles&1)?-1:1;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template <typename T>
 | 
					template <typename T>
 | 
				
			||||||
Partition<T> CyclePerm<T>::cycles(const T n) const
 | 
					CompressedPartition<T> CyclePerm<T>::cycles(const T n) const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#ifdef DEBUG
 | 
					#ifdef DEBUG
 | 
				
			||||||
if(!this->is_valid()) laerror("operation with an invalid cycleperm");
 | 
					if(!this->is_valid()) laerror("operation with an invalid cycleperm");
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
Partition<T> r(n); r.clear();
 | 
					CompressedPartition<T> r(n); r.clear();
 | 
				
			||||||
T ncycles=this->size();
 | 
					T ncycles=this->size();
 | 
				
			||||||
for(T i=1; i<=ncycles; ++i)
 | 
					for(T i=1; i<=ncycles; ++i)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@ -718,12 +718,133 @@ return s;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
///////////////////////////////////////////////////////
 | 
					///////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					PERM_RANK_TYPE CompressedPartition<T>::Sn_class_size() const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
					if(!this->is_valid()) laerror("operation with an invalid partition");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					int n=this->size();
 | 
				
			||||||
 | 
					PERM_RANK_TYPE r=factorial(n);
 | 
				
			||||||
 | 
					for(int i=1; i<=n; ++i) 
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						T m=(*this)[i];
 | 
				
			||||||
 | 
						if(i>1 && m>0) r/=ipow(i,m);
 | 
				
			||||||
 | 
						if(m>1) r/=factorial(m);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					return r;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					PERM_RANK_TYPE Partition<T>::Sn_irrep_dim() const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
					if(!this->is_valid()) laerror("operation with an invalid partition");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					int n=this->size();
 | 
				
			||||||
 | 
					PERM_RANK_TYPE prod=1;
 | 
				
			||||||
 | 
					Partition<T> adj=this->adjoint();
 | 
				
			||||||
 | 
					//hook length formula
 | 
				
			||||||
 | 
					for(int i=1; i<=adj[1]; ++i) //rows
 | 
				
			||||||
 | 
						for(int j=1; j<= (*this)[i]; ++j) //cols
 | 
				
			||||||
 | 
							prod *= (*this)[i]-j+adj[j]-i+1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					return factorial(n)/prod;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					Partition<T> Partition<T>::adjoint() const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
					if(!this->is_valid()) laerror("operation with an invalid partition");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					int n=this->size();
 | 
				
			||||||
 | 
					Partition<T> r(n);
 | 
				
			||||||
 | 
					r.clear();
 | 
				
			||||||
 | 
					for(int i=1;i<=n;++i)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
							int j;
 | 
				
			||||||
 | 
					                for(j=1; j<=n&&(*this)[j]>=i; ++j);
 | 
				
			||||||
 | 
					                r[i]=j-1;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					return r;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PERM_RANK_TYPE ipow(PERM_RANK_TYPE x, int i)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					if(i<0) return 0;
 | 
				
			||||||
 | 
					PERM_RANK_TYPE y=1;
 | 
				
			||||||
 | 
					do
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					        if(i&1) y *= x;
 | 
				
			||||||
 | 
						i >>= 1;
 | 
				
			||||||
 | 
					        if(i) x *= x;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					while(i);
 | 
				
			||||||
 | 
					return y ;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//aux for the recursive procedure
 | 
				
			||||||
 | 
					static PERM_RANK_TYPE partitioncount;
 | 
				
			||||||
 | 
					template <typename T> static void (*_pcallback)(const Partition<T>&);
 | 
				
			||||||
 | 
					static int partitiontyp;
 | 
				
			||||||
 | 
					static int partitiontypabs;
 | 
				
			||||||
 | 
					template <typename T> static Partition<T> *partition;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					void partgen(int remain, int pos)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					int hi,lo;
 | 
				
			||||||
 | 
					if(remain==0) {++partitioncount; (*_pcallback<T>)(*partition<T>); return;}
 | 
				
			||||||
 | 
					if(partitiontyp) lo=(remain+partitiontypabs-pos)/(partitiontypabs-pos+1); else lo=1;
 | 
				
			||||||
 | 
					hi=remain;
 | 
				
			||||||
 | 
					if(partitiontyp>0) hi -= partitiontypabs-pos;
 | 
				
			||||||
 | 
					if(pos>1 && (*partition<T>)[pos-1] < hi) hi= (*partition<T>)[pos-1];
 | 
				
			||||||
 | 
					for((*partition<T>)[pos]=hi; (*partition<T>)[pos]>=lo; --(*partition<T>)[pos]) partgen<T>(remain-(*partition<T>)[pos],pos+1);
 | 
				
			||||||
 | 
					(*partition<T>)[pos]=0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					PERM_RANK_TYPE Partition<T>::generate_all(void (*callback)(const Partition<T>&), int nparts) 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					int n=this->size();
 | 
				
			||||||
 | 
					if(n==0) return 0;
 | 
				
			||||||
 | 
					if(nparts>0 && n<nparts) return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					this->copyonwrite();
 | 
				
			||||||
 | 
					this->clear();
 | 
				
			||||||
 | 
					partitioncount=0;
 | 
				
			||||||
 | 
					_pcallback<T> =callback;
 | 
				
			||||||
 | 
					partitiontyp=nparts;
 | 
				
			||||||
 | 
					partition<T> = this;
 | 
				
			||||||
 | 
					partitiontypabs= nparts>=0?nparts:-nparts;
 | 
				
			||||||
 | 
					partgen<T>(n,1);
 | 
				
			||||||
 | 
					return partitioncount;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					YoungTableaux<T>::YoungTableaux(const Partition<T> &frame)
 | 
				
			||||||
 | 
					: NRVec_from1<NRVec_from1<T> >()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
					if(!frame.is_valid()) laerror("invalid partition used as young frame");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					int nlines=frame.nparts();
 | 
				
			||||||
 | 
					this->resize(nlines);
 | 
				
			||||||
 | 
					for(int i=1; i<=nlines; ++i) (*this)[i].resize(frame[i]);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/***************************************************************************//**
 | 
					/***************************************************************************//**
 | 
				
			||||||
 * forced instantization in the corresponding object file
 | 
					 * forced instantization in the corresponding object file
 | 
				
			||||||
 ******************************************************************************/
 | 
					 ******************************************************************************/
 | 
				
			||||||
template class NRPerm<int>;
 | 
					template class NRPerm<int>;
 | 
				
			||||||
template class CyclePerm<int>;
 | 
					template class CyclePerm<int>;
 | 
				
			||||||
 | 
					template class CompressedPartition<int>;
 | 
				
			||||||
template class Partition<int>;
 | 
					template class Partition<int>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define INSTANTIZE(T) \
 | 
					#define INSTANTIZE(T) \
 | 
				
			||||||
 | 
				
			|||||||
@ -33,6 +33,7 @@ namespace LA {
 | 
				
			|||||||
template <typename T> class NRVec_from1;
 | 
					template <typename T> class NRVec_from1;
 | 
				
			||||||
template <typename T> class CyclePerm;
 | 
					template <typename T> class CyclePerm;
 | 
				
			||||||
template <typename T> class Partition;
 | 
					template <typename T> class Partition;
 | 
				
			||||||
 | 
					template <typename T> class CompressedPartition;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template <typename T>
 | 
					template <typename T>
 | 
				
			||||||
class NRPerm : public NRVec_from1<T> {
 | 
					class NRPerm : public NRVec_from1<T> {
 | 
				
			||||||
@ -64,6 +65,7 @@ public:
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern PERM_RANK_TYPE factorial(const int n);
 | 
					extern PERM_RANK_TYPE factorial(const int n);
 | 
				
			||||||
 | 
					extern PERM_RANK_TYPE ipow(PERM_RANK_TYPE x, int i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//permutations represented in the cycle format
 | 
					//permutations represented in the cycle format
 | 
				
			||||||
template <typename T>
 | 
					template <typename T>
 | 
				
			||||||
@ -78,9 +80,10 @@ public:
 | 
				
			|||||||
	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;}
 | 
						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;
 | 
						CompressedPartition<T> cycles(const T n) const;
 | 
				
			||||||
	void readfrom(const std::string &line);
 | 
						void readfrom(const std::string &line);
 | 
				
			||||||
	CyclePerm operator*(const CyclePerm q) const; //q is rhs and applied first, this applied second
 | 
						CyclePerm operator*(const CyclePerm q) const; //q is rhs and applied first, this applied second
 | 
				
			||||||
 | 
						//@@@order = lcm of cycle lengths
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -92,24 +95,54 @@ std::ostream & operator<<(std::ostream &s, const CyclePerm<T> &x);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//partitions stored as #of 1s, #of 2s, etc.
 | 
					//compressed partitions stored as #of 1s, #of 2s, etc.
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					class CompressedPartition : public NRVec_from1<T> {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						CompressedPartition(): NRVec_from1<T>() {};
 | 
				
			||||||
 | 
						CompressedPartition(const int n) : NRVec_from1<T>(n) {};
 | 
				
			||||||
 | 
						T sum() const {T s=0; for(int i=1; i<=this->size(); ++i) s += i*(*this)[i]; return s;}
 | 
				
			||||||
 | 
						T nparts() const {T s=0; for(int i=1; i<=this->size(); ++i) s += (*this)[i]; return s;}
 | 
				
			||||||
 | 
						T nclasses() const {T s=0; for(int i=1; i<=this->size(); ++i) if((*this)[i]) ++s; return s;}
 | 
				
			||||||
 | 
						bool is_valid() const {return this->size() == this->sum();}
 | 
				
			||||||
 | 
						explicit CompressedPartition(const Partition<T> &rhs) : NRVec_from1<T>(rhs.size()) {this->clear(); for(int i=1; i<=rhs.size(); ++i) if(!rhs[i]) break; else (*this)[rhs[i]]++; }
 | 
				
			||||||
 | 
						PERM_RANK_TYPE Sn_class_size() const; 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//@@@output formatted as in the group character table
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template <typename T>
 | 
					template <typename T>
 | 
				
			||||||
class Partition : public NRVec_from1<T> {
 | 
					class Partition : public NRVec_from1<T> {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	Partition(): NRVec_from1<T>() {};
 | 
					        Partition(): NRVec_from1<T>() {};
 | 
				
			||||||
	Partition(const int n) : NRVec_from1<T>(n) {};
 | 
					        Partition(const int n) : NRVec_from1<T>(n) {};
 | 
				
			||||||
	T sum() const {T s=0; for(T i=1; i<=this->size(); ++i) s += i*(*this)[i]; return s;}
 | 
					        T nparts() const {T s=0; for(int i=1; i<=this->size(); ++i) if((*this)[i]) ++s; return s;}
 | 
				
			||||||
	T nparts() const {T s=0; for(T i=1; i<=this->size(); ++i) s += (*this)[i]; return s;}
 | 
					        bool is_valid() const {if(this->size() != this->sum()) return false; for(int i=2; i<=this->size(); ++i) if((*this)[i]>(*this)[i-1]) return false; return true; }
 | 
				
			||||||
	T nclasses() const {T s=0; for(T i=1; i<=this->size(); ++i) if((*this)[i]) ++s; return s;}
 | 
						explicit Partition(const CompressedPartition<T>  &rhs) : NRVec_from1<T>(rhs.size()) {this->clear(); int ithru=0; for(int i=rhs.size(); i>=1; --i) for(int j=0; j<rhs[i]; ++j) (*this)[++ithru]=i; }
 | 
				
			||||||
	bool is_valid() const {return this->size() == this->sum();}
 | 
						Partition adjoint() const;
 | 
				
			||||||
 | 
						PERM_RANK_TYPE Sn_irrep_dim() const;
 | 
				
			||||||
 | 
						PERM_RANK_TYPE generate_all(void (*callback)(const Partition<T>&), int nparts=0); //nparts <0 means at most to -nparts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//@@@generate all partitions, 
 | 
					
 | 
				
			||||||
//@@@enumerator of partitions of n to r parts and total
 | 
					//@@@yamanouchi symbol
 | 
				
			||||||
//@@@adjoint partition, 
 | 
					 | 
				
			||||||
//@@@output formatted as in the group character table
 | 
					 | 
				
			||||||
//@@@Sn character table computation
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					class YoungTableaux : public NRVec_from1<NRVec_from1<T> > {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					        YoungTableaux() :  NRVec_from1<NRVec_from1<T> >() {};
 | 
				
			||||||
 | 
					        explicit YoungTableaux(const Partition<T> &frame);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool is_valid() const; //@@@shape forms a partition
 | 
				
			||||||
 | 
					        bool filled_correctly() const; //is it filled correctly
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//@@@enumerator of partitions of n to r parts and total from expr
 | 
				
			||||||
 | 
					//@@@Sn character table computation from young - young frame filling
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}//namespace
 | 
					}//namespace
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										24
									
								
								t.cc
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								t.cc
									
									
									
									
									
								
							@ -68,6 +68,17 @@ for(int i=0; i<4; ++i)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void pprintme(const Partition<int> &p)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					cout<<p;
 | 
				
			||||||
 | 
					Partition<int> q=p.adjoint();
 | 
				
			||||||
 | 
					cout<<"IR dim "<<p.Sn_irrep_dim()<<endl;
 | 
				
			||||||
 | 
					cout <<q;
 | 
				
			||||||
 | 
					CompressedPartition qc(q);
 | 
				
			||||||
 | 
					cout<<"Class size "<<qc.Sn_class_size()<<endl;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main()
 | 
					int main()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -2085,7 +2096,7 @@ cout <<p;
 | 
				
			|||||||
}while(p.next());
 | 
					}while(p.next());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if(1)
 | 
					if(0)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
int n;
 | 
					int n;
 | 
				
			||||||
cin >>n;
 | 
					cin >>n;
 | 
				
			||||||
@ -2094,4 +2105,15 @@ int tot=p.generate_all_lex(printme);
 | 
				
			|||||||
cout <<"generated "<<tot<<endl;
 | 
					cout <<"generated "<<tot<<endl;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if(1)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					int n;
 | 
				
			||||||
 | 
					cin >>n;
 | 
				
			||||||
 | 
					Partition<int> p(n);
 | 
				
			||||||
 | 
					int tot=p.generate_all(pprintme,0);
 | 
				
			||||||
 | 
					cout <<"generated "<<tot<<endl;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user