Пример #1
0
def test_varsh_872_4(nuclear: NuclearBogoliubovDrudge):
    """Test simplification based on Varshalovich 8.7.2 Eq (4)."""
    dr = nuclear
    c, gamma, c_prm, gamma_prm = symbols('c gamma cprm gammaprm', integer=True)
    a, alpha, b, beta = symbols('a alpha b beta', integer=True)

    m_range = Range('m')
    sums = [
        (alpha, m_range[-a, a + 1]), (beta, m_range[-b, b + 1])
    ]
    amp = CG(a, alpha, b, beta, c, gamma) * CG(
        a, alpha, b, beta, c_prm, gamma_prm
    )

    # Make sure that the pattern matching works in any way the summations are
    # written.
    for sums_i in [sums, reversed(sums)]:
        tensor = dr.sum(*sums_i, amp)
        res = tensor.simplify_am()
        assert res.n_terms == 1
        term = res.local_terms[0]
        assert len(term.sums) == 0
        assert term.amp == KroneckerDelta(
            c, c_prm
        ) * KroneckerDelta(gamma, gamma_prm)
Пример #2
0
def test_varsh_911_8(nuclear: NuclearBogoliubovDrudge):
    """Test simplification based on the rule in Varshalovich 9.1.1 Eq (8).
    """
    dr = nuclear
    j, m, j12, m12, j2, m2, j1, m1, j_prm, m_prm, j23, m23, j3, m3 = symbols(
        'j m j12 m12 j2 m2 j1 m1 jprm mprm j23 m23 j3 m3', integer=True
    )
    m_range = Range('m')
    sums = [(m_i, m_range[-j_i, j_i + 1]) for m_i, j_i in [
        (m1, j1), (m2, j2), (m3, j3), (m12, j12), (m23, j23)
    ]]
    amp = CG(j12, m12, j3, m3, j, m) * CG(j1, m1, j2, m2, j12, m12) * CG(
        j1, m1, j23, m23, j_prm, m_prm
    ) * CG(j2, m2, j3, m3, j23, m23)

    expected = (
            KroneckerDelta(j, j_prm) * KroneckerDelta(m, m_prm)
            * (-1) ** (j1 + j2 + j3 + j)
            * sqrt(2 * j12 + 1) * sqrt(2 * j23 + 1)
            * Wigner6j(j1, j2, j12, j3, j, j23)
    )

    # For performance reason, just test a random arrangement of the summations.
    random.shuffle(sums)
    tensor = dr.sum(*sums, amp)
    res = tensor.deep_simplify().merge()
    assert res.n_terms == 1
    term = res.local_terms[0]
    assert len(term.sums) == 0
    assert len(term.vecs) == 0
    assert (term.amp - expected).simplify() == 0
Пример #3
0
    def __init__(self, c, hyperparameter):
        """Initialize the Hopfield network.

        Args:
        n: number of cities
        d: distances between cities
        """
        self.n = c.shape[0]
        self.c = c

        # hyperparameter represents how much you weigh the distance term relative to constraint term
        self.hyperparameter = hyperparameter

        # weights between neurons
        self.w = np.zeros((self.n, self.n, self.n, self.n))
        for x in range(self.n):
            for i in range(self.n):
                for y in range(self.n):
                    for j in range(self.n):
                        self.w[x][i][y][j] = -2 * (KroneckerDelta(x, y) + KroneckerDelta(i, j) + self.d[x][y] * KroneckerDelta((i + 1) % self.n, j) * self.hyperparameter)

        # biases to neurons
        self.b = np.zeros((self.n, self.n))
        for x in range(self.n):
            for i in range(self.n):
                self.b[x][i] = 4

        # states of neurons
        self.s = np.random.choice([0, 1], (self.n, self.n))
