@q $Id: permutation.cweb 332 2005-07-15 13:41:48Z kamenik $ @> @q Copyright 2004, Ondra Kamenik @> @ Start of {\tt permutation.cweb} file. @c #include "permutation.h" #include "tl_exception.h" @<|Permutation::apply| code@>; @<|Permutation::inverse| code@>; @<|Permutation::tailIdentity| code@>; @<|Permutation::computeSortingMap| code@>; @<|PermutationSet| constructor code 1@>; @<|PermutationSet| constructor code 2@>; @<|PermutationSet| destructor code@>; @<|PermutationSet::getPreserving| code@>; @<|PermutationBundle| constructor code@>; @<|PermutationBundle| destructor code@>; @<|PermutationBundle::get| code@>; @<|PermutationBundle::generateUpTo| code@>; @ This is easy, we simply apply the map in the fashion $s\circ m$.. @<|Permutation::apply| code@>= void Permutation::apply(const IntSequence& src, IntSequence& tar) const { TL_RAISE_IF(src.size() != permap.size() || tar.size() != permap.size(), "Wrong sizes of input or output in Permutation::apply"); for (int i = 0; i < permap.size(); i++) tar[i] = src[permap[i]]; } void Permutation::apply(IntSequence& tar) const { IntSequence tmp(tar); apply(tmp, tar); } @ @<|Permutation::inverse| code@>= void Permutation::inverse() { IntSequence former(permap); for (int i = 0; i < size(); i++) permap[former[i]] = i; } @ Here we find a number of trailing indices which are identical with the permutation. @<|Permutation::tailIdentity| code@>= int Permutation::tailIdentity() const { int i = permap.size(); while (i > 0 && permap[i-1] == i-1) i--; return permap.size() - i; } @ This calculates a map which corresponds to sorting in the following sense: $(\hbox{sorted }s)\circ m = s$, where $s$ is a given sequence. We go through |s| and find an the same item in sorted |s|. We construct the |permap| from the found pair of indices. We have to be careful, to not assign to two positions in |s| the same position in sorted |s|, so we maintain a bitmap |flag|, in which we remember indices from the sorted |s| already assigned. @<|Permutation::computeSortingMap| code@>= void Permutation::computeSortingMap(const IntSequence& s) { IntSequence srt(s); srt.sort(); IntSequence flags(s.size(),0); for (int i = 0; i < s.size(); i++) { int j = 0; while (j < s.size() && (flags[j] || srt[j] != s[i])) j++; TL_RAISE_IF(j == s.size(), "Internal algorithm error in Permutation::computeSortingMap"); flags[j] = 1; permap[i] = j; } } @ @<|PermutationSet| constructor code 1@>= PermutationSet::PermutationSet() : order(1), size(1), pers(new const Permutation*[size]) { pers[0] = new Permutation(1); } @ @<|PermutationSet| constructor code 2@>= PermutationSet::PermutationSet(const PermutationSet& sp, int n) : order(n), size(n*sp.size), pers(new const Permutation*[size]) { for (int i = 0; i < size; i++) pers[i] = NULL; TL_RAISE_IF(n != sp.order+1, "Wrong new order in PermutationSet constructor"); int k = 0; for (int i = 0; i < sp.size; i++) { for (int j = 0; j < order; j++,k++) { pers[k] = new Permutation(*(sp.pers[i]), j); } } } @ @<|PermutationSet| destructor code@>= PermutationSet::~PermutationSet() { for (int i = 0; i < size; i++) if (pers[i]) delete pers[i]; delete [] pers; } @ @<|PermutationSet::getPreserving| code@>= vector PermutationSet::getPreserving(const IntSequence& s) const { TL_RAISE_IF(s.size() != order, "Wrong sequence length in PermutationSet::getPreserving"); vector res; IntSequence tmp(s.size()); for (int i = 0; i < size; i++) { pers[i]->apply(s, tmp); if (s == tmp) { res.push_back(pers[i]); } } return res; } @ @<|PermutationBundle| constructor code@>= PermutationBundle::PermutationBundle(int nmax) { nmax = max(nmax, 1); generateUpTo(nmax); } @ @<|PermutationBundle| destructor code@>= PermutationBundle::~PermutationBundle() { for (unsigned int i = 0; i < bundle.size(); i++) delete bundle[i]; } @ @<|PermutationBundle::get| code@>= const PermutationSet& PermutationBundle::get(int n) const { if (n > (int)(bundle.size()) || n < 1) { TL_RAISE("Permutation set not found in PermutationSet::get"); return *(bundle[0]); } else { return *(bundle[n-1]); } } @ @<|PermutationBundle::generateUpTo| code@>= void PermutationBundle::generateUpTo(int nmax) { if (bundle.size() == 0) bundle.push_back(new PermutationSet()); int curmax = bundle.size(); for (int n = curmax+1; n <= nmax; n++) { bundle.push_back(new PermutationSet(*(bundle.back()), n)); } } @ End of {\tt permutation.cweb} file.