/** * 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); }
struct sparsematrix partition_to_matrix(struct sparsematrix* A){ struct sparsematrix A1 = assignMatrix(A,1); struct sparsematrix A2 = assignMatrix(A,2); struct sparsematrix B; MMSparseMatrixInit(&B); B.m = A->m; B.n = A->n; B.NrNzElts = A->NrNzElts; B.i = vecallocl(B.NrNzElts); B.j = vecallocl(B.NrNzElts); B.ReValue = vecallocd(B.NrNzElts); int index_B = 0, i; for(i=0;i<A1.NrNzElts;i++){ B.i[index_B] = A1.i[i]; B.j[index_B] = A1.j[i]; B.ReValue[index_B++] = 1.0; } for(i=0;i<A2.NrNzElts;i++){ B.i[index_B] = A2.i[i]; B.j[index_B] = A2.j[i]; B.ReValue[index_B++] = 2.0; } MMDeleteSparseMatrix(&A1); MMDeleteSparseMatrix(&A2); struct sparsematrixplus plus = reorder_row_incr(&B); MMDeleteSparseMatrix(&B); vecfreel(plus.perm); return plus.matrix; }