Пример #4
0
def test_varsh_872_5(nuclear: NuclearBogoliubovDrudge):
    """Test simplification based on the rule in Varshalovich 8.7.2 Eq (5).
    """
    dr = nuclear
    a, alpha, b, beta, b_prm, beta_prm = symbols(
        'a alpha b beta bprm betaprm', integer=True
    )
    c, gamma = symbols('c gamma', integer=True)
    sums = [
        (alpha, Range('m', -a, a + 1)),
        (gamma, Range('M', -c, c + 1))
    ]
    amp = CG(a, alpha, b, beta, c, gamma) * CG(
        a, alpha, b_prm, beta_prm, c, gamma
    )

    expected = (
            KroneckerDelta(b, b_prm) * KroneckerDelta(beta, beta_prm)
            * (2 * c + 1) / (2 * b + 1)
    )
    for sums_i in [sums, reversed(sums)]:
        tensor = dr.sum(*sums_i, amp)
        res = tensor.deep_simplify().merge()
        assert res.n_terms == 1
        term = res.local_terms[0]
        assert len(term.sums) == 0
        assert len(term.vecs) == 0
        assert (term.amp - expected).simplify() == 0
Пример #5
0
    def generators(self,
                   indexed=False) -> list[Union[Matrix, Tuple[Matrix, tuple]]]:
        """Generators for SO(N).

        Args:
            indexed (bool, Optional): For N > 3, there exists a naming scheme for generators. If True returns a tuple
            of the matrix and its (m,n) index.

        Returns:
            list[Union[Matrix, Tuple[Matrix, tuple]]]: list of (mathematical) generators

        Sources:
            - http://www.astro.sunysb.edu/steinkirch/books/group.pdf
        """
        results = []
        for m in range(self.dimension):
            for n in range(m):
                mat = zeros(self.dimension)
                for i in range(self.dimension):
                    for j in range(self.dimension):
                        mat[i, j] = -I * (
                            KroneckerDelta(m, i) * KroneckerDelta(n, j) -
                            KroneckerDelta(m, j) * KroneckerDelta(n, i))
                results.append((mat, (m, n)) if indexed else mat)
        if indexed:
            return sorted(results, key=lambda y: y[1])
        return results
Пример #6
0
def _swap_ug(vec1: Vec, vec2: Vec, depth=None, *,spec: _UGSpec):
    """Swap two vectors based on the commutation rules for Unitary Group generators.
    Here, we introduce an additional input parameter 'depth' which is never
    specified by the user. Rather, it is put to make use os the anti-symmetric 
    nature of the commutation relations and make the function def compact. 
    """
    if depth is None:
        depth = 1
    
    char1, indice1, key1 = _parse_vec_uga(vec1,spec)
    char2, indice2, key2 = _parse_vec_uga(vec2,spec)
    
    p = indice1[0]
    q = indice1[1]
    r = indice2[0]
    s = indice2[1]

    if p != r:
        if p is min(p,r,key=default_sort_key):
            return None
        elif r is min(p,r,key=default_sort_key):
            expr = KroneckerDelta(q,r)*spec.uga[p,s] - KroneckerDelta(p,s)*spec.uga[r,q]
            return _UNITY, expr
        else:
            return None
    elif p == r:
        if q is min(q,s,key=default_sort_key):
            return None
        elif s is min(q,s,key=default_sort_key):
            expr = KroneckerDelta(q,r)*spec.uga[p,s] - KroneckerDelta(p,s)*spec.uga[r,q]
            return _UNITY, expr
        else:
            return None
    else:
        assert False
