/** * Compute the Kramer-Mesner matrix. * * Precondition: t < k */ KramerMesnerMatrix computeKMMatrix(const Group& G, unsigned int t, unsigned int k) { std::vector<KMBuilderOutput> builderOutputs; // stores the relevant data for k = 2 onwards Matrix A; for (int i = 2; i <= k; i++) { boost::scoped_ptr<KMBuilder> builder; // Get orbit representatives of (i - 1)-subsets std::vector<Subset> orbitReps; if (i == 2) { // As it is the first time, we have to compute the orbit representatives of singleton subsets... Subset pointsRemaining = generateX(G.getNumPoints()); while (!pointsRemaining.empty()) { typedef OrbitSet<Permutation, unsigned long>::const_iterator OrbitSetIterator; unsigned long point = *(pointsRemaining.begin()); // A new representative... Subset singletonSet = makeSingletonSet(point); // ...as a set orbitReps.push_back(singletonSet); // Compute the orbit of the point, and remove it from the remaining points OrbitSet<Permutation, unsigned long> orbit = G.orbit(point, Transversal::TrivialAction()); for (OrbitSetIterator it = orbit.begin(); it != orbit.end(); it++) { pointsRemaining.erase(pointsRemaining.find(*it)); } } builder.reset(new KMBuilder(G, i, orbitReps)); } else { // We get them from what we computed earlier KMBuilderOutput& input = builderOutputs[i - 3]; orbitReps = input.getNewReps(); builder.reset(new KMBuilder(G, i, orbitReps, input.getPrunerData())); } KMBuilderOutput builderOutput = builder->build(); builderOutputs.push_back(builderOutput); // From the identity that A[t][k] = A[t][s] * A[s][k] / combinat(k - t, k - s) for any s // between t and k, we get the following: if (i == t + 1) { assignMatrix(A, builderOutput.getNewMatrix()); } else if (i > t + 1) { assignMatrix(A, matrixMultiply(A, builderOutput.getNewMatrix())); scalarDivide(i - t, A); } } return KramerMesnerMatrix(G, builderOutputs[t - 2].getNewReps(), builderOutputs[k - 2].getNewReps(), A); }
void testOneSet(const BSGSIN& bsgs, const unsigned long n, const dset& testSet, bool withStabilizer = false) { typedef typename BSGSIN::PERMtype PERM; OrbitSet<PERM,dset> orbit; orbit.orbit(testSet, bsgs.S, DSetAction<PERM>(n)); typedef OrbitLexMinSearch<BSGSIN> OrbitLexMinSearchClass; OrbitLexMinSearchClass orbLexMin(bsgs); const dset lexMin = orbLexMin.lexMin(testSet); //cout << "lexMin = " << lexMin << endl; BOOST_REQUIRE(orbit.contains(lexMin)); BOOST_FOREACH(const dset& el, make_pair(orbit.begin(), orbit.end())) { //cout << el << " - " << lexMin << " : " << OrbitLexMinSearch<int>::isLexSmaller(el, lexMin) << endl; BOOST_CHECK(!OrbitLexMinSearchClass::isLexSmaller(el, lexMin)); } }