Esempio n. 1
0
def test_matrix_expression_from_index_summation():
    from sympy.abc import a, b, c, d
    A = MatrixSymbol("A", k, k)
    B = MatrixSymbol("B", k, k)
    C = MatrixSymbol("C", k, k)

    expr = Sum(W[a, b] * X[b, c] * Z[c, d], (b, 0, l - 1), (c, 0, m - 1))
    assert MatrixExpr.from_index_summation(expr, a) == W * X * Z
    expr = Sum(W.T[b, a] * X[b, c] * Z[c, d], (b, 0, l - 1), (c, 0, m - 1))
    assert MatrixExpr.from_index_summation(expr, a) == W * X * Z
    expr = Sum(A[b, a] * B[b, c] * C[c, d], (b, 0, k - 1), (c, 0, k - 1))
    assert MatrixSymbol.from_index_summation(expr, a) == A.T * B * C
    expr = Sum(A[b, a] * B[c, b] * C[c, d], (b, 0, k - 1), (c, 0, k - 1))
    assert MatrixSymbol.from_index_summation(expr, a) == A.T * B.T * C
    expr = Sum(C[c, d] * A[b, a] * B[c, b], (b, 0, k - 1), (c, 0, k - 1))
    assert MatrixSymbol.from_index_summation(expr, a) == A.T * B.T * C
    expr = Sum(A[a, b] + B[a, b], (a, 0, k - 1), (b, 0, k - 1))
    assert MatrixExpr.from_index_summation(expr, a) == A + B
    expr = Sum((A[a, b] + B[a, b]) * C[b, c], (b, 0, k - 1))
    assert MatrixExpr.from_index_summation(expr, a) == (A + B) * C
    expr = Sum((A[a, b] + B[b, a]) * C[b, c], (b, 0, k - 1))
    assert MatrixExpr.from_index_summation(expr, a) == (A + B.T) * C
    expr = Sum(A[a, b] * A[b, c] * A[c, d], (b, 0, k - 1), (c, 0, k - 1))
    assert MatrixExpr.from_index_summation(expr, a) == MatMul(A, A, A)
    expr = Sum(A[a, b] * A[b, c] * B[c, d], (b, 0, k - 1), (c, 0, k - 1))
    assert MatrixExpr.from_index_summation(expr, a) == MatMul(A, A, B)

    # Parse the trace of a matrix:

    expr = Sum(A[a, a], (a, 0, k - 1))
    assert MatrixExpr.from_index_summation(expr, None) == trace(A)
    expr = Sum(A[a, a] * B[b, c] * C[c, d], (a, 0, k - 1), (c, 0, k - 1))
    assert MatrixExpr.from_index_summation(expr, b) == trace(A) * B * C

    # Check wrong sum ranges (should raise an exception):

    ## Case 1: 0 to m instead of 0 to m-1
    expr = Sum(W[a, b] * X[b, c] * Z[c, d], (b, 0, l - 1), (c, 0, m))
    raises(ValueError, lambda: MatrixExpr.from_index_summation(expr, a))
    ## Case 2: 1 to m-1 instead of 0 to m-1
    expr = Sum(W[a, b] * X[b, c] * Z[c, d], (b, 0, l - 1), (c, 1, m - 1))
    raises(ValueError, lambda: MatrixExpr.from_index_summation(expr, a))

    # Parse nested sums:
    expr = Sum(A[a, b] * Sum(B[b, c] * C[c, d], (c, 0, k - 1)), (b, 0, k - 1))
    assert MatrixExpr.from_index_summation(expr, a) == A * B * C

    # Test Kronecker delta:
    expr = Sum(A[a, b] * KroneckerDelta(b, c) * B[c, d], (b, 0, k - 1),
               (c, 0, k - 1))
    assert MatrixExpr.from_index_summation(expr, a) == A * B
Esempio n. 2
0
def test_matrix_expression_from_index_summation():
    from sympy.abc import a,b,c,d
    A = MatrixSymbol("A", k, k)
    B = MatrixSymbol("B", k, k)
    C = MatrixSymbol("C", k, k)

    expr = Sum(W[a,b]*X[b,c]*Z[c,d], (b, 0, l-1), (c, 0, m-1))
    assert MatrixExpr.from_index_summation(expr, a) == W*X*Z
    expr = Sum(W.T[b,a]*X[b,c]*Z[c,d], (b, 0, l-1), (c, 0, m-1))
    assert MatrixExpr.from_index_summation(expr, a) == W*X*Z
    expr = Sum(A[b, a]*B[b, c]*C[c, d], (b, 0, k-1), (c, 0, k-1))
    assert MatrixSymbol.from_index_summation(expr, a) == A.T*B*C
    expr = Sum(A[b, a]*B[c, b]*C[c, d], (b, 0, k-1), (c, 0, k-1))
    assert MatrixSymbol.from_index_summation(expr, a) == A.T*B.T*C
    expr = Sum(C[c, d]*A[b, a]*B[c, b], (b, 0, k-1), (c, 0, k-1))
    assert MatrixSymbol.from_index_summation(expr, a) == A.T*B.T*C
    expr = Sum(A[a, b] + B[a, b], (a, 0, k-1), (b, 0, k-1))
    assert MatrixExpr.from_index_summation(expr, a) == A + B
    expr = Sum((A[a, b] + B[a, b])*C[b, c], (b, 0, k-1))
    assert MatrixExpr.from_index_summation(expr, a) == (A+B)*C
    expr = Sum((A[a, b] + B[b, a])*C[b, c], (b, 0, k-1))
    assert MatrixExpr.from_index_summation(expr, a) == (A+B.T)*C
    expr = Sum(A[a, b]*A[b, c]*A[c, d], (b, 0, k-1), (c, 0, k-1))
    assert MatrixExpr.from_index_summation(expr, a) == MatMul(A, A, A)
    expr = Sum(A[a, b]*A[b, c]*B[c, d], (b, 0, k-1), (c, 0, k-1))
    assert MatrixExpr.from_index_summation(expr, a) == MatMul(A, A, B)

    # Parse the trace of a matrix:

    expr = Sum(A[a, a], (a, 0, k-1))
    assert MatrixExpr.from_index_summation(expr, None) == trace(A)
    expr = Sum(A[a, a]*B[b, c]*C[c, d], (a, 0, k-1), (c, 0, k-1))
    assert MatrixExpr.from_index_summation(expr, b) == trace(A)*B*C

    # Check wrong sum ranges (should raise an exception):

    ## Case 1: 0 to m instead of 0 to m-1
    expr = Sum(W[a,b]*X[b,c]*Z[c,d], (b, 0, l-1), (c, 0, m))
    raises(ValueError, lambda: MatrixExpr.from_index_summation(expr, a))
    ## Case 2: 1 to m-1 instead of 0 to m-1
    expr = Sum(W[a,b]*X[b,c]*Z[c,d], (b, 0, l-1), (c, 1, m-1))
    raises(ValueError, lambda: MatrixExpr.from_index_summation(expr, a))

    # Parse nested sums:
    expr = Sum(A[a, b]*Sum(B[b, c]*C[c, d], (c, 0, k-1)), (b, 0, k-1))
    assert MatrixExpr.from_index_summation(expr, a) == A*B*C

    # Test Kronecker delta:
    expr = Sum(A[a, b]*KroneckerDelta(b, c)*B[c, d], (b, 0, k-1), (c, 0, k-1))
    assert MatrixExpr.from_index_summation(expr, a) == A*B
Esempio n. 3
0
    def _calculate_structure_constants(self):
        """Calculates the structure constants"""

        # For improved performance use explicit Symengine backend
        gens = [_CMatrix(x) for x in self.generators()]
        n = len(gens)

        f = MutableDenseNDimArray.zeros(n, n, n) * sympify("0")
        d = MutableDenseNDimArray.zeros(n, n, n) * sympify("0")

        for i in range(n):
            for j in range(n):
                for k in range(n):
                    f[i, j, k] = -2 * I * \
                        trace(commutator(gens[i], gens[j]) * gens[k])
                    d[i, j, k] = 2 * \
                        trace(commutator(
                            gens[i], gens[j], anti=True) * gens[k])
        return (f, d)