Пример #7
0
def test_Sum_doit():
    assert Sum(n * Integral(a**2), (n, 0, 2)).doit() == a**3
    assert Sum(n*Integral(a**2), (n, 0, 2)).doit(deep=False) == \
        3*Integral(a**2)
    assert summation(n * Integral(a**2), (n, 0, 2)) == 3 * Integral(a**2)

    # test nested sum evaluation
    s = Sum(Sum(Sum(2, (z, 1, n + 1)), (y, x + 1, n)), (x, 1, n))
    assert 0 == (s.doit() - n * (n + 1) * (n - 1)).factor()

    assert Sum(Sum(KroneckerDelta(m, n), (m, 1, 3)), (n, 1, 3)).doit() == 3
    assert Sum(Sum(KroneckerDelta(k, m), (m, 1, 3)), (n, 1, 3)).doit() == \
        3*Piecewise((1, And(S(1) <= k, k <= 3)), (0, True))
    assert Sum(f(n)*Sum(KroneckerDelta(m, n), (m, 0, oo)), (n, 1, 3)).doit() == \
        f(1) + f(2) + f(3)
    assert Sum(f(n)*Sum(KroneckerDelta(m, n), (m, 0, oo)), (n, 1, oo)).doit() == \
        Sum(Piecewise((f(n), And(Le(0, n), n < oo)), (0, True)), (n, 1, oo))
    l = Symbol('l', integer=True, positive=True)
    assert Sum(f(l)*Sum(KroneckerDelta(m, l), (m, 0, oo)), (l, 1, oo)).doit() == \
        Sum(f(l), (l, 1, oo))

    # issue 2597
    nmax = symbols('N', integer=True, positive=True)
    pw = Piecewise((1, And(S(1) <= n, n <= nmax)), (0, True))
    assert Sum(pw, (n, 1, nmax)).doit() == Sum(pw, (n, 1, nmax))
Пример #8
0
def test_matrixelement_diff():
    dexpr = diff((D*w)[k,0], w[p,0])

    assert w[k, p].diff(w[k, p]) == 1
    assert w[k, p].diff(w[0, 0]) == KroneckerDelta(0, k)*KroneckerDelta(0, p)
    assert str(dexpr) == "Sum(KroneckerDelta(_i_1, p)*D[k, _i_1], (_i_1, 0, n - 1))"
    assert str(dexpr.doit()) == 'Piecewise((D[k, p], (p >= 0) & (p <= n - 1)), (0, True))'
Пример #9
0
def test_complicated_derivative_with_Indexed():
    x, y = symbols("x,y", cls=IndexedBase)
    sigma = symbols("sigma")
    i, j, k = symbols("i,j,k")
    m0, m1, m2, m3, m4, m5 = symbols("m0:6")
    f = Function("f")

    expr = f((x[i] - y[i])**2 / sigma)
    _xi_1 = symbols("xi_1", cls=Dummy)
    assert expr.diff(x[m0]).dummy_eq(
        (x[i] - y[i])*KroneckerDelta(i, m0)*\
        2*Subs(
            Derivative(f(_xi_1), _xi_1),
            (_xi_1,),
            ((x[i] - y[i])**2/sigma,)
        )/sigma
    )
    assert expr.diff(x[m0]).diff(x[m1]).dummy_eq(
        2*KroneckerDelta(i, m0)*\
        KroneckerDelta(i, m1)*Subs(
            Derivative(f(_xi_1), _xi_1),
            (_xi_1,),
            ((x[i] - y[i])**2/sigma,)
         )/sigma + \
        4*(x[i] - y[i])**2*KroneckerDelta(i, m0)*KroneckerDelta(i, m1)*\
        Subs(
            Derivative(f(_xi_1), _xi_1, _xi_1),
            (_xi_1,),
            ((x[i] - y[i])**2/sigma,)
        )/sigma**2
    )
Пример #10
0
def test_matrixelement_diff():
    dexpr = diff((D*w)[k,0], w[p,0])

    assert w[k, p].diff(w[k, p]) == 1
    assert w[k, p].diff(w[0, 0]) == KroneckerDelta(0, k, (0, n-1))*KroneckerDelta(0, p, (0, 0))
    _i_1 = Dummy("_i_1")
    assert dexpr.dummy_eq(Sum(KroneckerDelta(_i_1, p, (0, n-1))*D[k, _i_1], (_i_1, 0, n - 1)))
    assert dexpr.doit() == D[k, p]
Пример #11
0
    def _eval_derivative(self, v):
        if not isinstance(v, MatrixElement):
            return S.Zero

        if self.args[0] != v.args[0]:
            return S.Zero

        from sympy import KroneckerDelta
        return KroneckerDelta(self.args[1], v.args[1])*KroneckerDelta(self.args[2], v.args[2])
