From 41e9c359d5f079c945832264ee113636702c8f27 Mon Sep 17 00:00:00 2001 From: Jiri Pittner Date: Tue, 16 Jan 2024 15:52:43 +0100 Subject: [PATCH] permutation generation outputting explicitly PermutationAlgebra class --- permutation.cc | 69 +++++++++++++++++++++++++++++++++++++++++++++----- permutation.h | 4 ++- t.cc | 9 ++++--- 3 files changed, 70 insertions(+), 12 deletions(-) diff --git a/permutation.cc b/permutation.cc index 515ed4e..3f0a1fc 100644 --- a/permutation.cc +++ b/permutation.cc @@ -262,7 +262,7 @@ PERM_RANK_TYPE sumperm=0; p2: sumperm++; - if(!select || (select&1) == (sumperm&1)) (*callback)(*this); + if(callback) {if(!select || (select&1) == (sumperm&1)) {(*callback)(*this); this->copyonwrite();}} j=n; s=0; p4: q=c[j]+d[j]; @@ -284,6 +284,36 @@ end: return select? sumperm/2:sumperm; } + + +template +static PermutationAlgebra *list_all_return; + +static PERM_RANK_TYPE list_all_index; + +template +static void list_all_callback(const NRPerm &p) +{ +(*list_all_return)[list_all_index].weight= (list_all_index&1)?-1:1; +(*list_all_return)[list_all_index].perm=p; +(*list_all_return)[list_all_index].perm.copyonwrite(); +++list_all_index; +} + +template +PermutationAlgebra NRPerm::list_all(int parity_sel) +{ +PERM_RANK_TYPE number = factorial(this->size()); +if(parity_sel) number/=2; +PermutationAlgebra ret(number); +list_all_return = &ret; +list_all_index=0; +this->generate_all(list_all_callback,parity_sel); +return ret; +} + + + //Algorithm L2 from Knuth's volume 4 for multiset permutations //input must be initialized with (repeated) numbers in any order template @@ -298,7 +328,7 @@ while(1) T t; sumperm++; - (*callback)(*this); + if(callback) (*callback)(*this); j=this->size()-1; while(j>0 && (*this)[j]>=(*this)[j+1]) j--; if(j==0) break; /*finished*/ @@ -347,7 +377,7 @@ if(n<= _n) else { _sumperm++; - (*_callback)(*_perm); + if(_callback) (*_callback)(*_perm); } } @@ -373,7 +403,7 @@ PERM_RANK_TYPE np=0; this->identity(); do{ ++np; -(*callback)(*this); +if(callback) (*callback)(*this); }while(this->next()); return np; } @@ -429,12 +459,13 @@ if(n<=_n2) else { _sumperm2++; - (*_callback2)(*_perm2); + if(_callback2) {(*_callback2)(*_perm2); _perm2 -> copyonwrite();} } } + template PERM_RANK_TYPE NRPerm::generate_restricted(void (*callback)(const NRPerm&), const NRVec_from1 &classes, int restriction_type) { @@ -451,6 +482,30 @@ permg2(1); return _sumperm2; } +template +static PermutationAlgebra *list_restricted_return; + +static PERM_RANK_TYPE list_restricted_index; + +template +static void list_restricted_callback(const NRPerm &p) +{ +(*list_restricted_return)[list_restricted_index].weight=p.parity(); +(*list_restricted_return)[list_restricted_index].perm=p; +(*list_restricted_return)[list_restricted_index].copyonwrite(); +++list_restricted_index; +} + +template +PermutationAlgebra NRPerm::list_restricted(const NRVec_from1 &classes, int restriction_type) +{ +PERM_RANK_TYPE number = this->generate_restricted(NULL,classes,restriction_type); +PermutationAlgebra ret(number); +list_restricted_return = &ret; +list_restricted_index=0; +generate_restricted(list_restricted_callback,classes,restriction_type); +return ret; +} template @@ -1140,7 +1195,7 @@ template void partgen(int remain, int pos) { int hi,lo; -if(remain==0) {++partitioncount; (*_pcallback)(*partition); return;} +if(remain==0) {++partitioncount; if(_pcallback) (*_pcallback)(*partition); return;} if(partitiontyp) lo=(remain+partitiontypabs-pos)/(partitiontypabs-pos+1); else lo=1; hi=remain; if(partitiontyp>0) hi -= partitiontypabs-pos; @@ -1539,7 +1594,7 @@ if(ncyc> _ncycles) { if(_callyoung) { - _young_callback(*_tchi); + if(_young_callback) _young_callback(*_tchi); _character ++; } else _character += _tchi->character_contribution(_ncycles); diff --git a/permutation.h b/permutation.h index 322454e..eadb07e 100644 --- a/permutation.h +++ b/permutation.h @@ -69,10 +69,12 @@ public: void randomize(void); //uniformly random by Fisher-Yates shuffle bool next(); //generate next permutation in lex order PERM_RANK_TYPE generate_all(void (*callback)(const NRPerm&), int parity_select=0); //Algorithm L from Knuth's vol.4, efficient but not in lex order! - PERM_RANK_TYPE generate_all_multi(void (*callback)(const NRPerm&)); //Algorithm L2 from Knuth's vol.4, for multiset (repeated numbers, not really permutations) + PermutationAlgebra list_all(int parity_select=0); + PERM_RANK_TYPE generate_all_multi(void (*callback)(const NRPerm&)); //Algorithm L2 from Knuth's vol.4, for a multiset (repeated numbers, not really permutations) PERM_RANK_TYPE generate_all2(void (*callback)(const NRPerm&)); //recursive method, also not lexicographic PERM_RANK_TYPE generate_all_lex(void (*callback)(const NRPerm&)); //generate in lex order using next() PERM_RANK_TYPE generate_restricted(void (*callback)(const NRPerm&), const NRVec_from1 &classes, int restriction_type=0); + PermutationAlgebra list_restricted(const NRVec_from1 &classes, int restriction_type=0); //weight is set to parity (antisymmetrizer) by default PERM_RANK_TYPE rank() const; //counted from 0 to n!-1 NRVec_from1 inversions(const int type, PERM_RANK_TYPE *prank=NULL) const; //inversion tables explicit NRPerm(const int type, const NRVec_from1 &inversions); //compute permutation from inversions diff --git a/t.cc b/t.cc index 855cd67..b391900 100644 --- a/t.cc +++ b/t.cc @@ -2211,18 +2211,19 @@ int tot=p.generate_all_multi(printme0); cout <<"generated "<>n; NRPerm p(n); NRVec_from1 classes; cin>>classes; if(classes.size()!=p.size()) laerror("sizes do not match"); -int tot=p.generate_restricted(printme1,classes,-2); -cout <<"generated "< tot = p.list_restricted(classes,-2); +cout <<"generated\n"<>n >>unitary_n;