def orbit_traversal(self, alpha, af=False): """ compute the orbit traversal Output: list of group elements; applying each to alpha one gets the orbit of alpha Examples ======== >>> from sympy.combinatorics.permutations import Permutation >>> from sympy.combinatorics.perm_groups import PermutationGroup >>> a = Permutation([0, 2, 1]) >>> b = Permutation([1, 0, 2]) >>> G = PermutationGroup([a, b]) >>> G.orbit_traversal(1, af=True) [[1, 0, 2], [0, 1, 2], [0, 2, 1]] """ genv = [p.array_form for p in self.generators] n = self._degree coset_repr = [None] * n if af: coset_repr[alpha] = range(n) else: coset_repr[alpha] = Permutation(range(n)) h = 0 r = len(genv) stg = [range(n)] sta = [alpha] pos = [0] * n while 1: # backtrack when finished iterating over generators if pos[h] >= r: if h == 0: return coset_repr pos[h] = 0 h -= 1 sta.pop() stg.pop() continue g = genv[pos[h]] pos[h] += 1 alpha = sta[-1] ag = g[alpha] if coset_repr[ag] == None: gen1 = perm_af_mul(g, stg[-1]) if af: coset_repr[ag] = gen1 else: coset_repr[ag] = Permutation(gen1) sta.append(ag) stg.append(gen1) h += 1
def test_PermutationMatrix_matmul(): p = Permutation([1, 2, 0]) P = PermutationMatrix(p) M = Matrix([[0, 1, 2], [3, 4, 5], [6, 7, 8]]) assert (P*M).as_explicit() == P.as_explicit()*M assert (M*P).as_explicit() == M*P.as_explicit() P1 = PermutationMatrix(Permutation([1, 2, 0])) P2 = PermutationMatrix(Permutation([2, 1, 0])) P3 = PermutationMatrix(Permutation([1, 0, 2])) assert P1*P2 == P3
def test_codegen_array_parse(): expr = M[i, j] assert _codegen_array_parse(expr) == (M, (i, j)) expr = M[i, j] * N[k, l] assert _codegen_array_parse(expr) == (CodegenArrayTensorProduct(M, N), (i, j, k, l)) expr = M[i, j] * N[j, k] assert _codegen_array_parse(expr) == (CodegenArrayDiagonal( CodegenArrayTensorProduct(M, N), (1, 2)), (i, k, j)) expr = Sum(M[i, j] * N[j, k], (j, 0, k - 1)) assert _codegen_array_parse(expr) == (CodegenArrayContraction( CodegenArrayTensorProduct(M, N), (1, 2)), (i, k)) expr = M[i, j] + N[i, j] assert _codegen_array_parse(expr) == (CodegenArrayElementwiseAdd(M, N), (i, j)) expr = M[i, j] + N[j, i] assert _codegen_array_parse(expr) == (CodegenArrayElementwiseAdd( M, CodegenArrayPermuteDims(N, Permutation([1, 0]))), (i, j)) expr = M[i, j] + M[j, i] assert _codegen_array_parse(expr) == (CodegenArrayElementwiseAdd( M, CodegenArrayPermuteDims(M, Permutation([1, 0]))), (i, j)) expr = (M * N * P)[i, j] assert _codegen_array_parse(expr) == (CodegenArrayContraction( CodegenArrayTensorProduct(M, N, P), (1, 2), (3, 4)), (i, j)) expr = expr.function # Disregard summation in previous expression ret1, ret2 = _codegen_array_parse(expr) assert ret1 == CodegenArrayDiagonal(CodegenArrayTensorProduct(M, N, P), (1, 2), (3, 4)) assert str(ret2) == "(i, j, _i_1, _i_2)" expr = KroneckerDelta(i, j) * M[i, k] assert _codegen_array_parse(expr) == (M, ({i, j}, k)) expr = KroneckerDelta(i, j) * KroneckerDelta(j, k) * M[i, l] assert _codegen_array_parse(expr) == (M, ({i, j, k}, l)) expr = KroneckerDelta(j, k) * (M[i, j] * N[k, l] + N[i, j] * M[k, l]) assert _codegen_array_parse(expr) == (CodegenArrayDiagonal( CodegenArrayElementwiseAdd( CodegenArrayTensorProduct(M, N), CodegenArrayPermuteDims(CodegenArrayTensorProduct(M, N), Permutation(0, 2)(1, 3))), (1, 2)), (i, l, frozenset({j, k}))) expr = KroneckerDelta(j, m) * KroneckerDelta( m, k) * (M[i, j] * N[k, l] + N[i, j] * M[k, l]) assert _codegen_array_parse(expr) == (CodegenArrayDiagonal( CodegenArrayElementwiseAdd( CodegenArrayTensorProduct(M, N), CodegenArrayPermuteDims(CodegenArrayTensorProduct(M, N), Permutation(0, 2)(1, 3))), (1, 2)), (i, l, frozenset({j, m, k}))) expr = KroneckerDelta(i, j) * KroneckerDelta(j, k) * KroneckerDelta( k, m) * M[i, 0] * KroneckerDelta(m, n) assert _codegen_array_parse(expr) == (M, ({i, j, k, m, n}, 0)) expr = M[i, i] assert _codegen_array_parse(expr) == (CodegenArrayDiagonal(M, (0, 1)), (i, ))
def test_contraction_permutation_mix(): Me = M.subs(k, 3).as_explicit() Ne = N.subs(k, 3).as_explicit() cg1 = CodegenArrayContraction( CodegenArrayPermuteDims(CodegenArrayTensorProduct(M, N), Permutation([0, 2, 1, 3])), (2, 3)) cg2 = CodegenArrayContraction(CodegenArrayTensorProduct(M, N), (1, 3)) assert cg1 == cg2 assert recognize_matrix_expression(cg2) == M * N.T cge1 = tensorcontraction( permutedims(tensorproduct(Me, Ne), Permutation([0, 2, 1, 3])), (2, 3)) cge2 = tensorcontraction(tensorproduct(Me, Ne), (1, 3)) assert cge1 == cge2 cg1 = CodegenArrayPermuteDims(CodegenArrayTensorProduct(M, N), Permutation([0, 1, 3, 2])) cg2 = CodegenArrayTensorProduct( M, CodegenArrayPermuteDims(N, Permutation([1, 0]))) assert cg1 == cg2 assert recognize_matrix_expression(cg1) == CodegenArrayTensorProduct( M, N.T) assert recognize_matrix_expression(cg2) == CodegenArrayTensorProduct( M, N.T) cg1 = CodegenArrayContraction( CodegenArrayPermuteDims(CodegenArrayTensorProduct(M, N, P, Q), Permutation([0, 2, 3, 1, 4, 5, 7, 6])), (1, 2), (3, 5)) cg2 = CodegenArrayContraction( CodegenArrayTensorProduct( M, N, P, CodegenArrayPermuteDims(Q, Permutation([1, 0]))), (1, 5), (2, 3)) assert cg1 == cg2 assert recognize_matrix_expression(cg1) == CodegenArrayTensorProduct( M * P.T * Trace(N), Q.T) assert recognize_matrix_expression(cg2) == CodegenArrayTensorProduct( M * P.T * Trace(N), Q.T) cg1 = CodegenArrayContraction( CodegenArrayPermuteDims(CodegenArrayTensorProduct(M, N, P, Q), Permutation([1, 0, 4, 6, 2, 7, 5, 3])), (0, 1), (2, 6), (3, 7)) cg2 = CodegenArrayPermuteDims( CodegenArrayContraction(CodegenArrayTensorProduct(M, P, Q, N), (0, 1), (2, 3), (4, 7)), [1, 0]) assert cg1 == cg2 cg1 = CodegenArrayContraction( CodegenArrayPermuteDims(CodegenArrayTensorProduct(M, N, P, Q), Permutation([1, 0, 4, 6, 7, 2, 5, 3])), (0, 1), (2, 6), (3, 7)) cg2 = CodegenArrayPermuteDims( CodegenArrayContraction( CodegenArrayTensorProduct(CodegenArrayPermuteDims(M, [1, 0]), N, P, Q), (0, 1), (3, 6), (4, 5)), Permutation([1, 0])) assert cg1 == cg2
def test_matrix_derivative_non_matrix_result(): # This is a 4-dimensional array: I = Identity(k) AdA = PermuteDims(ArrayTensorProduct(I, I), Permutation(3)(1, 2)) assert A.diff(A) == AdA assert A.T.diff(A) == PermuteDims(ArrayTensorProduct(I, I), Permutation(3)(1, 2, 3)) assert (2 * A).diff(A) == PermuteDims(ArrayTensorProduct(2 * I, I), Permutation(3)(1, 2)) assert MatAdd(A, A).diff(A) == ArrayAdd(AdA, AdA) assert (A + B).diff(A) == AdA
def test_bell_perm(): assert [len(set(generate_bell(i))) for i in range(1, 7)] == [factorial(i) for i in range(1, 7)] assert list(generate_bell(3)) == [(0, 1, 2), (0, 2, 1), (2, 0, 1), (2, 1, 0), (1, 2, 0), (1, 0, 2)] # generate_bell and trotterjohnson are advertised to return the same # permutations; this is not technically necessary so this test could # be removed for n in range(1, 5): p = Permutation(range(n)) b = generate_bell(n) for bi in b: assert bi == tuple(p.array_form) p = p.next_trotterjohnson() raises(ValueError, lambda: list(generate_bell(0))) # XXX is this consistent with other permutation algorithms?
def test_arrayexpr_convert_index_to_array_support_function(): expr = M[i, j] assert _convert_indexed_to_array(expr) == (M, (i, j)) expr = M[i, j] * N[k, l] assert _convert_indexed_to_array(expr) == (ArrayTensorProduct(M, N), (i, j, k, l)) expr = M[i, j] * N[j, k] assert _convert_indexed_to_array(expr) == (ArrayDiagonal( ArrayTensorProduct(M, N), (1, 2)), (i, k, j)) expr = Sum(M[i, j] * N[j, k], (j, 0, k - 1)) assert _convert_indexed_to_array(expr) == (ArrayContraction( ArrayTensorProduct(M, N), (1, 2)), (i, k)) expr = M[i, j] + N[i, j] assert _convert_indexed_to_array(expr) == (ArrayAdd(M, N), (i, j)) expr = M[i, j] + N[j, i] assert _convert_indexed_to_array(expr) == (ArrayAdd( M, PermuteDims(N, Permutation([1, 0]))), (i, j)) expr = M[i, j] + M[j, i] assert _convert_indexed_to_array(expr) == (ArrayAdd( M, PermuteDims(M, Permutation([1, 0]))), (i, j)) expr = (M * N * P)[i, j] assert _convert_indexed_to_array(expr) == (_array_contraction( ArrayTensorProduct(M, N, P), (1, 2), (3, 4)), (i, j)) expr = expr.function # Disregard summation in previous expression ret1, ret2 = _convert_indexed_to_array(expr) assert ret1 == ArrayDiagonal(ArrayTensorProduct(M, N, P), (1, 2), (3, 4)) assert str(ret2) == "(i, j, _i_1, _i_2)" expr = KroneckerDelta(i, j) * M[i, k] assert _convert_indexed_to_array(expr) == (M, ({i, j}, k)) expr = KroneckerDelta(i, j) * KroneckerDelta(j, k) * M[i, l] assert _convert_indexed_to_array(expr) == (M, ({i, j, k}, l)) expr = KroneckerDelta(j, k) * (M[i, j] * N[k, l] + N[i, j] * M[k, l]) assert _convert_indexed_to_array(expr) == (_array_diagonal( _array_add( ArrayTensorProduct(M, N), _permute_dims(ArrayTensorProduct(M, N), Permutation(0, 2)(1, 3))), (1, 2)), (i, l, frozenset({j, k}))) expr = KroneckerDelta(j, m) * KroneckerDelta( m, k) * (M[i, j] * N[k, l] + N[i, j] * M[k, l]) assert _convert_indexed_to_array(expr) == (_array_diagonal( _array_add( ArrayTensorProduct(M, N), _permute_dims(ArrayTensorProduct(M, N), Permutation(0, 2)(1, 3))), (1, 2)), (i, l, frozenset({j, m, k}))) expr = KroneckerDelta(i, j) * KroneckerDelta(j, k) * KroneckerDelta( k, m) * M[i, 0] * KroneckerDelta(m, n) assert _convert_indexed_to_array(expr) == (M, ({i, j, k, m, n}, 0)) expr = M[i, i] assert _convert_indexed_to_array(expr) == (ArrayDiagonal(M, (0, 1)), (i, ))
def test_homomorphism(): # FpGroup -> PermutationGroup F, a, b = free_group("a, b") G = FpGroup(F, [a**3, b**3, (a*b)**2]) c = Permutation(3)(0, 1, 2) d = Permutation(3)(1, 2, 3) A = AlternatingGroup(4) T = homomorphism(G, A, [a, b], [c, d]) assert T(a*b**2*a**-1) == c*d**2*c**-1 assert T.is_isomorphism() assert T(T.invert(Permutation(3)(0, 2, 3))) == Permutation(3)(0, 2, 3) T = homomorphism(G, AlternatingGroup(4), G.generators) assert T.is_trivial() assert T.kernel().order() == G.order() E, e = free_group("e") G = FpGroup(E, [e**8]) P = PermutationGroup([Permutation(0, 1, 2, 3), Permutation(0, 2)]) T = homomorphism(G, P, [e], [Permutation(0, 1, 2, 3)]) assert T.image().order() == 4 assert T(T.invert(Permutation(0, 2)(1, 3))) == Permutation(0, 2)(1, 3) T = homomorphism(E, AlternatingGroup(4), E.generators, [c]) assert T.invert(c**2) == e**-1 #order(c) == 3 so c**2 == c**-1 # FreeGroup -> FreeGroup T = homomorphism(F, E, [a], [e]) assert T(a**-2*b**4*a**2).is_identity # FreeGroup -> FpGroup G = FpGroup(F, [a*b*a**-1*b**-1]) T = homomorphism(F, G, F.generators, G.generators) assert T.invert(a**-1*b**-1*a**2) == a*b**-1 # PermutationGroup -> PermutationGroup D = DihedralGroup(8) p = Permutation(0, 1, 2, 3, 4, 5, 6, 7) P = PermutationGroup(p) T = homomorphism(P, D, [p], [p]) assert T.is_injective() assert not T.is_isomorphism() assert T.invert(p**3) == p**3 T2 = homomorphism(F, P, [F.generators[0]], P.generators) T = T.compose(T2) assert T.domain == F assert T.codomain == D assert T(a*b) == p
def test_MartrixPermute_basic(): p = Permutation(0, 1) P = PermutationMatrix(p) A = MatrixSymbol('A', 2, 2) raises(ValueError, lambda: MatrixPermute(Symbol('x'), p)) raises(ValueError, lambda: MatrixPermute(A, Symbol('x'))) assert MatrixPermute(A, P) == MatrixPermute(A, p) raises(ValueError, lambda: MatrixPermute(A, p, 2)) pp = Permutation(0, 1, size=3) assert MatrixPermute(A, pp) == MatrixPermute(A, p) pp = Permutation(0, 1, 2) raises(ValueError, lambda: MatrixPermute(A, pp))
def test_bell_perm(): assert [len(set(generate_bell(i))) for i in range(1, 7)] == [ factorial(i) for i in range(1, 7)] assert list(generate_bell(3)) == [ (0, 1, 2), (0, 2, 1), (2, 0, 1), (2, 1, 0), (1, 2, 0), (1, 0, 2)] # generate_bell and trotterjohnson are advertised to return the same # permutations; this is not technically necessary so this test could # be removed for n in range(1, 5): p = Permutation(range(n)) b = generate_bell(n) for bi in b: assert bi == tuple(p.array_form) p = p.next_trotterjohnson() raises(ValueError, lambda: list(generate_bell(0))) # XXX is this consistent with other permutation algorithms?
def test_arrayexpr_contraction_permutation_mix(): Me = M.subs(k, 3).as_explicit() Ne = N.subs(k, 3).as_explicit() cg1 = _array_contraction(PermuteDims(_array_tensor_product(M, N), Permutation([0, 2, 1, 3])), (2, 3)) cg2 = _array_contraction(_array_tensor_product(M, N), (1, 3)) assert cg1 == cg2 cge1 = tensorcontraction(permutedims(tensorproduct(Me, Ne), Permutation([0, 2, 1, 3])), (2, 3)) cge2 = tensorcontraction(tensorproduct(Me, Ne), (1, 3)) assert cge1 == cge2 cg1 = _permute_dims(_array_tensor_product(M, N), Permutation([0, 1, 3, 2])) cg2 = _array_tensor_product(M, _permute_dims(N, Permutation([1, 0]))) assert cg1 == cg2 cg1 = _array_contraction( _permute_dims( _array_tensor_product(M, N, P, Q), Permutation([0, 2, 3, 1, 4, 5, 7, 6])), (1, 2), (3, 5) ) cg2 = _array_contraction( _array_tensor_product(M, N, P, _permute_dims(Q, Permutation([1, 0]))), (1, 5), (2, 3) ) assert cg1 == cg2 cg1 = _array_contraction( _permute_dims( _array_tensor_product(M, N, P, Q), Permutation([1, 0, 4, 6, 2, 7, 5, 3])), (0, 1), (2, 6), (3, 7) ) cg2 = _permute_dims( _array_contraction( _array_tensor_product(M, P, Q, N), (0, 1), (2, 3), (4, 7)), [1, 0] ) assert cg1 == cg2 cg1 = _array_contraction( _permute_dims( _array_tensor_product(M, N, P, Q), Permutation([1, 0, 4, 6, 7, 2, 5, 3])), (0, 1), (2, 6), (3, 7) ) cg2 = _permute_dims( _array_contraction( _array_tensor_product(_permute_dims(M, [1, 0]), N, P, Q), (0, 1), (3, 6), (4, 5) ), Permutation([1, 0]) ) assert cg1 == cg2
def Reconnection(self, Graph, a, b, RM_ID): w = 1 G = copy.deepcopy(Graph) Average_Connections =\ [ [x, [x[0]+'*',Permutation(a)(x[1]),'R',x[3]]]\ for x in self.PRE.RMLg1_relabeled[RM_ID] if x[2] == 'L'] +\ [ [x, [x[0]+'*',Permutation(b)(x[1]),'L',x[3]]]\ for x in self.PRE.RMLg1_relabeled[RM_ID] if x[2] == 'R'] # making node names in strings and adding new edes to the graph. Average_Connections_List =\ [[self.PRE.Label_Dic_inv[x[0][0]+str(x[0][1])]+x[0][2]+str(x[0][3]),\ self.PRE.Label_Dic_inv[x[1][0]+str(x[1][1])]+x[1][2]+str(x[1][3])] for x in Average_Connections] G.add_edges_from(Average_Connections_List) # tidying up: for y in self.PRE.RMLg_String[RM_ID]: # for each RM lim neighbour = list(G.neighbors(y)) if len(neighbour ) == 2: #case where the lim is connected to two nodes. G.remove_node(y) G.add_edge(neighbour[0], neighbour[1], info=neighbour) elif G.degree(y) == 2: G.remove_node(y) else: # case the node is a pendant. if G.node[y]['original'][0][-1] != '*' and G.node[y][ 'original'][2] == 'L': side = 1 elif G.node[y]['original'][0][-1] == '*' and G.node[y][ 'original'][2] == 'R': side = 1 else: side = 2 w *= self.RM_List[RM_ID][side][G.nodes[y]['original'][3]] G.remove_node(y) #Multiplying Weingarten function. t = len(self.PRE.RM1_grouped[RM_ID]) b_inv = [b.index(i) for i in range(t)] c = (Permutation(a) * Permutation(b_inv)).full_cyclic_form Cycle = sorted([len(cycle) for cycle in c], reverse=True) Address = self.WGF_all.Addressbook['wg{}'.format(t)].index(Cycle) w *= self.WGF_all.Dic['wg{}'.format(t)][Address][1] return G, simplify(w)
def generate_fixing_permutations(l): """ Explicitly generate the permutations leaving a list invariant. Parameters ---------- l: list The list mentionned above. Returns ------- list The list of the permutations (in sympy format) leaving the list invariant. """ distinct_elts = {} for index, elt in enumerate(l): if elt not in distinct_elts: distinct_elts[elt] = [] distinct_elts[elt].append(index) fixing_permutations = [] for sub_permutations in product(*[ generate_permuted_lists(distinct_elt_indices) for distinct_elt, distinct_elt_indices in distinct_elts.items() ]): fixing_permutation = [None] * len(l) for sub_permutation_index, distinct_elt_indices in enumerate( distinct_elts.values()): for distinct_elt_index_enum, distinct_elt_index in enumerate( distinct_elt_indices): fixing_permutation[distinct_elt_index] = sub_permutations[ sub_permutation_index][distinct_elt_index_enum] fixing_permutations.append(Permutation(fixing_permutation)) return fixing_permutations
def standard_form(p): """ Return the standard form of the permutation, i.e. cycles written with largest element first, and largest elements in increasing order. """ p = Permutation(p).full_cyclic_form m = [max(cycle) for cycle in p] m.sort() pp = [] for mm in m: for cycle in p: if mm in cycle: l = len(cycle) if l == 1: pp.append(cycle) else: z = cycle.index(mm) cycle = [cycle[(z + i) % l] for i in range(l)] pp.append(cycle) else: pass return pp
def __init__(self, *partition): self.partition = tuple(i for i in partition if i > 0) # Strip tailing zeros self.n = sum(partition) # Compute the entries in the rows and columns self.rows = [] self.columns = [[] for _ in range(self.partition[0])] start = 0 for x in self.partition: self.rows.append(list(range(start, start + x))) for i in range(x): self.columns[i].append(start + i) start += x # Permutation that helps setting up the column stabilizer self.column_reorderer = ~Permutation(list(chain(*self.columns))) # Calculate sym. dimension and product of all hook numbers self.boxes = [(i, j) for j, col in enumerate(self.columns) for i in range(len(col))] self.lastbox = len(self.boxes) - 1 self.hookprod = self.HookProduct() self.sym_dim = factorial(self.n) // self.hookprod
def __new__(cls, expr, permutation, nest_permutation=True): from sympy.combinatorics import Permutation expr = _sympify(expr) permutation = Permutation(permutation) permutation_size = permutation.size expr_rank = get_rank(expr) if permutation_size != expr_rank: raise ValueError("Permutation size must be the length of the shape of expr") if isinstance(expr, PermuteDims): subexpr = expr.expr subperm = expr.permutation permutation = permutation * subperm expr = subexpr if isinstance(expr, ArrayContraction): expr, permutation = cls._handle_nested_contraction(expr, permutation) if isinstance(expr, ArrayTensorProduct): expr, permutation = cls._sort_components(expr, permutation) if isinstance(expr, (ZeroArray, ZeroMatrix)): return ZeroArray(*[expr.shape[i] for i in permutation.array_form]) plist = permutation.array_form if plist == sorted(plist): return expr obj = Basic.__new__(cls, expr, permutation) obj._subranks = [get_rank(expr)] shape = expr.shape if shape is None: obj._shape = None else: obj._shape = tuple(shape[permutation(i)] for i in range(len(shape))) return obj
def calcula_dist(pi): I = Permutation([], size=pi.size) countPorts = 0 while pi != I: atempt = search_2move(pi) if atempt != None: pi = atempt countPorts += 1 continue atempt = search_0move(pi) if atempt != None: pi = atempt countPorts += 1 continue atemp, aux = search_seq(pi) if aux != 0: pi = atemp countPorts += aux continue print('Error! Could not solve.', pi, '\n') return 0 return countPorts
def block_homomorphism(group, blocks): ''' Return the homomorphism induced by the action of the permutation group `group` on the block system `blocks`. The latter should be of the same form as returned by the `minimal_block` method for permutation groups, namely a list of length `group.degree` where the i-th entry is a representative of the block i belongs to. ''' from sympy.combinatorics import Permutation from sympy.combinatorics.named_groups import SymmetricGroup n = len(blocks) # number the blocks; m is the total number, # b is such that b[i] is the number of the block i belongs to, # p is the list of length m such that p[i] is the representative # of the i-th block m = 0 p = [] b = [None]*n for i in range(n): if blocks[i] == i: p.append(i) b[i] = m m += 1 for i in range(n): b[i] = b[blocks[i]] codomain = SymmetricGroup(m) # the list corresponding to the identity permutation in codomain identity = range(m) images = {g: Permutation([b[p[i]^g] for i in identity]) for g in group.generators} H = GroupHomomorphism(group, codomain, images) return H
def test_connected_components(): a, b, c, d, e, f, g, h, i, j, k, l, m = symbols('a:m') M = Matrix([[a, 0, 0, 0, b, 0, 0, 0, 0, 0, c, 0, 0], [0, d, 0, 0, 0, e, 0, 0, 0, 0, 0, f, 0], [0, 0, g, 0, 0, 0, h, 0, 0, 0, 0, 0, i], [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [m, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], [0, m, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], [0, 0, m, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0], [j, 0, 0, 0, k, 0, 0, 1, 0, 0, l, 0, 0], [0, j, 0, 0, 0, k, 0, 0, 1, 0, 0, l, 0], [0, 0, j, 0, 0, 0, k, 0, 0, 1, 0, 0, l], [0, 0, 0, 0, d, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, d, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0, d, 0, 0, 0, 0, 0, 1]]) cc = M.connected_components() assert cc == [[0, 4, 7, 10], [1, 5, 8, 11], [2, 6, 9, 12], [3]] P, B = M.connected_components_decomposition() p = Permutation([0, 4, 7, 10, 1, 5, 8, 11, 2, 6, 9, 12, 3]) assert P == PermutationMatrix(p) B0 = Matrix([[a, b, 0, c], [m, 1, 0, 0], [j, k, 1, l], [0, d, 0, 1]]) B1 = Matrix([[d, e, 0, f], [m, 1, 0, 0], [j, k, 1, l], [0, d, 0, 1]]) B2 = Matrix([[g, h, 0, i], [m, 1, 0, 0], [j, k, 1, l], [0, d, 0, 1]]) B3 = Matrix([[1]]) assert B == BlockDiagMatrix(B0, B1, B2, B3)
def find_mapping_permutation(source_list, target_list): """ Determine a permutation p (not unique if source_list has repeated elements) such that target_list[p[i]] = source_list[i]. Parameters ---------- source_list: list See description of the function. target_list: list See description of the function. Returns ------- Permutation A sympy permutation describing the permutation p defined in the description of the function. """ source_distinct_elts = {} target_distinct_elts = {} for source_index, source_value in enumerate(source_list): if source_value not in source_distinct_elts: source_distinct_elts[source_value] = [] source_distinct_elts[source_value].append(source_index) for target_index, target_value in enumerate(target_list): if target_value not in target_distinct_elts: target_distinct_elts[target_value] = [] target_distinct_elts[target_value].append(target_index) perm = [None] * len(source_list) for source_distinct_elt, source_distinct_elt_indices in source_distinct_elts.items( ): target_distinct_elt_indices = target_distinct_elts[source_distinct_elt] for (source_distinct_elt_index, target_distinct_elt_index) in zip(source_distinct_elt_indices, target_distinct_elt_indices): perm[source_distinct_elt_index] = target_distinct_elt_index return Permutation(perm)
def _check_perms(self, perms): """ for each permutation in perms, check whether or not it is in the puzzle group inputs: ------- perms - (list) of (list) of (int) - list of permutations given as lists representing the bottom row of the long standard notation for permutations (NOT cyclic notation) Example: the permutation (1 2 3 4 5 6) (2 4 5 1 3 6) should be given as [2,4,5,1,3,6] returns: -------- (int) or (float) - probability that the current state represented by the given permutations is valid. If it's exactly 0 or 1, returns an int, otherwise a float in range [0,1] """ result_list = list() for perm in perms: perm = get_cycles(perm) perm = Permutation(perm, size=len(self.solved_state)) result_list.append(perm in self.puzzle_group) if len(set(result_list)) == 1: return int(result_list[0]) return result_list.count(True) / len(result_list)
def read_log_signature(filename, blocks, s): with open(filename) as f: lines = [] for x in f: x = [int(i) - 1 for i in x.split()] lines.append(x) dalpha = defaultdict(dict) dbeta = defaultdict(dict) c = 0 for i in range(s): for j in range(blocks - i): #print(i, j, lines[c]) dalpha[i][j] = Permutation(lines[c][:10]) dbeta[i][j] = Permutation(lines[c][10:]) c += 1 return dalpha, dbeta
def test_array_symbol_and_element(): A = ArraySymbol("A", (2, )) A0 = ArrayElement(A, (0, )) A1 = ArrayElement(A, (1, )) assert A[0] == A0 assert A[1] != A0 assert A.as_explicit() == ImmutableDenseNDimArray([A0, A1]) A2 = tensorproduct(A, A) assert A2.shape == (2, 2) # TODO: not yet supported: # assert A2.as_explicit() == Array([[A[0]*A[0], A[1]*A[0]], [A[0]*A[1], A[1]*A[1]]]) A3 = tensorcontraction(A2, (0, 1)) assert A3.shape == () # TODO: not yet supported: # assert A3.as_explicit() == Array([]) A = ArraySymbol("A", (2, 3, 4)) Ae = A.as_explicit() assert Ae == ImmutableDenseNDimArray( [[[ArrayElement(A, (i, j, k)) for k in range(4)] for j in range(3)] for i in range(2)]) p = _permute_dims(A, Permutation(0, 2, 1)) assert isinstance(p, PermuteDims)
def get_generators(perms: List[Permutation]): identity = Permutation([], size=perms[0].size) gens = [] perms_tmp = [ identity, ] for g in perms: if g in perms_tmp: continue gens.append(g) que = Queue() for h in perms_tmp: que.put(h) while not que.empty(): h = que.get() gh = g * h if gh not in perms_tmp: que.put(gh) perms_tmp.append(gh) hg = h * g if hg not in perms_tmp: que.put(hg) perms_tmp.append(hg) assert len(perms_tmp) == len(perms) return gens
def permute_tensor_factors(dims: Union[int, List[int]], perm: List[int]) -> np.ndarray: r""" Return a permutation matrix that appropriately swaps spaces of the given dimension(s). Given a Hilbert space dimension dim and an list representing the permutation perm of the tensor product Hilbert spaces, returns a dim**len(perm) by dim**len(perm) permutation matrix. 1) Suppose dims=2 and perm=[0, 1] Returns the identity operator on two qubits 2) Suppose dims=2 and perm=[1, 0] Returns the SWAP operator on two qubits which maps :math:`A_1 \otimes A_2 \rightarrow A_2 \otimes A_1` 3) Suppose dims=[2, 4] and perm=[1, 0] Returns the SWAP operator on three qubits which maps :math:`A_1 \otimes (A_2 \otimes A_3) \rightarrow (A_2 \otimes A_3)` See: Equations 5.11, 5.12, and 5.13 in [SCOTT]_ .. [SCOTT] Optimizing quantum process tomography with unitary 2-designs. A. J. Scott. J. Phys. A 41, 055308 (2008). https://dx.doi.org/10.1088/1751-8113/41/5/055308 https://arxiv.org/abs/0711.1017 This function is used in tests for other functions. However, it can also be useful when thinking about higher moment (N>2) integrals over the Haar measure. :param dims: The dimension of each Hilbert space factor given in order of the pre-permuted factorization of the total space. If an int is specified then each space in the permutation is assumed to have this dimension. :param perm: A list representing the permutation of the tensor factors. :return: a permutation matrix that permutes the factors of the given dimension. """ if isinstance(dims, int): dim_list = [dims for _ in range(2 * len(perm))] total_dim = dims**len(perm) else: assert len(dims) == len( perm ), "Please specify the dimension of each factor to be permuted." dim_list = [dim for _ in range(2) for dim in dims] total_dim = np.prod(dims) transpositions = Permutation(perm).transpositions() # start with identity perm_matrix = np.eye(total_dim, total_dim) # reshape for easy implementation of transpositions perm_matrix = np.reshape(perm_matrix, dim_list) # build up the permutation one transposition at a time for swap in transpositions: perm_matrix = np.swapaxes(perm_matrix, swap[0], swap[1]) # reshape to act on total_dim space return np.reshape(perm_matrix, [total_dim, total_dim])
def plot_permutation_groups(base_structure, output_name): rotations, translations = get_symmetry_operations(base_structure) displacement_set = base_structure.frac_coords list_data = [] for index in range(2, 10 + 1): for hnf in tqdm(generate_all_superlattices(index)): dsperm = DerivativeStructurePermutation(hnf, displacement_set, rotations, translations) perms = [ Permutation(g) for g in dsperm.get_symmetry_operation_permutations() ] gens = get_generators(perms) G = PermutationGroup(gens) data = { "index": index, "hnf": hnf, "generators": gens, "group": G, "order": G.order(), "orbits": G.orbits(), } list_data.append(data) df = pd.DataFrame(list_data) sns.swarmplot(x="index", y="order", data=df) plt.title(output_name) plt.savefig(output_name + ".png") return df
def test_mixed_deriv_mixed_expressions(): expr = 3 * Trace(A) assert expr.diff(A) == 3 * Identity(k) expr = k deriv = expr.diff(A) assert isinstance(deriv, ZeroMatrix) assert deriv == ZeroMatrix(k, k) expr = Trace(A)**2 assert expr.diff(A) == (2 * Trace(A)) * Identity(k) expr = Trace(A) * A I = Identity(k) assert expr.diff(A) == ArrayAdd( ArrayTensorProduct(I, A), PermuteDims(ArrayTensorProduct(Trace(A) * I, I), Permutation(3)(1, 2))) expr = Trace(Trace(A) * A) assert expr.diff(A) == (2 * Trace(A)) * Identity(k) expr = Trace(Trace(Trace(A) * A) * A) assert expr.diff(A) == (3 * Trace(A)**2) * Identity(k)
def test_permute(): a = OperationsOnlyMatrix(3, 4, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) raises(IndexError, lambda: a.permute([[0, 5]])) b = a.permute_rows([[0, 2], [0, 1]]) assert a.permute([[0, 2], [0, 1]]) == b == Matrix( [[5, 6, 7, 8], [9, 10, 11, 12], [1, 2, 3, 4]]) b = a.permute_cols([[0, 2], [0, 1]]) assert a.permute([[0, 2], [0, 1]], orientation='cols') == b ==\ Matrix([ [ 2, 3, 1, 4], [ 6, 7, 5, 8], [10, 11, 9, 12]]) b = a.permute_cols([[0, 2], [0, 1]], direction='backward') assert a.permute([[0, 2], [0, 1]], orientation='cols', direction='backward') == b ==\ Matrix([ [ 3, 1, 2, 4], [ 7, 5, 6, 8], [11, 9, 10, 12]]) assert a.permute([1, 2, 0, 3]) == Matrix([[5, 6, 7, 8], [9, 10, 11, 12], [1, 2, 3, 4]]) from sympy.combinatorics import Permutation assert a.permute(Permutation([1, 2, 0, 3])) == Matrix([[5, 6, 7, 8], [9, 10, 11, 12], [1, 2, 3, 4]])
def _to_perm_group(self): ''' Return an isomorphic permutation group and the isomorphism. The implementation is dependent on coset enumeration so will only terminate for finite groups. ''' from sympy.combinatorics import Permutation, PermutationGroup from sympy.combinatorics.homomorphisms import homomorphism from sympy import S if self.order() == S.Infinity: raise NotImplementedError("Permutation presentation of infinite " "groups is not implemented") if self._perm_isomorphism: T = self._perm_isomorphism P = T.image() else: C = self.coset_table([]) gens = self.generators images = [[C[i][2 * gens.index(g)] for i in range(len(C))] for g in gens] images = [Permutation(i) for i in images] P = PermutationGroup(images) T = homomorphism(self, P, gens, images, check=False) self._perm_isomorphism = T return P, T
def test_arrayexpr_nested_permutations(): cg = _permute_dims(_permute_dims(M, (1, 0)), (1, 0)) assert cg == M times = 3 plist1 = [list(range(6)) for i in range(times)] plist2 = [list(range(6)) for i in range(times)] for i in range(times): random.shuffle(plist1[i]) random.shuffle(plist2[i]) plist1.append([2, 5, 4, 1, 0, 3]) plist2.append([3, 5, 0, 4, 1, 2]) plist1.append([2, 5, 4, 0, 3, 1]) plist2.append([3, 0, 5, 1, 2, 4]) plist1.append([5, 4, 2, 0, 3, 1]) plist2.append([4, 5, 0, 2, 3, 1]) Me = M.subs(k, 3).as_explicit() Ne = N.subs(k, 3).as_explicit() Pe = P.subs(k, 3).as_explicit() cge = tensorproduct(Me, Ne, Pe) for permutation_array1, permutation_array2 in zip(plist1, plist2): p1 = Permutation(permutation_array1) p2 = Permutation(permutation_array2) cg = _permute_dims( _permute_dims( _array_tensor_product(M, N, P), p1), p2 ) result = _permute_dims( _array_tensor_product(M, N, P), p2*p1 ) assert cg == result # Check that `permutedims` behaves the same way with explicit-component arrays: result1 = _permute_dims(_permute_dims(cge, p1), p2) result2 = _permute_dims(cge, p2*p1) assert result1 == result2
def process_composite_contractions(contraction, elementary_contractions, n_indices, expand_hole, base_order_map, upper_indices_set, lower_indices_set): """ Process a single composite contraction expressed in terms of indices of elementary contractions. :param contraction: a composite contraction :param elementary_contractions: a list of density cumulants / hole densities :param n_indices: the total number of indices :param expand_hole: expand hole densities to Kronecker delta minus one density if True :param base_order_map: the index map to ordering index, e.g., {"ug0": 0, "lg0": 1, ...}, u/l for upper/lower :param upper_indices_set: the set of all creation operators :param lower_indices_set: the set of all annihilation operators :return: a list of contractions in terms of (sign, list_of_densities, sq_op) """ list_of_densities = [] current_order = [] n_open = 0 for con in contraction: ele_con = elementary_contractions[con] list_of_densities.append(ele_con) n_open += ele_con.n_upper if isinstance(ele_con, HoleDensity): current_order += [ f"l{ele_con.lower_indices[0].name}", f"u{ele_con.upper_indices[0].name}" ] else: current_order += [f"u{i.name}" for i in ele_con.upper_indices] current_order += [ f"l{i.name}" for i in ele_con.lower_indices[::-1] ] n_open = n_indices - 2 * n_open # sort the open indices if n_open != 0: contracted = set(current_order) open_upper_indices = IndicesSpinOrbital( sorted(Index(i[1:]) for i in upper_indices_set - contracted)) open_lower_indices = IndicesSpinOrbital( sorted(Index(i[1:]) for i in lower_indices_set - contracted)) current_order += [f"u{i.name}" for i in open_upper_indices] current_order += [f"l{i.name}" for i in open_lower_indices[::-1]] sq_op = SecondQuantizedOperator(open_upper_indices, open_lower_indices) else: sq_op = SecondQuantizedOperator.make_empty() # expand hole densities to delta - lambda_1 sign_densities_pairs = expand_hole_densities( list_of_densities) if expand_hole else [(1, list_of_densities)] # determine sign sign = (-1)**Permutation([base_order_map[i] for i in current_order]).inversions() return [(sign * _s, list_of_densities, sq_op) for _s, list_of_densities in sign_densities_pairs]
def cyclic_form(self): """Return the indices of the corners in cyclic notation. The indices are given relative to the original position of corners. See Also ======== corners, array_form """ return Perm._af_new(self.array_form).cyclic_form
def _string_to_perm(s): rv = [Perm(range(20))] p = None for si in s: if si not in '01': count = int(si) - 1 else: count = 1 if si == '0': p = _f0 elif si == '1': p = _f1 rv.extend([p]*count) return Perm.rmul(*rv)
def _naive_list_centralizer(self, other, af=False): from sympy.combinatorics.perm_groups import PermutationGroup """ Return a list of elements for the centralizer of a subgroup/set/element. This is a brute force implementation that goes over all elements of the group and checks for membership in the centralizer. It is used to test ``.centralizer()`` from ``sympy.combinatorics.perm_groups``. Examples ======== >>> from sympy.combinatorics.testutil import _naive_list_centralizer >>> from sympy.combinatorics.named_groups import DihedralGroup >>> D = DihedralGroup(4) >>> _naive_list_centralizer(D, D) [Permutation([0, 1, 2, 3]), Permutation([2, 3, 0, 1])] See Also ======== sympy.combinatorics.perm_groups.centralizer """ from sympy.combinatorics.permutations import _af_commutes_with if hasattr(other, "generators"): elements = list(self.generate_dimino(af=True)) gens = [x._array_form for x in other.generators] commutes_with_gens = lambda x: all(_af_commutes_with(x, gen) for gen in gens) centralizer_list = [] if not af: for element in elements: if commutes_with_gens(element): centralizer_list.append(Permutation._af_new(element)) else: for element in elements: if commutes_with_gens(element): centralizer_list.append(element) return centralizer_list elif hasattr(other, "getitem"): return _naive_list_centralizer(self, PermutationGroup(other), af) elif hasattr(other, "array_form"): return _naive_list_centralizer(self, PermutationGroup([other]), af)