Esempio n. 4
0
def get_pauli_coefficient(matrix, coefficient):
    """Extract given Pauli coefficient from matrix.

    The coefficient must be specified in the form of a tuple whose i-th
    element tells the Pauli operator acting on the i-th qubit.
    For example, `coefficient = (2, 1)` asks for the Y1 X2 coefficient.
    Generally speaking, it should be a valid input to `pauli_product`.

    The function works with sympy objects.
    """
    num_qubits = len(coefficient)
    return sympy.trace(matrix * pauli_product(*coefficient)) / 2**num_qubits
Esempio n. 5
0
def param_analysis(N, subplot, alpha=_alpha, k1=_k1, k_1=_k_1, k2=_k2, k_2=_k_2, k3=_k3):
    xstep = np.linspace(0, 1, N)
    x, y, k2 = sp.symbols('x y k2')
    #матрица Якоби
    f1 = k1 * (1 - x - y) - k_1 * x - k3 * (1 - x)**alpha * x * y
    f2 = k2 * (1 - x - y) ** 2 - k_2 * y**2 - k3 * (1 - x)**alpha * x * y

    # след и определитель Якобиана
    A = sp.Matrix([f1, f2])
    jacA = A.jacobian([x, y])
    det_jacA = jacA.det()
    trace = sp.trace(jacA)

    Y = sp.solve(f1, y)[0]
    print(Y)
    # Y = (k1 - k1 * x - k_1 * x) / (k1 + k3 * (1 - x)**2 * x)
    # K2 = (k_2 * Y**2 + k3 * (1-x)**alpha*x*Y) / (1-x-Y)**2
    K2 = sp.solve(f2, k2)[0]
    K2 = K2.subs(y, Y)
    ystep=[]
    k2step=[]
    realxstep = []
    dots = []
    for i in xstep:
        tmpy = Y.subs(x, i)
        if(tmpy >= 0 and tmpy <= 1 and tmpy + i >= 0 and tmpy + i <= 1):
            if K2.subs(x, i) != sp.zoo:
                k2step.append(K2.subs(x, i))
                ystep.append(tmpy)
                realxstep.append(i)
            if i > 0:
                det = det_jacA.subs(y, Y)
                prev = det.subs([(x, realxstep[len(realxstep) - 2]), (y, ystep[len(realxstep) - 2]), (k2, k2step[len(realxstep) - 2])])
                curr = det.subs([(x, realxstep[len(realxstep) - 1]), (y, ystep[len(realxstep) - 1]), (k2, k2step[len(realxstep) - 1])])
                if prev * curr < 0:
                    dots.extend(dot_correct(det, len(realxstep) - 2, realxstep, ystep, k2step, K2, Y))

            if i > 0:
                det = det_jacA.subs(y, Y)
                prev = trace.subs([(x, realxstep[len(realxstep) - 2]), (y, ystep[len(realxstep) - 2]), (k2, k2step[len(realxstep) - 2])])
                curr = trace.subs([(x, realxstep[len(realxstep) - 1]), (y, ystep[len(realxstep) - 1]), (k2, k2step[len(realxstep) - 1])])
                if prev * curr < 0:
                    dots.extend(dot_correct(trace, len(realxstep) - 2, realxstep, ystep, k2step, K2, Y))
        else:
            break
    # dots = dot_correct(det, dots, realxstep, ystep, k2step, K2)
    print(dots)
    # param_plot(realxstep, ystep, k2step, subplot, dots)
    param_plot(realxstep, k2step, subplot, 'r', 0, 0, "$x_{k_2}$")
    param_plot(ystep, k2step, subplot, 'g', 0, 0, "$y_{k_2}$")
    dot_plot(subplot, dots)
Esempio n. 6
0
 def find_scalar_curvature(self):
     """
     Method performs scalar contraction on the Ricci tensor.
     """
     try:
         Ricci = self.Ricci
     except AttributeError:
         print "Ricci tensor must be determined first."
         return None
     g = self.g
     g_inv = self.g.inv()
     scalar_curv = sympy.simplify(g_inv*Ricci)
     scalar_curv = sympy.trace(scalar_curv)
     self.scalar_curv = scalar_curv
     return self.scalar_curv
Esempio n. 7
0
 def find_scalar_curvature(self):
     """
     Method performs scalar contraction on the Ricci tensor.
     """
     try:
         Ricci = self.Ricci
     except AttributeError:
         print "Ricci tensor must be determined first."
         return None
     g = self.g
     g_inv = self.g.inv()
     scalar_curv = sympy.simplify(g_inv * Ricci)
     scalar_curv = sympy.trace(scalar_curv)
     self.scalar_curv = scalar_curv
     return self.scalar_curv
Esempio n. 8
0
def _trace_single_line(t):
    """
    Evaluate the trace of a single gamma matrix line inside a ``TensExpr``.

    Notes
    =====

    If there are ``DiracSpinorIndex.auto_left`` and ``DiracSpinorIndex.auto_right``
    indices trace over them; otherwise traces are not implied (explain)


    Examples
    ========

    >>> from sympy.physics.hep.gamma_matrices import GammaMatrix as G, \
        LorentzIndex, _trace_single_line
    >>> from sympy.tensor.tensor import tensor_indices, tensorhead
    >>> p = tensorhead('p', [LorentzIndex], [[1]])
    >>> i0,i1,i2,i3,i4,i5 = tensor_indices('i0:6', LorentzIndex)
    >>> _trace_single_line(G(i0)*G(i1))
    4*metric(i0, i1)
    >>> _trace_single_line(G(i0)*p(-i0)*G(i1)*p(-i1)) - 4*p(i0)*p(-i0)
    0

    """
    def _trace_single_line1(t):
        t = t.sorted_components()
        components = t.components
        ncomps = len(components)
        g = LorentzIndex.metric
        # gamma matirices are in a[i:j]
        hit = 0
        for i in range(ncomps):
            if components[i] == GammaMatrix:
                hit = 1
                break

        for j in range(i + hit, ncomps):
            if components[j] != GammaMatrix:
                break
        else:
            j = ncomps
        numG = j - i
        if numG == 0:
            tcoeff = t.coeff
            return t.nocoeff if tcoeff else t
        if numG % 2 == 1:
            return TensMul.from_data(S.Zero, [], [], [])
        elif numG > 4:
            # find the open matrix indices and connect them:
            a = t.split()
            ind1 = a[i].get_indices()[0]
            ind2 = a[i + 1].get_indices()[0]
            aa = a[:i] + a[i + 2:]
            t1 = tensor_mul(*aa)*g(ind1, ind2)
            t1 = t1.contract_metric(g)
            args = [t1]
            sign = 1
            for k in range(i + 2, j):
                sign = -sign
                ind2 = a[k].get_indices()[0]
                aa = a[:i] + a[i + 1:k] + a[k + 1:]
                t2 = sign*tensor_mul(*aa)*g(ind1, ind2)
                t2 = t2.contract_metric(g)
                t2 = simplify_gpgp(t2, False)
                args.append(t2)
            t3 = TensAdd(*args)
            t3 = _trace_single_line(t3)
            return t3
        else:
            a = t.split()
            t1 = _gamma_trace1(*a[i:j])
            a2 = a[:i] + a[j:]
            t2 = tensor_mul(*a2)
            t3 = t1*t2
            if not t3:
                return t3
            t3 = t3.contract_metric(g)
            return t3

    t = t.expand()
    if isinstance(t, TensAdd):
        a = [_trace_single_line1(x)*x.coeff for x in t.args]
        return TensAdd(*a)
    elif isinstance(t, (Tensor, TensMul)):
        r = t.coeff*_trace_single_line1(t)
        return r
    else:
        return trace(t)
Esempio n. 9
0
    return out


# formulate the PDE
x = sp.symbols("x0:2")
n = sp.symbols("n0:2")
u = (sp.Function("u0")(*x), sp.Function("u1")(*x))
# L = sp.Function('lambda')(*x)
# M = sp.Function('mu')(*x)
L = sp.symbols("lambda")
M = sp.symbols("mu")
dim = 2
F = [[u[i].diff(x[j]) for i in range(dim)] for j in range(dim)]
F = sp.Matrix(F)
strain = sp.Rational(1, 2) * (F + F.T)
stress = L * sp.eye(dim) * sp.trace(strain) + 2 * M * strain
PDEs = [sum(stress[i, j].diff(x[j]) for j in range(dim)) for i in range(dim)]
FreeBCs = [sum(stress[i, j] * n[j] for j in range(dim)) for i in range(dim)]
FixBCs = [u[i] for i in range(dim)]