Пример #12
0
            def D_Ddag_comm_expr(a, b, c, d):
                del_ac = KroneckerDelta(a, c)
                del_bd = KroneckerDelta(b, d)
                b_ac = beta[a, c]
                b_db = beta[d, b]

                exprn = del_ac*del_bd*(spec.cartan[a]-spec.cartan[b]) + \
                    del_bd*b_ac*( eta[a]*spec.lower[a,c] - eta[c]*spec.raise_[a,c]) +\
                    del_ac*b_db*( eta[d]*spec.lower[b,d] - eta[b]*spec.raise_[b,d])
                exprn = eta[a] * eta[c] * exprn
                return exprn
Пример #13
0
def test_matrixelement_diff():
    dexpr = diff((D*w)[k,0], w[p,0])

    assert w[k, p].diff(w[k, p]) == 1
    assert w[k, p].diff(w[0, 0]) == KroneckerDelta(0, k)*KroneckerDelta(0, p)
    assert str(dexpr) == "Sum(KroneckerDelta(_i_1, p)*D[k, _i_1], (_i_1, 0, n - 1))"
    assert str(dexpr.doit()) == 'Piecewise((D[k, p], (p >= 0) & (p <= n - 1)), (0, True))'
    # TODO: bug with .dummy_eq( ), the previous 2 lines should be replaced by:
    return  # stop eval
    _i_1 = Dummy("_i_1")
    assert dexpr.dummy_eq(Sum(KroneckerDelta(_i_1, p)*D[k, _i_1], (_i_1, 0, n - 1)))
    assert dexpr.doit().dummy_eq(Piecewise((D[k, p], (p >= 0) & (p <= n - 1)), (0, True)))
Пример #14
0
def test_DiagonalMatrix():
    x = MatrixSymbol('x', n, m)
    D = DiagonalMatrix(x)
    assert D.diagonal_length is None
    assert D.shape == (n, m)

    x = MatrixSymbol('x', n, n)
    D = DiagonalMatrix(x)
    assert D.diagonal_length == n
    assert D.shape == (n, n)
    assert D[1, 2] == 0
    assert D[1, 1] == x[1, 1]
    i = Symbol('i')
    j = Symbol('j')
    x = MatrixSymbol('x', 3, 3)
    ij = DiagonalMatrix(x)[i, j]
    assert ij != 0
    assert ij.subs({i:0, j:0}) == x[0, 0]
    assert ij.subs({i:0, j:1}) == 0
    assert ij.subs({i:1, j:1}) == x[1, 1]
    assert ask(Q.diagonal(D))  # affirm that D is diagonal

    x = MatrixSymbol('x', n, 3)
    D = DiagonalMatrix(x)
    assert D.diagonal_length == 3
    assert D.shape == (n, 3)
    assert D[2, m] == KroneckerDelta(2, m)*x[2, m]
    assert D[3, m] == 0
    raises(IndexError, lambda: D[m, 3])

    x = MatrixSymbol('x', 3, n)
    D = DiagonalMatrix(x)
    assert D.diagonal_length == 3
    assert D.shape == (3, n)
    assert D[m, 2] == KroneckerDelta(m, 2)*x[m, 2]
    assert D[m, 3] == 0
    raises(IndexError, lambda: D[3, m])

    x = MatrixSymbol('x', n, m)
    D = DiagonalMatrix(x)
    assert D.diagonal_length is None
    assert D.shape == (n, m)
    assert D[m, 4] != 0

    x = MatrixSymbol('x', 3, 4)
    assert [DiagonalMatrix(x)[i] for i in range(12)] == [
        x[0, 0], 0, 0, 0, 0, x[1, 1], 0, 0, 0, 0, x[2, 2], 0]

    # shape is retained, issue 12427
    assert (
        DiagonalMatrix(MatrixSymbol('x', 3, 4))*
        DiagonalMatrix(MatrixSymbol('x', 4, 2))).shape == (3, 2)
