from sympy.combinatorics.perm_groups import PermutationGroup from sympy.combinatorics.permutations import Permutation from sympy.utilities.iterables import uniq _af_new = Permutation._af_new def DirectProduct(*groups): """ Returns the direct product of several groups as a permutation group. Explanation =========== This is implemented much like the __mul__ procedure for taking the direct product of two permutation groups, but the idea of shifting the generators is realized in the case of an arbitrary number of groups. A call to DirectProduct(G1, G2, ..., Gn) is generally expected to be faster than a call to G1*G2*...*Gn (and thus the need for this algorithm). Examples ======== >>> from sympy.combinatorics.group_constructs import DirectProduct >>> from sympy.combinatorics.named_groups import CyclicGroup >>> C = CyclicGroup(4) >>> G = DirectProduct(C, C, C) >>> G.order() 64 See Also ======== sympy.combinatorics.perm_groups.PermutationGroup.__mul__ """ degrees = [] gens_count = [] total_degree = 0 total_gens = 0 for group in groups: current_deg = group.degree current_num_gens = len(group.generators) degrees.append(current_deg) total_degree += current_deg gens_count.append(current_num_gens) total_gens += current_num_gens array_gens = [] for i in range(total_gens): array_gens.append(list(range(total_degree))) current_gen = 0 current_deg = 0 for i in range(len(gens_count)): for j in range(current_gen, current_gen + gens_count[i]): gen = ((groups[i].generators)[j - current_gen]).array_form array_gens[j][current_deg:current_deg + degrees[i]] = \ [x + current_deg for x in gen] current_gen += gens_count[i] current_deg += degrees[i] perm_gens = list(uniq([_af_new(list(a)) for a in array_gens])) return PermutationGroup(perm_gens, dups=False)