#pragma once #include #include /// \ingroup core /// /// Generic permutation group material. Largely follows the notation of xperm to avoid /// confusion. /// /// Example: 1->4, 4->3, 3->1, 5->6, 6->5 /// /// Perm( 3, 2, 4, 1, 6, 5 ) /// Images( 4, 2, 1, 3, 6, 5 ) class PermutationException : std::logic_error { public: PermutationException(const std::string& ex) : std::logic_error(ex) {}; }; class Perm { public: std::vector perm; /// Find the permutation that takes [start1, end1> to [start2, end2>. /// This will be available in 'perm' afterwards. template void find(iterator start1, iterator end1, iterator start2, iterator end2); /// Apply the permutation 'perm' on the given range. template void apply(iterator start1, iterator end1); }; class Images { public: std::vector images; /// Find the permutation that takes [start1, end1> to [start2, end2>. template void find(iterator start1, iterator end1, iterator start2, iterator end2); }; template void Perm::find(iterator start1, iterator end1, iterator start2, iterator end2) { perm.clear(); while(start2!=end2) { auto it=start1; int num=0; while(it!=end1) { if(*start2==*it) { perm.push_back(num); break; } ++num; ++it; } if(it==end1) throw PermutationException("Sets do not contain the same elements."); ++start2; } } template void Perm::apply(iterator start, iterator end) { typedef typename std::remove_reference::type value_type; std::vector orig; auto it=start; while(it!=end) { orig.push_back(*it); ++it; } // std::cerr << orig.size() << ", " << perm.size() << std::endl; if(orig.size()!=perm.size()) { std::cerr << "Perm::apply: orig.size()=" << orig.size() << ", " << "perm.size()=" << perm.size() << std::endl; assert(orig.size()==perm.size()); } for(unsigned int i=0; i void Images::find(iterator start1, iterator end1, iterator start2, iterator end2) { images.clear(); while(start1!=end1) { auto it=start2; int num=0; while(it!=end2) { if(*start1==*it) { images.push_back(num); break; } ++num; ++it; } if(it==end2) throw PermutationException("Sets do not contain the same elements."); ++start1; } }