Пример #15
0
def test_DiagonalizeVector():
    x = MatrixSymbol('x', n, 1)
    d = DiagonalizeVector(x)
    assert d.shape == (n, n)
    assert d[0, 1] == 0
    assert d[0, 0] == x[0, 0]

    a = MatrixSymbol('a', 1, 1)
    d = diagonalize_vector(a)
    assert isinstance(d, MatrixSymbol)
    assert a == d
    assert diagonalize_vector(Identity(3)) == Identity(3)
    assert DiagonalizeVector(Identity(3)).doit() == Identity(3)
    assert isinstance(DiagonalizeVector(Identity(3)), DiagonalizeVector)

    # A diagonal matrix is equal to its transpose:
    assert DiagonalizeVector(x).T == DiagonalizeVector(x)
    assert diagonalize_vector(x.T) == DiagonalizeVector(x)

    dx = DiagonalizeVector(x)
    assert dx[0, 0] == x[0, 0]
    assert dx[1, 1] == x[1, 0]
    assert dx[0, 1] == 0
    assert dx[0, m] == x[0, 0] * KroneckerDelta(0, m)

    z = MatrixSymbol('z', 1, n)
    dz = DiagonalizeVector(z)
    assert dz[0, 0] == z[0, 0]
    assert dz[1, 1] == z[0, 1]
    assert dz[0, 1] == 0
    assert dz[0, m] == z[0, m] * KroneckerDelta(0, m)

    v = MatrixSymbol('v', 3, 1)
    dv = DiagonalizeVector(v)
    assert dv.as_explicit() == Matrix([
        [v[0, 0], 0, 0],
        [0, v[1, 0], 0],
        [0, 0, v[2, 0]],
    ])

    v = MatrixSymbol('v', 1, 3)
    dv = DiagonalizeVector(v)
    assert dv.as_explicit() == Matrix([
        [v[0, 0], 0, 0],
        [0, v[0, 1], 0],
        [0, 0, v[0, 2]],
    ])

    dv = DiagonalizeVector(3 * v)
    assert dv.args == (3 * v, )
    assert dv.doit() == 3 * DiagonalizeVector(v)
    assert isinstance(dv.doit(), MatMul)
Пример #16
0
    def _eval_derivative(self, v):
        if not isinstance(v, MatrixElement):
            from sympy import MatrixBase
            if isinstance(self.parent, MatrixBase):
                return self.parent.diff(v)[self.i, self.j]
            return S.Zero

        if self.args[0] != v.args[0]:
            return S.Zero

        from sympy import KroneckerDelta
        return KroneckerDelta(self.args[1], v.args[1]) * KroneckerDelta(
            self.args[2], v.args[2])
Пример #17
0
def test_up_down_enum_symbs():
    """Test the desired mathematical properties of enumeration symbols."""

    for i in [UP, DOWN]:
        assert KroneckerDelta(i, i) == 1

    assert KroneckerDelta(UP, DOWN) == 0
    assert KroneckerDelta(DOWN, UP) == 0

    sigma = symbols('sigma')
    for i in [UP, DOWN]:
        assert KroneckerDelta(i, sigma) != 0
        assert KroneckerDelta(sigma, i) != 0
