diff --git a/permutation.cc b/permutation.cc index 386ac32..b8fe706 100644 --- a/permutation.cc +++ b/permutation.cc @@ -603,12 +603,12 @@ return (n_even_cycles&1)?-1:1; template -Partition CyclePerm::cycles(const T n) const +CompressedPartition CyclePerm::cycles(const T n) const { #ifdef DEBUG if(!this->is_valid()) laerror("operation with an invalid cycleperm"); #endif -Partition r(n); r.clear(); +CompressedPartition r(n); r.clear(); T ncycles=this->size(); for(T i=1; i<=ncycles; ++i) { @@ -718,12 +718,133 @@ return s; /////////////////////////////////////////////////////// +template +PERM_RANK_TYPE CompressedPartition::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 +PERM_RANK_TYPE Partition::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 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 +Partition Partition::adjoint() const +{ +#ifdef DEBUG +if(!this->is_valid()) laerror("operation with an invalid partition"); +#endif +int n=this->size(); +Partition 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 static void (*_pcallback)(const Partition&); +static int partitiontyp; +static int partitiontypabs; +template static Partition *partition; + +template +void partgen(int remain, int pos) +{ +int hi,lo; +if(remain==0) {++partitioncount; (*_pcallback)(*partition); 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)[pos-1] < hi) hi= (*partition)[pos-1]; +for((*partition)[pos]=hi; (*partition)[pos]>=lo; --(*partition)[pos]) partgen(remain-(*partition)[pos],pos+1); +(*partition)[pos]=0; +} + + + +template +PERM_RANK_TYPE Partition::generate_all(void (*callback)(const Partition&), int nparts) +{ +int n=this->size(); +if(n==0) return 0; +if(nparts>0 && ncopyonwrite(); +this->clear(); +partitioncount=0; +_pcallback =callback; +partitiontyp=nparts; +partition = this; +partitiontypabs= nparts>=0?nparts:-nparts; +partgen(n,1); +return partitioncount; +} + +template +YoungTableaux::YoungTableaux(const Partition &frame) +: NRVec_from1 >() +{ +#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 ******************************************************************************/ template class NRPerm; template class CyclePerm; +template class CompressedPartition; template class Partition; #define INSTANTIZE(T) \ diff --git a/permutation.h b/permutation.h index d75a84e..5aa38f5 100644 --- a/permutation.h +++ b/permutation.h @@ -33,6 +33,7 @@ namespace LA { template class NRVec_from1; template class CyclePerm; template class Partition; +template class CompressedPartition; template class NRPerm : public NRVec_from1 { @@ -64,6 +65,7 @@ public: }; 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 template @@ -78,9 +80,10 @@ public: CyclePerm inverse() const; //reverse all 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 cycles(const T n) const; + CompressedPartition cycles(const T n) const; void readfrom(const std::string &line); 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 &x); -//partitions stored as #of 1s, #of 2s, etc. +//compressed partitions stored as #of 1s, #of 2s, etc. +template +class CompressedPartition : public NRVec_from1 { +public: + CompressedPartition(): NRVec_from1() {}; + CompressedPartition(const int n) : NRVec_from1(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 &rhs) : NRVec_from1(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 class Partition : public NRVec_from1 { public: - Partition(): NRVec_from1() {}; - Partition(const int n) : NRVec_from1(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(T i=1; i<=this->size(); ++i) s += (*this)[i]; return s;} - T nclasses() const {T s=0; for(T i=1; i<=this->size(); ++i) if((*this)[i]) ++s; return s;} - bool is_valid() const {return this->size() == this->sum();} + Partition(): NRVec_from1() {}; + Partition(const int n) : NRVec_from1(n) {}; + T nparts() const {T s=0; for(int i=1; i<=this->size(); ++i) if((*this)[i]) ++s; 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; } + explicit Partition(const CompressedPartition &rhs) : NRVec_from1(rhs.size()) {this->clear(); int ithru=0; for(int i=rhs.size(); i>=1; --i) for(int j=0; j&), int nparts=0); //nparts <0 means at most to -nparts -//@@@generate all partitions, -//@@@enumerator of partitions of n to r parts and total -//@@@adjoint partition, -//@@@output formatted as in the group character table -//@@@Sn character table computation + +//@@@yamanouchi symbol }; +template +class YoungTableaux : public NRVec_from1 > { +public: + YoungTableaux() : NRVec_from1 >() {}; + explicit YoungTableaux(const Partition &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 #endif diff --git a/t.cc b/t.cc index 2d5aa5a..56a2396 100644 --- a/t.cc +++ b/t.cc @@ -68,6 +68,17 @@ for(int i=0; i<4; ++i) } } +void pprintme(const Partition &p) +{ +cout< q=p.adjoint(); +cout<<"IR dim "<>n; @@ -2094,4 +2105,15 @@ int tot=p.generate_all_lex(printme); cout <<"generated "<>n; +Partition p(n); +int tot=p.generate_all(pprintme,0); +cout <<"generated "<