# norms is an array which is later defined
sym2num = {
    L: 1.0,
    M: 1.0,
    sp.Integer(1): 1.0,
    sp.Integer(2): 2.0,
    L.diff(x[0]): 0.0,
    L.diff(x[1]): 0.0,
    M.diff(x[0]): 0.0,
    M.diff(x[1]): 0.0,
    n[0]: lambda i: norms[i, 0],
Esempio n. 10
0
def duoparam_analysis(N, subplot, alpha=_alpha, k1=_k1, k_1=_k_1, k2=_k2, k_2=_k_2, k3=_k3):
    xstep = np.linspace(0, 1, N)
    x, y, k2, k1 = sp.symbols('x y k2 k1')
    f1 = k1 * (1 - x - y) - k_1 * x - k3 * (1 - x)**alpha * x * y
    f2 = k2 * (1 - x - y) ** 2 - k_2 * y**2 - k3 * (1 - x)**alpha * x * y

    eq1 = sp.lambdify((x, y, k1), f1)
    eq2 = sp.lambdify((x, y, k2), f2)
    Y, X = np.mgrid[0:.5:1000j, 0:1:2000j]

    U = eq1(X, Y, 0.012)
    V = eq2(X, Y, 0.012)
    print("HERE")
    velocity = np.sqrt(U * U + V * V)
    plt.streamplot(X, Y, U, V, density=[2.5, 0.8], color=velocity)
    plt.xlabel('x')
    plt.ylabel('y')
    # plt.xlim([0.1, 0.5])
    # plt.ylim([0.1, 0.5])
    # plt.title('Phase portrait')
    plt.show()

    #след и определитель Якобиана
    A = sp.Matrix([f1, f2])
    jacA = A.jacobian([x, y])
    det_jacA = jacA.det()
    trace = sp.trace(jacA)

    Y = sp.solve(f1, y)[0]
    Det = sp.solve(det_jacA.subs(y, Y), k2)[0]
    Trace = sp.solve(trace.subs(y, Y), k2)[0]
    K2 = sp.solve(f2.subs(y, Y), k2)[0]
    res = Det - K2
    tr = sp.solve(Trace - K2, k1)[0]
    print("3.5: ", res)
    print("tr", tr)
    # print("3.5: ", sp.expand(Det - K2))
    # K1 = sp.solve((Det - K2), k1)[0]
    # print("4 ", K1)

    k1step_det = []
    k2step_det = []
    k1step_tr = []
    k2step_tr = []

    dots = []
    for i in xstep:
        sol1 = sp.solve(res.subs(x, i), k1)
        # print("sol", sol1)
        if len(sol1) > 0:
            tmpk1_det = sol1[0]
            tmpk2_det = Det.subs([(k1, tmpk1_det), (x, i)])
            # print("tmpk1", tmpk1_det)
            # print("tmpk2", tmpk2_det)
            k1step_det.append(sp.re(tmpk1_det))
            k2step_det.append(sp.re(tmpk2_det))

        tmpk1_tr = tr.subs(x, i)
        tmpk2_tr = Trace.subs([(k1, tmpk1_tr), (x, i)])
        k1step_tr.append(sp.re(tmpk1_tr))
        k2step_tr.append(sp.re(tmpk2_tr))
        print(i)
    print("k1det", k1step_det)
    print("k1tr", k1step_tr)
    param_plot(k1step_det, k2step_det, subplot1, 'g', [0, 1], 0)
    param_plot(k1step_tr, k2step_tr, subplot1, 'b', [0, 1], 0)
Esempio n. 11
0
def test_matrix_expression_from_index_summation():
    from sympy.abc import a,b,c,d
    A = MatrixSymbol("A", k, k)
    B = MatrixSymbol("B", k, k)
    C = MatrixSymbol("C", k, k)
    w1 = MatrixSymbol("w1", k, 1)

    i0, i1, i2, i3, i4 = symbols("i0:5", cls=Dummy)

    expr = Sum(W[a,b]*X[b,c]*Z[c,d], (b, 0, l-1), (c, 0, m-1))
    assert MatrixExpr.from_index_summation(expr, a) == W*X*Z
    expr = Sum(W.T[b,a]*X[b,c]*Z[c,d], (b, 0, l-1), (c, 0, m-1))
    assert MatrixExpr.from_index_summation(expr, a) == W*X*Z
    expr = Sum(A[b, a]*B[b, c]*C[c, d], (b, 0, k-1), (c, 0, k-1))
    assert MatrixSymbol.from_index_summation(expr, a) == A.T*B*C
    expr = Sum(A[b, a]*B[c, b]*C[c, d], (b, 0, k-1), (c, 0, k-1))
    assert MatrixSymbol.from_index_summation(expr, a) == A.T*B.T*C
    expr = Sum(C[c, d]*A[b, a]*B[c, b], (b, 0, k-1), (c, 0, k-1))
    assert MatrixSymbol.from_index_summation(expr, a) == A.T*B.T*C
    expr = Sum(A[a, b] + B[a, b], (a, 0, k-1), (b, 0, k-1))
    assert MatrixExpr.from_index_summation(expr, a) == A + B
    expr = Sum((A[a, b] + B[a, b])*C[b, c], (b, 0, k-1))
    assert MatrixExpr.from_index_summation(expr, a) == (A+B)*C
    expr = Sum((A[a, b] + B[b, a])*C[b, c], (b, 0, k-1))
    assert MatrixExpr.from_index_summation(expr, a) == (A+B.T)*C
    expr = Sum(A[a, b]*A[b, c]*A[c, d], (b, 0, k-1), (c, 0, k-1))
    assert MatrixExpr.from_index_summation(expr, a) == MatMul(A, A, A)
    expr = Sum(A[a, b]*A[b, c]*B[c, d], (b, 0, k-1), (c, 0, k-1))
    assert MatrixExpr.from_index_summation(expr, a) == MatMul(A, A, B)

    # Parse the trace of a matrix:

    expr = Sum(A[a, a], (a, 0, k-1))
    assert MatrixExpr.from_index_summation(expr, None) == trace(A)
    expr = Sum(A[a, a]*B[b, c]*C[c, d], (a, 0, k-1), (c, 0, k-1))
    assert MatrixExpr.from_index_summation(expr, b) == trace(A)*B*C

    # Check wrong sum ranges (should raise an exception):

    ## Case 1: 0 to m instead of 0 to m-1
    expr = Sum(W[a,b]*X[b,c]*Z[c,d], (b, 0, l-1), (c, 0, m))
    raises(ValueError, lambda: MatrixExpr.from_index_summation(expr, a))
    ## Case 2: 1 to m-1 instead of 0 to m-1
    expr = Sum(W[a,b]*X[b,c]*Z[c,d], (b, 0, l-1), (c, 1, m-1))
    raises(ValueError, lambda: MatrixExpr.from_index_summation(expr, a))

    # Parse nested sums:
    expr = Sum(A[a, b]*Sum(B[b, c]*C[c, d], (c, 0, k-1)), (b, 0, k-1))
    assert MatrixExpr.from_index_summation(expr, a) == A*B*C

    # Test Kronecker delta:
    expr = Sum(A[a, b]*KroneckerDelta(b, c)*B[c, d], (b, 0, k-1), (c, 0, k-1))
    assert MatrixExpr.from_index_summation(expr, a) == A*B

    expr = Sum(KroneckerDelta(i1, m)*KroneckerDelta(i2, n)*A[i, i1]*A[j, i2], (i1, 0, k-1), (i2, 0, k-1))
    assert MatrixExpr.from_index_summation(expr, m) == A.T*A[j, n]

    # Test numbered indices:
    expr = Sum(A[i1, i2]*w1[i2, 0], (i2, 0, k-1))
    assert MatrixExpr.from_index_summation(expr, i1) == A*w1

    expr = Sum(A[i1, i2]*B[i2, 0], (i2, 0, k-1))
    assert MatrixExpr.from_index_summation(expr, i1) == MatrixElement(A*B, i1, 0)
Esempio n. 12
0
def GRAPE_pulse(H, duration, N, gamma=0.01, thres=1e-8, init_state=None, autostop=False):
    """ Main function to optimize pulse with GRAPE.
    ** H, qu.qobj: Hamiltonian operator as a qutip qobj
    ** duration, float: Time length of the pulse
    ** N, int: Number of time slices to split Ex and Ey into
    ** gamma, float: Learning parameter, at each step, simulator jumps by gamma * del f
    ** thres, float: Tolerance threshold for final converged run.
    ** autostop, bool: If True, terminate the run after 10000 iterations

    == OUT ==

    """
    ################################################
    # Setup
    ################################################
    print('Setting up run.')

    # Construct basis vectors and collapse operators for Hilbert space
    b_vec = []
    e_ops = []

    # In the future, allow for the implementation of spin ensembles with different
    # spins
    for ii in range(int(2*H.s+1)):
        basis_state = ob.basis(int(2*H.s+1),ii)#qu.basis(int(2*H.s+1), ii)
        for jj in range(H.N):
            if jj == 0:
                basis_vec = basis_state
                collapse_op = TensorProduct(basis_state, basis_state)#np.outer(basis_state, basis_state)#basis_state * basis_state.dag()
            else:
                basis_vec = TensorProduct(basis_vec, basis_state)#np.kron(basis_vec, basis_state)#qu.tensor(basis_vec, basis_state)
                collapse_op = TensorProduct(collapse_op, basis_state.T * basis_state)#np.kron(collapse_op, np.outer(basis_state, basis_state))#qu.tensor(collapse_op, basis_state * basis_state.dag())
        b_vec.append(basis_vec)
        e_ops.append(collapse_op)

    X_control = np.array(sym.symbols('x0:{0}'.format(N), real=True))
    Y_control = np.array(sym.symbols('y0:{0}'.format(N), real=True))

    U = H.unitary(X_control, Y_control, duration)

    # Create U lambda for convenience
    U_lambda = sym.lambdify(np.append(X_control, Y_control), np.array(U))

    ################################################
    # Build desired unitary
    ################################################
    print('Building desired unitary.')
    # Construct the desired unitary. For now, pick the one that swaps all of them down
    for ii in range(H.N):
        if ii == 0:
            Uideal = 2 * ob.spin_operator(0.5,'x')#qu.sigmax()
        else:
            Uideal = TensorProduct(Uideal, 2 * ob.spin_operator(0.5,'x'))#np.kron(Uideal, 2 * ob.spin_operator(0.5,'x'))#qu.tensor(Uideal, qu.sigmax())
    # Construct the ideal bra vectors
    bras_ideal = [sym.conjugate((Uideal * b_vec[ii]).T) for ii in range(len(b_vec))] #[b_vec[ii].dag() * Uideal.dag() for ii in range(len(b_vec))]

    ################################################
    # Calculate fidelity function
    ################################################
    print('Calculating fidelity.')
    if init_state == None:
        F = 0
        for ii in range(len(b_vec)):
            # Calculate <n|Uideal * Ugrape|n>
            term = (bras_ideal[ii] * U * b_vec[ii])[0,0]
            print(ii+1)
            F += term

        # Get fidelity, convert to fast lambda function
        F = sym.conjugate(F) * F / len(b_vec)**2
    else:
        if init_state.pure:
            desired_state = Uideal * init_state.vector
            actual_state = U * init_state.vector

            F = (sym.conjugate(desired_state.T) * actual_state)[0,0]
            F = (sym.conjugate(F) * F)
        else:
            raise ValueError('Error: Mixed state currently does not work. Aborting.')
            desired_state = Uideal * init_state.rho * sym.conjugate(Uideal.T)
            actual_state = U * init_state.rho * sym.conjugate(U.T)

            P, D = desired_state.diagonalize()
            sqrt_desired =  P * D ** (1/2) * P ** -1
            full = sqrt_desired * actual_state * sqrt_desired
            pdb.set_trace()
            P, D = full.diagonalize(); print('6')
            F = sym.trace( D ** (1/2) ) ** 2; print('7')

    F_func = sym.lambdify(np.append(X_control, Y_control), F)

    # Calculate the analytical gradient in both quadratures
    delF_x = []
    delF_y = []

    print('Calculate analytical gradient')
    for ii in range(N):
        diff_x = sym.lambdify(np.append(X_control, Y_control),
                               sym.diff(F, X_control[ii]))
        diff_y = sym.lambdify(np.append(X_control, Y_control),
                               sym.diff(F, Y_control[ii]))
        delF_x.append(diff_x)
        delF_y.append(diff_y)
        print(ii+1)
    print('Done.')

    ################################################
    # Initialize guess and simulation arrays
    ################################################
    print('Initialize guess.')
    # Dumb initial guess, uniform driving with no normalization whatsoever
    current_EpsX = 2 * np.pi * np.ones(N) / duration
    current_EpsY = np.zeros(N)

    # Look at initial Uideal to see if it's reasonable
    # Unfortunately, to evaluate, we need to iterate through all the values we want and cast
    # them as default Python floats (instead of numpy.float64)
    args = []
    for ii in range(len(current_EpsX)):
        args.append(float(current_EpsX[ii]))
    for ii in range(len(current_EpsY)):
        args.append(float(current_EpsY[ii]))

    #Uinit = sym.Matrix(U_lambda(*current_EpsX.astype(float), *current_EpsY.astype(float)))
    Uinit = sym.Matrix(U_lambda(*args))

    N_iter = 1
    F_list = [0] # Initialize list of fidelities
    EpsX_list = []
    EpsY_list = []

    ################################################
    # The fun bit
    ################################################
    print('Starting run.')
    init_trial = True # If this is the first run, delete the first element of F_list

    while ((1 - F_list[-1]) > thres):
        if init_trial: # Hokey bodge to make the while loop run the first time
            F_list = []
            init_trial = False

        start = time.time()

        # Numerically evaluate the fidelity and gradient at the trial point
        control_args = list(np.append(current_EpsX, current_EpsY))
        for ii in range(len(control_args)):
            control_args[ii] = complex(control_args[ii])

        # Calculate trial fidelity. Take real fidelity
        F_trial = np.real(F_func(*control_args))#F.xreplace(param_dict)

        # Append everything to arrays
        F_list.append(float(F_trial))
        EpsX_list.append(np.copy(current_EpsX))
        EpsY_list.append(np.copy(current_EpsY))
        #F_trial = sym.N(F_trial)

        print('F: {0}'.format(F_trial))

        delF_x_trial = np.array([])
        delF_y_trial = np.array([])
        for ii in range(len(delF_x)):
            delF_x_trial = np.append(delF_x_trial, delF_x[ii](*control_args))
            delF_y_trial = np.append(delF_y_trial, delF_y[ii](*control_args))

        # Make a step, keeping only the real part of the gradient (there is a numerical artifact)
        current_EpsX += gamma * np.real(delF_x_trial)
        current_EpsY += gamma * np.real(delF_y_trial)

        if (N_iter == 10000) & autostop:
            break

        N_iter += 1

    # Convert everything to arrays
    EpsX_list = np.array(EpsX_list)
    EpsY_list = np.array(EpsY_list)
    F_list = np.array(F_list)

    return EpsX_list, EpsY_list, F_list
Esempio n. 13
0
lam = E*nu/((1+nu)*(1-2*nu))
G   = E/(2*(1+nu))


# In[6]:

B1, B2, B3, Babs = symbols('B1:4 |B|')
g0,g1,g2,g3,g4 = symbols('g0:5')
(exx,exy,exz,eyx,eyy,eyz,ezx,ezy,ezz) = symbols('e1:4(1:4)')
B = Matrix([B1,B2,B3])
epst = Matrix([[exx,exy,exz],[eyx,eyy,eyz],[ezx,ezy,ezz]])


# In[7]:

epstd = epst-trace(epst)/3*eye(3)


# In[8]:

I1 = trace(epst)
I2 = 0.5*trace(epst*epst)
I4 = sum(B.T*B)
I5 = sum(B.T*epstd*B)
I6 = sum(B.T*epstd*epstd*B)
#I5 = 0
#I6 = 0


# In[9]:
Esempio n. 14
0
    return out


# formulate the PDE
x = sp.symbols('x0:2')
n = sp.symbols('n0:2')
u = (sp.Function('u0')(*x), sp.Function('u1')(*x))
#L = sp.Function('lambda')(*x)
#M = sp.Function('mu')(*x)
L = sp.symbols('lambda')
M = sp.symbols('mu')
dim = 2
F = [[u[i].diff(x[j]) for i in range(dim)] for j in range(dim)]
F = sp.Matrix(F)
strain = sp.Rational(1, 2) * (F + F.T)
stress = L * sp.eye(dim) * sp.trace(strain) + 2 * M * strain
PDEs = [sum(stress[i, j].diff(x[j]) for j in range(dim)) for i in range(dim)]
FreeBCs = [sum(stress[i, j] * n[j] for j in range(dim)) for i in range(dim)]
FixBCs = [u[i] for i in range(dim)]

# norms is an array which is later defined
sym2num = {
    L: 1.0,
    M: 1.0,
    sp.Integer(1): 1.0,
    sp.Integer(2): 2.0,
    L.diff(x[0]): 0.0,
    L.diff(x[1]): 0.0,
    M.diff(x[0]): 0.0,
    M.diff(x[1]): 0.0,
    n[0]: lambda i: norms[i, 0],
Esempio n. 15
0
 def init_r(self):
     """ Ricci scalar of the metric. """
     if isinstance(self.ricci, type(None)):
         self.init_ricci() # Initialize Ricci tensor (if not already done)
     self.r = sp.trace(sp.simplify(sp.Matrix(self.ricci)*self.inv))
Esempio n. 16
0
def two_parameter_analysis(f1, f2, param_dict, cond_mult, cond_y, const1,
                           const2):
    param1 = k_1
    param2 = k1

    jac_A = Matrix([f1, f2]).jacobian(Matrix([x, y]))
    det_A = jac_A.det()
    trace_A = trace(jac_A)

    y_of_x = solve(f2, y)[0]
    param2_of_x = solve(f1, param2)[0]

    param2_trace = solve(trace_A, param2)[0]
    param1_trace = solve(param2_trace - param2_of_x, param1)[0]

    param2_det = solve(det_A, param2)[0]
    param1_det = solve(param2_det - param2_of_x, param1)[0]

    x_grid = np.linspace(0, 1, 1000)

    y_of_x_func = lambdify([x, k3, k_3], y_of_x, 'numpy')
    y_grid = y_of_x_func(x_grid, param_dict[k3], param_dict[k_3])

    new_x_grid = []
    new_y_grid = []

    for curr_x, curr_y in zip(x_grid, y_grid):
        if 0 <= curr_x + cond_mult * curr_y <= 1 and 0 <= curr_y <= cond_y:
            new_x_grid.append(curr_x)
            new_y_grid.append(curr_y)

    x_grid = np.array(new_x_grid)
    y_grid = np.array(new_y_grid)

    param1_trace_subs = np.zeros(x_grid.shape)
    param2_trace_subs = np.zeros(x_grid.shape)
    param1_det_subs = np.zeros(x_grid.shape)
    param2_det_subs = np.zeros(x_grid.shape)

    for i in range(x_grid.shape[0]):
        param1_trace_subs[i] = param1_trace.subs({
            x: x_grid[i],
            y: y_grid[i],
            k2: param_dict[k2],
            k3: param_dict[k3],
            k_3: param_dict[k_3]
        })

        param2_trace_subs[i] = param2_of_x.subs({
            x: x_grid[i],
            y: y_grid[i],
            k_1: param1_trace_subs[i],
            k2: param_dict[k2],
            k3: param_dict[k3],
            k_3: param_dict[k_3]
        })

        param1_det_subs[i] = param1_det.subs({
            x: x_grid[i],
            y: y_grid[i],
            k2: param_dict[k2],
            k3: param_dict[k3],
            k_3: param_dict[k_3]
        })

        param2_det_subs[i] = param2_of_x.subs({
            x: x_grid[i],
            y: y_grid[i],
            k_1: param1_det_subs[i],
            k2: param_dict[k2],
            k3: param_dict[k3],
            k_3: param_dict[k_3]
        })

    e1, e2 = jac_A.eigenvals()

    for curr_x, curr_y, curr_param2, curr_param1 in zip(
            x_grid, y_grid, param2_trace_subs, param1_trace_subs):
        curr_e1 = e1.subs({
            x: curr_x,
            y: curr_y,
            k1: curr_param2,
            k_1: curr_param1,
            k2: param_dict[k2],
            k3: param_dict[k3],
            k_3: param_dict[k_3]
        })

        curr_e2 = e2.subs({
            x: curr_x,
            y: curr_y,
            k1: curr_param2,
            k_1: curr_param1,
            k2: param_dict[k2],
            k3: param_dict[k3],
            k_3: param_dict[k_3]
        })

        if curr_e1.is_real and curr_e2.is_real and curr_e1 < const1 and curr_e2 < const1:
            plt.plot(curr_param2, curr_param1, 'X', color='g')

    param1_det_diff = param1_det.diff(x)
    param1_det_diff_func = lambdify([x, y, k2, k3, k_3], param1_det_diff,
                                    'numpy')

    diff_arr = []

    for i in range(x_grid.shape[0]):
        if fabs(
                param1_det_diff_func(x_grid[i], y_grid[i], param_dict[k2],
                                     param_dict[k3],
                                     param_dict[k_3])) < const2:
            diff_arr.append(x_grid[i])

    c_x = sum(diff_arr) / len(diff_arr)
    c_y = y_of_x_func(c_x, param_dict[k3], param_dict[k_3])

    c_param1 = param1_det.subs({
        x: c_x,
        y: c_y,
        k2: param_dict[k2],
        #k1: param_dict[k1],
        k3: param_dict[k3],
        k_3: param_dict[k_3]
    })

    c_param2 = param2_of_x.subs({
        x: c_x,
        y: c_y,
        k_1: c_param1,
        k2: param_dict[k2],
        #k1: param_dict[k1],
        k3: param_dict[k3],
        k_3: param_dict[k_3]
    })

    plt.plot(param2_trace_subs, param1_trace_subs, '--', label='neutrality')
    plt.plot(param2_det_subs, param1_det_subs, label='multiplicity')

    plt.plot(c_param2, c_param1, 'ro', color='r')

    plt.xlabel('k1')
    plt.ylabel('k_1')

    plt.show()
 def recurse_expr(expr, index_ranges={}):
     if expr.is_Mul:
         nonmatargs = []
         pos_arg = []
         pos_ind = []
         dlinks = {}
         link_ind = []
         counter = 0
         args_ind = []
         for arg in expr.args:
             retvals = recurse_expr(arg, index_ranges)
             assert isinstance(retvals, list)
             if isinstance(retvals, list):
                 for i in retvals:
                     args_ind.append(i)
             else:
                 args_ind.append(retvals)
         for arg_symbol, arg_indices in args_ind:
             if arg_indices is None:
                 nonmatargs.append(arg_symbol)
                 continue
             if isinstance(arg_symbol, MatrixElement):
                 arg_symbol = arg_symbol.args[0]
             pos_arg.append(arg_symbol)
             pos_ind.append(arg_indices)
             link_ind.append([None]*len(arg_indices))
             for i, ind in enumerate(arg_indices):
                 if ind in dlinks:
                     other_i = dlinks[ind]
                     link_ind[counter][i] = other_i
                     link_ind[other_i[0]][other_i[1]] = (counter, i)
                 dlinks[ind] = (counter, i)
             counter += 1
         counter2 = 0
         lines = {}
         while counter2 < len(link_ind):
             for i, e in enumerate(link_ind):
                 if None in e:
                     line_start_index = (i, e.index(None))
                     break
             cur_ind_pos = line_start_index
             cur_line = []
             index1 = pos_ind[cur_ind_pos[0]][cur_ind_pos[1]]
             while True:
                 d, r = cur_ind_pos
                 if pos_arg[d] != 1:
                     if r % 2 == 1:
                         cur_line.append(transpose(pos_arg[d]))
                     else:
                         cur_line.append(pos_arg[d])
                 next_ind_pos = link_ind[d][1-r]
                 counter2 += 1
                 # Mark as visited, there will be no `None` anymore:
                 link_ind[d] = (-1, -1)
                 if next_ind_pos is None:
                     index2 = pos_ind[d][1-r]
                     lines[(index1, index2)] = cur_line
                     break
                 cur_ind_pos = next_ind_pos
         ret_indices = list(j for i in lines for j in i)
         lines = {k: MatMul.fromiter(v) if len(v) != 1 else v[0] for k, v in lines.items()}
         return [(Mul.fromiter(nonmatargs), None)] + [
             (MatrixElement(a, i, j), (i, j)) for (i, j), a in lines.items()
         ]
     elif expr.is_Add:
         res = [recurse_expr(i) for i in expr.args]
         d = collections.defaultdict(list)
         for res_addend in res:
             scalar = 1
             for elem, indices in res_addend:
                 if indices is None:
                     scalar = elem
                     continue
                 indices = tuple(sorted(indices, key=default_sort_key))
                 d[indices].append(scalar*remove_matelement(elem, *indices))
                 scalar = 1
         return [(MatrixElement(Add.fromiter(v), *k), k) for k, v in d.items()]
     elif isinstance(expr, KroneckerDelta):
         i1, i2 = expr.args
         if dimensions is not None:
             identity = Identity(dimensions[0])
         else:
             identity = S.One
         return [(MatrixElement(identity, i1, i2), (i1, i2))]
     elif isinstance(expr, MatrixElement):
         matrix_symbol, i1, i2 = expr.args
         if i1 in index_ranges:
             r1, r2 = index_ranges[i1]
             if r1 != 0 or matrix_symbol.shape[0] != r2+1:
                 raise ValueError("index range mismatch: {0} vs. (0, {1})".format(
                     (r1, r2), matrix_symbol.shape[0]))
         if i2 in index_ranges:
             r1, r2 = index_ranges[i2]
             if r1 != 0 or matrix_symbol.shape[1] != r2+1:
                 raise ValueError("index range mismatch: {0} vs. (0, {1})".format(
                     (r1, r2), matrix_symbol.shape[1]))
         if (i1 == i2) and (i1 in index_ranges):
             return [(trace(matrix_symbol), None)]
         return [(MatrixElement(matrix_symbol, i1, i2), (i1, i2))]
     elif isinstance(expr, Sum):
         return recurse_expr(
             expr.args[0],
             index_ranges={i[0]: i[1:] for i in expr.args[1:]}
         )
     else:
         return [(expr, None)]
Esempio n. 18
0
 def normalization_factor(self):
     return 1 / sp.sqrt(sp.trace(self.density_matrix()).simplify())
Esempio n. 19
0
def test_literature(force_model, stencil, method):
    # Be aware that the choice of the conserved moments does not affect the forcing although omega is introduced
    # in the forcing vector then. The reason is that:
    # m_{100}^{\ast} = m_{100} + \omega ( m_{100}^{eq} - m_{100} ) + \left( 1 - \frac{\omega}{2} \right) F_x
    # always simplifies to:
    # m_{100}^{\ast} = m_{100} + F_x
    # Thus the relaxation rate gets cancled again.

    stencil = LBStencil(stencil)

    omega_s = sp.Symbol("omega_s")
    omega_b = sp.Symbol("omega_b")
    omega_o = sp.Symbol("omega_o")
    omega_e = sp.Symbol("omega_e")
    if method == Method.SRT:
        rrs = [omega_s]
        omega_o = omega_b = omega_e = omega_s
    elif method == Method.TRT:
        rrs = [omega_e, omega_o]
        omega_s = omega_b = omega_e
    else:
        rrs = [omega_s, omega_b, omega_o, omega_e, omega_o, omega_e]

    F = sp.symbols(f"F_:{stencil.D}")

    lbm_config = LBMConfig(method=method,
                           weighted=True,
                           stencil=stencil,
                           relaxation_rates=rrs,
                           compressible=force_model != ForceModel.BUICK,
                           force_model=force_model,
                           force=F)

    lb_method = create_lb_method(lbm_config=lbm_config)
    omega_momentum = list(set(lb_method.relaxation_rates[1:stencil.D + 1]))
    assert len(omega_momentum) == 1
    omega_momentum = omega_momentum[0]

    subs_dict = lb_method.subs_dict_relxation_rate
    force_term = sp.simplify(lb_method.force_model(lb_method).subs(subs_dict))
    u = sp.Matrix(lb_method.first_order_equilibrium_moment_symbols)
    rho = lb_method.conserved_quantity_computation.zeroth_order_moment_symbol

    # see silva2020 for nomenclature
    F = sp.Matrix(F)
    uf = sp.Matrix(u).dot(F)
    F2 = sp.Matrix(F).dot(sp.Matrix(F))
    Fq = sp.zeros(stencil.Q, 1)
    uq = sp.zeros(stencil.Q, 1)
    for i, cq in enumerate(stencil):
        Fq[i] = sp.Matrix(cq).dot(sp.Matrix(F))
        uq[i] = sp.Matrix(cq).dot(u)

    common_plus = 3 * (1 - omega_e / 2)
    common_minus = 3 * (1 - omega_momentum / 2)

    result = []
    if method == Method.MRT and force_model == ForceModel.GUO:
        # check against eq. 4.68 from schiller2008thermal
        uf = u.dot(F) * sp.eye(len(F))
        G = (u * F.transpose() + F * u.transpose() - uf * sp.Rational(2, lb_method.dim)) * sp.Rational(1, 2) * \
            (2 - omega_s) + uf * sp.Rational(1, lb_method.dim) * (2 - omega_b)
        for direction, w_i in zip(lb_method.stencil, lb_method.weights):
            direction = sp.Matrix(direction)
            tr = sp.trace(G * (direction * direction.transpose() -
                               sp.Rational(1, 3) * sp.eye(len(F))))
            result.append(3 * w_i *
                          (F.dot(direction) + sp.Rational(3, 2) * tr))
    elif force_model == ForceModel.GUO:
        # check against table 2 in silva2020 (correct for SRT and TRT), matches eq. 20 from guo2002discrete (for SRT)
        Sq_plus = sp.zeros(stencil.Q, 1)
        Sq_minus = sp.zeros(stencil.Q, 1)
        for i, w_i in enumerate(lb_method.weights):
            Sq_plus[i] = common_plus * w_i * (3 * uq[i] * Fq[i] - uf)
            Sq_minus[i] = common_minus * w_i * Fq[i]
        result = Sq_plus + Sq_minus
    elif force_model == ForceModel.BUICK:
        # check against table 2 in silva2020 (correct for all collision models due to the simplicity of Buick),
        # matches eq. 18 from silva2010 (for SRT)
        Sq_plus = sp.zeros(stencil.Q, 1)
        Sq_minus = sp.zeros(stencil.Q, 1)
        for i, w_i in enumerate(lb_method.weights):
            Sq_plus[i] = 0
            Sq_minus[i] = common_minus * w_i * Fq[i]
        result = Sq_plus + Sq_minus
    elif force_model == ForceModel.EDM:
        # check against table 2 in silva2020
        if method == Method.MRT:
            # for mrt no literature terms are known at the time of writing this test case.
            # However it is most likly correct since SRT and TRT are derived from the moment space representation
            pytest.skip()
        Sq_plus = sp.zeros(stencil.Q, 1)
        Sq_minus = sp.zeros(stencil.Q, 1)
        for i, w_i in enumerate(lb_method.weights):
            Sq_plus[i] = common_plus * w_i * (3 * uq[i] * Fq[i] - uf) + (
                (w_i / (8 * rho)) * (3 * Fq[i]**2 - F2))
            Sq_minus[i] = common_minus * w_i * Fq[i]
        result = Sq_plus + Sq_minus
    elif force_model == ForceModel.SHANCHEN:
        # check against table 2 in silva2020
        if method == Method.MRT:
            # for mrt no literature terms are known at the time of writing this test case.
            # However it is most likly correct since SRT and TRT are derived from the moment space representation
            pytest.skip()
        Sq_plus = sp.zeros(stencil.Q, 1)
        Sq_minus = sp.zeros(stencil.Q, 1)
        for i, w_i in enumerate(lb_method.weights):
            Sq_plus[i] = common_plus * w_i * (3 * uq[i] * Fq[i] -
                                              uf) + common_plus**2 * (
                                                  (w_i / (2 * rho)) *
                                                  (3 * Fq[i]**2 - F2))
            Sq_minus[i] = common_minus * w_i * Fq[i]
        result = Sq_plus + Sq_minus
    assert list(sp.simplify(force_term -
                            sp.Matrix(result))) == [0] * len(stencil)
def div(u):
    return sym.trace(u.jacobian([x, y]))
Esempio n. 21
0
 def recurse_expr(expr, index_ranges={}):
     if expr.is_Mul:
         nonmatargs = []
         matargs = []
         pos_arg = []
         pos_ind = []
         dlinks = {}
         link_ind = []
         counter = 0
         for arg in expr.args:
             arg_symbol, arg_indices = recurse_expr(arg, index_ranges)
             if arg_indices is None:
                 nonmatargs.append(arg_symbol)
                 continue
             i1, i2 = arg_indices
             pos_arg.append(arg_symbol)
             pos_ind.append(i1)
             pos_ind.append(i2)
             link_ind.extend([None, None])
             if i1 in dlinks:
                 other_i1 = dlinks[i1]
                 link_ind[2*counter] = other_i1
                 link_ind[other_i1] = 2*counter
             if i2 in dlinks:
                 other_i2 = dlinks[i2]
                 link_ind[2*counter + 1] = other_i2
                 link_ind[other_i2] = 2*counter + 1
             dlinks[i1] = 2*counter
             dlinks[i2] = 2*counter + 1
             counter += 1
         cur_ind_pos = link_ind.index(None)
         first_index = pos_ind[cur_ind_pos]
         while True:
             d = cur_ind_pos // 2
             r = cur_ind_pos % 2
             if r == 1:
                 matargs.append(transpose(pos_arg[d]))
             else:
                 matargs.append(pos_arg[d])
             next_ind_pos = link_ind[2*d + 1 - r]
             if next_ind_pos is None:
                 last_index = pos_ind[2*d + 1 - r]
                 break
             cur_ind_pos = next_ind_pos
         return Mul.fromiter(nonmatargs)*MatMul.fromiter(matargs), (first_index, last_index)
     elif expr.is_Add:
         res = [recurse_expr(i) for i in expr.args]
         res = [
             ((transpose(i), (j[1], j[0]))
                 if default_sort_key(j[0]) > default_sort_key(j[1])
             else (i, j))
             for (i, j) in res
         ]
         addends, last_indices = zip(*res)
         last_indices = list(set(last_indices))
         if len(last_indices) > 1:
             print(last_indices)
             raise ValueError("incompatible summation")
         return MatAdd.fromiter(addends), last_indices[0]
     elif isinstance(expr, KroneckerDelta):
         i1, i2 = expr.args
         return S.One, (i1, i2)
     elif isinstance(expr, MatrixElement):
         matrix_symbol, i1, i2 = expr.args
         if i1 in index_ranges:
             r1, r2 = index_ranges[i1]
             if r1 != 0 or matrix_symbol.shape[0] != r2+1:
                 raise ValueError("index range mismatch: {0} vs. (0, {1})".format(
                     (r1, r2), matrix_symbol.shape[0]))
         if i2 in index_ranges:
             r1, r2 = index_ranges[i2]
             if r1 != 0 or matrix_symbol.shape[1] != r2+1:
                 raise ValueError("index range mismatch: {0} vs. (0, {1})".format(
                     (r1, r2), matrix_symbol.shape[1]))
         if (i1 == i2) and (i1 in index_ranges):
             return trace(matrix_symbol), None
         return matrix_symbol, (i1, i2)
     elif isinstance(expr, Sum):
         return recurse_expr(
             expr.args[0],
             index_ranges={i[0]: i[1:] for i in expr.args[1:]}
         )
     else:
         return expr, None
Esempio n. 22
0
def test_matrix_expression_from_index_summation():
    from sympy.abc import a, b, c, d

    A = MatrixSymbol("A", k, k)
    B = MatrixSymbol("B", k, k)
    C = MatrixSymbol("C", k, k)
    w1 = MatrixSymbol("w1", k, 1)

    i0, i1, i2, i3, i4 = symbols("i0:5", cls=Dummy)

    expr = Sum(W[a, b] * X[b, c] * Z[c, d], (b, 0, l - 1), (c, 0, m - 1))
    assert MatrixExpr.from_index_summation(expr, a) == W * X * Z
    expr = Sum(W.T[b, a] * X[b, c] * Z[c, d], (b, 0, l - 1), (c, 0, m - 1))
    assert MatrixExpr.from_index_summation(expr, a) == W * X * Z
    expr = Sum(A[b, a] * B[b, c] * C[c, d], (b, 0, k - 1), (c, 0, k - 1))
    assert MatrixSymbol.from_index_summation(expr, a) == A.T * B * C
    expr = Sum(A[b, a] * B[c, b] * C[c, d], (b, 0, k - 1), (c, 0, k - 1))
    assert MatrixSymbol.from_index_summation(expr, a) == A.T * B.T * C
    expr = Sum(C[c, d] * A[b, a] * B[c, b], (b, 0, k - 1), (c, 0, k - 1))
    assert MatrixSymbol.from_index_summation(expr, a) == A.T * B.T * C
    expr = Sum(A[a, b] + B[a, b], (a, 0, k - 1), (b, 0, k - 1))
    assert MatrixExpr.from_index_summation(expr, a) == A + B
    expr = Sum((A[a, b] + B[a, b]) * C[b, c], (b, 0, k - 1))
    assert MatrixExpr.from_index_summation(expr, a) == (A + B) * C
    expr = Sum((A[a, b] + B[b, a]) * C[b, c], (b, 0, k - 1))
    assert MatrixExpr.from_index_summation(expr, a) == (A + B.T) * C
    expr = Sum(A[a, b] * A[b, c] * A[c, d], (b, 0, k - 1), (c, 0, k - 1))
    assert MatrixExpr.from_index_summation(expr, a) == A**3
    expr = Sum(A[a, b] * A[b, c] * B[c, d], (b, 0, k - 1), (c, 0, k - 1))
    assert MatrixExpr.from_index_summation(expr, a) == A**2 * B

    # Parse the trace of a matrix:

    expr = Sum(A[a, a], (a, 0, k - 1))
    assert MatrixExpr.from_index_summation(expr, None) == trace(A)
    expr = Sum(A[a, a] * B[b, c] * C[c, d], (a, 0, k - 1), (c, 0, k - 1))
    assert MatrixExpr.from_index_summation(expr, b) == trace(A) * B * C

    # Check wrong sum ranges (should raise an exception):

    ## Case 1: 0 to m instead of 0 to m-1
    expr = Sum(W[a, b] * X[b, c] * Z[c, d], (b, 0, l - 1), (c, 0, m))
    raises(ValueError, lambda: MatrixExpr.from_index_summation(expr, a))
    ## Case 2: 1 to m-1 instead of 0 to m-1
    expr = Sum(W[a, b] * X[b, c] * Z[c, d], (b, 0, l - 1), (c, 1, m - 1))
    raises(ValueError, lambda: MatrixExpr.from_index_summation(expr, a))

    # Parse nested sums:
    expr = Sum(A[a, b] * Sum(B[b, c] * C[c, d], (c, 0, k - 1)), (b, 0, k - 1))
    assert MatrixExpr.from_index_summation(expr, a) == A * B * C

    # Test Kronecker delta:
    expr = Sum(A[a, b] * KroneckerDelta(b, c) * B[c, d], (b, 0, k - 1),
               (c, 0, k - 1))
    assert MatrixExpr.from_index_summation(expr, a) == A * B

    expr = Sum(
        KroneckerDelta(i1, m) * KroneckerDelta(i2, n) * A[i, i1] * A[j, i2],
        (i1, 0, k - 1),
        (i2, 0, k - 1),
    )
    assert MatrixExpr.from_index_summation(expr, m) == A.T * A[j, n]

    # Test numbered indices:
    expr = Sum(A[i1, i2] * w1[i2, 0], (i2, 0, k - 1))
    assert MatrixExpr.from_index_summation(expr, i1) == A * w1

    expr = Sum(A[i1, i2] * B[i2, 0], (i2, 0, k - 1))
    assert MatrixExpr.from_index_summation(expr,
                                           i1) == MatrixElement(A * B, i1, 0)
Esempio n. 23
0
def _trace_single_line(t):
    """
    Evaluate the trace of a single gamma matrix line inside a ``TensExpr``.

    Notes
    =====

    If there are ``DiracSpinorIndex.auto_left`` and ``DiracSpinorIndex.auto_right``
    indices trace over them; otherwise traces are not implied (explain)


    Examples
    ========

    >>> from sympy.physics.hep.gamma_matrices import GammaMatrix as G, \
        LorentzIndex, _trace_single_line
    >>> from sympy.tensor.tensor import tensor_indices, tensorhead
    >>> p = tensorhead('p', [LorentzIndex], [[1]])
    >>> i0,i1,i2,i3,i4,i5 = tensor_indices('i0:6', LorentzIndex)
    >>> _trace_single_line(G(i0)*G(i1))
    4*metric(i0, i1)
    >>> _trace_single_line(G(i0)*p(-i0)*G(i1)*p(-i1)) - 4*p(i0)*p(-i0)
    0

    """
    def _trace_single_line1(t):
        t = t.sorted_components()
        components = t.components
        ncomps = len(components)
        g = LorentzIndex.metric
        # gamma matirices are in a[i:j]
        hit = 0
        for i in range(ncomps):
            if components[i] == GammaMatrix:
                hit = 1
                break

        for j in range(i + hit, ncomps):
            if components[j] != GammaMatrix:
                break
        else:
            j = ncomps
        numG = j - i
        if numG == 0:
            tcoeff = t.coeff
            return t.nocoeff if tcoeff else t
        if numG % 2 == 1:
            return TensMul.from_data(S.Zero, [], [], [])
        elif numG > 4:
            # find the open matrix indices and connect them:
            a = t.split()
            ind1 = a[i].get_indices()[0]
            ind2 = a[i + 1].get_indices()[0]
            aa = a[:i] + a[i + 2:]
            t1 = tensor_mul(*aa)*g(ind1, ind2)
            t1 = t1.contract_metric(g)
            args = [t1]
            sign = 1
            for k in range(i + 2, j):
                sign = -sign
                ind2 = a[k].get_indices()[0]
                aa = a[:i] + a[i + 1:k] + a[k + 1:]
                t2 = sign*tensor_mul(*aa)*g(ind1, ind2)
                t2 = t2.contract_metric(g)
                t2 = simplify_gpgp(t2, False)
                args.append(t2)
            t3 = TensAdd(*args)
            t3 = _trace_single_line(t3)
            return t3
        else:
            a = t.split()
            t1 = _gamma_trace1(*a[i:j])
            a2 = a[:i] + a[j:]
            t2 = tensor_mul(*a2)
            t3 = t1*t2
            if not t3:
                return t3
            t3 = t3.contract_metric(g)
            return t3

    if isinstance(t, TensAdd):
        a = [_trace_single_line1(x)*x.coeff for x in t.args]
        return TensAdd(*a)
    elif isinstance(t, (Tensor, TensMul)):
        r = t.coeff*_trace_single_line1(t)
        return r
    else:
        return trace(t)
Esempio n. 24
0
 def recurse_expr(expr, index_ranges={}):
     if expr.is_Mul:
         nonmatargs = []
         pos_arg = []
         pos_ind = []
         dlinks = {}
         link_ind = []
         counter = 0
         args_ind = []
         for arg in expr.args:
             retvals = recurse_expr(arg, index_ranges)
             assert isinstance(retvals, list)
             if isinstance(retvals, list):
                 for i in retvals:
                     args_ind.append(i)
             else:
                 args_ind.append(retvals)
         for arg_symbol, arg_indices in args_ind:
             if arg_indices is None:
                 nonmatargs.append(arg_symbol)
                 continue
             if isinstance(arg_symbol, MatrixElement):
                 arg_symbol = arg_symbol.args[0]
             pos_arg.append(arg_symbol)
             pos_ind.append(arg_indices)
             link_ind.append([None]*len(arg_indices))
             for i, ind in enumerate(arg_indices):
                 if ind in dlinks:
                     other_i = dlinks[ind]
                     link_ind[counter][i] = other_i
                     link_ind[other_i[0]][other_i[1]] = (counter, i)
                 dlinks[ind] = (counter, i)
             counter += 1
         counter2 = 0
         lines = {}
         while counter2 < len(link_ind):
             for i, e in enumerate(link_ind):
                 if None in e:
                     line_start_index = (i, e.index(None))
                     break
             cur_ind_pos = line_start_index
             cur_line = []
             index1 = pos_ind[cur_ind_pos[0]][cur_ind_pos[1]]
             while True:
                 d, r = cur_ind_pos
                 if pos_arg[d] != 1:
                     if r % 2 == 1:
                         cur_line.append(transpose(pos_arg[d]))
                     else:
                         cur_line.append(pos_arg[d])
                 next_ind_pos = link_ind[d][1-r]
                 counter2 += 1
                 # Mark as visited, there will be no `None` anymore:
                 link_ind[d] = (-1, -1)
                 if next_ind_pos is None:
                     index2 = pos_ind[d][1-r]
                     lines[(index1, index2)] = cur_line
                     break
                 cur_ind_pos = next_ind_pos
         ret_indices = list(j for i in lines for j in i)
         lines = {k: MatMul.fromiter(v) if len(v) != 1 else v[0] for k, v in lines.items()}
         return [(Mul.fromiter(nonmatargs), None)] + [
             (MatrixElement(a, i, j), (i, j)) for (i, j), a in lines.items()
         ]
     elif expr.is_Add:
         res = [recurse_expr(i) for i in expr.args]
         d = collections.defaultdict(list)
         for res_addend in res:
             scalar = 1
             for elem, indices in res_addend:
                 if indices is None:
                     scalar = elem
                     continue
                 indices = tuple(sorted(indices, key=default_sort_key))
                 d[indices].append(scalar*remove_matelement(elem, *indices))
                 scalar = 1
         return [(MatrixElement(Add.fromiter(v), *k), k) for k, v in d.items()]
     elif isinstance(expr, KroneckerDelta):
         i1, i2 = expr.args
         if dimensions is not None:
             identity = Identity(dimensions[0])
         else:
             identity = S.One
         return [(MatrixElement(identity, i1, i2), (i1, i2))]
     elif isinstance(expr, MatrixElement):
         matrix_symbol, i1, i2 = expr.args
         if i1 in index_ranges:
             r1, r2 = index_ranges[i1]
             if r1 != 0 or matrix_symbol.shape[0] != r2+1:
                 raise ValueError("index range mismatch: {0} vs. (0, {1})".format(
                     (r1, r2), matrix_symbol.shape[0]))
         if i2 in index_ranges:
             r1, r2 = index_ranges[i2]
             if r1 != 0 or matrix_symbol.shape[1] != r2+1:
                 raise ValueError("index range mismatch: {0} vs. (0, {1})".format(
                     (r1, r2), matrix_symbol.shape[1]))
         if (i1 == i2) and (i1 in index_ranges):
             return [(trace(matrix_symbol), None)]
         return [(MatrixElement(matrix_symbol, i1, i2), (i1, i2))]
     elif isinstance(expr, Sum):
         return recurse_expr(
             expr.args[0],
             index_ranges={i[0]: i[1:] for i in expr.args[1:]}
         )
     else:
         return [(expr, None)]
Esempio n. 25
0
def one_parameter_analysis(f1, f2, param_values, k2_bot, k2_top, const1,
                           const2):
    """
    One-parameter analysis
    The analysis is performed by parameter k2
    """
    jac_A = Matrix([f1, f2]).jacobian(Matrix([x, y]))

    param_dict = deepcopy(param_values)
    del param_dict[k2]

    f1_subs = f1.subs([(key, value) for key, value in param_dict.items()])
    f2_subs = f2.subs([(key, value) for key, value in param_dict.items()])

    solution = solve([f1_subs, f2_subs], x, k2, dict=True)[0]

    y_list = np.linspace(0, 1, 1000)
    y_final = deepcopy(y_list)

    x_list = []
    k2_list = []
    j = 0

    for i, val in enumerate(y_list):
        curr_x = re(solution[x].subs({y: val}))
        curr_k2 = re(solution[k2].subs({y: val}))

        if not (0 <= curr_x <= 1) or not (0 <= val + curr_x <= 1):
            y_final = np.delete(y_final, i - j)
            j += 1
            continue

        x_list.append(curr_x)
        k2_list.append(curr_k2)

    y_list = y_final

    jac_subs = jac_A.subs([(key, value) for key, value in param_dict.items()])
    jac_subs_listed = [
        jac_subs.subs({
            y: val,
            x: x_list[i],
            k2: k2_list[i]
        }) for i, val in enumerate(y_list)
    ]

    det_list = []
    trace_list = []

    for jac in jac_subs_listed:
        det_list.append(jac.det())
        trace_list.append(trace(jac))

    for i in range(2, len(det_list)):
        if det_list[i] * det_list[i - 1] <= const1:
            plt.plot(k2_list[i], x_list[i], 'rx', label='saddle-node')
            plt.plot(k2_list[i], y_list[i], 'rx', label='saddle-node')

        if trace_list[i] * trace_list[i - 1] <= const2:
            plt.plot(k2_list[i], x_list[i], 'go', label='hopf')
            plt.plot(k2_list[i], y_list[i], 'go', label='hopf')

    plt.plot(k2_list, x_list, linewidth=1.5, label='k2(x)')
    plt.plot(k2_list, y_list, linestyle='--', linewidth=1.5, label='k2(y)')

    plt.xlabel('k2')
    plt.ylabel('x, y')

    plt.xlim(k2_bot, k2_top)
    plt.ylim(0.0, 1.0)

    plt.show()