/* Cadabra: a field-theory motivated computer algebra system. Copyright (C) 2001-2011 Kasper Peeters This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* - TODO: has_nullifying trace is wrong, but needs to be merged with the input_asym code in order to be more useful. */ #pragma once #include #include #include #include #include #include #include "Combinatorics.hh" #include typedef mpz_class yngint_t; typedef mpq_class yngrat_t; /// Generic Young tableaux routines namespace yngtab { // The tableau_base is the abstract interface; does not depend on the // actual storage format. class tableau_base { public: tableau_base(); virtual ~tableau_base(); virtual unsigned int number_of_rows() const=0; virtual unsigned int row_size(unsigned int row) const=0; virtual unsigned int column_size(unsigned int col) const; // FIXME: maybe make pure virt too virtual void add_box(unsigned int row)=0; virtual void remove_box(unsigned int row)=0; virtual void add_row(unsigned int row_size); virtual void clear()=0; yngrat_t multiplicity; // also keeps track of signs int selfdual_column; // -n, 0, n for antiselfdual, no, selfdual (count from 1) yngint_t dimension(unsigned int) const; unsigned long hook_length(unsigned int row, unsigned int col) const; yngint_t hook_length_prod() const; }; class tableau : public tableau_base { public: virtual ~tableau(); virtual unsigned int number_of_rows() const; virtual unsigned int row_size(unsigned int row) const; virtual void add_box(unsigned int row); virtual void remove_box(unsigned int row); virtual void clear(); tableau& operator=(const tableau&); private: std::vector rows; }; template class tableaux; template class filled_tableau : public tableau { public: typedef T value_type; virtual ~filled_tableau(); virtual unsigned int number_of_rows() const; virtual unsigned int row_size(unsigned int row) const; virtual void add_box(unsigned int row); virtual void remove_box(unsigned int row); std::pair find(const T&) const; virtual void clear(); void copy_shape(const tableau&); T& operator()(unsigned int row, unsigned int col); const T& operator()(unsigned int row, unsigned int col) const; const T& operator[](unsigned int boxnum) const; void add_box(unsigned int rownum, T val); void swap_columns(unsigned int c1, unsigned int c2); bool compare_without_multiplicity(const filled_tableau& other) const; bool has_nullifying_trace() const; void sort_within_columns(); void sort_columns(); /// Sort equal-length columns and sort within columns. void canonicalise(); std::pair nonstandard_loc() const; template void sort_within_columns(StrictWeakOrdering comp); template void sort_columns(StrictWeakOrdering comp); template void canonicalise(StrictWeakOrdering comp, bool only_col_ex=false); void projector(combin::symmetriser&, bool modulo_monoterm=false) const; void projector(combin::symmetriser&, combin::range_vector_t&) const; yngrat_t projector_normalisation() const; filled_tableau& operator=(const filled_tableau&); class iterator_base { public: typedef T value_type; typedef T* pointer; typedef T& reference; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef std::random_access_iterator_tag iterator_category; }; class const_iterator_base { public: typedef T value_type; typedef const T* pointer; typedef const T& reference; typedef size_t size_type; typedef ptrdiff_t difference_type; typedef std::random_access_iterator_tag iterator_category; }; class const_iterator; class in_column_iterator; class in_column_const_iterator; class in_row_iterator; class in_row_const_iterator; /// An iterator which stays inside a given column of a tableau. class in_column_iterator : public iterator_base { public: in_column_iterator(unsigned int r, unsigned int c, filled_tableau *); T& operator*() const; T* operator->() const; in_column_iterator& operator++(); in_column_iterator operator++(int); in_column_iterator& operator--(); in_column_iterator operator--(int); in_column_iterator operator+(unsigned int); in_column_iterator operator-(unsigned int); in_column_iterator& operator+=(unsigned int); in_column_iterator& operator-=(unsigned int); T& operator[](int n) const; bool operator<(const in_column_iterator& other) const; bool operator>(const in_column_iterator& other) const; bool operator<=(const in_column_iterator& other) const; bool operator>=(const in_column_iterator& other) const; ptrdiff_t operator-(const in_column_iterator&) const; bool operator==(const in_column_iterator&) const; bool operator!=(const in_column_iterator&) const; friend class filled_tableau; friend class filled_tableau::in_column_const_iterator; private: filled_tableau *tab; unsigned int column_number, row_number; }; /// A const iterator which stays inside a given column of a tableau. class in_column_const_iterator : public const_iterator_base { public: in_column_const_iterator(unsigned int r, unsigned int c, const filled_tableau*); in_column_const_iterator(const in_column_iterator& other); const T& operator*() const; const T* operator->() const; in_column_const_iterator& operator++(); in_column_const_iterator operator++(int); in_column_const_iterator& operator--(); in_column_const_iterator operator--(int); in_column_const_iterator operator+(unsigned int); in_column_const_iterator operator-(unsigned int); in_column_const_iterator& operator+=(unsigned int); in_column_const_iterator& operator-=(unsigned int); bool operator<(const in_column_const_iterator& other) const; bool operator>(const in_column_const_iterator& other) const; bool operator<=(const in_column_const_iterator& other) const; bool operator>=(const in_column_const_iterator& other) const; ptrdiff_t operator-(const in_column_const_iterator&) const; bool operator==(const in_column_const_iterator&) const; bool operator!=(const in_column_const_iterator&) const; friend class filled_tableau; private: const filled_tableau* tab; unsigned int column_number, row_number; }; /// An iterator which stays inside a given row of a tableau. class in_row_iterator : public iterator_base { public: in_row_iterator(unsigned int r, unsigned int c, filled_tableau*); T& operator*() const; T* operator->() const; in_row_iterator& operator++(); in_row_iterator operator++(int); in_row_iterator& operator--(); in_row_iterator operator--(int); in_row_iterator operator+(unsigned int); in_row_iterator operator-(unsigned int); in_row_iterator& operator+=(unsigned int); in_row_iterator& operator-=(unsigned int); bool operator<(const in_row_iterator& other) const; bool operator>(const in_row_iterator& other) const; bool operator<=(const in_row_iterator& other) const; bool operator>=(const in_row_iterator& other) const; ptrdiff_t operator-(const in_row_iterator&) const; bool operator==(const in_row_iterator&) const; bool operator!=(const in_row_iterator&) const; friend class filled_tableau; friend class filled_tableau::in_row_const_iterator; private: filled_tableau* tab; unsigned int column_number, row_number; }; class in_row_const_iterator : public const_iterator_base { public: in_row_const_iterator(unsigned int r, unsigned int c, const filled_tableau*); in_row_const_iterator(const in_row_iterator& other); const T& operator*() const; const T* operator->() const; in_row_const_iterator& operator++(); in_row_const_iterator operator++(int); in_row_const_iterator& operator--(); in_row_const_iterator operator--(int); in_row_const_iterator operator+(unsigned int); in_row_const_iterator operator-(unsigned int); in_row_const_iterator& operator+=(unsigned int); in_row_const_iterator& operator-=(unsigned int); bool operator<(const in_row_const_iterator& other) const; bool operator>(const in_row_const_iterator& other) const; bool operator<=(const in_row_const_iterator& other) const; bool operator>=(const in_row_const_iterator& other) const; ptrdiff_t operator-(const in_row_const_iterator&) const; bool operator==(const in_row_const_iterator&) const; bool operator!=(const in_row_const_iterator&) const; friend class filled_tableau; private: const filled_tableau* tab; unsigned int column_number, row_number; }; /// An iterator over all boxes of a tableau, left to right, top to bottom. class iterator : public iterator_base { public: iterator(unsigned int r, unsigned int c, filled_tableau *); T& operator*() const; T* operator->() const; iterator& operator++(); iterator operator++(int); iterator& operator--(); iterator operator--(int); iterator operator+(unsigned int); iterator operator-(unsigned int); iterator& operator+=(unsigned int); iterator& operator-=(unsigned int); bool operator<(const iterator& other) const; bool operator>(const iterator& other) const; ptrdiff_t operator-(const iterator&) const; bool operator==(const iterator&) const; bool operator!=(const iterator&) const; friend class filled_tableau; friend class filled_tableau::const_iterator; private: filled_tableau *tab; unsigned int column_number, row_number; }; class const_iterator : public const_iterator_base { public: const_iterator(unsigned int r, unsigned int c, const filled_tableau*); const_iterator(const iterator& other); const T& operator*() const; const T* operator->() const; const_iterator& operator++(); const_iterator operator++(int); const_iterator& operator--(); const_iterator operator--(int); const_iterator operator+(unsigned int); const_iterator operator-(unsigned int); const_iterator& operator+=(unsigned int); const_iterator& operator-=(unsigned int); bool operator<(const const_iterator& other) const; bool operator>(const const_iterator& other) const; ptrdiff_t operator-(const const_iterator&) const; bool operator==(const const_iterator&) const; bool operator!=(const const_iterator&) const; friend class filled_tableau; private: const filled_tableau* tab; unsigned int column_number, row_number; }; in_column_iterator begin_column(unsigned int column_number); in_column_iterator end_column(unsigned int column_number); in_column_const_iterator begin_column(unsigned int column_number) const; in_column_const_iterator end_column(unsigned int column_number) const; in_column_const_iterator cbegin_column(unsigned int column_number) const; in_column_const_iterator cend_column(unsigned int column_number) const; in_row_iterator begin_row(unsigned int row_number); in_row_iterator end_row(unsigned int row_number); in_row_const_iterator begin_row(unsigned int row_number) const; in_row_const_iterator end_row(unsigned int row_number) const; in_row_const_iterator cbegin_row(unsigned int row_number) const; in_row_const_iterator cend_row(unsigned int row_number) const; iterator begin(); iterator end(); const_iterator begin() const; const_iterator end() const; const_iterator cbegin() const; const_iterator cend() const; template OutputIterator Garnir_set(OutputIterator, unsigned int, unsigned int) const; private: typedef std::vector box_row; typedef std::vector row_stack; row_stack rows; }; template class tableaux { public: yngint_t total_dimension(unsigned int dim); void remove_nullifying_traces(); /// Put the set of tableaux into standard form by using Garnir symmetries. /// Return value indicates whether the tableaux were already all in standard form. bool standard_form(); void add_tableau(const T&); void symmetrise(const T& tabsym); typedef std::list tableau_container_t; tableau_container_t storage; typedef std::back_insert_iterator back_insert_iterator; back_insert_iterator get_back_insert_iterator(); }; bool legal_box(const std::vector >& prev, const std::vector >& ths, int colpos, int trypos); // -------------------------------------- template typename tableaux::back_insert_iterator tableaux::get_back_insert_iterator() { return back_insert_iterator(storage); } template void tableaux::remove_nullifying_traces() { typename tableau_container_t::iterator it=storage.begin(); while(it!=storage.end()) { if(it->has_nullifying_trace()) it=storage.erase(it); else ++it; } } template void tableaux::symmetrise(const T&) { // // typename tableau_container_t::iterator thetab=storage.begin(); // while(thetab!=storage.end()) { // (*thetab).sort_columns(); // std::pair where=(*thetab).nonstandard_loc(); // if(where.first!=-1) { // combinations com; // /* FIXME: we should have two LR_tensor routines, because if you do 'alltabs', you should keep track of which boxes came from tableau 2. So do a LR_tensor with numbered boxes, and then after the LR_tensor apply the symmetries of the original tableaux, put back the original index names, sort columns and determine whether the tableau is identically non-zero. Then add to the product. Another issue: adding to tableaux should have an option to not insert doubles. There was something third, forgotten... */ } template void filled_tableau::copy_shape(const tableau& other) { rows.clear(); for(unsigned int r=0; r bool filled_tableau::compare_without_multiplicity(const filled_tableau& other) const { return (rows==other.rows); } template bool filled_tableau::has_nullifying_trace() const { return false; // Old, probably incorrect code: // // for(unsigned int r1=0; r1 std::pair filled_tableau::find(const T& obj) const { for(unsigned int ir=0; ir(ir, ic); } } return std::pair(-1,-1); } template void filled_tableau::sort_within_columns() { std::less comp; sort_within_columns(comp); } template void filled_tableau::sort_columns() { std::less comp; sort_columns(comp); } template void filled_tableau::canonicalise() { std::less comp; canonicalise(comp); } template template void filled_tableau::sort_within_columns(StrictWeakOrdering comp) { filled_tableau tmp(*this); if(number_of_rows()==0) return; for(unsigned int c=0; c template void filled_tableau::sort_columns(StrictWeakOrdering comp) { for(unsigned int c1=0; c1 template void filled_tableau::canonicalise(StrictWeakOrdering comp, bool only_col_ex) { if(!only_col_ex) sort_within_columns(comp); sort_columns(comp); } //--------------------------------------------------------------------------- // in_column_iterator template filled_tableau::in_column_iterator::in_column_iterator(unsigned int r, unsigned int c, filled_tableau *t) : tab(t), column_number(c), row_number(r) { } template typename filled_tableau::in_column_iterator filled_tableau::in_column_iterator::operator+(unsigned int n) { typename filled_tableau::in_column_iterator it2(*this); it2+=n; return it2; } template typename filled_tableau::in_column_iterator filled_tableau::in_column_iterator::operator-(unsigned int n) { typename filled_tableau::in_column_iterator it2(*this); it2-=n; return it2; } template ptrdiff_t filled_tableau::in_column_iterator::operator-(const in_column_iterator& other) const { return row_number-other.row_number; } template T& filled_tableau::in_column_iterator::operator[](int n) const { return (*tab)(row_number + n, column_number); } template T& filled_tableau::in_column_iterator::operator*() const { return (*tab)(row_number,column_number); } template T* filled_tableau::in_column_iterator::operator->() const { return &((*tab)(row_number,column_number)); } template typename filled_tableau::in_column_iterator& filled_tableau::in_column_iterator::operator++() { ++row_number; return (*this); } template typename filled_tableau::in_column_iterator& filled_tableau::in_column_iterator::operator+=(unsigned int n) { row_number+=n; return (*this); } template typename filled_tableau::in_column_iterator& filled_tableau::in_column_iterator::operator--() { --row_number; return (*this); } template typename filled_tableau::in_column_iterator filled_tableau::in_column_iterator::operator--(int) { in_column_iterator tmp(*this); --row_number; return tmp; } template typename filled_tableau::in_column_iterator filled_tableau::in_column_iterator::operator++(int) { in_column_iterator tmp(*this); ++row_number; return tmp; } template typename filled_tableau::in_column_iterator& filled_tableau::in_column_iterator::operator-=(unsigned int n) { row_number-=n; return (*this); } template bool filled_tableau::in_column_iterator::operator==(const in_column_iterator& other) const { if(tab==other.tab && row_number==other.row_number && column_number==other.column_number) return true; return false; } template bool filled_tableau::in_column_iterator::operator<=(const in_column_iterator& other) const { if(row_number<=other.row_number) return true; return false; } template bool filled_tableau::in_column_iterator::operator>=(const in_column_iterator& other) const { if(row_number>=other.row_number) return true; return false; } template bool filled_tableau::in_column_iterator::operator<(const in_column_iterator& other) const { if(row_number bool filled_tableau::in_column_iterator::operator>(const in_column_iterator& other) const { if(row_number>other.row_number) return true; return false; } template bool filled_tableau::in_column_iterator::operator!=(const in_column_iterator& other) const { return !((*this)==other); } //--------------------------------------------------------------------------- // in_column_const_iterator template filled_tableau::in_column_const_iterator::in_column_const_iterator(unsigned int r, unsigned int c, const filled_tableau* t) : tab(t), column_number(c), row_number(r) { } template filled_tableau::in_column_const_iterator::in_column_const_iterator(const filled_tableau::in_column_iterator& other) : tab(other.tab), column_number(other.column_number), row_number(other.row_number) { } template typename filled_tableau::in_column_const_iterator filled_tableau::in_column_const_iterator::operator+(unsigned int n) { typename filled_tableau::in_column_const_iterator it2(*this); it2 += n; return it2; } template typename filled_tableau::in_column_const_iterator filled_tableau::in_column_const_iterator::operator-(unsigned int n) { typename filled_tableau::in_column_const_iterator it2(*this); it2 -= n; return it2; } template ptrdiff_t filled_tableau::in_column_const_iterator::operator-(const in_column_const_iterator& other) const { return row_number - other.row_number; } template const T& filled_tableau::in_column_const_iterator::operator*() const { return (*tab)(row_number, column_number); } template const T* filled_tableau::in_column_const_iterator::operator->() const { return &((*tab)(row_number, column_number)); } template typename filled_tableau::in_column_const_iterator& filled_tableau::in_column_const_iterator::operator++() { ++row_number; return (*this); } template typename filled_tableau::in_column_const_iterator& filled_tableau::in_column_const_iterator::operator+=(unsigned int n) { row_number += n; return (*this); } template typename filled_tableau::in_column_const_iterator& filled_tableau::in_column_const_iterator::operator--() { --row_number; return (*this); } template typename filled_tableau::in_column_const_iterator filled_tableau::in_column_const_iterator::operator--(int) { in_column_const_iterator tmp(*this); --row_number; return tmp; } template typename filled_tableau::in_column_const_iterator filled_tableau::in_column_const_iterator::operator++(int) { in_column_const_iterator tmp(*this); ++row_number; return tmp; } template typename filled_tableau::in_column_const_iterator& filled_tableau::in_column_const_iterator::operator-=(unsigned int n) { row_number -= n; return (*this); } template bool filled_tableau::in_column_const_iterator::operator==(const in_column_const_iterator& other) const { if (tab == other.tab && row_number == other.row_number && column_number == other.column_number) return true; return false; } template bool filled_tableau::in_column_const_iterator::operator<=(const in_column_const_iterator & other) const { if (row_number <= other.row_number) return true; return false; } template bool filled_tableau::in_column_const_iterator::operator>=(const in_column_const_iterator & other) const { if (row_number >= other.row_number) return true; return false; } template bool filled_tableau::in_column_const_iterator::operator<(const in_column_const_iterator & other) const { if (row_number < other.row_number) return true; return false; } template bool filled_tableau::in_column_const_iterator::operator>(const in_column_const_iterator & other) const { if (row_number > other.row_number) return true; return false; } template bool filled_tableau::in_column_const_iterator::operator!=(const in_column_const_iterator & other) const { return !((*this) == other); } //--------------------------------------------------------------------------- // in_row_iterator template filled_tableau::in_row_iterator::in_row_iterator(unsigned int r, unsigned int c, filled_tableau* t) : tab(t), column_number(c), row_number(r) { } template typename filled_tableau::in_row_iterator filled_tableau::in_row_iterator::operator+(unsigned int n) { typename filled_tableau::in_row_iterator it2(*this); it2 += n; return it2; } template typename filled_tableau::in_row_iterator filled_tableau::in_row_iterator::operator-(unsigned int n) { typename filled_tableau::in_row_iterator it2(*this); it2 -= n; return it2; } template ptrdiff_t filled_tableau::in_row_iterator::operator-(const in_row_iterator& other) const { return column_number - other.column_number; } template T& filled_tableau::in_row_iterator::operator*() const { return (*tab)(row_number, column_number); } template T* filled_tableau::in_row_iterator::operator->() const { return &((*tab)(row_number, column_number)); } template typename filled_tableau::in_row_iterator& filled_tableau::in_row_iterator::operator++() { ++column_number; return (*this); } template typename filled_tableau::in_row_iterator& filled_tableau::in_row_iterator::operator+=(unsigned int n) { column_number += n; return (*this); } template typename filled_tableau::in_row_iterator& filled_tableau::in_row_iterator::operator--() { --column_number; return (*this); } template typename filled_tableau::in_row_iterator filled_tableau::in_row_iterator::operator--(int) { in_row_iterator tmp(*this); --column_number; return tmp; } template typename filled_tableau::in_row_iterator filled_tableau::in_row_iterator::operator++(int) { in_row_iterator tmp(*this); ++column_number; return tmp; } template typename filled_tableau::in_row_iterator& filled_tableau::in_row_iterator::operator-=(unsigned int n) { column_number -= n; return (*this); } template bool filled_tableau::in_row_iterator::operator==(const in_row_iterator& other) const { if (tab == other.tab && row_number == other.row_number && column_number == other.column_number) return true; return false; } template bool filled_tableau::in_row_iterator::operator<=(const in_row_iterator & other) const { if (column_number <= other.column_number) return true; return false; } template bool filled_tableau::in_row_iterator::operator>=(const in_row_iterator & other) const { if (column_number >= other.column_number) return true; return false; } template bool filled_tableau::in_row_iterator::operator<(const in_row_iterator & other) const { if (column_number < other.column_number) return true; return false; } template bool filled_tableau::in_row_iterator::operator>(const in_row_iterator & other) const { if (column_number > other.column_number) return true; return false; } template bool filled_tableau::in_row_iterator::operator!=(const in_row_iterator & other) const { return !((*this) == other); } //--------------------------------------------------------------------------- // in_row_const_iterator template filled_tableau::in_row_const_iterator::in_row_const_iterator(unsigned int r, unsigned int c, const filled_tableau* t) : tab(t), column_number(c), row_number(r) { } template filled_tableau::in_row_const_iterator::in_row_const_iterator(const filled_tableau::in_row_iterator& other) : tab(other.tab), column_number(other.column_number), row_number(other.row_number) { } template typename filled_tableau::in_row_const_iterator filled_tableau::in_row_const_iterator::operator+(unsigned int n) { typename filled_tableau::in_row_const_iterator it2(*this); it2 += n; return it2; } template typename filled_tableau::in_row_const_iterator filled_tableau::in_row_const_iterator::operator-(unsigned int n) { typename filled_tableau::in_row_const_iterator it2(*this); it2 -= n; return it2; } template ptrdiff_t filled_tableau::in_row_const_iterator::operator-(const in_row_const_iterator& other) const { return column_number - other.column_number; } template const T& filled_tableau::in_row_const_iterator::operator*() const { return (*tab)(row_number, column_number); } template const T* filled_tableau::in_row_const_iterator::operator->() const { return &((*tab)(row_number, column_number)); } template typename filled_tableau::in_row_const_iterator& filled_tableau::in_row_const_iterator::operator++() { ++column_number; return (*this); } template typename filled_tableau::in_row_const_iterator& filled_tableau::in_row_const_iterator::operator+=(unsigned int n) { column_number += n; return (*this); } template typename filled_tableau::in_row_const_iterator& filled_tableau::in_row_const_iterator::operator--() { --column_number; return (*this); } template typename filled_tableau::in_row_const_iterator filled_tableau::in_row_const_iterator::operator--(int) { in_row_const_iterator tmp(*this); --column_number; return tmp; } template typename filled_tableau::in_row_const_iterator filled_tableau::in_row_const_iterator::operator++(int) { in_row_const_iterator tmp(*this); ++column_number; return tmp; } template typename filled_tableau::in_row_const_iterator& filled_tableau::in_row_const_iterator::operator-=(unsigned int n) { column_number -= n; return (*this); } template bool filled_tableau::in_row_const_iterator::operator==(const in_row_const_iterator& other) const { if (tab == other.tab && row_number == other.row_number && column_number == other.column_number) return true; return false; } template bool filled_tableau::in_row_const_iterator::operator<=(const in_row_const_iterator & other) const { if (column_number <= other.column_number) return true; return false; } template bool filled_tableau::in_row_const_iterator::operator>=(const in_row_const_iterator & other) const { if (column_number >= other.column_number) return true; return false; } template bool filled_tableau::in_row_const_iterator::operator<(const in_row_const_iterator & other) const { if (column_number < other.column_number) return true; return false; } template bool filled_tableau::in_row_const_iterator::operator>(const in_row_const_iterator & other) const { if (column_number > other.column_number) return true; return false; } template bool filled_tableau::in_row_const_iterator::operator!=(const in_row_const_iterator & other) const { return !((*this) == other); } //--------------------------------------------------------------------------- // iterator template filled_tableau::iterator::iterator(unsigned int r, unsigned int c, filled_tableau *t) : tab(t), column_number(c), row_number(r) { } template typename filled_tableau::iterator filled_tableau::iterator::operator+(unsigned int n) { typename filled_tableau::iterator it2(*this); it2+=n; return it2; } template typename filled_tableau::iterator filled_tableau::iterator::operator-(unsigned int n) { typename filled_tableau::iterator it2(*this); it2-=n; return it2; } template ptrdiff_t filled_tableau::iterator::operator-(const iterator& other) const { return row_number-other.row_number; } template T& filled_tableau::iterator::operator*() const { return (*tab)(row_number,column_number); } template T* filled_tableau::iterator::operator->() const { return &((*tab)(row_number,column_number)); } template typename filled_tableau::iterator& filled_tableau::iterator::operator++() { if(++column_number==tab->rows[row_number].size()) { column_number=0; ++row_number; } return (*this); } template typename filled_tableau::iterator& filled_tableau::iterator::operator+=(unsigned int n) { while(n>0) { if(++column_number==tab->rows[row_number]) { column_number=0; ++row_number; } --n; } return (*this); } template typename filled_tableau::iterator& filled_tableau::iterator::operator--() { if(column_number==0) { --row_number; column_number=tab->rows[row_number].size()-1; } else --column_number; return (*this); } template typename filled_tableau::iterator filled_tableau::iterator::operator--(int) { iterator tmp(*this); if(column_number==0) { --row_number; column_number=tab->rows[row_number].size()-1; } else --column_number; return tmp; } template typename filled_tableau::iterator filled_tableau::iterator::operator++(int) { iterator tmp(*this); while(this->n>0) { if(++column_number==tab->rows[row_number]) { column_number=0; ++row_number; } --this->n; } return tmp; } template typename filled_tableau::iterator& filled_tableau::iterator::operator-=(unsigned int n) { while(n>0) { if(column_number==0) { --row_number; column_number=tab->rows[row_number].size()-1; } else --column_number; --n; } return (*this); } template bool filled_tableau::iterator::operator==(const iterator& other) const { if(tab==other.tab && row_number==other.row_number && column_number==other.column_number) return true; return false; } template bool filled_tableau::iterator::operator<(const iterator& other) const { if(row_number bool filled_tableau::iterator::operator>(const iterator& other) const { if(row_number>other.row_number) return true; return false; } template bool filled_tableau::iterator::operator!=(const iterator& other) const { return !((*this)==other); } //--------------------------------------------------------------------------- // const_iterator template filled_tableau::const_iterator::const_iterator(unsigned int r, unsigned int c, const filled_tableau* t) : tab(t), column_number(c), row_number(r) { } template filled_tableau::const_iterator::const_iterator(const filled_tableau::iterator& other) : tab(other.tab), column_number(other.column_number), row_number(other.row_number) { } template typename filled_tableau::const_iterator filled_tableau::const_iterator::operator+(unsigned int n) { typename filled_tableau::const_iterator it2(*this); it2 += n; return it2; } template typename filled_tableau::const_iterator filled_tableau::const_iterator::operator-(unsigned int n) { typename filled_tableau::const_iterator it2(*this); it2 -= n; return it2; } template ptrdiff_t filled_tableau::const_iterator::operator-(const const_iterator& other) const { return row_number - other.row_number; } template const T& filled_tableau::const_iterator::operator*() const { return (*tab)(row_number, column_number); } template const T* filled_tableau::const_iterator::operator->() const { return &((*tab)(row_number, column_number)); } template typename filled_tableau::const_iterator& filled_tableau::const_iterator::operator++() { if (++column_number == tab->rows[row_number].size()) { column_number = 0; ++row_number; } return (*this); } template typename filled_tableau::const_iterator& filled_tableau::const_iterator::operator+=(unsigned int n) { while (n > 0) { if (++column_number == tab->rows[row_number]) { column_number = 0; ++row_number; } --n; } return (*this); } template typename filled_tableau::const_iterator& filled_tableau::const_iterator::operator--() { if (column_number == 0) { --row_number; column_number = tab->rows[row_number].size() - 1; } else --column_number; return (*this); } template typename filled_tableau::const_iterator filled_tableau::const_iterator::operator--(int) { const_iterator tmp(*this); if (column_number == 0) { --row_number; column_number = tab->rows[row_number].size() - 1; } else --column_number; return tmp; } template typename filled_tableau::const_iterator filled_tableau::const_iterator::operator++(int) { const_iterator tmp(*this); while (this->n > 0) { if (++column_number == tab->rows[row_number]) { column_number = 0; ++row_number; } --this->n; } return tmp; } template typename filled_tableau::const_iterator& filled_tableau::const_iterator::operator-=(unsigned int n) { while (n > 0) { if (column_number == 0) { --row_number; column_number = tab->rows[row_number].size() - 1; } else --column_number; --n; } return (*this); } template bool filled_tableau::const_iterator::operator==(const const_iterator& other) const { if (tab == other.tab && row_number == other.row_number && column_number == other.column_number) return true; return false; } template bool filled_tableau::const_iterator::operator<(const const_iterator & other) const { if (row_number < other.row_number) return true; return false; } template bool filled_tableau::const_iterator::operator>(const const_iterator & other) const { if (row_number > other.row_number) return true; return false; } template bool filled_tableau::const_iterator::operator!=(const const_iterator & other) const { return !((*this) == other); } //--- // other template typename filled_tableau::iterator filled_tableau::begin() { return iterator(0, 0, this); } template typename filled_tableau::iterator filled_tableau::end() { return iterator(rows.size(), 0, this); } template typename filled_tableau::const_iterator filled_tableau::cbegin() const { return const_iterator(0,0,this); } template typename filled_tableau::const_iterator filled_tableau::cend() const { return const_iterator(rows.size(), 0, this); } template typename filled_tableau::const_iterator filled_tableau::begin() const { return cbegin(); } template typename filled_tableau::const_iterator filled_tableau::end() const { return cend(); } template typename filled_tableau::in_column_iterator filled_tableau::begin_column(unsigned int column) { typename filled_tableau::in_column_iterator it(0,column,this); assert(number_of_rows()>0); assert(column typename filled_tableau::in_column_iterator filled_tableau::end_column(unsigned int column) { unsigned int r=0; while(r::in_column_iterator it(r,column,this); return it; } template typename filled_tableau::in_column_const_iterator filled_tableau::cbegin_column(unsigned int column) const { typename filled_tableau::in_column_const_iterator it(0, column, this); assert(number_of_rows() > 0); assert(column < row_size(0)); return it; } template typename filled_tableau::in_column_const_iterator filled_tableau::cend_column(unsigned int column) const { unsigned int r = 0; while (r < number_of_rows()) { if (row_size(r) <= column) break; ++r; } typename filled_tableau::in_column_const_iterator it(r, column, this); return it; } template typename filled_tableau::in_column_const_iterator filled_tableau::begin_column(unsigned int column) const { return cbegin_column(column); } template typename filled_tableau::in_column_const_iterator filled_tableau::end_column(unsigned int column) const { return cend_column(column); } template typename filled_tableau::in_row_iterator filled_tableau::begin_row(unsigned int row) { return in_row_iterator{ row, 0, this }; } template typename filled_tableau::in_row_iterator filled_tableau::end_row(unsigned int row) { return in_row_iterator{ row, row_size(row), this }; } template typename filled_tableau::in_row_const_iterator filled_tableau::cbegin_row(unsigned int row) const { return in_row_const_iterator{ row, 0, this }; } template typename filled_tableau::in_row_const_iterator filled_tableau::cend_row(unsigned int row) const { return in_row_const_iterator{ row, row_size(row), this }; } template typename filled_tableau::in_row_const_iterator filled_tableau::begin_row(unsigned int row) const { return cbegin_row(row); } template typename filled_tableau::in_row_const_iterator filled_tableau::end_row(unsigned int row) const { return cend_row(row); } template template OutputIterator filled_tableau::Garnir_set(OutputIterator it, unsigned int row, unsigned int col) const { assert(col>0); unsigned int r=row, c=col; *it=(*this)(r,c); ++it; while(r>0) { --r; *it=(*this)(r,c); ++it; } r=row; --c; *it=(*this)(r,c); ++it; while(r+1 std::pair filled_tableau::nonstandard_loc() const { unsigned int r=number_of_rows(); assert(r>0); do { --r; for(unsigned int c=0; c (*this)(r,c+1) ) return std::pair(r,c); } } while(r>0); return std::pair(-1,-1); } template bool tableaux::standard_form() { bool already_standard=true; typename tableau_container_t::iterator thetab=storage.begin(); while(thetab!=storage.end()) { (*thetab).sort_within_columns(); std::pair where=(*thetab).nonstandard_loc(); if(where.first!=-1) { already_standard=false; combin::combinations com; for(unsigned int i1=where.first; i1<(*thetab).column_size(where.second); ++i1) com.original.push_back((*thetab)(i1,where.second)); for(unsigned int i1=0; i1<=(unsigned int)(where.first); ++i1) com.original.push_back((*thetab)(i1,where.second+1)); com.sublengths.push_back((*thetab).column_size(where.second)-where.first); com.sublengths.push_back(where.first+1); com.permute(); for(unsigned int tabi=1; tabi void tableaux::add_tableau(const T& ntab) { typename tableau_container_t::iterator it=storage.begin(); while(it!=storage.end()) { if((*it).compare_without_multiplicity(ntab)) { (*it).multiplicity+=ntab.multiplicity; if((*it).multiplicity==0) storage.erase(it); return; } ++it; } storage.push_back(ntab); } template yngrat_t filled_tableau::projector_normalisation() const { yngrat_t norm=1; norm/=hook_length_prod(); return norm; } template void filled_tableau::projector(combin::symmetriser& sym, bool modulo_monoterm) const { for(unsigned int r=0; r1) sym.apply_symmetry(); } } // sym.collect(); } template void filled_tableau::projector(combin::symmetriser& sym, combin::range_vector_t& sublengths_scattered) const { for(unsigned int r=0; r0) --m; // sym.sublengths.push_back(overlap+1); // } // unsigned int sum=0; // for(unsigned int m=0; m1) sym.apply_symmetry(); } } template filled_tableau& filled_tableau::operator=(const filled_tableau& other) { rows=other.rows; tableau::operator=(other); return (*this); } template yngint_t tableaux::total_dimension(unsigned int dim) { yngint_t totdim=0; typename tableau_container_t::const_iterator it=storage.begin(); while(it!=storage.end()) { totdim+=(*it).dimension(dim); ++it; } return totdim; } template void LR_tensor(const tableaux& tabs1, const T& tab2, unsigned int maxrows, OutputIterator out, bool alltabs=false) { typename tableaux::tableau_container_t::const_iterator it=tabs1.storage.begin(); while(it!=tabs1.storage.end()) { LR_tensor((*it), tab2, maxrows, out, alltabs); ++it; } } template void add_box(T1& tab1, unsigned int row1, const T2& tab2, unsigned int row2, unsigned int col2) { tab1.add_box(row1, tab2(row2,col2)); } template void add_box(T1& tab1, unsigned int row1, const tableau&, unsigned int, unsigned int) { tab1.add_box(row1); } typedef filled_tableau > keeptrack_tab_t; template 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) { // Are we at the end of the current row of boxes in tab2 ? if((++curcol2)==tab2.row_size(currow2)) { // Are we at the end of tab2 altogether? if((++currow2)==tab2.number_of_rows()) { *outit=newtab; // Store the product tableau just created. return; } curcol2=0; startrow=0; } // Rule "row_by_row". for(unsigned int rowpos=startrow; rowpos0 && rowpos0) { int numi=0, numimin1=0; if(rowpos>0) { for(unsigned int sr=0; srnumimin1) goto rule_violated; // continue counting to see whether a previously valid box is now invalid for(unsigned int sr=rowpos; sr=0; --sc) { // right to left if(Ycurrent(sr,sc).first==(int)(currow2)) ++numi; if(Ycurrent(sr,sc).first==(int)(currow2)-1) ++numimin1; if(numi>numimin1) goto rule_violated; } } // Put the box at row 'rowpos' and call LR_add_box recursively // to add the other boxes. Ycurrent.add_box(rowpos, std::pair(currow2, curcol2)); add_box(newtab, rowpos, tab2, currow2, curcol2); LR_add_box(tab2, newtab, currow2, curcol2, alltabs?0:rowpos, maxrows, outit, Ycurrent, alltabs); // Remove the box again in preparation for trying to add it to other rows. newtab.remove_box(rowpos); Ycurrent.remove_box(rowpos); rule_violated: ; } } template void LR_tensor(const Tab& tab1, const Tab& tab2, unsigned int maxrows, OutputIterator outit, bool alltabs=false) { // Make a copy of tab1 because LR_add_box has to change it and // tab1 is const here. Tab newtab(tab1); // Tableau which keeps track of the LR rules. It contains the // current (incomplete) shape of the tensor product, and for all boxes // which come from tab2 we store the row and column of tab2 // from which they originated. Tab1 boxes have (-2,-2) stored. keeptrack_tab_t Ycurrent; Ycurrent.copy_shape(tab1); keeptrack_tab_t::iterator yi=Ycurrent.begin(); while(yi!=Ycurrent.end()) { (*yi)=std::pair(-2,-2); ++yi; } LR_add_box(tab2, newtab, 0, -1, 0, maxrows, outit, Ycurrent, alltabs); } template void LR_tensor(const tableaux&, bool, unsigned int, OutputIterator ) { assert(1==0); } std::ostream& operator<<(std::ostream&, const tableau& ); template std::ostream& operator<<(std::ostream&, const tableaux& ); template std::ostream& operator<<(std::ostream&, const filled_tableau& ); template unsigned int filled_tableau::number_of_rows() const { return rows.size(); } template unsigned int filled_tableau::row_size(unsigned int num) const { assert(num T& filled_tableau::operator()(unsigned int row, unsigned int col) { assert(row const T& filled_tableau::operator()(unsigned int row, unsigned int col) const { assert(row const T& filled_tableau::operator[](unsigned int boxnum) const { unsigned int row = 0; while (true) { if (boxnum < row_size(row)) break; boxnum -= row_size(row); ++row; } return rows[row][boxnum]; } template filled_tableau::~filled_tableau() { } template void filled_tableau::add_box(unsigned int rownum) { if(rownum>=rows.size()) rows.resize(rownum+1); assert(rownum void filled_tableau::add_box(unsigned int rownum, T val) { if(rownum>=rows.size()) rows.resize(rownum+1); assert(rownum void filled_tableau::swap_columns(unsigned int c1, unsigned int c2) { assert(c1 void filled_tableau::remove_box(unsigned int rownum) { assert(rownum0); rows[rownum].pop_back(); if(rows[rownum].size()==0) rows.pop_back(); } template void filled_tableau::clear() { rows.clear(); tableau::clear(); } template std::ostream& operator<<(std::ostream& str, const tableaux& tabs) { typename tableaux::tableau_container_t::const_iterator it=tabs.storage.begin(); while(it!=tabs.storage.end()) { str << (*it) << std::endl << std::endl; ++it; } return str; } template std::ostream& operator<<(std::ostream& str, const filled_tableau& tab) { for(unsigned int i=0; i