00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef SIMPLEBASECHANGE_H_
00034 #define SIMPLEBASECHANGE_H_
00035
00036 #include <permlib/change/base_change.h>
00037
00038 namespace permlib {
00039
00041 template<class PERM, class TRANS, class BASETRANSPOSE>
00042 class SimpleBaseChange : public BaseChange<PERM,TRANS> {
00043 public:
00045 explicit SimpleBaseChange(const BSGS<PERM,TRANS>&);
00046
00048 template <class InputIterator>
00049 void change(BSGS<PERM,TRANS> &bsgs, InputIterator baseBegin, InputIterator baseEnd, bool skipRedundant = false) const;
00050 };
00051
00052
00053
00054
00055
00056 template<class PERM, class TRANS, class BASETRANSPOSE>
00057 SimpleBaseChange<PERM,TRANS,BASETRANSPOSE>::SimpleBaseChange(const BSGS<PERM,TRANS>&)
00058 : BaseChange<PERM,TRANS>()
00059 { }
00060
00061 template<class PERM, class TRANS, class BASETRANSPOSE>
00062 template<class InputIterator>
00063 void SimpleBaseChange<PERM,TRANS,BASETRANSPOSE>::change(BSGS<PERM,TRANS> &bsgs, InputIterator baseBegin, InputIterator baseEnd, bool skipRedundant) const {
00064 if (baseBegin == baseEnd)
00065 return;
00066
00067 const ulong origOrder __attribute__((unused)) = bsgs.order();
00068 BASETRANSPOSE trans;
00069
00070 uint baseTargetPos = 0;
00071 while (baseBegin != baseEnd && baseTargetPos < bsgs.B.size()) {
00072 ulong alpha = *baseBegin;
00073 ulong beta = bsgs.B[baseTargetPos];
00074 const bool redundant = skipRedundant && isRedundant(bsgs, baseTargetPos, alpha);
00075
00076 if (!redundant && beta != alpha) {
00077 uint pos = bsgs.insertRedundantBasePoint(alpha);
00078 for (; pos > baseTargetPos; --pos) {
00079 trans.transpose(bsgs, pos-1);
00080 ++BaseChange<PERM,TRANS>::m_statTranspositions;
00081 }
00082 }
00083
00084 ++baseBegin;
00085 if (!redundant)
00086 ++baseTargetPos;
00087 }
00088
00089 while (!skipRedundant && baseBegin != baseEnd) {
00090 const ulong alpha = *baseBegin;
00091 bsgs.insertRedundantBasePoint(alpha, baseTargetPos);
00092
00093 ++baseBegin;
00094 ++baseTargetPos;
00095 }
00096
00097 bsgs.stripRedundantBasePoints(baseTargetPos);
00098 BaseChange<PERM,TRANS>::m_statScheierGeneratorsConsidered += trans.m_statScheierGeneratorsConsidered;
00099
00100 BOOST_ASSERT(origOrder == bsgs.order());
00101 }
00102
00103 }
00104
00105 #endif // -- SIMPLEBASECHANGE_H_