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
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
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)
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
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)
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
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
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)
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],
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)
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)
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
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]:
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],
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))
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)]
def normalization_factor(self): return 1 / sp.sqrt(sp.trace(self.density_matrix()).simplify())
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]))
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
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)
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)
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()