def test_literal_evalf_is_number_is_zero_is_comparable(): from diofant.integrals.integrals import Integral from diofant.core.symbol import symbols from diofant.core.function import Function x = symbols('x') f = Function('f') # the following should not be changed without a lot of dicussion # `foo.is_number` should be equivalent to `not foo.free_symbols` # it should not attempt anything fancy; see is_zero, is_constant # and equals for more rigorous tests. assert f(1).is_number is True i = Integral(0, (x, x, x)) # expressions that are symbolically 0 can be difficult to prove # so in case there is some easy way to know if something is 0 # it should appear in the is_zero property for that object; # if is_zero is true evalf should always be able to compute that # zero assert i.n() == 0 assert i.is_zero assert i.is_number is False assert i.evalf(2, strict=False) == 0 # issue sympy/sympy#10272 n = sin(1)**2 + cos(1)**2 - 1 assert n.is_comparable is not True assert n.n(2).is_comparable is not True
def test_sympyissue_8825(): t1, t2 = symbols('t1:3') d = weakref.WeakKeyDictionary([(t1, 1), (t2, 2)]) assert sstr(list(ordered(d.items()))) == '[(t1, 1), (t2, 2)]' del t1 clear_cache() gc.collect() assert sstr(list(ordered(d.items()))) == '[(t2, 2)]'
def test_sympyissue_8825(): import weakref a, b = symbols('a b') d = weakref.WeakKeyDictionary([(a, 1), (b, 2)]) assert sstr(list(ordered(d.items()))) == '[(a, 1), (b, 2)]' del a clear_cache() assert sstr(list(ordered(d.items()))) == '[(b, 2)]'
def test_TensMul_data(): Lorentz = TensorIndexType('Lorentz', metric=False, dummy_fmt='L', dim=4) Lorentz.data = [-1, 1, 1, 1] mu, nu, alpha, beta = tensor_indices('\\mu, \\nu, \\alpha, \\beta', Lorentz) Vec = TensorType([Lorentz], tensorsymmetry([1])) A2 = TensorType([Lorentz] * 2, tensorsymmetry([2])) u = Vec('u') u.data = [1, 0, 0, 0] F = A2('F') Ex, Ey, Ez, Bx, By, Bz = symbols('E_x E_y E_z B_x B_y B_z') F.data = [[0, Ex, Ey, Ez], [-Ex, 0, Bz, -By], [-Ey, -Bz, 0, Bx], [-Ez, By, -Bx, 0]] E = F(mu, nu) * u(-nu) assert ((E(mu) * E(nu)).data == numpy.array([[0, 0, 0, 0], [0, Ex**2, Ex * Ey, Ex * Ez], [0, Ex * Ey, Ey**2, Ey * Ez], [0, Ex * Ez, Ey * Ez, Ez**2]])).all() assert ((E(mu) * E(nu)).canon_bp().data == (E(mu) * E(nu)).data).all() assert ((F(mu, alpha) * F(beta, nu) * u(-alpha) * u(-beta)).data == -(E(mu) * E(nu)).data).all() assert ((F(alpha, mu) * F(beta, nu) * u(-alpha) * u(-beta)).data == (E(mu) * E(nu)).data).all() S2 = TensorType([Lorentz] * 2, tensorsymmetry([1] * 2)) g = S2('g') g.data = Lorentz.data # tensor 'perp' is orthogonal to vector 'u' perp = u(mu) * u(nu) + g(mu, nu) mul_1 = u(-mu) * perp(mu, nu) assert (mul_1.data == numpy.array([0, 0, 0, 0])).all() mul_2 = u(-mu) * perp(mu, alpha) * perp(nu, beta) assert (mul_2.data == numpy.zeros(shape=(4, 4, 4))).all() Fperp = perp(mu, alpha) * perp(nu, beta) * F(-alpha, -beta) assert (Fperp.data[0, :] == numpy.array([0, 0, 0, 0])).all() assert (Fperp.data[:, 0] == numpy.array([0, 0, 0, 0])).all() mul_3 = u(-mu) * Fperp(mu, nu) assert (mul_3.data == numpy.array([0, 0, 0, 0])).all()
def test_call(): x, y = symbols('x y') # See the long history of this in issues 5026 and 5105. pytest.raises(TypeError, lambda: sin(x)({x: 1, sin(x): 2})) pytest.raises(TypeError, lambda: sin(x)(1)) # No effect as there are no callables assert sin(x).rcall(1) == sin(x) assert (1 + sin(x)).rcall(1) == 1 + sin(x) # Effect in the pressence of callables l = Lambda(x, 2 * x) assert (l + x).rcall(y) == 2 * y + x assert (x**l).rcall(2) == x**4
def test_valued_assign_numpy_ndarray(): (A, B, AB, BA, C, Lorentz, E, px, py, pz, LorentzD, mu0, mu1, mu2, ndm, n0, n1, n2, NA, NB, NC, minkowski, ba_matrix, ndm_matrix, i0, i1, i2, i3, i4) = _get_valued_base_test_variables() # this is needed to make sure that a numpy.ndarray can be assigned to a # tensor. arr = [E + 1, px - 1, py, pz] A.data = numpy.array(arr) for i in range(4): assert A(i0).data[i] == arr[i] qx, qy, qz = symbols('qx qy qz') A(-i0).data = numpy.array([E, qx, qy, qz]) for i in range(4): assert A(i0).data[i] == [E, -qx, -qy, -qz][i] assert A.data[i] == [E, -qx, -qy, -qz][i] # test on multi-indexed tensors. random_4x4_data = [[(i**3 - 3 * i**2) % (j + 7) for i in range(4)] for j in range(4)] AB(-i0, -i1).data = random_4x4_data for i in range(4): for j in range(4): assert AB(i0, i1).data[i, j] == random_4x4_data[i][j] * ( -1 if i else 1) * (-1 if j else 1) assert AB(-i0, i1).data[i, j] == random_4x4_data[i][j] * (-1 if j else 1) assert AB(i0, -i1).data[i, j] == random_4x4_data[i][j] * (-1 if i else 1) assert AB(-i0, -i1).data[i, j] == random_4x4_data[i][j] AB(-i0, i1).data = random_4x4_data for i in range(4): for j in range(4): assert AB(i0, i1).data[i, j] == random_4x4_data[i][j] * (-1 if i else 1) assert AB(-i0, i1).data[i, j] == random_4x4_data[i][j] assert AB(i0, -i1).data[i, j] == random_4x4_data[i][j] * ( -1 if i else 1) * (-1 if j else 1) assert AB(-i0, -i1).data[i, j] == random_4x4_data[i][j] * (-1 if j else 1)
def test_valued_tensor_expressions(): (A, B, AB, BA, C, Lorentz, E, px, py, pz, LorentzD, mu0, mu1, mu2, ndm, n0, n1, n2, NA, NB, NC, minkowski, ba_matrix, ndm_matrix, i0, i1, i2, i3, i4) = _get_valued_base_test_variables() x1, x2, x3 = symbols('x1:4') # test coefficient in contraction: rank2coeff = x1 * A(i3) * B(i2) assert rank2coeff[1, 1] == x1 * px assert rank2coeff[3, 3] == 3 * pz * x1 coeff_expr = ((x1 * A(i4)) * (B(-i4) / x2)).data assert coeff_expr.expand( ) == -px * x1 / x2 - 2 * py * x1 / x2 - 3 * pz * x1 / x2 add_expr = A(i0) + B(i0) assert add_expr[0] == E assert add_expr[1] == px + 1 assert add_expr[2] == py + 2 assert add_expr[3] == pz + 3 sub_expr = A(i0) - B(i0) assert sub_expr[0] == E assert sub_expr[1] == px - 1 assert sub_expr[2] == py - 2 assert sub_expr[3] == pz - 3 assert (add_expr * B(-i0)).data == -px - 2 * py - 3 * pz - 14 expr1 = x1 * A(i0) + x2 * B(i0) expr2 = expr1 * B(i1) * (-4) expr3 = expr2 + 3 * x3 * AB(i0, i1) expr4 = expr3 / 2 assert expr4 * 2 == expr3 expr5 = (expr4 * BA(-i1, -i0)) assert expr5.data.expand( ) == 28 * E * x1 + 12 * px * x1 + 20 * py * x1 + 28 * pz * x1 + 136 * x2 + 3 * x3
def test_noncommuting_components(): (A, B, AB, BA, C, Lorentz, E, px, py, pz, LorentzD, mu0, mu1, mu2, ndm, n0, n1, n2, NA, NB, NC, minkowski, ba_matrix, ndm_matrix, i0, i1, i2, i3, i4) = _get_valued_base_test_variables() euclid = TensorIndexType('Euclidean') euclid.data = [1, 1] i1, i2, i3 = tensor_indices('i1:4', euclid) a, b, c, d = symbols('a b c d', commutative=False) V1 = tensorhead('V1', [euclid] * 2, [[1]] * 2) V1.data = [[a, b], (c, d)] V2 = tensorhead('V2', [euclid] * 2, [[1]] * 2) V2.data = [[a, c], [b, d]] vtp = V1(i1, i2) * V2(-i2, -i1) assert vtp.data == a**2 + b**2 + c**2 + d**2 assert vtp.data != a**2 + 2 * b * c + d**2 Vc = (b * V1(i1, -i1)).data assert Vc.expand() == b * a + b * d
def test_preorder_traversal(): expr = Basic(b21, b3) assert list( preorder_traversal(expr)) == [expr, b21, b2, b1, b1, b3, b2, b1] assert list(preorder_traversal( ('abc', ('d', 'ef')))) == [('abc', ('d', 'ef')), 'abc', ('d', 'ef'), 'd', 'ef'] result = [] pt = preorder_traversal(expr) for i in pt: result.append(i) if i == b2: pt.skip() assert result == [expr, b21, b2, b1, b3, b2] w, x, y, z = symbols('w:z') expr = z + w * (x + y) assert list(preorder_traversal([expr], keys=default_sort_key)) == \ [[w*(x + y) + z], w*(x + y) + z, z, w*(x + y), w, x + y, x, y] assert list(preorder_traversal((x + y)*z, keys=True)) == \ [z*(x + y), z, x + y, x, y]
from diofant.concrete.products import Product from diofant.concrete.summations import Sum from diofant.core.function import Derivative from diofant.core.numbers import Integer, Rational, Float, oo from diofant.core.relational import Rel from diofant.core.symbol import symbols from diofant.functions import sin from diofant.integrals.integrals import Integral from diofant.series.order import Order from diofant.printing.precedence import precedence, PRECEDENCE __all__ = () x, y = symbols("x,y") def test_Add(): assert precedence(x + y) == PRECEDENCE["Add"] assert precedence(x * y + 1) == PRECEDENCE["Add"] def test_Function(): assert precedence(sin(x)) == PRECEDENCE["Atom"] assert precedence(Derivative(x, y)) == PRECEDENCE["Atom"] def test_Integral(): assert precedence(Integral(x, y)) == PRECEDENCE["Atom"]
def test_sorted_args(): x = symbols('x') assert b21._sorted_args == b21.args pytest.raises(AttributeError, lambda: x._sorted_args)
from diofant.concrete.products import Product from diofant.concrete.summations import Sum from diofant.core.function import Derivative from diofant.core.numbers import Float, Integer, Rational, oo from diofant.core.relational import Rel from diofant.core.symbol import symbols from diofant.functions import sin from diofant.integrals.integrals import Integral from diofant.printing.precedence import PRECEDENCE, precedence from diofant.series.order import Order __all__ = () x, y = symbols("x,y") def test_Add(): assert precedence(x + y) == PRECEDENCE["Add"] assert precedence(x*y + 1) == PRECEDENCE["Add"] def test_Function(): assert precedence(sin(x)) == PRECEDENCE["Func"] def test_Derivative(): assert precedence(Derivative(x, y)) == PRECEDENCE["Atom"] def test_Integral():
def rubik(n): """Return permutations for an nxn Rubik's cube. Permutations returned are for rotation of each of the slice from the face up to the last face for each of the 3 sides (in this order): front, right and bottom. Hence, the first n - 1 permutations are for the slices from the front. """ if n < 2: raise ValueError('dimension of cube must be > 1') # 1-based reference to rows and columns in Matrix def getr(f, i): return faces[f].col(n - i) def getl(f, i): return faces[f].col(i - 1) def getu(f, i): return faces[f].row(i - 1) def getd(f, i): return faces[f].row(n - i) def setr(f, i, s): faces[f][:, n - i] = Matrix(n, 1, s) def setl(f, i, s): faces[f][:, i - 1] = Matrix(n, 1, s) def setu(f, i, s): faces[f][i - 1, :] = Matrix(1, n, s) def setd(f, i, s): faces[f][n - i, :] = Matrix(1, n, s) # motion of a single face def cw(F, r=1): for _ in range(r): face = faces[F] rv = [] for c in range(n): for r in range(n - 1, -1, -1): rv.append(face[r, c]) faces[F] = Matrix(n, n, rv) def ccw(F): cw(F, 3) # motion of plane i from the F side; # fcw(0) moves the F face, fcw(1) moves the plane # just behind the front face, etc... def fcw(i, r=1): for _ in range(r): if i == 0: cw(F) i += 1 temp = getr(L, i) setr(L, i, list((getu(D, i)))) setu(D, i, list(reversed(getl(R, i)))) setl(R, i, list((getd(U, i)))) setd(U, i, list(reversed(temp))) i -= 1 def fccw(i): fcw(i, 3) # motion of the entire cube from the F side def FCW(r=1): for _ in range(r): cw(F) ccw(B) cw(U) t = faces[U] cw(L) faces[U] = faces[L] cw(D) faces[L] = faces[D] cw(R) faces[D] = faces[R] faces[R] = t def FCCW(): FCW(3) # motion of the entire cube from the U side def UCW(r=1): for _ in range(r): cw(U) ccw(D) t = faces[F] faces[F] = faces[R] faces[R] = faces[B] faces[B] = faces[L] faces[L] = t def UCCW(): UCW(3) # defining the permutations for the cube U, F, R, B, L, D = names = symbols('U, F, R, B, L, D') # the faces are represented by nxn matrices faces = {} count = 0 for fi in range(6): f = [] for a in range(n**2): f.append(count) count += 1 faces[names[fi]] = Matrix(n, n, f) # this will either return the value of the current permutation # (show != 1) or else append the permutation to the group, g def perm(show=0): # add perm to the list of perms p = [] for f in names: p.extend(faces[f]) if show: return p g.append(Permutation(p)) g = [] # container for the group's permutations I = list(range(6 * n**2)) # the identity permutation used for checking # define permutations corresponding to cw rotations of the planes # up TO the last plane from that direction; by not including the # last plane, the orientation of the cube is maintained. # F slices for i in range(n - 1): fcw(i) perm() fccw(i) # restore assert perm(1) == I # R slices # bring R to front UCW() for i in range(n - 1): fcw(i) # put it back in place UCCW() # record perm() # restore # bring face to front UCW() fccw(i) # restore UCCW() assert perm(1) == I # D slices # bring up bottom FCW() UCCW() FCCW() for i in range(n - 1): # turn strip fcw(i) # put bottom back on the bottom FCW() UCW() FCCW() # record perm() # restore # bring up bottom FCW() UCCW() FCCW() # turn strip fccw(i) # put bottom back on the bottom FCW() UCW() FCCW() assert perm(1) == I return g
def roots_quintic(f): """ Calulate exact roots of a solvable quintic """ result = [] coeff_5, coeff_4, p, q, r, s = f.all_coeffs() # Eqn must be of the form x^5 + px^3 + qx^2 + rx + s if coeff_4: return result if coeff_5 != 1: l = [p/coeff_5, q/coeff_5, r/coeff_5, s/coeff_5] if not all(coeff.is_Rational for coeff in l): return result f = Poly(f/coeff_5) quintic = PolyQuintic(f) # Eqn standardized. Algo for solving starts here if not f.is_irreducible: return result f20 = quintic.f20 # Check if f20 has linear factors over domain Z if f20.is_irreducible: return result # Now, we know that f is solvable for _factor in f20.factor_list()[1]: if _factor[0].is_linear: theta = _factor[0].root(0) break d = discriminant(f) delta = sqrt(d) # zeta = a fifth root of unity zeta1, zeta2, zeta3, zeta4 = quintic.zeta T = quintic.T(theta, d) tol = Float(1e-10) alpha = T[1] + T[2]*delta alpha_bar = T[1] - T[2]*delta beta = T[3] + T[4]*delta beta_bar = T[3] - T[4]*delta disc = alpha**2 - 4*beta disc_bar = alpha_bar**2 - 4*beta_bar l0 = quintic.l0(theta) l1 = _quintic_simplify((-alpha + sqrt(disc)) / Integer(2)) l4 = _quintic_simplify((-alpha - sqrt(disc)) / Integer(2)) l2 = _quintic_simplify((-alpha_bar + sqrt(disc_bar)) / Integer(2)) l3 = _quintic_simplify((-alpha_bar - sqrt(disc_bar)) / Integer(2)) order = quintic.order(theta, d) test = (order*delta.n()) - ( (l1.n() - l4.n())*(l2.n() - l3.n()) ) # Comparing floats if not comp(test, 0, tol): l2, l3 = l3, l2 # Now we have correct order of l's R1 = l0 + l1*zeta1 + l2*zeta2 + l3*zeta3 + l4*zeta4 R2 = l0 + l3*zeta1 + l1*zeta2 + l4*zeta3 + l2*zeta4 R3 = l0 + l2*zeta1 + l4*zeta2 + l1*zeta3 + l3*zeta4 R4 = l0 + l4*zeta1 + l3*zeta2 + l2*zeta3 + l1*zeta4 Res = [None, [None]*5, [None]*5, [None]*5, [None]*5] Res_n = [None, [None]*5, [None]*5, [None]*5, [None]*5] sol = Symbol('sol') # Simplifying improves performace a lot for exact expressions R1 = _quintic_simplify(R1) R2 = _quintic_simplify(R2) R3 = _quintic_simplify(R3) R4 = _quintic_simplify(R4) # Solve imported here. Causing problems if imported as 'solve' # and hence the changed name from diofant.solvers.solvers import solve as _solve a, b = symbols('a b', cls=Dummy) _sol = _solve( sol**5 - a - I*b, sol) for i in range(5): _sol[i] = factor(_sol[i]) R1 = R1.as_real_imag() R2 = R2.as_real_imag() R3 = R3.as_real_imag() R4 = R4.as_real_imag() for i, root in enumerate(_sol): Res[1][i] = _quintic_simplify(root.subs({ a: R1[0], b: R1[1] })) Res[2][i] = _quintic_simplify(root.subs({ a: R2[0], b: R2[1] })) Res[3][i] = _quintic_simplify(root.subs({ a: R3[0], b: R3[1] })) Res[4][i] = _quintic_simplify(root.subs({ a: R4[0], b: R4[1] })) for i in range(1, 5): for j in range(5): Res_n[i][j] = Res[i][j].n() Res[i][j] = _quintic_simplify(Res[i][j]) r1 = Res[1][0] r1_n = Res_n[1][0] for i in range(5): if comp(im(r1_n*Res_n[4][i]), 0, tol): r4 = Res[4][i] break u, v = quintic.uv(theta, d) sqrt5 = math.sqrt(5) # Now we have various Res values. Each will be a list of five # values. We have to pick one r value from those five for each Res u, v = quintic.uv(theta, d) testplus = (u + v*delta*sqrt(5)).n() testminus = (u - v*delta*sqrt(5)).n() # Evaluated numbers suffixed with _n # We will use evaluated numbers for calculation. Much faster. r4_n = r4.n() r2 = r3 = None for i in range(5): r2temp_n = Res_n[2][i] for j in range(5): # Again storing away the exact number and using # evaluated numbers in computations r3temp_n = Res_n[3][j] if (comp(r1_n*r2temp_n**2 + r4_n*r3temp_n**2 - testplus, 0, tol) and comp(r3temp_n*r1_n**2 + r2temp_n*r4_n**2 - testminus, 0, tol)): r2 = Res[2][i] r3 = Res[3][j] break if r2: break # Now, we have r's so we can get roots x1 = (r1 + r2 + r3 + r4)/5 x2 = (r1*zeta4 + r2*zeta3 + r3*zeta2 + r4*zeta1)/5 x3 = (r1*zeta3 + r2*zeta1 + r3*zeta4 + r4*zeta2)/5 x4 = (r1*zeta2 + r2*zeta4 + r3*zeta1 + r4*zeta3)/5 x5 = (r1*zeta1 + r2*zeta2 + r3*zeta3 + r4*zeta4)/5 result = [x1, x2, x3, x4, x5] # Now check if solutions are distinct saw = set() for r in result: r = r.n(2) if r in saw: # Roots were identical. Abort, return [] # and fall back to usual solve return [] saw.add(r) return result
from diofant.vector.coordsysrect import CoordSysCartesian from diofant.vector.deloperator import Del from diofant.vector.functions import (curl, divergence, gradient, is_conservative, is_solenoidal, scalar_potential, scalar_potential_difference) from diofant.vector.vector import Vector __all__ = () C = CoordSysCartesian('C') i, j, k = C.base_vectors() x, y, z = C.base_scalars() delop = C.delop a, b, c, q = symbols('a b c q') def test_del_operator(): pytest.raises(TypeError, lambda: Del(Integer(1))) # Tests for curl assert (delop ^ Vector.zero == (Derivative(0, C.y) - Derivative(0, C.z))*C.i + (-Derivative(0, C.x) + Derivative(0, C.z))*C.j + (Derivative(0, C.x) - Derivative(0, C.y))*C.k) assert ((delop ^ Vector.zero).doit() == Vector.zero == curl(Vector.zero, C)) assert delop.cross(Vector.zero) == delop ^ Vector.zero assert (delop ^ i).doit() == Vector.zero assert delop.cross(2*y**2*j, doit=True) == Vector.zero
from diofant.vector.vector import Vector from diofant.vector.coordsysrect import CoordSysCartesian from diofant.simplify import simplify from diofant.core.symbol import symbols from diofant.core.numbers import Integer from diofant import sin, cos from diofant.vector.functions import (curl, divergence, gradient, is_conservative, is_solenoidal, scalar_potential, scalar_potential_difference) C = CoordSysCartesian('C') i, j, k = C.base_vectors() x, y, z = C.base_scalars() delop = C.delop a, b, c, q = symbols('a b c q') def test_del_operator(): # Tests for curl assert (delop ^ Vector.zero == (Derivative(0, C.y) - Derivative(0, C.z)) * C.i + (-Derivative(0, C.x) + Derivative(0, C.z)) * C.j + (Derivative(0, C.x) - Derivative(0, C.y)) * C.k) assert ((delop ^ Vector.zero).doit() == Vector.zero == curl( Vector.zero, C)) assert delop.cross(Vector.zero) == delop ^ Vector.zero assert (delop ^ i).doit() == Vector.zero assert delop.cross(2 * y**2 * j, doit=True) == Vector.zero assert delop.cross(2 * y**2 * j) == delop ^ 2 * y**2 * j
def _get_valued_base_test_variables(): minkowski = Matrix(( (1, 0, 0, 0), (0, -1, 0, 0), (0, 0, -1, 0), (0, 0, 0, -1), )) Lorentz = TensorIndexType('Lorentz', dim=4) Lorentz.data = minkowski i0, i1, i2, i3, i4 = tensor_indices('i0:5', Lorentz) E, px, py, pz = symbols('E px py pz') A = tensorhead('A', [Lorentz], [[1]]) A.data = [E, px, py, pz] B = tensorhead('B', [Lorentz], [[1]], 'Gcomm') B.data = range(4) AB = tensorhead("AB", [Lorentz] * 2, [[1]] * 2) AB.data = minkowski ba_matrix = Matrix(( (1, 2, 3, 4), (5, 6, 7, 8), (9, 0, -1, -2), (-3, -4, -5, -6), )) BA = tensorhead("BA", [Lorentz] * 2, [[1]] * 2) BA.data = ba_matrix BA(i0, i1) * A(-i0) * B(-i1) # Let's test the diagonal metric, with inverted Minkowski metric: LorentzD = TensorIndexType('LorentzD') LorentzD.data = [-1, 1, 1, 1] mu0, mu1, mu2 = tensor_indices('mu0:3', LorentzD) C = tensorhead('C', [LorentzD], [[1]]) C.data = [E, px, py, pz] # ### non-diagonal metric ### ndm_matrix = ( ( 1, 1, 0, ), (1, 0, 1), ( 0, 1, 0, ), ) ndm = TensorIndexType("ndm") ndm.data = ndm_matrix n0, n1, n2 = tensor_indices('n0:3', ndm) NA = tensorhead('NA', [ndm], [[1]]) NA.data = range(10, 13) NB = tensorhead('NB', [ndm] * 2, [[1]] * 2) NB.data = [[i + j for j in range(10, 13)] for i in range(10, 13)] NC = tensorhead('NC', [ndm] * 3, [[1]] * 3) NC.data = [[[i + j + k for k in range(4, 7)] for j in range(1, 4)] for i in range(2, 5)] return (A, B, AB, BA, C, Lorentz, E, px, py, pz, LorentzD, mu0, mu1, mu2, ndm, n0, n1, n2, NA, NB, NC, minkowski, ba_matrix, ndm_matrix, i0, i1, i2, i3, i4)