concatenation of permutations

This commit is contained in:
Jiri Pittner 2024-01-11 17:21:08 +01:00
parent 6ea863627d
commit 387491204c
2 changed files with 47 additions and 6 deletions

View File

@ -94,9 +94,36 @@ for(T i=1; i<=this->size(); ++i) q[i]=(*this)[this->size()-i+1];
return q; return q;
} }
template <typename T>
NRPerm<T> NRPerm<T>::operator+(const NRPerm<T> &q) const
{
#ifdef DEBUG
if(!this->is_valid() || !q.is_valid()) laerror("concatenation of invalid permutation");
#endif
NRPerm<T> r(size()+q.size());
for(int i=1; i<=size(); ++i) r[i]=(*this)[i];
for(int i=1; i<=q.size(); ++i) r[size()+i]=size()+q[i];
return r;
}
template <typename T> template <typename T>
NRPerm<T> NRPerm<T>::operator*(const NRPerm<T> q) const NRPerm<T> NRPerm<T>::operator-(const NRPerm<T> &q) const
{
#ifdef DEBUG
if(!this->is_valid() || !q.is_valid()) laerror("concatenation of invalid permutation");
#endif
NRPerm<T> r(size()+q.size());
for(int i=1; i<=q.size(); ++i) r[i]=size()+q[i];
for(int i=1; i<=size(); ++i) r[q.size()+i]=(*this)[i];
return r;
}
template <typename T>
NRPerm<T> NRPerm<T>::operator*(const NRPerm<T> &q) const
{ {
#ifdef DEBUG #ifdef DEBUG
if(!this->is_valid() || !q.is_valid()) laerror("multiplication of invalid permutation"); if(!this->is_valid() || !q.is_valid()) laerror("multiplication of invalid permutation");
@ -111,7 +138,7 @@ return r;
} }
template <typename T> template <typename T>
NRPerm<T> NRPerm<T>::conjugate_by(const NRPerm<T> q) const NRPerm<T> NRPerm<T>::conjugate_by(const NRPerm<T> &q) const
{ {
#ifdef DEBUG #ifdef DEBUG
if(!this->is_valid() || !q.is_valid()) laerror("multiplication of invalid permutation"); if(!this->is_valid() || !q.is_valid()) laerror("multiplication of invalid permutation");
@ -126,6 +153,16 @@ return r;
} }
template <typename T>
CyclePerm<T> CyclePerm<T>::conjugate_by(const CyclePerm<T> &q) const
{
#ifdef DEBUG
if(!this->is_valid() || !q.is_valid()) laerror("multiplication of invalid permutation");
#endif
return q.inverse()*((*this)*q);
}
template <typename T> template <typename T>
int NRPerm<T>::parity() const int NRPerm<T>::parity() const
{ {
@ -740,7 +777,7 @@ return r;
//multiplication via NRPerm - could there be a more efficient direct algorithm? //multiplication via NRPerm - could there be a more efficient direct algorithm?
template <typename T> template <typename T>
CyclePerm<T> CyclePerm<T>::operator*(const CyclePerm q) const CyclePerm<T> CyclePerm<T>::operator*(const CyclePerm &q) const
{ {
int m=this->max(); int m=this->max();
int mm=q.max(); int mm=q.max();

View File

@ -50,14 +50,17 @@ public:
explicit NRPerm(const CyclePerm<T> &rhs, const int n=0); explicit NRPerm(const CyclePerm<T> &rhs, const int n=0);
//specific operations //specific operations
int size() const {return NRVec_from1<T>::size();};
void identity(); void identity();
bool is_valid() const; //is it really a permutation bool is_valid() const; //is it really a permutation
bool is_identity() const; bool is_identity() const;
NRPerm inverse() const; NRPerm inverse() const;
NRPerm reverse() const; //backward order NRPerm reverse() const; //backward order
NRPerm operator*(const NRPerm q) const; //q is rhs and applied first, this applied second NRPerm operator+(const NRPerm &rhs) const; //concatenate the permutations this,rhs, renumbering rhs (not commutative)
NRPerm operator-(const NRPerm &rhs) const; //concatenate the permutations rhs,this, renumbering rhs (not commutative)
NRPerm operator*(const NRPerm &q) const; //q is rhs and applied first, this applied second
NRPerm operator*(const CyclePerm<T> &r) const; NRPerm operator*(const CyclePerm<T> &r) const;
NRPerm conjugate_by(const NRPerm q) const; //q^-1 p q NRPerm conjugate_by(const NRPerm &q) const; //q^-1 p q
int parity() const; //returns +/- 1 int parity() const; //returns +/- 1
void randomize(void); //uniformly random by Fisher-Yates shuffle void randomize(void); //uniformly random by Fisher-Yates shuffle
bool next(); //generate next permutation in lex order bool next(); //generate next permutation in lex order
@ -94,8 +97,9 @@ public:
T max() const {T m=0; for(int i=1; i<=this->size(); ++i) {T mm= (*this)[i].max(); if(mm>m) m=mm;} return m;} T max() const {T m=0; for(int i=1; i<=this->size(); ++i) {T mm= (*this)[i].max(); if(mm>m) m=mm;} return m;}
CompressedPartition<T> cycles(const T n) const; CompressedPartition<T> cycles(const T n) const;
void readfrom(const std::string &line); void readfrom(const std::string &line);
CyclePerm operator*(const CyclePerm q) const; //q is rhs and applied first, this applied second CyclePerm operator*(const CyclePerm &q) const; //q is rhs and applied first, this applied second
NRPerm<T> operator*(const NRPerm<T> &r) const; NRPerm<T> operator*(const NRPerm<T> &r) const;
CyclePerm conjugate_by(const CyclePerm &q) const; //q^-1 p q
PERM_RANK_TYPE order() const; //lcm of cycle lengths PERM_RANK_TYPE order() const; //lcm of cycle lengths
bool operator==(const CyclePerm &rhs) const {return NRPerm<T>(*this) == NRPerm<T>(rhs);}; //cycle representation is not unique, cannot inherit operator== from NRVec bool operator==(const CyclePerm &rhs) const {return NRPerm<T>(*this) == NRPerm<T>(rhs);}; //cycle representation is not unique, cannot inherit operator== from NRVec
void simplify(bool keep1=false); //remove cycles of size 0 or 1 void simplify(bool keep1=false); //remove cycles of size 0 or 1