Пример #18
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) == (ArrayContraction(
        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) == (ArrayDiagonal(
        ArrayAdd(
            ArrayTensorProduct(M, N),
            PermuteDims(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) == (ArrayDiagonal(
        ArrayAdd(
            ArrayTensorProduct(M, N),
            PermuteDims(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, ))
Пример #19
0
def func(x, y, z1, z2, mr, m, z3, z4, mr1, m1):
    return KroneckerDelta(x, 1) * (
        (complex(z1, z2)) / (y + (complex(mr, m))**2) + (complex(z1, -z2)) /
        (y + (complex(mr, -m))**2) + (complex(z3, z4)) /
        (y + (complex(mr1, m1))**2) + (complex(z3, -z4)) /
        (y + (complex(mr1, -m1))**2)) + KroneckerDelta(x, 2) * (
            ((complex(z1, z2)) * (complex(mr, m))) / (y +
                                                      (complex(mr, m))**2) +
            ((complex(z1, -z2)) * (complex(mr, -m))) / (y +
                                                        (complex(mr, -m))**2) +
            ((complex(z3, z4)) *
             (complex(mr1, m1))) / (y + (complex(mr1, m1))**2) +
            ((complex(z3, -z4)) *
             (complex(mr1, -m1))) / (y + (complex(mr1, -m1))**2))
Пример #20
0
def _contr_ancr_by_delta(label1, indices1, label2, indices2):
    """Contract an annihilation and a creation operator by delta."""

    # For the delta contraction, some additional checking is needed for it to
    # make sense.

    err_header = 'Invalid field operators to contract by delta'

    # When the operators are on different base, it is likely that delta is not
    # what is intended.

    if label1 != label2:
        raise ValueError(err_header, (label1, label2),
                         'expecting the same base')

    if len(indices1) != len(indices2):
        raise ValueError(err_header, (indices1, indices2),
                         'expecting same number of indices')

    res = 1
    for i, j in zip(indices1, indices2):
        # TODO: Maybe support continuous indices here.
        res *= KroneckerDelta(i, j)
        continue

    return res
Пример #21
0
def Rot_AngAx(n, theta):
    """
    Rotation matrix
    Rodrigues formula
    angle-axis parametrization
    INPUT: n - vector [nx,ny,nz]
           0 <= theta <= pi
    OUTPUT: Rot - matrix(3x3)
    nx,ny,nz = symbols('nx,ny,nz')
    n = [nx,ny,nz]
    """

    dimens = 3
    """
    R = sp.MatrixSymbol('R', dimens, dimens)
    """
    i, j = sp.symbols('i,j')
    R = sp.FunctionMatrix(dimens, dimens,
                          sp.Lambda((i, j),
                                    cos(theta) * KroneckerDelta(i, j)))
    for k in range(dimens):
        R -= sp.FunctionMatrix(
            dimens, dimens, sp.Lambda((i, j),
                                      sin(theta) * Eijk(i, j, k) * n[k]))

    Rot = sp.Matrix(R)

    R2 = sp.zeros(dimens)
    for i in range(dimens):
        R2.row_op(i, lambda v, j: (1 - cos(theta)) * n[i] * n[j])
    Rot += R2
    Rot = sp.N(Rot, 4)
    #Rot = sp.matrix2numpy(Rot)
    return Rot
Пример #22
0
def _swap_lattice_gens(vec1: Vec, vec2: Vec, bcast_swap_info):
    """Swap the generators with lattice indices."""
    swap_info: _SwapInfo = bcast_swap_info.value
    base_ranks = swap_info.base_ranks
    comms = swap_info.comms
    assume_comm = swap_info.assume_comm
    vecs = (vec1, vec2)

    indices1, indices2 = [i.indices for i in vecs]
    if len(indices1) != len(indices2):
        raise ValueError('Unmatching lattice indices for', vec1, vec2)

    base1, base2 = [vec.base for vec in vecs]
    try:
        rank1 = base_ranks[base1]
        rank2 = base_ranks[base2]
    except KeyError as exc:
        raise ValueError('Vector with unspecified normal order', exc.args)

    if rank1 < rank2:
        return None
    elif rank1 == rank2:
        # Same generator at possibly different sites always commute.
        key1, key2 = [
            tuple(sympy_key(j) for j in i) for i in (indices1, indices2)
        ]
        if key1 <= key2:
            return None
        else:
            return _UNITY, _NOUGHT
    else:
        given = (base1, base2)
        rev = (base2, base1)

        if given in comms:
            comm, phase = _get_comm_phase(comms, given, indices1)
            comm_factor = _UNITY
        elif rev in comms:
            # a b = phi b a + kappa => phi b a = a b - kappa
            # => b a = (a b - kappa) / phi
            comm, phase = _get_comm_phase(comms, rev, indices1)
            comm_factor = -1 / phase
            phase = 1 / phase
        elif assume_comm:
            comm = _NOUGHT
            phase = _UNITY
            comm_factor = _UNITY
        else:
            raise ValueError('Commutation rules unspecified', vec1, vec2)

        delta = functools.reduce(operator.mul,
                                 (KroneckerDelta(i, j)
                                  for i, j in zip(indices1, indices2)), _UNITY)

        terms = Terms(
            Term(
                term.sums, delta * comm_factor * term.amp,
                tuple(i[indices1] if len(i.indices) == 0 else i
                      for i in term.vecs)) for term in comm)
        return phase, terms
Пример #23
0
def _get_fermi_partitions(term: Term, spec: _AGPFSpec):
    """Given a term with a list of fermionic vectors, extract the various
    partitions of N, Pdag and P kind of terms.

    Assumes: All possible simplification and Pairing / SU2 extraction
    has been performed, i.e. all the indices are distinct.
    """

    vecs = term.vecs
    amp = term.amp
    fermi_indcs = []

    cr = spec.c_dag.base
    an = spec.c_.base

    # First extract all the indices of fermion operators
    for v in vecs:
        if v.base in (cr, an):
            fermi_indcs.append(v.indices[1])

    if len(fermi_indcs) == 0:
        # if there are no fermion operators, return the term as it is
        return [Term(sums=term.sums, amp=amp, vecs=vecs)]
    else:
        # if there are fermion operators, then get all the possible
        # partitions of indices
        deltas_partns = list(_generate_partitions(fermi_indcs))

    # get a list of even partitions, i.e. throw away partitions involving
    # odd number of indices
    evens = [
        all(
            len(deltas_partns[i][j]) % 2 == 0
            for j in range(len(deltas_partns[i])))
        for i in range(len(deltas_partns))
    ]

    # Now iterate through the list of partitions and form the deltas expression
    # for the amplitude
    delta_amp = Integer(0)

    for i in range(len(deltas_partns)):
        # if statement for even partitions
        if evens[i]:
            pt = deltas_partns[i]
        else:
            continue

        # Form the delta expressions
        delta_intmd = Integer(1)
        for i in range(len(pt)):
            delta_intmd *= _construct_deltas(pt[i])
            if i > 0:
                delta_intmd *= (1 - KroneckerDelta(pt[i][0], pt[i - 1][0]))
        delta_amp += delta_intmd

    new_amp = amp * delta_amp

    return [Term(sums=term.sums, amp=new_amp, vecs=vecs)]
Пример #24
0
def _construct_deltas(indices):
    """Given a list of indices, form all possible KroneckerDelta pairs
    """
    del_pairs = Integer(1)
    for i in range(len(indices) - 1):
        del_pairs *= KroneckerDelta(indices[i], indices[i + 1])

    return del_pairs
Пример #25
0
 def compute_density(self, expr, **kwargs):
     z = Dummy('z', real=True, finite=True)
     rvs = random_symbols(expr)
     if any(pspace(rv).is_Continuous for rv in rvs):
         expr = self.integrate(DiracDelta(expr - z), **kwargs)
     else:
         expr = self.integrate(KroneckerDelta(expr, z), **kwargs)
     return Lambda(z, expr)
Пример #26
0
def test_wigner3j_sum_to_wigner6j(nuclear: NuclearBogoliubovDrudge):
    """Test simplification of sum of product of four 3j's to a 6j.

    This test tries to simplify the original LHS of the equation from the
    Wolfram website.
    """

    dr = nuclear
    j1, j2, j3, jprm3, j4, j5, j6 = symbols(
        'j1 j2 j3 jprm3 j4 j5 j6', integer=True
    )
    m1, m2, m3, mprm3, m4, m5, m6 = symbols(
        'm1 m2 m3 mprm3 m4 m5 m6', integer=True
    )

    m_range = Range('m')
    sums = [(m_i, m_range[-j_i, j_i + 1]) for m_i, j_i in [
        (m1, j1), (m2, j2), (m4, j4), (m5, j5), (m6, j6)
    ]]

    phase = (-1) ** (
            j1 + j2 + j4 + j5 + j6 - m1 - m2 - m4 - m5 - m6
    )
    amp = (
            Wigner3j(j2, m2, j3, -m3, j1, m1)
            * Wigner3j(j1, -m1, j5, m5, j6, m6)
            * Wigner3j(j5, -m5, jprm3, mprm3, j4, m4)
            * Wigner3j(j4, -m4, j2, -m2, j6, -m6)
    )

    expected = (
            ((-1) ** (j3 - m3) / (2 * j3 + 1))
            * KroneckerDelta(j3, jprm3) * KroneckerDelta(m3, mprm3)
            * Wigner6j(j1, j2, j3, j4, j5, j6)
    ).expand().simplify()

    # For performance reason, just test a random arrangement of the summations.
    random.shuffle(sums)
    tensor = dr.sum(*sums, phase * amp)
    res = tensor.deep_simplify().merge()
    assert res.n_terms == 1
    term = res.local_terms[0]
    assert len(term.sums) == 0
    assert len(term.vecs) == 0
    assert (term.amp - expected).simplify() == 0
Пример #27
0
def test_simplify_delta_of_two_ranges(free_alg):
    """Test simplification of delta of two disjoint ranges."""

    dr = free_alg
    p = dr.names
    tensor = dr.sum(KroneckerDelta(p.i, p.alpha) * p.v)
    assert tensor.n_terms == 1
    assert tensor.simplify_deltas() == 0
    assert tensor.simplify() == 0
Пример #28
0
 def compute_density(self, expr, **kwargs):
     rvs = random_symbols(expr)
     if any(pspace(rv).is_Continuous for rv in rvs):
         z = Dummy('z', real=True)
         expr = self.compute_expectation(DiracDelta(expr - z), **kwargs)
     else:
         z = Dummy('z', integer=True)
         expr = self.compute_expectation(KroneckerDelta(expr, z), **kwargs)
     return Lambda(z, expr)
Пример #29
0
def test_simplify_delta_of_unsolvable_functions(free_alg):
    """Test simplification of delta of with functions unable to solve."""

    dr = free_alg
    p = dr.names
    f = Function('f')
    tensor = dr.sum((p.i, p.R), KroneckerDelta(f(p.i), p.alpha) * p.v)
    assert tensor.n_terms == 1
    assert tensor.simplify_deltas() == tensor
    assert tensor.simplify() == tensor
Пример #30
0
def test_tensor_can_be_simplified_amp(free_alg):
    """Test the amplitude simplification for tensors.

    More than trivial tensor amplitude simplification is tested here.  Currently
    it mostly concentrates on the dispatching to SymPy and delta simplification.
    The master simplification is also tested.
    """

    dr = free_alg
    p = dr.names
    r = p.R
    s = p.S
    v = p.v
    i, j = p.R_dumms[:2]
    alpha = p.alpha

    x = IndexedBase('x')
    y = IndexedBase('y')
    theta = sympify('theta')

    tensor = (dr.sum(
        (i, r),
        sin(theta)**2 * x[i] * v[i]) + dr.sum(
            (i, r), (j, r),
            cos(theta)**2 * x[j] * KroneckerDelta(i, j) * v[i]) + dr.sum(
                (i, r), (alpha, s),
                KroneckerDelta(i, alpha) * y[i] * v[i]))
    assert tensor.n_terms == 3

    first = tensor.simplify_deltas().simplify_amps()
    # Now we should have one term killed.
    assert first.n_terms == 2

    # Merge again should really simplify.
    merged = first.reset_dumms().merge().simplify_amps()
    assert merged.n_terms == 1
    expected = dr.sum((i, r), x[i] * v[i])
    assert merged == expected

    # The master simplification should do it in one turn.
    simpl = tensor.simplify()
    assert simpl == expected