Beispiel #1
0
    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
Beispiel #2
0
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
Beispiel #3
0
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, ))
Beispiel #4
0
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
Beispiel #5
0
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
Beispiel #6
0
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?
Beispiel #7
0
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, ))
Beispiel #8
0
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
Beispiel #9
0
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))
Beispiel #10
0
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
Beispiel #12
0
    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
Beispiel #14
0
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
Beispiel #15
0
    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
Beispiel #16
0
 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
Beispiel #17
0
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
Beispiel #18
0
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
Beispiel #19
0
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)
Beispiel #22
0
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
Beispiel #23
0
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)
Beispiel #24
0
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
Beispiel #25
0
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])
Beispiel #26
0
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
Beispiel #27
0
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)
Beispiel #28
0
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]])
Beispiel #29
0
    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]
Beispiel #32
0
    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
Beispiel #33
0
 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)
Beispiel #34
0
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)