/// <summary> /// Change the base of the group to the new base <paramref name="newBase"/>. /// </summary> /// <param name="newBase">the new base for the group</param> public void ChangeBase(Permutation newBase) { var h = new PermutationGroup(newBase); int firstDiffIndex = basePermutation.FirstIndexOfDifference(newBase); for (int j = firstDiffIndex; j < size; j++) { for (int a = 0; a < size; a++) { Permutation g = permutations[j][a]; if (g != null) { h.Enter(g); } } } for (int j = 0; j < firstDiffIndex; j++) { for (int a = 0; a < size; a++) { Permutation g = permutations[j][a]; if (g != null) { int hj = h.basePermutation[j]; int x = g[hj]; h.permutations[j][x] = new Permutation(g); } } } this.basePermutation = new Permutation(h.basePermutation); this.permutations = (Permutation[][])h.permutations.Clone(); }
public void EnterTest() { int size = 4; PermutationGroup group = new PermutationGroup(size); group.Enter(new Permutation(1, 0, 3, 2)); Assert.AreEqual(2, group.Order()); }
/// <summary> /// Does the work of the class, that refines a coarse partition into a finer /// one using the supplied automorphism group to prune the search. /// </summary> /// <param name="group">the automorphism group of the graph</param> /// <param name="coarser">the partition to refine</param> private void Refine(PermutationGroup group, Partition coarser) { int vertexCount = GetVertexCount(); Partition finer = equitableRefiner.Refine(coarser); int firstNonDiscreteCell = finer.GetIndexOfFirstNonDiscreteCell(); if (firstNonDiscreteCell == -1) { firstNonDiscreteCell = vertexCount; } Permutation pi1 = new Permutation(firstNonDiscreteCell); Result result = Result.Better; if (bestExist) { pi1 = finer.SetAsPermutation(firstNonDiscreteCell); result = CompareRowwise(pi1); } // partition is discrete if (finer.Count == vertexCount) { if (!bestExist) { best = finer.ToPermutation(); first = finer.ToPermutation(); bestExist = true; } else { if (result == Result.Better) { best = new Permutation(pi1); } else if (result == Result.Equal) { group.Enter(pi1.Multiply(best.Invert())); } } } else { if (result != Result.Worse) { var blockCopy = finer.CopyBlock(firstNonDiscreteCell); for (int vertexInBlock = 0; vertexInBlock < vertexCount; vertexInBlock++) { if (blockCopy.Contains(vertexInBlock)) { Partition nextPartition = finer.SplitBefore(firstNonDiscreteCell, vertexInBlock); this.Refine(group, nextPartition); int[] permF = new int[vertexCount]; int[] invF = new int[vertexCount]; for (int i = 0; i < vertexCount; i++) { permF[i] = i; invF[i] = i; } for (int j = 0; j <= firstNonDiscreteCell; j++) { int x = nextPartition.GetFirstInCell(j); int i = invF[x]; int h = permF[j]; permF[j] = x; permF[i] = h; invF[h] = i; invF[x] = j; } Permutation pPermF = new Permutation(permF); group.ChangeBase(pPermF); for (int j = 0; j < vertexCount; j++) { Permutation g = group[firstNonDiscreteCell, j]; if (g != null) { blockCopy.Remove(g[vertexInBlock]); } } } } } } }