Cadabra
Computer algebra system for field theory problems
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
YoungTab.hh
Go to the documentation of this file.
1 /*
2 
3  Cadabra: a field-theory motivated computer algebra system.
4  Copyright (C) 2001-2011 Kasper Peeters <kasper.peeters@aei.mpg.de>
5 
6  This program is free software: you can redistribute it and/or
7  modify it under the terms of the GNU General Public License as
8  published by the Free Software Foundation, either version 3 of the
9  License, or (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
19 */
20 
21 /*
22  - TODO: has_nullifying trace is wrong, but needs to be merged with the
23  input_asym code in order to be more useful.
24 
25 */
26 
27 #pragma once
28 
29 #include <cstddef>
30 #include <iostream>
31 #include <iterator>
32 #include <vector>
33 #include <list>
34 #include <gmpxx.h>
35 #include "Combinatorics.hh"
36 #include <cstddef>
37 
38 typedef mpz_class yngint_t;
39 typedef mpq_class yngrat_t;
40 
42 namespace yngtab {
43 
44 // The tableau_base is the abstract interface; does not depend on the
45 // actual storage format.
46 
47 class tableau_base {
48  public:
49  tableau_base();
50  virtual ~tableau_base();
51  virtual unsigned int number_of_rows() const=0;
52  virtual unsigned int row_size(unsigned int row) const=0;
53  virtual unsigned int column_size(unsigned int col) const; // FIXME: maybe make pure virt too
54  virtual void add_box(unsigned int row)=0;
55  virtual void remove_box(unsigned int row)=0;
56  virtual void add_row(unsigned int row_size);
57  virtual void clear()=0;
58 
59  yngrat_t multiplicity; // also keeps track of signs
60  int selfdual_column; // -n, 0, n for antiselfdual, no, selfdual (count from 1)
61  yngint_t dimension(unsigned int) const;
62  unsigned long hook_length(unsigned int row, unsigned int col) const;
63  yngint_t hook_length_prod() const;
64 };
65 
66 class tableau : public tableau_base {
67  public:
68  virtual ~tableau();
69  virtual unsigned int number_of_rows() const;
70  virtual unsigned int row_size(unsigned int row) const;
71  virtual void add_box(unsigned int row);
72  virtual void remove_box(unsigned int row);
73  virtual void clear();
74 
75  tableau& operator=(const tableau&);
76  private:
77  std::vector<int> rows;
78 };
79 
80 template<class T>
81 class tableaux;
82 
83 template<class T>
84 class filled_tableau : public tableau {
85  public:
86  typedef T value_type;
87 
88  virtual ~filled_tableau();
89  virtual unsigned int number_of_rows() const;
90  virtual unsigned int row_size(unsigned int row) const;
91  virtual void add_box(unsigned int row);
92  virtual void remove_box(unsigned int row);
93  std::pair<int, int> find(const T&) const;
94  virtual void clear();
95 
96  void copy_shape(const tableau&);
97 
98  T& operator()(unsigned int row, unsigned int col);
99  const T& operator()(unsigned int row, unsigned int col) const;
100  const T& operator[](unsigned int boxnum) const;
101  void add_box(unsigned int rownum, T val);
102  void swap_columns(unsigned int c1, unsigned int c2);
103 
104  bool compare_without_multiplicity(const filled_tableau<T>& other) const;
105  bool has_nullifying_trace() const;
106  void sort_within_columns();
107  void sort_columns();
109  void canonicalise();
110  std::pair<int, int> nonstandard_loc() const;
111  template<class StrictWeakOrdering> void sort_within_columns(StrictWeakOrdering comp);
112  template<class StrictWeakOrdering> void sort_columns(StrictWeakOrdering comp);
113  template<class StrictWeakOrdering> void canonicalise(StrictWeakOrdering comp, bool only_col_ex=false);
114  void projector(combin::symmetriser<T>&, bool modulo_monoterm=false) const;
117 
119 
121  public:
122  typedef T value_type;
123  typedef T* pointer;
124  typedef T& reference;
125  typedef size_t size_type;
126  typedef ptrdiff_t difference_type;
127  typedef std::random_access_iterator_tag iterator_category;
128  };
129 
132  public:
133  in_column_iterator(unsigned int r, unsigned int c, filled_tableau<T> *);
134  T& operator*() const;
135  T* operator->() const;
140  in_column_iterator operator+(unsigned int);
141  in_column_iterator operator-(unsigned int);
142  in_column_iterator& operator+=(unsigned int);
143  in_column_iterator& operator-=(unsigned int);
144  bool operator<(const in_column_iterator& other) const;
145  bool operator>(const in_column_iterator& other) const;
146  bool operator<=(const in_column_iterator& other) const;
147  bool operator>=(const in_column_iterator& other) const;
148  ptrdiff_t operator-(const in_column_iterator&) const;
149  bool operator==(const in_column_iterator&) const;
150  bool operator!=(const in_column_iterator&) const;
151 
152  friend class filled_tableau<T>;
153  private:
155  unsigned int column_number, row_number;
156  };
157 
159  class iterator : public iterator_base {
160  public:
161  iterator(unsigned int r, unsigned int c, filled_tableau<T> *);
162  T& operator*() const;
163  T* operator->() const;
164  iterator& operator++();
165  iterator operator++(int);
166  iterator& operator--();
167  iterator operator--(int);
168  iterator operator+(unsigned int);
169  iterator operator-(unsigned int);
170  iterator& operator+=(unsigned int);
171  iterator& operator-=(unsigned int);
172  bool operator<(const iterator& other) const;
173  bool operator>(const iterator& other) const;
174  ptrdiff_t operator-(const iterator&) const;
175  bool operator==(const iterator&) const;
176  bool operator!=(const iterator&) const;
177 
178  friend class filled_tableau<T>;
179  private:
181  unsigned int column_number, row_number;
182  };
183 
184 
185  in_column_iterator begin_column(unsigned int column_number);
186  in_column_iterator end_column(unsigned int column_number);
187  iterator begin() const;
188  iterator end() const;
189 
190  template<class OutputIterator>
191  OutputIterator Garnir_set(OutputIterator, unsigned int, unsigned int) const;
192  private:
193  typedef std::vector<T> box_row;
194  typedef std::vector<box_row> row_stack;
196 };
197 
198 template<class T>
199 class tableaux {
200  public:
201  yngint_t total_dimension(unsigned int dim);
205  bool standard_form();
206  void add_tableau(const T&);
207  void symmetrise(const T& tabsym);
208 
209  typedef std::list<T> tableau_container_t;
211 
212  typedef std::back_insert_iterator<tableau_container_t> back_insert_iterator;
213 
215 };
216 
217 bool legal_box(const std::vector<std::pair<int,int> >& prev,
218  const std::vector<std::pair<int,int> >& ths,
219  int colpos, int trypos);
220 
221 // --------------------------------------
222 
223 
224 template<class T>
226  {
227  return back_insert_iterator(storage);
228  }
229 
230 template<class T>
232  {
233  typename tableau_container_t::iterator it=storage.begin();
234  while(it!=storage.end()) {
235  if(it->has_nullifying_trace())
236  it=storage.erase(it);
237  else ++it;
238  }
239  }
240 
241 template<class T>
242 void tableaux<T>::symmetrise(const T& symtab)
243  {
244 //
245 // typename tableau_container_t::iterator thetab=storage.begin();
246 // while(thetab!=storage.end()) {
247 // (*thetab).sort_columns();
248 // std::pair<int,int> where=(*thetab).nonstandard_loc();
249 // if(where.first!=-1) {
250 // combinations<typename T::value_type> com;
251 //
252 
253 /*
254  FIXME: we should have two LR_tensor routines, because if you do 'alltabs', you should
255  keep track of which boxes came from tableau 2. So do a LR_tensor with numbered boxes,
256  and then after the LR_tensor apply the symmetries of the original tableaux, put back
257  the original index names, sort columns and determine whether the tableau is identically
258  non-zero. Then add to the product.
259 
260  Another issue: adding to tableaux should have an option to not insert doubles.
261 
262  There was something third, forgotten...
263 */
264  }
265 
266 template<class T>
268  {
269  rows.clear();
270  for(unsigned int r=0; r<other.number_of_rows(); ++r) {
271  rows.push_back(box_row(other.row_size(r)));
272  }
273  tableau::operator=(other);
274  }
275 
276 template<class T>
278  {
279  return (rows==other.rows);
280  }
281 
282 template<class T>
284  {
285  return false;
286 
287 // Old, probably incorrect code:
288 //
289 // for(unsigned int r1=0; r1<number_of_rows(); ++r1) {
290 // for(unsigned c1=0; c1<row_size(r1); ++c1) {
291 // for(unsigned int c2=c1+1; c2<row_size(r1); ++c2) {
292 // // (r1,c1) and (r1,c2)
293 // for(unsigned int c3=0; c3<row_size(0); ++c3) {
294 // unsigned int r3=0;
295 // while(r3<number_of_rows()-1 && c3<row_size(r3)) {
296 // unsigned int r4=r3+1;
297 // while(r4<number_of_rows() && c3<row_size(r4)) {
298 // if((rows[r1][c1]==rows[r3][c3] && rows[r1][c2]==rows[r4][c3]) ||
299 // (rows[r1][c1]==rows[r4][c3] && rows[r1][c2]==rows[r3][c3]) )
300 // return true;
301 // ++r4;
302 // }
303 // ++r3;
304 // }
305 // }
306 // }
307 // }
308 // }
309 // return false;
310  }
311 
312 template<class T>
313 std::pair<int, int> filled_tableau<T>::find(const T& obj) const
314  {
315  for(unsigned int ir=0; ir<rows.size(); ++ir) {
316  for(unsigned int ic=0; ic<rows[ir].size(); ++ic) {
317  if(rows[ir][ic]==obj)
318  return std::pair<int,int>(ir, ic);
319  }
320  }
321  return std::pair<int,int>(-1,-1);
322  }
323 
324 template<class T>
326  {
327  std::less<T> comp;
328  sort_within_columns(comp);
329  }
330 
331 template<class T>
333  {
334  std::less<T> comp;
335  sort_columns(comp);
336  }
337 
338 template<class T>
340  {
341  std::less<T> comp;
342  canonicalise(comp);
343  }
344 
345 template<class T>
346 template<class StrictWeakOrdering>
347 void filled_tableau<T>::sort_within_columns(StrictWeakOrdering comp)
348  {
349  filled_tableau<T> tmp(*this);
350  if(number_of_rows()==0) return;
351  for(unsigned int c=0; c<row_size(0); ++c) {
352  std::sort(begin_column(c), end_column(c), comp);
353  multiplicity*=combin::ordersign(begin_column(c), end_column(c), tmp.begin_column(c), tmp.end_column(c));
354  }
355  }
356 
357 template<class T>
358 template<class StrictWeakOrdering>
359 void filled_tableau<T>::sort_columns(StrictWeakOrdering comp)
360  {
361  for(unsigned int c1=0; c1<row_size(0); ++c1) {
362  for(unsigned int c2=c1; c2<row_size(0); ++c2) {
363  if(column_size(c1)==column_size(c2)) {
364  if(comp((*this)(0,c2), (*this)(0,c1)))
365  swap_columns(c1,c2);
366  }
367  }
368  }
369  }
370 
371 template<class T>
372 template<class StrictWeakOrdering>
373 void filled_tableau<T>::canonicalise(StrictWeakOrdering comp, bool only_col_ex)
374  {
375  if(!only_col_ex)
376  sort_within_columns(comp);
377  sort_columns(comp);
378  }
379 
380 //---------------------------------------------------------------------------
381 // in_column_iterator
382 
383 template<class T>
385  : tab(t), column_number(c), row_number(r)
386  {
387  }
388 
389 template<class T>
391  {
392  typename filled_tableau<T>::in_column_iterator it2(*this);
393  it2+=n;
394  return it2;
395  }
396 
397 template<class T>
399  {
400  typename filled_tableau<T>::in_column_iterator it2(*this);
401  it2-=n;
402  return it2;
403  }
404 
405 template<class T>
406 ptrdiff_t filled_tableau<T>::in_column_iterator::operator-(const in_column_iterator& other) const
407  {
408  return row_number-other.row_number;
409  }
410 
411 template<class T>
413  {
414  return (*tab)(row_number,column_number);
415  }
416 
417 template<class T>
419  {
420  return &((*tab)(row_number,column_number));
421  }
422 
423 template<class T>
425  {
426  ++row_number;
427  return (*this);
428  }
429 
430 template<class T>
432  {
433  row_number+=n;
434  return (*this);
435  }
436 
437 template<class T>
439  {
440  --row_number;
441  return (*this);
442  }
443 
444 template<class T>
446  {
447  in_column_iterator tmp(*this);
448  --row_number;
449  return tmp;
450  }
451 
452 template<class T>
454  {
455  in_column_iterator tmp(*this);
456  ++row_number;
457  return tmp;
458  }
459 
460 template<class T>
462  {
463  row_number-=n;
464  return (*this);
465  }
466 
467 template<class T>
469  {
470  if(tab==other.tab && row_number==other.row_number && column_number==other.column_number)
471  return true;
472  return false;
473  }
474 
475 template<class T>
477  {
478  if(row_number<=other.row_number) return true;
479  return false;
480  }
481 
482 template<class T>
484  {
485  if(row_number>=other.row_number) return true;
486  return false;
487  }
488 
489 template<class T>
491  {
492  if(row_number<other.row_number) return true;
493  return false;
494  }
495 
496 template<class T>
498  {
499  if(row_number>other.row_number) return true;
500  return false;
501  }
502 
503 template<class T>
505  {
506  return !((*this)==other);
507  }
508 
509 //---------------------------------------------------------------------------
510 // iterator
511 
512 template<class T>
513 filled_tableau<T>::iterator::iterator(unsigned int r, unsigned int c, filled_tableau<T> *t)
514  : tab(t), column_number(c), row_number(r)
515  {
516  }
517 
518 template<class T>
520  {
521  typename filled_tableau<T>::iterator it2(*this);
522  it2+=n;
523  return it2;
524  }
525 
526 template<class T>
528  {
529  typename filled_tableau<T>::iterator it2(*this);
530  it2-=n;
531  return it2;
532  }
533 
534 template<class T>
535 ptrdiff_t filled_tableau<T>::iterator::operator-(const iterator& other) const
536  {
537  return row_number-other.row_number;
538  }
539 
540 template<class T>
542  {
543  return (*tab)(row_number,column_number);
544  }
545 
546 template<class T>
548  {
549  return &((*tab)(row_number,column_number));
550  }
551 
552 template<class T>
554  {
555  if(++column_number==tab->rows[row_number].size()) {
556  column_number=0;
557  ++row_number;
558  }
559  return (*this);
560  }
561 
562 template<class T>
564  {
565  while(n>0) {
566  if(++column_number==tab->rows[row_number]) {
567  column_number=0;
568  ++row_number;
569  }
570  --n;
571  }
572  return (*this);
573  }
574 
575 template<class T>
577  {
578  if(column_number==0) {
579  --row_number;
580  column_number=tab->rows[row_number].size()-1;
581  }
582  else --column_number;
583  return (*this);
584  }
585 
586 template<class T>
588  {
589  iterator tmp(*this);
590  if(column_number==0) {
591  --row_number;
592  column_number=tab->rows[row_number].size()-1;
593  }
594  else --column_number;
595  return tmp;
596  }
597 
598 template<class T>
600  {
601  iterator tmp(*this);
602  while(this->n>0) {
603  if(++column_number==tab->rows[row_number]) {
604  column_number=0;
605  ++row_number;
606  }
607  --this->n;
608  }
609  return tmp;
610  }
611 
612 template<class T>
614  {
615  while(n>0) {
616  if(column_number==0) {
617  --row_number;
618  column_number=tab->rows[row_number].size()-1;
619  }
620  else --column_number;
621  --n;
622  }
623  return (*this);
624  }
625 
626 template<class T>
628  {
629  if(tab==other.tab && row_number==other.row_number && column_number==other.column_number)
630  return true;
631  return false;
632  }
633 
634 template<class T>
636  {
637  if(row_number<other.row_number) return true;
638  return false;
639  }
640 
641 template<class T>
643  {
644  if(row_number>other.row_number) return true;
645  return false;
646  }
647 
648 template<class T>
650  {
651  return !((*this)==other);
652  }
653 
654 //---
655 // other
656 
657 template<class T>
659  {
660  return iterator(0,0,const_cast<filled_tableau<T> *>(this));
661  }
662 
663 template<class T>
665  {
666  return iterator(rows.size(), 0, const_cast<filled_tableau<T> *>(this));
667  }
668 
669 template<class T>
671  {
672  typename filled_tableau<T>::in_column_iterator it(0,column,this);
673  assert(number_of_rows()>0);
674  assert(column<row_size(0));
675  return it;
676  }
677 
678 template<class T>
680  {
681  unsigned int r=0;
682  while(r<number_of_rows()) {
683  if(row_size(r)<=column)
684  break;
685  ++r;
686  }
687  typename filled_tableau<T>::in_column_iterator it(r,column,this);
688  return it;
689  }
690 
691 template<class T>
692 template<class OutputIterator>
693 OutputIterator filled_tableau<T>::Garnir_set(OutputIterator it, unsigned int row, unsigned int col) const
694  {
695  assert(col>0);
696  unsigned int r=row, c=col;
697  *it=(*this)(r,c);
698  ++it;
699  while(r>0) {
700  --r;
701  *it=(*this)(r,c);
702  ++it;
703  }
704  r=row;
705  --c;
706  *it=(*this)(r,c);
707  ++it;
708  while(r+1<column_size(c)) {
709  ++r;
710  *it=(*this)(r,c);
711  ++it;
712  }
713  return it;
714  }
715 
716 template<class T>
717 std::pair<int, int> filled_tableau<T>::nonstandard_loc() const
718  {
719  unsigned int r=number_of_rows();
720  assert(r>0);
721  do {
722  --r;
723  for(unsigned int c=0; c<row_size(r)-1; ++c) {
724  if((*this)(r,c) > (*this)(r,c+1) )
725  return std::pair<int, int>(r,c);
726  }
727  } while(r>0);
728  return std::pair<int,int>(-1,-1);
729  }
730 
731 template<class T>
733  {
734  bool already_standard=true;
735 
736  typename tableau_container_t::iterator thetab=storage.begin();
737  while(thetab!=storage.end()) {
738  (*thetab).sort_within_columns();
739  std::pair<int,int> where=(*thetab).nonstandard_loc();
740  if(where.first!=-1) {
741  already_standard=false;
743  for(unsigned int i1=where.first; i1<(*thetab).column_size(where.second); ++i1)
744  com.original.push_back((*thetab)(i1,where.second));
745  for(unsigned int i1=0; i1<=(unsigned int)(where.first); ++i1)
746  com.original.push_back((*thetab)(i1,where.second+1));
747  com.sublengths.push_back((*thetab).column_size(where.second)-where.first);
748  com.sublengths.push_back(where.first+1);
749  com.permute();
750  for(unsigned int tabi=1; tabi<com.size(); ++tabi) {
751  T ntab((*thetab));
752  unsigned int offset=0;
753  for(unsigned int i1=where.first; i1<(*thetab).column_size(where.second); ++i1, ++offset)
754  ntab(i1,where.second)=com[tabi][offset];
755  for(unsigned int i1=0; i1<=(unsigned int)(where.first); ++i1, ++offset)
756  ntab(i1,where.second+1)=com[tabi][offset];
757  ntab.multiplicity*=-1*com.ordersign(tabi);
758  add_tableau(ntab);
759  }
760  thetab=storage.erase(thetab);
761  }
762  else ++thetab;
763  }
764  return already_standard;
765  }
766 
767 template<class T>
768 void tableaux<T>::add_tableau(const T& ntab)
769  {
770  typename tableau_container_t::iterator it=storage.begin();
771  while(it!=storage.end()) {
772  if((*it).compare_without_multiplicity(ntab)) {
773  (*it).multiplicity+=ntab.multiplicity;
774  if((*it).multiplicity==0)
775  storage.erase(it);
776  return;
777  }
778  ++it;
779  }
780  storage.push_back(ntab);
781  }
782 
783 
784 template<class T>
786  {
787  yngrat_t norm=1;
788  norm/=hook_length_prod();
789  return norm;
790  }
791 
792 template<class T>
793 void filled_tableau<T>::projector(combin::symmetriser<T>& sym, bool modulo_monoterm) const
794  {
795  for(unsigned int r=0; r<number_of_rows(); ++r)
796  for(unsigned int c=0; c<row_size(r); ++c)
797  sym.original.push_back(rows[r][c]);
798 
799  unsigned int offset=0;
800  // symmetrise over boxes in rows
801  for(unsigned int r=0; r<number_of_rows(); ++r) {
802  sym.permutation_sign=1;
803  sym.permute_blocks.clear();
804  sym.block_length=1;
805  sym.input_asym.clear();
806  for(unsigned int c=0; c<row_size(r); ++c)
807  sym.permute_blocks.push_back(offset++);
808  sym.apply_symmetry();
809  }
810 // sym.collect();
811  // anti-symmetrise over boxes in columns
812  if(modulo_monoterm) {
813  int newmult=1;
814  for(unsigned int c=0; c<row_size(0); ++c)
815  newmult*=combin::factorial(column_size(c));
816  for(unsigned int i=0; i<sym.size(); ++i)
817  sym.set_multiplicity(i, sym.signature(i)*newmult);
818  }
819  else {
820  sym.permute_blocks.clear();
821  for(unsigned int c=0; c<row_size(0); ++c) {
822  unsigned int r=0;
823  sym.value_permute.clear();
824  sym.permutation_sign=-1;
825  sym.input_asym.clear();
826  while(r<number_of_rows() && c<row_size(r))
827  sym.value_permute.push_back(rows[r++][c]);
828  if(sym.value_permute.size()>1)
829  sym.apply_symmetry();
830  }
831  }
832 // sym.collect();
833  }
834 
835 template<class T>
837  combin::range_vector_t& sublengths_scattered) const
838  {
839  for(unsigned int r=0; r<number_of_rows(); ++r)
840  for(unsigned int c=0; c<row_size(r); ++c)
841  sym.original.push_back(rows[r][c]);
842 
843  unsigned int offset=0;
844  // symmetrise over boxes in rows
845  for(unsigned int r=0; r<number_of_rows(); ++r) {
846  sym.permutation_sign=1;
847  sym.permute_blocks.clear();
848  sym.block_length=1;
849  sym.input_asym.clear();
850  for(unsigned int c=0; c<row_size(r); ++c)
851  sym.permute_blocks.push_back(offset++);
852  sym.apply_symmetry();
853  }
855  sym.permute_blocks.clear();
856  for(unsigned int c=0; c<row_size(0); ++c) {
857  unsigned int r=0;
858  sym.value_permute.clear();
859  sym.permutation_sign=-1;
860  while(r<number_of_rows() && c<row_size(r))
861  sym.value_permute.push_back(rows[r++][c]);
862 
863  sym.sublengths_scattered=sublengths_scattered;
864 
865 // // Now setup sublengths_scattered to take into account
866 // // asym_ranges. These asym_ranges refer to values stored in the
867 // // boxes of the full tableau. We need to find the locations of
868 // // these values inside the full original, as that is what goes
869 // // into sublengths_scattered.
870 //
871 // sym.input_asym.clear();
872 // sym.sublengths.clear();
873 // sym.sublengths_scattered.clear();
874 // for(unsigned int m=0; m<sym.value_permute.size(); ++m) {
875 // // Try to find this value in an asym range.
876 // unsigned int overlap=0;
877 // for(unsigned int n=0; n<asym_ranges.size(); ++n) {
878 // for(unsigned int nn=0; nn<asym_ranges[n].size(); ++nn) {
879 // if(sym.value_permute[m]==asym_ranges[n][nn]) {
880 // std::cout << "found " << sym.value_permute[m] << " in range" << std::endl;
881 // // FIXME: this assumes that even though asym_ranges[n] is a superset
882 // // of the current part of value_permute, elements are in the same order.
883 // ++m; ++nn;
884 // while(nn<asym_ranges[n].size()) {
885 // if(sym.value_permute[m]==asym_ranges[n][nn]) {
886 // std::cout << "same range: " << sym.value_permute[m] << std::endl;
887 // ++m;
888 // ++overlap;
889 // }
890 // ++nn;
891 // }
892 // break;
893 // }
894 // }
895 // }
896 // if(overlap>0) --m;
897 // sym.sublengths.push_back(overlap+1);
898 // }
899 // unsigned int sum=0;
900 // for(unsigned int m=0; m<sym.sublengths.size(); ++m)
901 // sum+=sym.sublengths[m];
902 //
903 // std::cout << sum << " " << sym.value_permute.size() << std::endl;
904 // assert(sum==sym.value_permute.size());
905 
906  // All set to run...
907  if(sym.value_permute.size()>1)
908  sym.apply_symmetry();
909  }
910  }
911 
912 template<class T>
914  {
915  rows=other.rows;
916  tableau::operator=(other);
917  return (*this);
918  }
919 
920 template<class T>
922  {
923  yngint_t totdim=0;
924  typename tableau_container_t::const_iterator it=storage.begin();
925  while(it!=storage.end()) {
926  totdim+=(*it).dimension(dim);
927  ++it;
928  }
929  return totdim;
930  }
931 
932 template<class T, class OutputIterator>
933 void LR_tensor(const tableaux<T>& tabs1, const T& tab2, unsigned int maxrows,
934  OutputIterator out, bool alltabs=false)
935  {
937  while(it!=tabs1.storage.end()) {
938  LR_tensor((*it), tab2, maxrows, out, alltabs);
939  ++it;
940  }
941  }
942 
943 template<class T1, class T2>
944 void add_box(T1& tab1, unsigned int row1,
945  const T2& tab2, unsigned int row2, unsigned int col2)
946  {
947  tab1.add_box(row1, tab2(row2,col2));
948  }
949 
950 template<class T1>
951 void add_box(T1& tab1, unsigned int row1,
952  const tableau& tab2, unsigned int row2, unsigned int col2)
953  {
954  tab1.add_box(row1);
955  }
956 
958 
959 template<class Tab, class OutputIterator>
960 void LR_add_box(const Tab& tab2, Tab& newtab,
961  unsigned int currow2, unsigned int curcol2, unsigned int startrow,
962  unsigned int maxrows,
963  OutputIterator outit,
964  keeptrack_tab_t& Ycurrent,
965  bool alltabs)
966  {
967  // Are we at the end of the current row of boxes in tab2 ?
968  if((++curcol2)==tab2.row_size(currow2)) {
969  // Are we at the end of tab2 altogether?
970  if((++currow2)==tab2.number_of_rows()) {
971  *outit=newtab; // Store the product tableau just created.
972  return;
973  }
974  curcol2=0;
975  startrow=0;
976  }
977 
978  // Rule "row_by_row".
979  for(unsigned int rowpos=startrow; rowpos<std::min(newtab.number_of_rows()+1,maxrows); ++rowpos) {
980  // Rule "always_young".
981  if(rowpos>0 && rowpos<newtab.number_of_rows())
982  if(newtab.row_size(rowpos-1)==newtab.row_size(rowpos))
983  continue; // No, would lead to non-Young tableau shape.
984 
985  // The column where the box will be added.
986  unsigned int colpos=(rowpos==newtab.number_of_rows())?0:newtab.row_size(rowpos);
987 
988  // Rule "avoid_sym2asym".
989  for(unsigned int rr=0; rr<rowpos; ++rr)
990  if(Ycurrent(rr,colpos).first==(int)(currow2))
991  goto rule_violated;
992 
993  // Rule "avoid_asym2sym".
994  if(alltabs) // if not generating all tabs, ordered will take care of this already.
995  for(unsigned int cc=0; cc<colpos; ++cc)
996  if(Ycurrent(rowpos,cc).second==(int)(curcol2))
997  goto rule_violated;
998 
999  // Rule "ordered".
1000  if(!alltabs && currow2>0) {
1001  int numi=0, numimin1=0;
1002  if(rowpos>0) {
1003  for(unsigned int sr=0; sr<rowpos; ++sr) // top to bottom
1004  for(unsigned int sc=0; sc<Ycurrent.row_size(sr); ++sc) { // right to left
1005  // Count all boxes from currow2 and from currow2-1.
1006  if(Ycurrent(sr,sc).first==(int)(currow2)) ++numi;
1007  if(Ycurrent(sr,sc).first==(int)(currow2)-1) ++numimin1;
1008  }
1009  }
1010  ++numi; // the box to be added
1011  if(numi>numimin1)
1012  goto rule_violated;
1013 
1014  // continue counting to see whether a previously valid box is now invalid
1015  for(unsigned int sr=rowpos; sr<Ycurrent.number_of_rows(); ++sr) // top to bottom
1016  for(int sc=Ycurrent.row_size(sr)-1; sc>=0; --sc) { // right to left
1017  if(Ycurrent(sr,sc).first==(int)(currow2)) ++numi;
1018  if(Ycurrent(sr,sc).first==(int)(currow2)-1) ++numimin1;
1019  if(numi>numimin1)
1020  goto rule_violated;
1021  }
1022  }
1023 
1024  // Put the box at row 'rowpos' and call LR_add_box recursively
1025  // to add the other boxes.
1026  Ycurrent.add_box(rowpos, std::pair<int,int>(currow2, curcol2));
1027  add_box(newtab, rowpos, tab2, currow2, curcol2);
1028  LR_add_box(tab2, newtab, currow2, curcol2, alltabs?0:rowpos, maxrows,
1029  outit, Ycurrent, alltabs);
1030 
1031  // Remove the box again in preparation for trying to add it to other rows.
1032  newtab.remove_box(rowpos);
1033  Ycurrent.remove_box(rowpos);
1034 
1035  rule_violated: ;
1036  }
1037  }
1038 
1039 template<class Tab, class OutputIterator>
1040 void LR_tensor(const Tab& tab1, const Tab& tab2, unsigned int maxrows,
1041  OutputIterator outit, bool alltabs=false)
1042  {
1043  // Make a copy of tab1 because LR_add_box has to change it and
1044  // tab1 is const here.
1045  Tab newtab(tab1);
1046 
1047  // Tableau which keeps track of the LR rules. It contains the
1048  // current (incomplete) shape of the tensor product, and for all boxes
1049  // which come from tab2 we store the row and column of tab2
1050  // from which they originated. Tab1 boxes have (-2,-2) stored.
1051  keeptrack_tab_t Ycurrent;
1052  Ycurrent.copy_shape(tab1);
1053  keeptrack_tab_t::iterator yi=Ycurrent.begin();
1054  while(yi!=Ycurrent.end()) {
1055  (*yi)=std::pair<int,int>(-2,-2);
1056  ++yi;
1057  }
1058 
1059  LR_add_box(tab2, newtab, 0, -1, 0, maxrows, outit, Ycurrent, alltabs);
1060  }
1061 
1062 template<class T, class OutputIterator>
1063 void LR_tensor(const tableaux<T>&, bool symmetric, unsigned int maxrows, OutputIterator outit)
1064  {
1065  assert(1==0);
1066  }
1067 
1068 
1069 
1070 std::ostream& operator<<(std::ostream&, const tableau& );
1071 
1072 template<class T>
1073 std::ostream& operator<<(std::ostream&, const tableaux<T>& );
1074 
1075 template<class T>
1076 std::ostream& operator<<(std::ostream&, const filled_tableau<T>& );
1077 
1078 template<class T>
1080  {
1081  return rows.size();
1082  }
1083 
1084 template<class T>
1085 unsigned int filled_tableau<T>::row_size(unsigned int num) const
1086  {
1087  assert(num<rows.size());
1088  return rows[num].size();
1089  }
1090 
1091 template<class T>
1092 T& filled_tableau<T>::operator()(unsigned int row, unsigned int col)
1093  {
1094  assert(row<rows.size());
1095  assert(col<rows[row].size());
1096  return rows[row][col];
1097  }
1098 
1099 template<class T>
1100 const T& filled_tableau<T>::operator()(unsigned int row, unsigned int col) const
1101  {
1102  assert(row<rows.size());
1103  assert(col<rows[row].size());
1104  return rows[row][col];
1105  }
1106 
1107 template<class T>
1108 const T& filled_tableau<T>::operator[](unsigned int boxnum) const
1109  {
1110  assert(1==0);
1111  assert(this->row<rows.size());
1112  assert(this->col<rows[this->row].size());
1113  return rows[this->row][this->col];
1114  }
1115 
1116 template<class T>
1118  {
1119  }
1120 
1121 template<class T>
1122 void filled_tableau<T>::add_box(unsigned int rownum)
1123  {
1124  if(rownum>=rows.size())
1125  rows.resize(rownum+1);
1126  assert(rownum<rows.size());
1127  rows[rownum].push_back(T());
1128  }
1129 
1130 template<class T>
1131 void filled_tableau<T>::add_box(unsigned int rownum, T val)
1132  {
1133  if(rownum>=rows.size())
1134  rows.resize(rownum+1);
1135  assert(rownum<rows.size());
1136  rows[rownum].push_back(val);
1137  }
1138 
1139 template<class T>
1140 void filled_tableau<T>::swap_columns(unsigned int c1, unsigned int c2)
1141  {
1142  assert(c1<row_size(0) && c2<row_size(0));
1143  assert(column_size(c1)==column_size(c2));
1144  for(unsigned int r=0; r<column_size(c1); ++r) {
1145  T tmp=(*this)(r,c1);
1146  (*this)(r,c1)=(*this)(r,c2);
1147  (*this)(r,c2)=tmp;
1148  }
1149  }
1150 
1151 template<class T>
1152 void filled_tableau<T>::remove_box(unsigned int rownum)
1153  {
1154  assert(rownum<rows.size());
1155  assert(rows[rownum].size()>0);
1156  rows[rownum].pop_back();
1157  if(rows[rownum].size()==0)
1158  rows.pop_back();
1159  }
1160 
1161 template<class T>
1163  {
1164  rows.clear();
1165  tableau::clear();
1166  }
1167 
1168 template<class T>
1169 std::ostream& operator<<(std::ostream& str, const tableaux<T>& tabs)
1170  {
1172  while(it!=tabs.storage.end()) {
1173  str << (*it) << std::endl << std::endl;
1174  ++it;
1175  }
1176  return str;
1177  }
1178 
1179 template<class T>
1180 std::ostream& operator<<(std::ostream& str, const filled_tableau<T>& tab)
1181  {
1182  for(unsigned int i=0; i<tab.number_of_rows(); ++i) {
1183  for(unsigned int j=0; j<tab.row_size(i); ++j) {
1184 // str << "|" << tab(i,j) << "|";
1185  str << tab(i,j);
1186  }
1187  if(i==0) {
1188  str << " " << tab.dimension(10);
1189  if(tab.has_nullifying_trace()) str << " null";
1190  }
1191  if(i!=tab.number_of_rows()-1)
1192  str << std::endl;
1193  else
1194  str << " (" << tab.multiplicity << ")" << std::endl;
1195  }
1196  return str;
1197  }
1198 
1199 };
1200 
1201 
const T & operator[](unsigned int boxnum) const
Definition: YoungTab.hh:1108
in_column_iterator(unsigned int r, unsigned int c, filled_tableau< T > *)
Definition: YoungTab.hh:384
std::vector< int > rows
Definition: YoungTab.hh:77
An iterator over all boxes of a tableau, left to right, top to bottom.
Definition: YoungTab.hh:159
bool compare_without_multiplicity(const filled_tableau< T > &other) const
Definition: YoungTab.hh:277
T & operator*() const
Definition: YoungTab.hh:541
T * operator->() const
Definition: YoungTab.hh:547
std::pair< int, int > nonstandard_loc() const
Definition: YoungTab.hh:717
bool operator==(const iterator &) const
Definition: YoungTab.hh:627
range_vector_t sublengths_scattered
Definition: Combinatorics.hh:167
virtual unsigned int row_size(unsigned int row) const
Definition: YoungTab.hh:1085
virtual unsigned int number_of_rows() const
Definition: YoungTab.hh:1079
virtual unsigned int number_of_rows() const
Definition: YoungTab.cc:110
unsigned int column_number
Definition: YoungTab.hh:155
std::vector< T > box_row
Definition: YoungTab.hh:193
unsigned int row_number
Definition: YoungTab.hh:155
unsigned long hook_length(unsigned int row, unsigned int col) const
Definition: YoungTab.cc:72
std::list< T > tableau_container_t
Definition: YoungTab.hh:209
bool has_nullifying_trace() const
Definition: YoungTab.hh:283
in_column_iterator & operator++()
Definition: YoungTab.hh:424
mpq_class yngrat_t
Definition: YoungTab.hh:39
yngrat_t projector_normalisation() const
Definition: YoungTab.hh:785
An iterator which stays inside a given column of a tableau.
Definition: YoungTab.hh:131
ptrdiff_t difference_type
Definition: YoungTab.hh:126
T & operator()(unsigned int row, unsigned int col)
Definition: YoungTab.hh:1092
in_column_iterator & operator--()
Definition: YoungTab.hh:438
Definition: Combinatorics.hh:125
virtual void add_box(unsigned int row)=0
Definition: YoungTab.hh:81
bool operator!=(const iterator &) const
Definition: YoungTab.hh:649
int permutation_sign
Definition: Combinatorics.hh:163
void copy_shape(const tableau &)
Definition: YoungTab.hh:267
void sort_columns()
Definition: YoungTab.hh:332
bool legal_box(const std::vector< std::pair< int, int > > &prev, const std::vector< std::pair< int, int > > &ths, int colpos, int trypos)
yngint_t total_dimension(unsigned int dim)
Definition: YoungTab.hh:921
in_column_iterator operator-(unsigned int)
virtual unsigned int row_size(unsigned int row) const
Definition: YoungTab.cc:115
virtual void clear()
Definition: YoungTab.hh:1162
virtual void add_box(unsigned int row)
Definition: YoungTab.hh:1122
unsigned long factorial(unsigned int x)
Definition: Combinatorics.cc:23
virtual void add_row(unsigned int row_size)
Definition: YoungTab.cc:39
unsigned int block_length
Definition: Combinatorics.hh:160
OutputIterator Garnir_set(OutputIterator, unsigned int, unsigned int) const
Definition: YoungTab.hh:693
unsigned int row_number
Definition: YoungTab.hh:181
iterator & operator--()
Definition: YoungTab.hh:576
tableau_base()
Definition: YoungTab.cc:26
std::vector< unsigned int > permute_blocks
Definition: Combinatorics.hh:161
virtual void add_box(unsigned int row)
Definition: YoungTab.cc:91
bool standard_form()
Put the set of tableaux into standard form by using Garnir symmetries.
Definition: YoungTab.hh:732
int ordersign(unsigned int) const
Definition: Combinatorics.hh:456
tableau_container_t storage
Definition: YoungTab.hh:210
virtual unsigned int row_size(unsigned int row) const =0
T value_type
Definition: YoungTab.hh:122
void permute(long start=-1, long end=-1)
Definition: Combinatorics.hh:349
filled_tableau< T > * tab
Definition: YoungTab.hh:154
std::ostream & operator<<(std::ostream &str, const tableau &tab)
Definition: YoungTab.cc:132
int selfdual_column
Definition: YoungTab.hh:60
unsigned int size() const
Definition: Combinatorics.hh:427
T * operator->() const
Definition: YoungTab.hh:418
iterator operator+(unsigned int)
Definition: YoungTab.hh:519
bool operator<(const in_column_iterator &other) const
Definition: YoungTab.hh:490
void symmetrise(const T &tabsym)
Definition: YoungTab.hh:242
iterator & operator++()
Definition: YoungTab.hh:553
std::vector< T > value_permute
Definition: Combinatorics.hh:162
Definition: YoungTab.hh:66
unsigned int column_number
Definition: YoungTab.hh:181
std::vector< unsigned int > sublengths
Definition: Combinatorics.hh:74
iterator end() const
Definition: YoungTab.hh:664
void remove_nullifying_traces()
Definition: YoungTab.hh:231
yngint_t hook_length_prod() const
Definition: YoungTab.cc:82
Definition: YoungTab.hh:84
Definition: YoungTab.hh:120
virtual void clear()
Definition: YoungTab.cc:121
bool operator<(const iterator &other) const
Definition: YoungTab.hh:635
std::pair< int, int > find(const T &) const
Definition: YoungTab.hh:313
T * pointer
Definition: YoungTab.hh:123
T & operator*() const
Definition: YoungTab.hh:412
bool operator!=(const in_column_iterator &) const
Definition: YoungTab.hh:504
void sort_within_columns()
Definition: YoungTab.hh:325
std::vector< T > original
Definition: Combinatorics.hh:159
row_stack rows
Definition: YoungTab.hh:195
virtual ~tableau()
Definition: YoungTab.cc:35
iterator & operator-=(unsigned int)
Definition: YoungTab.hh:613
virtual void remove_box(unsigned int row)
Definition: YoungTab.cc:102
tableau & operator=(const tableau &)
Definition: YoungTab.cc:126
T & reference
Definition: YoungTab.hh:124
in_column_iterator operator+(unsigned int)
Definition: YoungTab.hh:390
yngint_t dimension(unsigned int) const
Definition: YoungTab.cc:47
filled_tableau< T > & operator=(const filled_tableau< T > &)
Definition: YoungTab.hh:913
in_column_iterator & operator-=(unsigned int)
Definition: YoungTab.hh:461
virtual unsigned int number_of_rows() const =0
mpz_class yngint_t
Definition: YoungTab.hh:38
bool operator==(const in_column_iterator &) const
Definition: YoungTab.hh:468
std::vector< box_row > row_stack
Definition: YoungTab.hh:194
void apply_symmetry(long start=-1, long end=-1)
Definition: Combinatorics.hh:693
iterator operator-(unsigned int)
in_column_iterator & operator+=(unsigned int)
Definition: YoungTab.hh:431
void projector(combin::symmetriser< T > &, bool modulo_monoterm=false) const
Definition: YoungTab.hh:793
std::vector< T > original
Definition: Combinatorics.hh:76
bool operator>=(const in_column_iterator &other) const
Definition: YoungTab.hh:483
std::random_access_iterator_tag iterator_category
Definition: YoungTab.hh:127
unsigned int size() const
Definition: Combinatorics.hh:904
virtual ~filled_tableau()
Definition: YoungTab.hh:1117
void swap_columns(unsigned int c1, unsigned int c2)
Definition: YoungTab.hh:1140
Definition: YoungTab.hh:47
void set_multiplicity(unsigned int pos, int val)
Definition: Combinatorics.hh:1001
bool operator>(const iterator &other) const
Definition: YoungTab.hh:642
yngrat_t multiplicity
Definition: YoungTab.hh:59
int signature(unsigned int) const
Definition: Combinatorics.hh:994
size_t size_type
Definition: YoungTab.hh:125
Definition: Combinatorics.hh:101
std::vector< range_t > range_vector_t
Definition: Combinatorics.hh:40
void canonicalise()
Sort equal-length columns and sort within columns.
Definition: YoungTab.hh:339
virtual void clear()=0
void add_tableau(const T &)
Definition: YoungTab.hh:768
back_insert_iterator get_back_insert_iterator()
Definition: YoungTab.hh:225
virtual void remove_box(unsigned int row)
Definition: YoungTab.hh:1152
virtual unsigned int column_size(unsigned int col) const
Definition: YoungTab.cc:61
bool operator<=(const in_column_iterator &other) const
Definition: YoungTab.hh:476
virtual ~tableau_base()
Definition: YoungTab.cc:31
in_column_iterator begin_column(unsigned int column_number)
Definition: YoungTab.hh:670
filled_tableau< T > * tab
Definition: YoungTab.hh:180
bool operator>(const in_column_iterator &other) const
Definition: YoungTab.hh:497
void LR_add_box(const Tab &tab2, Tab &newtab, unsigned int currow2, unsigned int curcol2, unsigned int startrow, unsigned int maxrows, OutputIterator outit, keeptrack_tab_t &Ycurrent, bool alltabs)
Definition: YoungTab.hh:960
std::back_insert_iterator< tableau_container_t > back_insert_iterator
Definition: YoungTab.hh:212
iterator(unsigned int r, unsigned int c, filled_tableau< T > *)
Definition: YoungTab.hh:513
void LR_tensor(const tableaux< T > &tabs1, const T &tab2, unsigned int maxrows, OutputIterator out, bool alltabs=false)
Definition: YoungTab.hh:933
int ordersign(iterator1 b1, iterator1 e1, iterator2 b2, iterator2 e2, int stepsize=1)
Definition: Combinatorics.hh:224
in_column_iterator end_column(unsigned int column_number)
Definition: YoungTab.hh:679
T value_type
Definition: YoungTab.hh:86
iterator & operator+=(unsigned int)
Definition: YoungTab.hh:563
filled_tableau< std::pair< int, int > > keeptrack_tab_t
Definition: YoungTab.hh:957
range_vector_t input_asym
Definition: Combinatorics.hh:166
virtual void remove_box(unsigned int row)=0
iterator begin() const
Definition: YoungTab.hh:658