(self, points)
return parents
r"""For a transitive group, finds the block system generated by
        ``points``.

        If a group ``G`` acts on a set ``S``, a nonempty subset ``B`` of ``S``
        is called a block under the action of ``G`` if for all ``g`` in ``G``
        we have ``gB = B`` (``g`` fixes ``B``) or ``gB`` and ``B`` have no
        common points (``g`` moves ``B`` entirely). ([1], p.23; [6]).

        The distinct translates ``gB`` of a block ``B`` for ``g`` in ``G``
        partition the set ``S`` and this set of translates is known as a block
        system. Moreover, we obviously have that all blocks in the partition
        have the same size, hence the block size divides ``|S|`` ([1], p.23).
        A ``G``-congruence is an equivalence relation ``~`` on the set ``S``
        such that ``a ~ b`` implies ``g(a) ~ g(b)`` for all ``g`` in ``G``.
        For a transitive group, the equivalence classes of a ``G``-congruence
        and the blocks of a block system are the same thing ([1], p.23).

        The algorithm below checks the group for transitivity, and then finds
        the ``G``-congruence generated by the pairs ``(p_0, p_1), (p_0, p_2),
        ..., (p_0,p_{k-1})`` which is the same as finding the maximal block
        system (i.e., the one with minimum block size) such that
        ``p_0, ..., p_{k-1}`` are in the same block ([1], p.83).

        It is an implementation of Atkinson's algorithm, as suggested in [1],
        and manipulates an equivalence relation on the set ``S`` using a
        union-find data structure. The running time is just above
        ``O(|points||S|)``. ([1], pp. 83-87; [7]).

        Examples
        ========

        >>> from sympy.combinatorics.perm_groups import PermutationGroup
        >>> from sympy.combinatorics.named_groups import DihedralGroup
        >>> D = DihedralGroup(10)
        >>> D.minimal_block([0,5])
        [0, 6, 2, 8, 4, 0, 6, 2, 8, 4]
        >>> D.minimal_block([0,1])
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

        See Also
        ========

        _union_find_rep, _union_find_merge, is_transitive, is_primitive
r"""For a transitive group, finds the block system generated by
        ``points``.
r For a transitive group finds the block system generated by points .
def minimal_block(self, points):
        r"""For a transitive group, finds the block system generated by
        ``points``.

        If a group ``G`` acts on a set ``S``, a nonempty subset ``B`` of ``S``
        is called a block under the action of ``G`` if for all ``g`` in ``G``
        we have ``gB = B`` (``g`` fixes ``B``) or ``gB`` and ``B`` have no
        common points (``g`` moves ``B`` entirely). ([1], p.23; [6]).

        The distinct translates ``gB`` of a block ``B`` for ``g`` in ``G``
        partition the set ``S`` and this set of translates is known as a block
        system. Moreover, we obviously have that all blocks in the partition
        have the same size, hence the block size divides ``|S|`` ([1], p.23).
        A ``G``-congruence is an equivalence relation ``~`` on the set ``S``
        such that ``a ~ b`` implies ``g(a) ~ g(b)`` for all ``g`` in ``G``.
        For a transitive group, the equivalence classes of a ``G``-congruence
        and the blocks of a block system are the same thing ([1], p.23).

        The algorithm below checks the group for transitivity, and then finds
        the ``G``-congruence generated by the pairs ``(p_0, p_1), (p_0, p_2),
        ..., (p_0,p_{k-1})`` which is the same as finding the maximal block
        system (i.e., the one with minimum block size) such that
        ``p_0, ..., p_{k-1}`` are in the same block ([1], p.83).

        It is an implementation of Atkinson's algorithm, as suggested in [1],
        and manipulates an equivalence relation on the set ``S`` using a
        union-find data structure. The running time is just above
        ``O(|points||S|)``. ([1], pp. 83-87; [7]).

        Examples
        ========

        >>> from sympy.combinatorics.perm_groups import PermutationGroup
        >>> from sympy.combinatorics.named_groups import DihedralGroup
        >>> D = DihedralGroup(10)
        >>> D.minimal_block([0,5])
        [0, 6, 2, 8, 4, 0, 6, 2, 8, 4]
        >>> D.minimal_block([0,1])
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

        See Also
        ========

        _union_find_rep, _union_find_merge, is_transitive, is_primitive

        """
        if not self.is_transitive():
            return False
        n = self.degree
        gens = self.generators
        # initialize the list of equivalence class representatives
        parents = list(range(n))
        ranks = [1]*n
        not_rep = []
        k = len(points)
        # the block size must divide the degree of the group
        if k > self.max_div:
            return [0]*n
        for i in range(k - 1):
            parents[points[i + 1]] = points[0]
            not_rep.append(points[i + 1])
        ranks[points[0]] = k
        i = 0
        len_not_rep = k - 1
        while i < len_not_rep:
            temp = not_rep[i]
            i += 1
            for gen in gens:
                # find has side effects: performs path compression on the list
                # of representatives
                delta = self._union_find_rep(temp, parents)
                # union has side effects: performs union by rank on the list
                # of representatives
                temp = self._union_find_merge(gen(temp), gen(delta), ranks,
                                              parents, not_rep)
                if temp == -1:
                    return [0]*n
                len_not_rep += temp
        for i in range(n):
            # force path compression to get the final state of the equivalence
            # relation
            self._union_find_rep(i, parents)
        return parents
def minimal_block ( self , points ) : if not self . is_transitive ( ) : return False n = self . degree gens = self . generators # initialize the list of equivalence class representatives parents = list ( range ( n ) ) ranks = [ 1 ] * n not_rep = [ ] k = len ( points ) # the block size must divide the degree of the group if k > self . max_div : return [ 0 ] * n for i in range ( k - 1 ) : parents [ points [ i + 1 ] ] = points [ 0 ] not_rep . append ( points [ i + 1 ] ) ranks [ points [ 0 ] ] = k i = 0 len_not_rep = k - 1 while i < len_not_rep : temp = not_rep [ i ] i += 1 for gen in gens : # find has side effects: performs path compression on the list # of representatives delta = self . _union_find_rep ( temp , parents ) # union has side effects: performs union by rank on the list # of representatives temp = self . _union_find_merge ( gen ( temp ) , gen ( delta ) , ranks , parents , not_rep ) if temp == - 1 : return [ 0 ] * n len_not_rep += temp for i in range ( n ) : # force path compression to get the final state of the equivalence # relation self . _union_find_rep ( i , parents ) return parents