def test_array_as_explicit_call(): assert ZeroArray(3, 2, 4).as_explicit() == ImmutableDenseNDimArray.zeros( 3, 2, 4) assert OneArray(3, 2, 4).as_explicit() == ImmutableDenseNDimArray( [1 for i in range(3 * 2 * 4)]).reshape(3, 2, 4) k = Symbol("k") X = ArraySymbol("X", k, 3, 2) raises(ValueError, lambda: X.as_explicit()) raises(ValueError, lambda: ZeroArray(k, 2, 3).as_explicit()) raises(ValueError, lambda: OneArray(2, k, 2).as_explicit()) A = ArraySymbol("A", 3, 3) B = ArraySymbol("B", 3, 3) texpr = tensorproduct(A, B) assert isinstance(texpr, ArrayTensorProduct) assert texpr.as_explicit() == tensorproduct(A.as_explicit(), B.as_explicit()) texpr = tensorcontraction(A, (0, 1)) assert isinstance(texpr, ArrayContraction) assert texpr.as_explicit() == A[0, 0] + A[1, 1] + A[2, 2] texpr = tensordiagonal(A, (0, 1)) assert isinstance(texpr, ArrayDiagonal) assert texpr.as_explicit() == ImmutableDenseNDimArray( [A[0, 0], A[1, 1], A[2, 2]]) texpr = permutedims(A, [1, 0]) assert isinstance(texpr, PermuteDims) assert texpr.as_explicit() == permutedims(A.as_explicit(), [1, 0])
def _extract_data(self, replacement_dict): from .array import derive_by_array, tensorcontraction indices, array = self.expr._extract_data(replacement_dict) for variable in self.variables: var_indices, var_array = variable._extract_data(replacement_dict) var_indices = [-i for i in var_indices] coeff_array, var_array = zip( *[i.as_coeff_Mul() for i in var_array]) dim_before = len(array.shape) array = derive_by_array(array, var_array) dim_after = len(array.shape) dim_increase = dim_after - dim_before array = permutedims(array, [i + dim_increase for i in range(dim_before)] + list(range(dim_increase))) array = array.as_mutable() # type: MutableDenseNDimArray varindex = var_indices[0] # type: TensorIndex # Remove coefficients of base vector: coeff_index = [0] + [slice(None) for i in range(len(indices))] for i, coeff in enumerate(coeff_array): coeff_index[0] = i array[tuple(coeff_index)] /= coeff if -varindex in indices: pos = indices.index(-varindex) array = tensorcontraction(array, (0, pos + 1)) indices.pop(pos) else: indices.append(varindex) return indices, array
def test_nested_permutations(): cg = CodegenArrayPermuteDims(CodegenArrayPermuteDims(M, (1, 0)), (1, 0)) assert cg == M times = 3 plist1 = [list(range(6)) for i in range(times)] plist2 = [list(range(6)) for i in range(times)] for i in range(times): random.shuffle(plist1[i]) random.shuffle(plist2[i]) plist1.append([2, 5, 4, 1, 0, 3]) plist2.append([3, 5, 0, 4, 1, 2]) plist1.append([2, 5, 4, 0, 3, 1]) plist2.append([3, 0, 5, 1, 2, 4]) plist1.append([5, 4, 2, 0, 3, 1]) plist2.append([4, 5, 0, 2, 3, 1]) Me = M.subs(k, 3).as_explicit() Ne = N.subs(k, 3).as_explicit() Pe = P.subs(k, 3).as_explicit() cge = tensorproduct(Me, Ne, Pe) for permutation_array1, permutation_array2 in zip(plist1, plist2): p1 = Permutation(permutation_array1) p2 = Permutation(permutation_array2) cg = CodegenArrayPermuteDims( CodegenArrayPermuteDims( CodegenArrayTensorProduct(M, N, P), p1), p2 ) result = CodegenArrayPermuteDims( CodegenArrayTensorProduct(M, N, P), p2*p1 ) assert cg == result # Check that `permutedims` behaves the same way with explicit-component arrays: result1 = permutedims(permutedims(cge, p1), p2) result2 = permutedims(cge, p2*p1) assert result1 == result2
def test_contraction_permutation_mix(): Me = M.subs(k, 3).as_explicit() Ne = N.subs(k, 3).as_explicit() cg1 = CodegenArrayContraction( CodegenArrayPermuteDims(CodegenArrayTensorProduct(M, N), Permutation([0, 2, 1, 3])), (2, 3)) cg2 = CodegenArrayContraction(CodegenArrayTensorProduct(M, N), (1, 3)) assert cg1 == cg2 assert recognize_matrix_expression(cg2) == M * N.T cge1 = tensorcontraction( permutedims(tensorproduct(Me, Ne), Permutation([0, 2, 1, 3])), (2, 3)) cge2 = tensorcontraction(tensorproduct(Me, Ne), (1, 3)) assert cge1 == cge2 cg1 = CodegenArrayPermuteDims(CodegenArrayTensorProduct(M, N), Permutation([0, 1, 3, 2])) cg2 = CodegenArrayTensorProduct( M, CodegenArrayPermuteDims(N, Permutation([1, 0]))) assert cg1 == cg2 assert recognize_matrix_expression(cg1) == CodegenArrayTensorProduct( M, N.T) assert recognize_matrix_expression(cg2) == CodegenArrayTensorProduct( M, N.T) cg1 = CodegenArrayContraction( CodegenArrayPermuteDims(CodegenArrayTensorProduct(M, N, P, Q), Permutation([0, 2, 3, 1, 4, 5, 7, 6])), (1, 2), (3, 5)) cg2 = CodegenArrayContraction( CodegenArrayTensorProduct( M, N, P, CodegenArrayPermuteDims(Q, Permutation([1, 0]))), (1, 5), (2, 3)) assert cg1 == cg2 assert recognize_matrix_expression(cg1) == CodegenArrayTensorProduct( M * P.T * Trace(N), Q.T) assert recognize_matrix_expression(cg2) == CodegenArrayTensorProduct( M * P.T * Trace(N), Q.T) cg1 = CodegenArrayContraction( CodegenArrayPermuteDims(CodegenArrayTensorProduct(M, N, P, Q), Permutation([1, 0, 4, 6, 2, 7, 5, 3])), (0, 1), (2, 6), (3, 7)) cg2 = CodegenArrayPermuteDims( CodegenArrayContraction(CodegenArrayTensorProduct(M, P, Q, N), (0, 1), (2, 3), (4, 7)), [1, 0]) assert cg1 == cg2 cg1 = CodegenArrayContraction( CodegenArrayPermuteDims(CodegenArrayTensorProduct(M, N, P, Q), Permutation([1, 0, 4, 6, 7, 2, 5, 3])), (0, 1), (2, 6), (3, 7)) cg2 = CodegenArrayPermuteDims( CodegenArrayContraction( CodegenArrayTensorProduct(CodegenArrayPermuteDims(M, [1, 0]), N, P, Q), (0, 1), (3, 6), (4, 5)), Permutation([1, 0])) assert cg1 == cg2
def test_arrayexpr_contraction_permutation_mix(): Me = M.subs(k, 3).as_explicit() Ne = N.subs(k, 3).as_explicit() cg1 = ArrayContraction(PermuteDims(ArrayTensorProduct(M, N), Permutation([0, 2, 1, 3])), (2, 3)) cg2 = ArrayContraction(ArrayTensorProduct(M, N), (1, 3)) assert cg1 == cg2 cge1 = tensorcontraction(permutedims(tensorproduct(Me, Ne), Permutation([0, 2, 1, 3])), (2, 3)) cge2 = tensorcontraction(tensorproduct(Me, Ne), (1, 3)) assert cge1 == cge2 cg1 = PermuteDims(ArrayTensorProduct(M, N), Permutation([0, 1, 3, 2])) cg2 = ArrayTensorProduct(M, PermuteDims(N, Permutation([1, 0]))) assert cg1 == cg2 cg1 = ArrayContraction( PermuteDims( ArrayTensorProduct(M, N, P, Q), Permutation([0, 2, 3, 1, 4, 5, 7, 6])), (1, 2), (3, 5) ) cg2 = ArrayContraction( ArrayTensorProduct(M, N, P, PermuteDims(Q, Permutation([1, 0]))), (1, 5), (2, 3) ) assert cg1 == cg2 cg1 = ArrayContraction( PermuteDims( ArrayTensorProduct(M, N, P, Q), Permutation([1, 0, 4, 6, 2, 7, 5, 3])), (0, 1), (2, 6), (3, 7) ) cg2 = PermuteDims( ArrayContraction( ArrayTensorProduct(M, P, Q, N), (0, 1), (2, 3), (4, 7)), [1, 0] ) assert cg1 == cg2 cg1 = ArrayContraction( PermuteDims( ArrayTensorProduct(M, N, P, Q), Permutation([1, 0, 4, 6, 7, 2, 5, 3])), (0, 1), (2, 6), (3, 7) ) cg2 = PermuteDims( ArrayContraction( ArrayTensorProduct(PermuteDims(M, [1, 0]), N, P, Q), (0, 1), (3, 6), (4, 5) ), Permutation([1, 0]) ) assert cg1 == cg2
def test_array_as_explicit_matrix_symbol(): A = MatrixSymbol("A", 3, 3) B = MatrixSymbol("B", 3, 3) texpr = tensorproduct(A, B) assert isinstance(texpr, ArrayTensorProduct) assert texpr.as_explicit() == tensorproduct(A.as_explicit(), B.as_explicit()) texpr = tensorcontraction(A, (0, 1)) assert isinstance(texpr, ArrayContraction) assert texpr.as_explicit() == A[0, 0] + A[1, 1] + A[2, 2] texpr = tensordiagonal(A, (0, 1)) assert isinstance(texpr, ArrayDiagonal) assert texpr.as_explicit() == ImmutableDenseNDimArray( [A[0, 0], A[1, 1], A[2, 2]]) texpr = permutedims(A, [1, 0]) assert isinstance(texpr, PermuteDims) assert texpr.as_explicit() == permutedims(A.as_explicit(), [1, 0])
def chain_config_change(): t = sympy.Array(tensor.tensor()) difflist = _difference_list(newconfig, tensor.config) for i, action in enumerate(difflist): if action == 0: continue else: t = simplify( tensorcontraction(tensorproduct(met_dict[action], t), (1, 2 + i))) # reshuffle the indices dest = list(range(len(t.shape))) dest.remove(0) dest.insert(i, 0) t = sympy.permutedims(t, dest) return t
def test_array_symbol_and_element(): A = ArraySymbol("A", 2) A0 = ArrayElement(A, (0,)) A1 = ArrayElement(A, (1,)) assert A.as_explicit() == ImmutableDenseNDimArray([A0, A1]) A2 = tensorproduct(A, A) assert A2.shape == (2, 2) # TODO: not yet supported: # assert A2.as_explicit() == Array([[A[0]*A[0], A[1]*A[0]], [A[0]*A[1], A[1]*A[1]]]) A3 = tensorcontraction(A2, (0, 1)) assert A3.shape == () # TODO: not yet supported: # assert A3.as_explicit() == Array([]) A = ArraySymbol("A", 2, 3, 4) Ae = A.as_explicit() assert Ae == ImmutableDenseNDimArray( [[[ArrayElement(A, (i, j, k)) for k in range(4)] for j in range(3)] for i in range(2)]) p = permutedims(A, Permutation(0, 2, 1)) assert isinstance(p, PermuteDims)
def lorentz_transform(self, transformation_matrix): """ Performs a Lorentz transform on the tensor. Parameters ---------- transformation_matrix : ~sympy.tensor.array.dense_ndim_array.ImmutableDenseNDimArray or list Sympy Array or multi-dimensional list containing Sympy Expressions Returns ------- ~einsteinpy.symbolic.tensor.BaseRelativityTensor lorentz transformed tensor(or vector) """ tm = sympy.Array(transformation_matrix) t = self.tensor() for i in range(self.order): if self.config[i] == "u": t = simplify( tensorcontraction(tensorproduct(tm, t), (1, 2 + i))) else: t = simplify( tensorcontraction(tensorproduct(tm, t), (0, 2 + i))) dest = list(range(len(t.shape))) dest.remove(0) dest.insert(i, 0) t = sympy.permutedims(t, dest) return BaseRelativityTensor( t, syms=self.syms, config=self.config, parent_metric=None, variables=self.variables, functions=self.functions, name=_change_name(self.name, context="__lt"), )
def diff(a, b): D = derive_by_array(a, b) dims = tuple([x + len(b.shape) for x in range(0, len(a.shape))]) + \ tuple(range(0, len(b.shape))) return permutedims(D, dims)
sp2grad = sp2.grad sph_map = [1, theta, phi] # Coordinate map for sphere of r = 1 print(r'(\theta,\phi)\rightarrow (r,\theta,\phi) = ', latex(sph_map)) (etheta, ephi) = sp2.mv() print(r'e_\theta | e_\theta = ', etheta | etheta) print(r'e_\phi | e_\phi = ', ephi | ephi) print('g =', sp2.g) print(r'\text{g\_inv = }', latex(sp2.g_inv)) #print(r'\text{signature = ', latex(sp2.signature())) Cf1 = sp2.Christoffel_symbols(mode=1) Cf1 = permutedims(Array(Cf1), (2, 0, 1)) print(r'\text{Christoffel symbols of the first kind: }') print(r'\Gamma_{1, \alpha, \beta} = ', latex(Cf1[0, :, :]), r'\quad', r'\Gamma_{2, \alpha, \beta} = ', latex(Cf1[1, :, :])) Cf2 = sp2.Christoffel_symbols(mode=2) Cf2 = permutedims(Array(Cf2), (2, 0, 1)) print(r'\text{Christoffel symbols of the second kind: }') print(r'\Gamma^{1}_{\phantom{1,}\alpha, \beta} = ', latex(Cf2[0, :, :]), r'\quad', r'\Gamma^{2}_{\phantom{2,}\alpha, \beta} = ', latex(Cf2[1, :, :])) F = sp2.mv('F', 'vector', f=True) #scalar function) f = sp2.mv('f', 'scalar', f=True) #vector function) print('grad = ', sp2grad) print('grad f =', sp2.grad * f)
def as_explicit(self): return permutedims(self.expr.as_explicit(), self.permutation)