def asymmetric(in_arr): """ Creates the asymmetric form of input tensor. Input: Arraypy or TensorArray with equal axes (array shapes). Output: asymmetric array. Output type - Arraypy or TensorArray, depends of input Examples ======== >>> from tensor_analysis.arraypy import list2arraypy >>> from tensor_analysis.tensor_methods import asymmetric >>> a = list2arraypy(list(range(9)), (3,3)) >>> b = asymmetric(a) >>> print (b) 0 -1 -2 1 0 -1 2 1 0 """ if not isinstance(in_arr, Arraypy): raise TypeError('Input must be Arraypy or TensorArray type') flag = 0 for j in range(in_arr.rank): if (in_arr.shape[0] != in_arr.shape[j]): raise ValueError('Different size of arrays axes') # forming list of tuples for Arraypy constructor of type a = Arraypy( [(a, # b), (c, d), ... , (y, z)] ) arg = [(in_arr.start_index[i], in_arr.end_index[i]) for i in range(in_arr.rank)] # if in_arr TensorArray, then res_arr will be TensorArray, else it will be # Arraypy if isinstance(in_arr, TensorArray): res_arr = TensorArray(Arraypy(arg), in_arr.ind_char) else: res_arr = Arraypy(arg) signs = [0 for i in range(factorial(in_arr.rank))] temp_i = 0 for p in permutations(range(in_arr.rank)): signs[temp_i] = perm_parity(list(p)) temp_i += 1 index = [in_arr.start_index[i] for i in range(in_arr.rank)] for i in range(len(in_arr)): perm = list(permutations(index)) perm_number = 0 for temp_index in perm: res_arr[tuple(index)] += signs[perm_number] * \ in_arr[tuple(temp_index)] perm_number += 1 res_arr[tuple(index)] /= factorial(in_arr.rank) res_arr[tuple(index)] = simplify(res_arr[tuple(index)]) index = in_arr.next_index(index) return res_arr
def test_christoffel_2_gtnsr(): x1, x2 = symbols('x1, x2') var_list = [x1, x2] g = Arraypy([2, 2, 1]).to_tensor((-1, -1)) g[1, 1] = cos(x2)**2 g[1, 2] = 0 g[2, 1] = 0 g[2, 2] = 1 res_arr = Arraypy([3, 2, 1]) res_arr[1, 1, 1] = 0 res_arr[1, 1, 2] = sin(x2) * cos(x2) res_arr[1, 2, 1] = -sin(x2) / cos(x2) res_arr[2, 1, 1] = -sin(x2) / cos(x2) res_arr[1, 2, 2] = 0 res_arr[2, 2, 1] = 0 res_arr[2, 1, 2] = 0 res_arr[2, 2, 2] = 0 res_ten = res_arr.to_tensor((1, -1, -1)) print('test_christoffel_2_gtnsr_t <=== actual test code') assert christoffel_2(g, var_list) == res_ten assert isinstance(christoffel_2(g, var_list), TensorArray) assert christoffel_2(g, var_list).type_pq == (1, 2) assert christoffel_2(g, var_list) == res_ten assert isinstance(christoffel_2(g, var_list, 't'), TensorArray) assert christoffel_2(g, var_list).type_pq == (1, 2) print('test_christoffel_2_gtnsr_a <=== actual test code') assert christoffel_2(g, var_list, 'a') == res_arr assert isinstance(christoffel_2(g, var_list, 'a'), Arraypy)
def test_christoffel_1_gm(): x1, x2 = symbols('x1, x2') var_list = [x1, x2] g = Matrix([[cos(x2)**2, 0], [0, 1]]) res_arr = Arraypy([3, 2, 0]) res_arr[0, 0, 0] = 0 res_arr[0, 0, 1] = sin(x2) * cos(x2) res_arr[0, 1, 0] = -sin(x2) * cos(x2) res_arr[1, 0, 0] = -sin(x2) * cos(x2) res_arr[0, 1, 1] = 0 res_arr[1, 1, 0] = 0 res_arr[1, 0, 1] = 0 res_arr[1, 1, 1] = 0 res_ten = res_arr.to_tensor((-1, -1, -1)) print('test_christoffel_1_gm_t <=== actual test code') assert christoffel_1(g, var_list) == res_ten assert isinstance(christoffel_1(g, var_list), TensorArray) assert christoffel_1(g, var_list).type_pq == (0, 3) assert christoffel_1(g, var_list, 't') == res_ten assert isinstance(christoffel_1(g, var_list, 't'), TensorArray) assert christoffel_1(g, var_list).type_pq == (0, 3) print('test_christoffel_1_gm_a <=== actual test code') assert christoffel_1(g, var_list, 'a') == res_arr assert isinstance(christoffel_1(g, var_list, 'a'), Arraypy)
def test_sparse(): sparse_array = Arraypy((2, 2), 'sparse') assert len(sparse_array) == 2 * 2 # dictionary where all data is assert len(sparse_array._output) == 0 # it's empty, even thought Arraypy knows that 'empty' data is zero if sys.version_info[0] >= 3: for i in sparse_array: assert i == 0 else: idx = sparse_array.start_index for i in range(len(sparse_array.start_index)): assert sparse_array[idx] == 0 idx = sparse_array.next_index(idx) sparse_array[0, 0] = 123 assert len(sparse_array._output) == 1 assert sparse_array[0, 0] == 123 # when element in sparse array become zero it will disappear from # dictionary sparse_array[0, 0] = 0 assert len(sparse_array._output) == 0 assert sparse_array[0, 0] == 0
def test_grad_gm_vl(): x1, x2, x3 = symbols('x1 x2 x3') f = x1**2 * x2 + sin(x2 * x3 - x2) var1 = [x1, x2, x3] g = Matrix([[2, 1, 0], [1, 3, 0], [0, 0, 1]]) k0 = Arraypy([1, 3, 1]).to_tensor(1) k0[1] = x1 k0[2] = x2 k0[3] = x3 res_ar = Arraypy([1, 3, 0]) res_ar[0] = -x1**2 / 5 + 6 * x1 * x2 / 5 - (x3 - 1) * cos(x2 * x3 - x2) / 5 res_ar[1] = 2 * x1**2 / 5 - 2 * x1 * x2 / \ 5 + cos(x2 * x3 - x2) * 2 * (x3 - 1) / 5 res_ar[2] = x2 * cos(x2 * x3 - x2) res_ten = res_ar.to_tensor(1) assert str( grad( f, k0, g, 'l')) == '[-x1**2/5 + 6*x1*x2/5 - (x3 - 1)*cos(x2*x3 - x2)/5, 2*x1**2/5 - 2*x1*x2/5 + 2*(x3 - 1)*cos(x2*x3 - x2)/5, x2*cos(x2*x3 - x2)]' assert isinstance(grad(f, k0, g, 'l'), list) assert grad(f, k0, g, 'a') == res_ar assert isinstance(grad(f, k0, g, 'a'), Arraypy) assert grad(f, k0, g, 't') == res_ten assert isinstance(grad(f, k0, g, 't'), TensorArray) assert grad(f, k0, g, 't').type_pq == (1, 0)
def test_delta(): x1, x2 = symbols('x1, x2') var_list = [x1, x2] T = Arraypy([2, 2, 0]).to_tensor((1, -1)) T[0, 0] = x2 T[0, 1] = -x2 T[1, 0] = -x1 T[1, 1] = x1 g = Arraypy((2, 2)).to_tensor((-1, -1)) g[0, 0] = cos(x2)**2 g[0, 1] = 0 g[1, 0] = 0 g[1, 1] = 1 ch_2 = Arraypy([3, 2, 0]) ch_2[0, 0, 0] = 0 ch_2[0, 0, 1] = sin(x2) * cos(x2) ch_2[0, 1, 1] = 0 ch_2[1, 1, 1] = 0 ch_2[1, 0, 1] = 0 ch_2[1, 1, 0] = 0 ch_2[1, 0, 0] = -sin(x2) * cos(x2) ch_2[0, 1, 0] = -sin(x2) * cos(x2) res_ten = Arraypy((2)).to_tensor((-1)) res_ten[0] = x1 * sin(x2) * cos(x2) + 1 res_ten[1] = 0 assert delta(T, g, ch_2, var_list) == res_ten assert isinstance(delta(T, g, ch_2, var_list), TensorArray)
def test_covar_der_xy(): x1, x2 = symbols('x1, x2') var_list = [x1, x2] g = Matrix([[cos(x2)**2, 0], [0, 1]]) X = [x1 * x2**3, x1 - cos(x2)] Y = [1, 2] res_arr = Arraypy([1, 2, 0]) res_arr[0] = -2 * x1 * x2**3 * \ sin(x2) / cos(x2) + 6 * x1 * x2**2 + \ x2**3 - (x1 - cos(x2)) * sin(x2) / cos(x2) res_arr[1] = x1 * x2**3 * sin(x2) * cos(x2) + 2 * sin(x2) + 1 res_ten = res_arr.to_tensor(1) print('test_covar_der_xy_t <=== actual test code') assert covar_der_xy(X, Y, g, var_list) == res_ten assert isinstance(covar_der_xy(X, Y, g, var_list), TensorArray) assert covar_der_xy(X, Y, g, var_list).type_pq == (1, 0) assert covar_der_xy(X, Y, g, var_list, 't') == res_ten assert isinstance(covar_der_xy(X, Y, g, var_list, 't'), TensorArray) assert covar_der_xy(X, Y, g, var_list, 't').type_pq == (1, 0) print('test_covar_der_xy_a <=== actual test code') assert covar_der_xy(X, Y, g, var_list, 'a') == res_arr assert isinstance(covar_der_xy(X, Y, g, var_list, 'a'), Arraypy)
def test_nabla(): x1, x2 = symbols('x1, x2') var_list = [x1, x2] T = Arraypy([2, 2, 0]).to_tensor((1, -1)) T[0, 0] = x2 T[0, 1] = -x2 T[1, 0] = -x1 T[1, 1] = x1 ch_2 = Arraypy([3, 2, 0]) ch_2[0, 0, 0] = 0 ch_2[0, 0, 1] = sin(x2) * cos(x2) ch_2[0, 1, 1] = 0 ch_2[1, 1, 1] = 0 ch_2[1, 0, 1] = 0 ch_2[1, 1, 0] = 0 ch_2[1, 0, 0] = -sin(x2) * cos(x2) ch_2[0, 1, 0] = -sin(x2) * cos(x2) res_ten = Arraypy([3, 2, 0]).to_tensor((1, -1, -1)) res_ten[0, 0, 0] = -x1 * sin(x2) * cos(x2) + x2 * sin(x2) * cos(x2) res_ten[0, 0, 1] = 0 res_ten[0, 1, 1] = x2 * sin(x2) * cos(x2) - 1 res_ten[1, 1, 1] = 0 res_ten[1, 0, 1] = -x1 * sin(x2) * cos(x2) - 1 res_ten[1, 1, 0] = -x1 * sin(x2) * cos(x2) + x2 * sin(x2) * cos(x2) res_ten[1, 0, 0] = -x1 * sin(x2) * cos(x2) - x2 * sin(x2) * cos(x2) res_ten[0, 1, 0] = x1 * sin(x2) * cos(x2) + x2 * sin(x2) * cos(x2) assert nabla(T, ch_2, var_list) == res_ten assert isinstance(nabla(T, ch_2, var_list), TensorArray)
def test_diverg_var_x_list(): x1, x2, x3 = symbols('x1 x2 x3') X = [x1 * x2**3, x2 - cos(x3), x3**3 - x1] var = [x1, x2, x3] g = Matrix([[2, 1, 0], [1, 3, 0], [0, 0, 1]]) ten = Arraypy([2, 3, 0]).to_tensor((-1, -1)) ten[0, 0] = 2 ten[0, 1] = 1 ten[0, 2] = 0 ten[1, 0] = 1 ten[1, 1] = 3 ten[1, 2] = 0 ten[2, 0] = 0 ten[2, 1] = 0 ten[2, 2] = 1 ten1 = Arraypy([2, 3, 1]).to_tensor((-1, -1)) ten1[1, 1] = 2 ten1[1, 2] = 1 ten1[1, 3] = 0 ten1[2, 1] = 1 ten1[2, 2] = 3 ten1[2, 3] = 0 ten1[3, 1] = 0 ten1[3, 2] = 0 ten1[3, 3] = 1 assert diverg(X, var) == x2**3 + 3 * x3**2 + 1 assert diverg(X, var, g) == x2**3 + 3 * x3**2 + 1 assert diverg(X, var, ten) == x2**3 + 3 * x3**2 + 1 assert diverg(X, var, ten1) == x2**3 + 3 * x3**2 + 1
def test_curl(): x1, x2, x3 = symbols('x1 x2 x3') X = [x1 * x2**3, x2 - cos(x3), x3**3 - x1] arg = [x1, x2, x3] j = Arraypy(3) k0 = TensorArray(j, (1)) k0[0] = x1 * x2**3 k0[1] = x2 - cos(x3) k0[2] = x3**3 - x1 k1 = Arraypy([1, 3, 1]).to_tensor(1) k1[1] = x1 * x2**3 k1[2] = x2 - cos(x3) k1[3] = x3**3 - x1 v0 = TensorArray(j, (1)) v0[0] = x1 v0[1] = x2 v0[2] = x3 v1 = Arraypy([1, 3, 1]).to_tensor(1) v1[1] = x1 v1[2] = x2 v1[3] = x3 s0 = TensorArray(j, (1)) s0[0] = -sin(x3) s0[1] = 1 s0[2] = -3 * x1 * x2**2 s1 = Arraypy([1, 3, 1]).to_tensor(1) s1[1] = -sin(x3) s1[2] = 1 s1[3] = -3 * x1 * x2**2 assert curl(X, arg) == [-sin(x3), 1, -3 * x1 * x2**2] assert isinstance(curl(X, arg), list) assert curl(X, arg, 'a') == list2arraypy([-sin(x3), 1, -3 * x1 * x2**2]) assert isinstance(curl(X, arg, 'a'), Arraypy) assert curl(X, arg, 't') == s0 assert isinstance(curl(X, arg, 't'), TensorArray) assert curl(X, arg, 't').type_pq == (1, 0) assert curl(k0, arg) == s0 assert isinstance(curl(k0, arg), TensorArray) assert curl(X, arg, 't').type_pq == (1, 0) assert curl(k0, arg, 'a') == list2arraypy([-sin(x3), 1, -3 * x1 * x2**2]) assert isinstance(curl(k0, arg, 'a'), Arraypy) assert curl(k0, arg, 't') == s0 assert isinstance(curl(k0, arg, 't'), TensorArray) assert curl(X, arg, 't').type_pq == (1, 0) assert curl(k1, v1, 't') == s1 assert isinstance(curl(k1, v1, 't'), TensorArray) assert curl(k1, v1, 't').type_pq == (1, 0)
def test_df_var_tnsr1(): x1, x2, x3 = symbols('x1 x2 x3') f = x1**2 * x2 + sin(x2 * x3 - x2) var_tnsr1 = Arraypy([1, 3, 1]).to_tensor(1) var_tnsr1[1] = x1 var_tnsr1[2] = x2 var_tnsr1[3] = x3 res_ar1 = Arraypy([1, 3, 1]) res_ar1[1] = 2 * x1 * x2 res_ar1[2] = x1**2 + (x3 - 1) * cos(x2 * x3 - x2) res_ar1[3] = x2 * cos(x2 * x3 - x2) res_ten1 = res_ar1.to_tensor(-1) assert df(f, var_tnsr1) == [ 2 * x1 * x2, x1**2 + (x3 - 1) * cos(x2 * x3 - x2), x2 * cos(x2 * x3 - x2)] assert isinstance(df(f, var_tnsr1), list) assert df(f, var_tnsr1, 'l') == [ 2 * x1 * x2, x1**2 + (x3 - 1) * cos(x2 * x3 - x2), x2 * cos(x2 * x3 - x2)] assert isinstance(df(f, var_tnsr1, 'l'), list) assert df(f, var_tnsr1, 'a') == res_ar1 assert isinstance(df(f, var_tnsr1, 'a'), Arraypy) assert df(f, var_tnsr1, 't') == res_ten1 assert isinstance(df(f, var_tnsr1, 't'), TensorArray) assert df(f, var_tnsr1, 't').type_pq == (0, 1)
def test_covar_der(): x1, x2 = symbols('x1, x2') var_list = [x1, x2] g = Matrix([[cos(x2)**2, 0], [0, 1]]) X = [x1 * x2**3, x1 - cos(x2)] res_arr = Arraypy([2, 2, 0]) res_arr[0, 0] = x2**3 - (x1 - cos(x2)) * sin(x2) / cos(x2) res_arr[0, 1] = x1 * x2**3 * sin(x2) * cos(x2) + 1 res_arr[1, 0] = -x1 * x2**3 * sin(x2) / cos(x2) + 3 * x1 * x2**2 res_arr[1, 1] = sin(x2) res_ten = res_arr.to_tensor((1, -1)) print('test_covar_der_t <=== actual test code') assert covar_der(X, g, var_list) == res_ten assert isinstance(covar_der(X, g, var_list), TensorArray) assert covar_der(X, g, var_list).type_pq == (1, 1) assert covar_der(X, g, var_list, 't') == res_ten assert isinstance(covar_der(X, g, var_list, 't'), TensorArray) assert covar_der(X, g, var_list, 't').type_pq == (1, 1) print('test_covar_der_a <=== actual test code') assert covar_der(X, g, var_list, 'a') == res_arr assert isinstance(covar_der(X, g, var_list, 'a'), Arraypy)
def test_reshape(): array = Arraypy(50) assert array.shape == (50,) assert array.rank == 1 array = array.reshape((5, 5, 2)) assert array.shape == (5, 5, 2) assert array.rank == 3 assert len(array) == 50
def wedgearray2tensor(B): """Function takes the Wedge_array(or dictionary) and creates a full skew array. Examples: ========= >>> from sympy import symbols >>> from tensor_analysis.arraypy import Arraypy, TensorArray >>> from tensor_analysis.tensor_fields import tensor2wedgearray, \ wedgearray2tensor >>> x1, x2, x3 = symbols('x1 x2 x3') >>> y2 = TensorArray(Arraypy((3, 3)), (-1, -1)) >>> y2[0, 1] = x3 >>> y2[0, 2] = -x2 >>> y2[1, 0] = -x3 >>> y2[1, 2] = x1 >>> y2[2, 0] = x2 >>> y2[2, 1] = -x1 >>> A=tensor2wedgearray(y2) >>> wdg=wedgearray2tensor(A) >>> print(wdg) 0 x3 -x2 -x3 0 x1 x2 -x1 0 """ if isinstance(B, Wedge_array): B = B._output else: raise TypeError('Input tensor must be of Wedge_array or dict type') list_indices = sorted(B.keys()) # (min_index, max_index) - the range of indexes max_index = max(max(list_indices)) # for the start index of arraypy min_index = min(min(list_indices)) # shape output array rank = len(list_indices[0]) # Creating the output array arr = Arraypy([rank, max_index - min_index + 1, min_index]) valence_list = [(-1) for k in range(max_index - min_index)] tensor = arr.to_tensor(valence_list) for key, value in B.items(): tensor[key] = value # multiply by the sign of the permutation for p in permutations(list(key)): tensor[p] = sign_permutations(list(p)) * value return tensor
def test_grad_varlist(): x1, x2, x3 = symbols('x1 x2 x3') f = x1**2 * x2 + sin(x2 * x3 - x2) var1 = [x1, x2, x3] res_ar1 = Arraypy([1, 3, 0]) res_ar1[0] = 2 * x1 * x2 res_ar1[1] = x1**2 + (x3 - 1) * cos(x2 * x3 - x2) res_ar1[2] = x2 * cos(x2 * x3 - x2) res_ten1 = res_ar1.to_tensor(1) res_ar = Arraypy([1, 3, 0]) res_ar[0] = -x1**2 / 5 + 6 * x1 * x2 / 5 - (x3 - 1) * cos(x2 * x3 - x2) / 5 res_ar[1] = 2 * x1**2 / 5 - 2 * x1 * x2 / \ 5 + cos(x2 * x3 - x2) * 2 * (x3 - 1) / 5 res_ar[2] = x2 * cos(x2 * x3 - x2) res_ten = res_ar.to_tensor(1) g = Matrix([[2, 1, 0], [1, 3, 0], [0, 0, 1]]) assert grad(f, var1, output_type='l') == [ 2 * x1 * x2, x1**2 + (x3 - 1) * cos(x2 * x3 - x2), x2 * cos(x2 * x3 - x2)] assert isinstance(grad(f, var1, output_type='l'), list) assert grad(f, var1) == [ 2 * x1 * x2, x1**2 + (x3 - 1) * cos(x2 * x3 - x2), x2 * cos(x2 * x3 - x2)] assert isinstance(grad(f, var1), list) assert grad(f, var1, output_type='a') == res_ar1 assert isinstance(grad(f, var1, output_type='t'), Arraypy) assert grad(f, var1, output_type='t') == res_ten1 assert isinstance(grad(f, var1, output_type='t'), TensorArray) assert grad(f, var1, output_type='t').type_pq == (1, 0) assert str( grad( f, var1, g, output_type='l')) == '[-x1**2/5 + 6*x1*x2/5 - (x3 - 1)*cos(x2*x3 - x2)/5, 2*x1**2/5 - 2*x1*x2/5 + 2*(x3 - 1)*cos(x2*x3 - x2)/5, x2*cos(x2*x3 - x2)]' assert isinstance(grad(f, var1, g, output_type='l'), list) assert grad(f, var1, g, output_type='a') == res_ar assert isinstance(grad(f, var1, g, output_type='a'), Arraypy) assert grad(f, var1, g, output_type='t') == res_ten assert isinstance(grad(f, var1, g, output_type='t'), TensorArray) assert grad(f, var1, g, output_type='t').type_pq == (1, 0)
def test_riemann_Li(): x1, x2 = symbols('x1, x2') var_list = [x1, x2] C = Arraypy([3, 2, 0]).to_tensor((1, -1, -1)) C[0, 0, 0] = 0 C[0, 0, 1] = sin(x2) * cos(x2) C[0, 1, 1] = 0 C[1, 1, 1] = 0 C[1, 0, 1] = 0 C[1, 1, 0] = 0 C[1, 0, 0] = -sin(x2) * cos(x2) C[0, 1, 0] = -sin(x2) * cos(x2) g = Arraypy((2, 2)).to_tensor((-1, -1)) g[0, 0] = cos(x2)**2 g[0, 1] = 0 g[1, 0] = 0 g[1, 1] = 1 res_arr = Arraypy([4, 2, 0]) res_arr[0, 0, 0, 0] = -0.25 * sin(x2)**2 * cos(x2)**2 res_arr[0, 0, 0, 1] = 0 res_arr[0, 0, 1, 1] = 0 res_arr[0, 1, 1, 1] = 0 res_arr[1, 1, 1, 1] = 0 res_arr[1, 1, 1, 0] = 0 res_arr[1, 1, 0, 0] = 0 res_arr[1, 0, 0, 0] = 0 res_arr[1, 0, 1, 0] = 0 res_arr[0, 1, 0, 1] = 0 res_arr[1, 1, 0, 1] = 0 res_arr[0, 0, 1, 0] = 0 res_arr[1, 0, 1, 1] = 0 res_arr[0, 1, 0, 0] = 0 res_arr[0, 1, 1, 0] = 0 res_arr[1, 0, 0, 1] = 0 res_ten = res_arr.to_tensor((1, -1, -1, -1)) print('test_riemann_li_t <=== actual test code') assert riemann_li(C, g, var_list) == res_ten assert isinstance(riemann_li(C, g, var_list), TensorArray) assert riemann_li(C, g, var_list).type_pq == (1, 3) assert riemann_li(C, g, var_list, 't') == res_ten assert isinstance(riemann_li(C, g, var_list, 't'), TensorArray) assert riemann_li(C, g, var_list, 't').type_pq == (1, 3) print('test_riemann_li_a <=== actual test code') assert riemann_li(C, g, var_list, 'a') == res_arr assert isinstance(riemann_li(C, g, var_list, 'a'), Arraypy)
def test_arraypy_initiation(): arr_with_one_element = Arraypy() assert len(arr_with_one_element) == 1 assert arr_with_one_element[0] == 0 assert arr_with_one_element.rank == 1 arr_with_symbol_element = Arraypy('Py') assert len(arr_with_symbol_element) == 1 assert arr_with_symbol_element[0] == Symbol('Py[0]') assert arr_with_symbol_element.rank == 1 vector_length = 5 vector = Arraypy(vector_length) assert len(vector) == vector_length assert vector.shape == (vector_length,) assert vector.start_index == (0,) assert vector.end_index == (vector_length - 1,) assert vector.rank == 1 array_shape = (3, 3, 3, 3) n_dim_array = Arraypy(array_shape) assert len(n_dim_array) == 3 * 3 * 3 * 3 assert n_dim_array.shape == array_shape assert n_dim_array.start_index == (0, 0, 0, 0) assert n_dim_array.end_index == (2, 2, 2, 2) assert n_dim_array.rank == 4 sparse_array = Arraypy(array_shape, 'sparse') assert sparse_array._sparse is True assert len(sparse_array._output) == 0 assert len(sparse_array) == 3 * 3 * 3 * 3 assert n_dim_array.shape == array_shape assert n_dim_array.start_index == (0, 0, 0, 0) assert n_dim_array.end_index == (2, 2, 2, 2) assert n_dim_array.rank == 4 arr_with_ranged_index = Arraypy('1..3, 2 .. 4, 3..5') assert arr_with_ranged_index.shape == (3, 3, 3) assert len(arr_with_ranged_index) == 3 * 3 * 3 assert arr_with_ranged_index.start_index == (1, 2, 3) assert arr_with_ranged_index.end_index == (3, 4, 5) assert arr_with_ranged_index.rank == 3 combined_arg = [2, 3, 1] array_with_combined_arg = Arraypy(combined_arg) assert len(array_with_combined_arg) == 3 * 3 assert array_with_combined_arg.shape == (3, 3) assert array_with_combined_arg.start_index == (1, 1) assert array_with_combined_arg.end_index == (3, 3) assert array_with_combined_arg.rank == 2 shape = (3, 3) array_with_many_arg = Arraypy(shape, 'X', 'sparse') assert len(array_with_many_arg) == 3 * 3 assert array_with_many_arg.shape == shape assert array_with_many_arg._sparse is True assert array_with_many_arg[0, 0] == Symbol('X[0, 0]') assert array_with_many_arg.rank == 2
def test_index_list(): array = Arraypy((2, 2)) indecies = array.index_list assert indecies[0] == (0, 0) == array.start_index assert indecies[1] == (0, 1) assert indecies[2] == (1, 0) assert indecies[3] == (1, 1) == array.end_index
def test_df_var_tnsr0(): x1, x2, x3 = symbols('x1 x2 x3') f = x1**2 * x2 + sin(x2 * x3 - x2) var_tnsr0 = TensorArray(Arraypy(3), (1)) var_tnsr0[0] = x1 var_tnsr0[1] = x2 var_tnsr0[2] = x3 assert df(f, var_tnsr0) == [ 2 * x1 * x2, x1**2 + (x3 - 1) * cos(x2 * x3 - x2), x2 * cos(x2 * x3 - x2)] assert isinstance(df(f, var_tnsr0), list) assert df(f, var_tnsr0, 'l') == [ 2 * x1 * x2, x1**2 + (x3 - 1) * cos(x2 * x3 - x2), x2 * cos(x2 * x3 - x2)] assert isinstance(df(f, var_tnsr0, 'l'), list) assert df(f, var_tnsr0, 'a') == list2arraypy( [2 * x1 * x2, x1**2 + (x3 - 1) * cos(x2 * x3 - x2), x2 * cos(x2 * x3 - x2)]) assert isinstance(df(f, var_tnsr0, 'a'), Arraypy) assert df(f, var_tnsr0, 't') == list2tensor( [2 * x1 * x2, x1**2 + (x3 - 1) * cos(x2 * x3 - x2), x2 * cos(x2 * x3 - x2)]) assert isinstance(df(f, var_tnsr0, 't'), TensorArray) assert df(f, var_tnsr0, 't').type_pq == (0, 1)
def test_kulkarni_nomizu(): x1, x2 = symbols('x1, x2') var_list = [x1, x2] h = Arraypy((2, 2)).to_tensor((-1, -1)) h[0, 0] = x1 h[0, 1] = 0 h[1, 0] = 0 h[1, 1] = x2 k = Arraypy((2, 2)).to_tensor((-1, -1)) k[0, 0] = x2 k[0, 1] = 0 k[1, 0] = 0 k[1, 1] = x1 res_arr = Arraypy([4, 2, 0]) res_arr[0, 0, 0, 0] = 0 res_arr[0, 0, 0, 1] = 0 res_arr[0, 0, 1, 1] = 0 res_arr[0, 1, 1, 1] = 0 res_arr[1, 1, 1, 1] = 0 res_arr[1, 1, 1, 0] = 0 res_arr[1, 1, 0, 0] = 0 res_arr[1, 0, 0, 0] = 0 res_arr[1, 0, 1, 0] = x1**2 + x2**2 res_arr[0, 1, 0, 1] = x1**2 + x2**2 res_arr[1, 1, 0, 1] = 0 res_arr[0, 0, 1, 0] = 0 res_arr[1, 0, 1, 1] = 0 res_arr[0, 1, 0, 0] = 0 res_arr[0, 1, 1, 0] = -x1**2 - x2**2 res_arr[1, 0, 0, 1] = -x1**2 - x2**2 res_ten = res_arr.to_tensor((-1, -1, -1, -1)) print('test_kulkarni_nomizu_t <=== actual test code') assert kulkarni_nomizu(h, k, var_list) == res_ten assert isinstance(kulkarni_nomizu(h, k, var_list), TensorArray) assert kulkarni_nomizu(h, k, var_list).type_pq == (0, 4) assert kulkarni_nomizu(h, k, var_list, 't') == res_ten assert isinstance(kulkarni_nomizu(h, k, var_list, 't'), TensorArray) assert kulkarni_nomizu(h, k, var_list, 't').type_pq == (0, 4) print('test_kulkarni_nomizu_a <=== actual test code') assert kulkarni_nomizu(h, k, var_list, 'a') == res_arr assert isinstance(kulkarni_nomizu(h, k, var_list, 'a'), Arraypy)
def test_calculation(): # Arraypy list_of_ones = [1 for i in range(9)] list_of_nines = [9 for i in range(9)] shape = (3, 3) a = list2arraypy(list_of_ones, shape) b = list2arraypy(list_of_nines, shape) if sys.version_info[0] >= 3: c = a + b for i in c: assert i == 10 c = b - a for i in c: assert i == 8 else: c = a + b idx = c.start_index for i in range(len(c)): assert c[idx] == 10 idx = c.next_index(idx) idx = c.start_index c = b - a for i in range(len(c)): assert c[idx] == 8 idx = c.next_index(idx) # TensorArray x0, x1, y0, y1 = symbols('X[0], X[1], Y[0], Y[1]') tensor1 = TensorArray(Arraypy(2, 'X'), 1) tensor2 = TensorArray(Arraypy(2, 'Y'), -1) assert tensor1.rank == tensor2.rank == 1 res_tensor = tensor_product(tensor1, tensor2) assert len(res_tensor) == 4 assert res_tensor.rank == 2 assert res_tensor[0, 0] == x0 * y0 assert res_tensor[0, 1] == x0 * y1 assert res_tensor[1, 0] == x1 * y0 assert res_tensor[1, 1] == x1 * y1
def test_grad_gtnsr(): x1, x2, x3 = symbols('x1 x2 x3') f = x1**2 * x2 + sin(x2 * x3 - x2) var1 = [x1, x2, x3] k1 = Arraypy([1, 3, 0]).to_tensor(1) k1[0] = x1 k1[1] = x2 k1[2] = x3 # g задано tensor, индекс с 1 и var-list a = Arraypy([2, 3, 1]) b = a.to_tensor((-1, -1)) b[1, 1] = 2 b[1, 2] = 1 b[1, 3] = 0 b[2, 1] = 1 b[2, 2] = 3 b[2, 3] = 0 b[3, 1] = 0 b[3, 2] = 0 b[3, 3] = 1 res_ar = Arraypy([1, 3, 1]) res_ar[1] = -x1**2 / 5 + 6 * x1 * x2 / 5 - (x3 - 1) * cos(x2 * x3 - x2) / 5 res_ar[2] = 2 * x1**2 / 5 - 2 * x1 * x2 / \ 5 + cos(x2 * x3 - x2) * 2 * (x3 - 1) / 5 res_ar[3] = x2 * cos(x2 * x3 - x2) res_ten = res_ar.to_tensor(1) res_ar1 = Arraypy([1, 3, 0]) res_ar1[0] = 2 * x1 * x2 res_ar1[1] = x1**2 + (x3 - 1) * cos(x2 * x3 - x2) res_ar1[2] = x2 * cos(x2 * x3 - x2) assert str( grad( f, var1, b, 'l')) == '[-x1**2/5 + 6*x1*x2/5 - (x3 - 1)*cos(x2*x3 - x2)/5, 2*x1**2/5 - 2*x1*x2/5 + 2*(x3 - 1)*cos(x2*x3 - x2)/5, x2*cos(x2*x3 - x2)]' assert isinstance(grad(f, var1, b, 'l'), list) assert grad(f, var1, b, 'a') == res_ar assert isinstance(grad(f, var1, b, 'a'), Arraypy) assert grad(f, k1, output_type='a') == res_ar1 assert isinstance(grad(f, k1, output_type='a'), Arraypy) assert grad(f, var1, b, 't') == res_ten assert isinstance(grad(f, var1, b, 't'), TensorArray) assert grad(f, var1, b, 't').type_pq == (1, 0) assert grad(f, var1, b) == res_ten assert isinstance(grad(f, var1, b, 't'), TensorArray) assert grad(f, var1, b, 't').type_pq == (1, 0)
def test_g_wedge(): l, m, n = symbols('l, m, n') X_w=Arraypy([1,3,1]).to_tensor((-1)) X_w[1]=l X_w[2]=m X_w[3]=n b1=Arraypy([2,3,1]).to_tensor((-1,-1)) b1[1,1]=2 b1[1,2]=1 b1[1,3]=0 b1[2,1]=1 b1[2,2]=3 b1[2,3]=0 b1[3,1]=0 b1[3,2]=0 b1[3,3]=1 assert g_wedge(X_w,X_w,b1)==l*(3*l/5 - m/5) + m*(-l/5 + 2*m/5) + n**2
def test_tensor_initiation(): base_shape = (2, 2, 2) tensor_base = Arraypy(base_shape) index_character = (1, -1, 1) tensor = TensorArray(tensor_base, index_character) assert tensor.ind_char == index_character assert tensor.shape == base_shape assert tensor.type_pq == (2, 1) assert tensor.rank == 3
def test_tensor_converting(): arr_tensor = TensorArray(Arraypy((2, 2)), (1, 1)) arr_list = arr_tensor.to_list() assert (isinstance(arr_list, list)) arr_arraypy = arr_tensor.to_arraypy() assert (isinstance(arr_arraypy, Arraypy)) arr_matrix = arr_tensor.to_matrix() assert (isinstance(arr_matrix, Matrix))
def test_k_sigma(): x1, x2 = symbols('x1, x2') var_list = [x1, x2] g = Matrix([[cos(x2)**2, 0], [0, 1]]) X = [1, 2] Y = [3, 4] g_ten = Arraypy([2, 2, 1]).to_tensor((-1, -1)) g_ten[1, 1] = cos(x2)**2 g_ten[1, 2] = 0 g_ten[2, 1] = 0 g_ten[2, 2] = 1 g_ten0 = Arraypy([2, 2, 0]).to_tensor((-1, -1)) g_ten0[0, 0] = cos(x2)**2 g_ten0[0, 1] = 0 g_ten0[1, 0] = 0 g_ten0[1, 1] = 1 riemann_arr = Arraypy([4, 2, 0]) riemann_arr[0, 0, 0, 0] = 0 riemann_arr[0, 0, 0, 1] = 0 riemann_arr[0, 0, 1, 1] = 0 riemann_arr[0, 1, 1, 1] = 0 riemann_arr[1, 1, 1, 1] = 0 riemann_arr[1, 1, 1, 0] = 0 riemann_arr[1, 1, 0, 0] = 0 riemann_arr[1, 0, 0, 0] = 0 riemann_arr[1, 0, 1, 0] = -1 riemann_arr[0, 1, 0, 1] = -cos(x2)**2 riemann_arr[1, 1, 0, 1] = 0 riemann_arr[0, 0, 1, 0] = 0 riemann_arr[1, 0, 1, 1] = 0 riemann_arr[0, 1, 0, 0] = 0 riemann_arr[0, 1, 1, 0] = 1 riemann_arr[1, 0, 0, 1] = cos(x2)**2 riemann_ten = riemann_arr.to_tensor((-1, -1, -1, 1)) assert k_sigma(X, Y, riemann_ten, g, var_list) == 1 assert k_sigma(X, Y, riemann_ten, g_ten, var_list) == 1 assert k_sigma(X, Y, riemann_ten, g_ten0, var_list) == 1
def test_scal_curv(): x1, x2 = symbols('x1, x2') var_list = [x1, x2] g = Matrix([[cos(x2)**2, 0], [0, 1]]) g_ten = Arraypy([2, 2, 1]).to_tensor((-1, -1)) g_ten[1, 1] = cos(x2)**2 g_ten[1, 2] = 0 g_ten[2, 1] = 0 g_ten[2, 2] = 1 g_ten0 = Arraypy([2, 2, 0]).to_tensor((-1, -1)) g_ten0[0, 0] = cos(x2)**2 g_ten0[0, 1] = 0 g_ten0[1, 0] = 0 g_ten0[1, 1] = 1 ricci = Matrix([[cos(x2)**2, 0], [0, 1]]) ricci_ten = Arraypy([2, 2, 1]).to_tensor((-1, -1)) ricci_ten[1, 1] = cos(x2)**2 ricci_ten[1, 2] = 0 ricci_ten[2, 1] = 0 ricci_ten[2, 2] = 1 ricci_ten0 = Arraypy([2, 2, 0]).to_tensor((-1, -1)) ricci_ten0[0, 0] = cos(x2)**2 ricci_ten0[0, 1] = 0 ricci_ten0[1, 0] = 0 ricci_ten0[1, 1] = 1 assert scal_curv(g, ricci, var_list) == 1 assert scal_curv(g_ten, ricci, var_list) == 1 assert scal_curv(g, ricci_ten, var_list) == 1 assert scal_curv(g_ten, ricci_ten, var_list) == 1 assert scal_curv(g_ten0, ricci, var_list) == 1 assert scal_curv(g_ten0, ricci_ten, var_list) == 1 assert scal_curv(g, ricci_ten0, var_list) == 1 assert scal_curv(g_ten, ricci_ten0, var_list) == 1 assert scal_curv(g_ten0, ricci_ten0, var_list) == 1
def test_nabla_x(): x1, x2 = symbols('x1, x2') var_list = [x1, x2] X = [x1 * x2**3, x1 - cos(x2)] T = Arraypy([2, 2, 0]).to_tensor((-1, -1)) T[0, 0] = x2 T[0, 1] = -x2 T[1, 0] = -x1 T[1, 1] = x1 ch_2 = Arraypy([3, 2, 0]) ch_2[0, 0, 0] = 0 ch_2[0, 0, 1] = sin(x2) * cos(x2) ch_2[0, 1, 1] = 0 ch_2[1, 1, 1] = 0 ch_2[1, 0, 1] = 0 ch_2[1, 1, 0] = 0 ch_2[1, 0, 0] = -sin(x2) * cos(x2) ch_2[0, 1, 0] = -sin(x2) * cos(x2) res_ten = Arraypy((2, 2)).to_tensor((-1, -1)) res_ten[0, 0] = x1 * x2**3 * (x1 * sin(x2) * cos(x2) + x2 * sin(x2) * cos(x2) ) + 2 * x2 * (x1 - cos(x2)) * sin(x2) * cos(x2) res_ten[ 0, 1] = x1 * x2**3 * (-x1 * sin(x2) * cos(x2) + x2 * sin(x2) * cos(x2) ) + (x1 - cos(x2)) * (-x2 * sin(x2) * cos(x2) - 1) res_ten[ 1, 0] = x1 * x2**3 * (-x1 * sin(x2) * cos(x2) + x2 * sin(x2) * cos(x2) ) + (x1 - cos(x2)) * (-x1 * sin(x2) * cos(x2) - 1) res_ten[1, 1] = x1 * x2**3 * (-x1 * sin(x2) * cos(x2) - x2 * sin(x2) * cos(x2)) assert nabla_x(T, ch_2, X, var_list) == res_ten assert isinstance(nabla_x(T, ch_2, X, var_list), TensorArray)
def test_scal_prod_gxy_list(): x1, x2 = symbols('x1, x2') var_list = [x1, x2] X = [1, 2] Y = [3, 4] g = Matrix([[cos(x2)**2, 0], [0, 1]]) ten_g = Arraypy((2, 2)).to_tensor((-1, -1)) ten_g[0, 0] = cos(x2)**2 ten_g[0, 1] = 0 ten_g[1, 0] = 0 ten_g[1, 1] = 1 ten_g1 = Arraypy([2, 2, 1]).to_tensor((-1, -1)) ten_g1[1, 1] = cos(x2)**2 ten_g1[1, 2] = 0 ten_g1[2, 1] = 0 ten_g1[2, 2] = 1 assert scal_prod(X, Y, g) == 3 * cos(x2)**2 + 8 assert scal_prod(X, Y, ten_g) == 3 * cos(x2)**2 + 8 assert scal_prod(X, Y, ten_g1) == 3 * cos(x2)**2 + 8
def tensor_product(first_tensor, second_tensor): """Returns tensor product. Rank of resulted tensor is a summary rank of two tensors. Examples ======== >>> from tensor_analysis.arraypy import Arraypy, TensorArray >>> from tensor_analysis.tensor_methods import tensor_product >>> a = TensorArray( Arraypy ('1..2', 'X'), 1) >>> b = TensorArray( Arraypy ('1..2', 'Y'), -1) >>> c = tensor_product(a, b) >>> print (c) X[1]*Y[1] X[1]*Y[2] X[2]*Y[1] X[2]*Y[2] >>> print(c.start_index) (1, 1) >>> print(c.end_index) (2, 2) >>> print(c.rank) 2 >>> print(c.ind_char) (1, -1) """ if not isinstance(first_tensor, TensorArray): raise TypeError('first attribute must be TensorArray') if not isinstance(second_tensor, TensorArray): raise TypeError('second attribute must be TensorArray') # forming list of tuples for Arraypy constructor of type a = Arraypy( # [(a, b), (c, d), ... , (y, z)] ) arg = [(first_tensor.start_index[i], first_tensor.end_index[i]) for i in range(first_tensor._rank)] arg = arg + [(second_tensor.start_index[i], second_tensor.end_index[i]) for i in range(second_tensor._rank)] # index charater of resulted tensor will be a concatination of two # index characters res = TensorArray(Arraypy(arg), first_tensor.ind_char + second_tensor.ind_char) # loop over current tensor for i in first_tensor.index_list: # loop over second_tensor tensor for j in second_tensor.index_list: res[i + j] = first_tensor[i] * second_tensor[j] return res
def test_inner_product(): x1, x2, x3, l, m, n = symbols('x1 x2 x3 l m n') omega2=Arraypy([2,3,1]).to_tensor((-1,-1)) omega2[1,2]=x3 omega2[1,3]=-x2 omega2[2,1]=-x3 omega2[2,3]=x1 omega2[3,1]=x2 omega2[3,2]=-x1 X_t=Arraypy([1,3,1]).to_tensor((1)) X_t[1]=l X_t[2]=m X_t[3]=n res_ar1 = Arraypy([1, 3, 1]) res_ar1[1] = -m*x3 + n*x2 res_ar1[2] = l*x3 - n*x1 res_ar1[3] = -l*x2 + m*x1 res_ten1 = res_ar1.to_tensor(-1) assert inner_product(omega2, X_t)==res_ten1
def df(f, args, output_type='l'): """Return an the 1-form df, differential of function f. Examples: ========= >>> from tensor_analysis.tensor_fields import df >>> from sympy import symbols, sin >>> from tensor_analysis.arraypy import Arraypy >>> x1, x2, x3= symbols('x1 x2 x3') f it's a function the differential of that is calculated: >>> f=x1**2*x2 + sin(x2*x3 - x2) args it's a list of symbol arguments of the function f. It can be in list, array of arraypy or contravariant tensor: >>> args_t=Arraypy([1,3,1]).to_tensor(1) >>> args_t[1]=x1 >>> args_t[2]=x2 >>> args_t[3]=x3 output_type it is an optional parameter accepting symbol value of 'l', 'a' or 't' and indicative on the type of result of calculations: - 'l' it is a result as a list(list); - 'a' it is a result as an unidimensional array of arraypy; - 't' it is a result as an unidimensional covariant tensor. Differential: >>> d = df(f, args_t, 't') >>> print(d) 2*x1*x2 x1**2 + (x3 - 1)*cos(x2*x3 - x2) x2*cos(x2*x3 - x2) The valence of the returned tensor: >>> d.type_pq (0, 1) """ # Handling of a vector of arguments check_vector_of_arguments(args) # The definition of the start index if isinstance(args, list): idx_start = 0 else: idx_start = args.start_index[0] # Creating the output array in accordance with the start index n = len(args) array = Arraypy([1, n, idx_start]) # Calculation for k in range(idx_start, idx_start + n): array[k] = diff(f, args[k]) # Handling of an output array if output_type == 't' or output_type == Symbol('t'): differential = Arraypy.to_tensor(array, -1) elif output_type == 'a' or output_type == Symbol('a'): differential = array elif output_type == 'l' or output_type == Symbol('l'): differential = Arraypy.to_list(array) else: raise TypeError( "The third argument must be 't' - TensorArray,'a' - Arraypy, \ 'l' - list") # Output return differential
def test_next_index(): array = Arraypy((2, 2), 'Py') assert array.next_index((0, 0)) == (0, 1) assert array.next_index((0, 1)) == (1, 0) assert array.next_index((1, 0)) == (1, 1) assert array.next_index((1, 1)) == (0, 0)
def inner_product(w, X): """Calculation of the inner product of the form and the vector field. Examples: ========= >>> from sympy import symbols >>> from tensor_analysis.arraypy import Arraypy >>> from tensor_analysis.tensor_fields import inner_product >>> x1, x2, x3, l, m, n = symbols('x1 x2 x3 l m n') >>> omega2=Arraypy([2,3,1]).to_tensor((-1,-1)) >>> omega2[1,2]=x3 >>> omega2[1,3]=-x2 >>> omega2[2,1]=-x3 >>> omega2[2,3]=x1 >>> omega2[3,1]=x2 >>> omega2[3,2]=-x1 >>> X_t=Arraypy([1,3,1]).to_tensor((1)) >>> X_t[1]=l >>> X_t[2]=m >>> X_t[3]=n >>> print(inner_product(omega2, X_t)) -m*x3 + n*x2 l*x3 - n*x1 -l*x2 + m*x1 """ # Handling of a differential form if not isinstance(w, (TensorArray, Arraypy)): raise ValueError( "The type of differential form must be TensorArray or Arraypy") # The valency (0,q) if (len(w.type_pq) == 1 and w.type_pq[0] != 1) or ( len(w.type_pq) > 1 and w.type_pq[0] != 0): raise ValueError("The valency of tensor must be (0,q)") if not is_asymmetric(w): raise ValueError("The form must be a skew-symmetric") # Handling of a vector field check_the_vector_field(X) if isinstance(X, (TensorArray, Arraypy)): idx_start_X = X.start_index[0] else: idx_start_X = 0 # Define the start index in the output form idx_start_w = w.start_index[0] if idx_start_w != idx_start_X: raise ValueError( "The start index of tensor and vector field must be equal") # Creating the output array in accordance with start indexes n = w.shape[0] # the dimension of the input array q = len(w.shape) # the rank of the input array if (q != 1): result_tensor = Arraypy([q - 1, n, idx_start_w]) # all indices are -1 valence_list = [(-1) for k in range(q - 1)] # result tensor int_prod = result_tensor.to_tensor(valence_list) for index in int_prod.index_list: # the sum on k.k is [0,n-1], n is len(X) for k in range(len(X)): idx = list(index) idx.insert(0, k + idx_start_w) int_prod[index] += w[tuple(idx)] * X[k + idx_start_w] if q == 1: # int_prod is number(symbolic expression) int_prod = 0 for index in w.index_list: for k in range(len(X)): int_prod += w[index] * X[k + idx_start_w] # Output return int_prod
def curl(X, args, output_type=None): """Return the rotor vector field curl(X) of a vector field X in R^3 (curl, rotation, rotor, vorticity). A rotor can be calculated for only in three-dimensional Euclidean space. Examples: ========= >>> from tensor_analysis.tensor_fields import curl >>> from sympy import symbols, cos >>> from tensor_analysis.arraypy import Arraypy, TensorArray >>> x1, x2, x3 = symbols('x1 x2 x3') X is a vector field, args it's a list of symbol arguments of a vector field X. They can be a list, array arraypy or contravariant tensor: >>> X=Arraypy(3) >>> X_t=TensorArray(X,(1)) >>> X_t[0]=x1*x2**3 >>> X_t[1]=x2-cos(x3) >>> X_t[2]=x3**3-x1 >>> arg=[x1,x2,x3] >>> r=curl(X_t,arg,'t') >>> print(r) -sin(x3) 1 -3*x1*x2**2 >>> r.type_pq (1, 0) """ # Handling of a vector of arguments check_vector_of_arguments(args) if len(args) != 3: raise ValueError("Three variables are required") # The definition of the start index if isinstance(args, list): idx_args = 0 else: idx_args = args.start_index[0] # Handling of a vector field check_the_vector_field(X) if len(X) != 3: raise ValueError("A three-dimensional vector field is necessary") # The definition of the start index and type of output if isinstance(X, (TensorArray, Arraypy)): if isinstance(X, TensorArray): out_t = 't' idx_X = X.start_index[0] else: idx_X = 0 out_t = 'l' # The definition type of output of an output array if output_type is None: if out_t is not None: output_type = out_t else: output_type = 'a' # The definition of the start index if isinstance(X, type(args)) and (idx_X != idx_args): raise ValueError( "The start index of vector field and vector of arguments must be \ equal") idx_st = idx_X # Creating the output array in accordance with the start index array = Arraypy([1, 3, idx_st]) # Calculation if isinstance(X, (TensorArray, Arraypy)): X = X.to_list() if isinstance(args, (TensorArray, Arraypy)): args = args.to_list() array[idx_st] = (diff(X[2], args[1]) - diff(X[1], args[2])) array[idx_st + 1] = diff(X[0], args[2]) - diff(X[2], args[0]) array[idx_st + 2] = diff(X[1], args[0]) - diff(X[0], args[1]) # Handling of an output array if output_type == 't' or output_type == Symbol('t'): rotor = Arraypy.to_tensor(array, 1) elif output_type == 'a' or output_type == Symbol('a'): rotor = array elif output_type == 'l' or output_type == Symbol('l'): rotor = Arraypy.to_list(array) else: raise TypeError( "The third argument must be 't'-tensor,'a'-Arraypy, \ 'l'-list") # Output return rotor
def lie_w(omega, X, args): """Return a skew-symmetric tensor of type (0,p). Function lie_w calculates all the components of the Lie derivative differential forms in a symbolic form. Indexes the output tensor will start as well as the input tensor (array) "omega". If all the input parameters of the same type, they must be equal to the initial indexes. Examples: ========= >>> from tensor_analysis.tensor_fields import lie_w >>> from sympy import symbols, cos >>> from tensor_analysis.arraypy import Arraypy >>> x1, x2, x3 = symbols('x1 x2 x3') omega - skew-symmetric tensor. Can be a tensor of type (0,p) or an array arraypy: >>> omega=Arraypy([2,3,1]).to_tensor((-1,-1)) >>> omega[1,2]=x3 >>> omega[1,3]=-x2 >>> omega[2,1]=-x3 >>> omega[2,3]=x1 >>> omega[3,1]=x2 >>> omega[3,2]=-x1 X - the vector field along which the derivative is calculated: >>> X = [x1*x2**3,x2-cos(x3),x3**3-x1] args it's a list of symbol arguments. It's can be in list, array of arraypy or contravariant tensor: >>> arg = [x1, x2, x3] Lie derivative of a differential form: >>> li = lie_w(omega,X,arg) >>> print(li) 0 x2**3*x3 + x3**3 + x3 -x2**4 - 3*x2*x3**2 - x2 + x3*sin(x3) + cos(x3) -x2**3*x3 - x3**3 - x3 0 -2*x1*x2**3 + 3*x1*x3**2 + x1 x2**4 + 3*x2*x3**2 + x2 - x3*sin(x3) - cos(x3) 2*x1*x2**3 - 3*x1*x3**2 - x1 0 >>> li.type_pq (0, 2) """ # Handling of a vector of arguments check_vector_of_arguments(args) if isinstance(args, list): idx_args = 0 else: idx_args = args.start_index[0] # Handling of a vector field check_the_vector_field(X) if isinstance(X, (TensorArray, Arraypy)): idx_X = X.start_index[0] else: idx_X = 0 # Handling of a differential form if not isinstance(omega, (TensorArray, Arraypy)): raise ValueError( "The type of differential form must be TensorArray or Arraypy") if not is_asymmetric(omega): raise ValueError("The differential form must be a skew-symmetric") idx_omega = omega.start_index[0] # Define the start index in the output tensor if type(omega) == type(X) == type(args): if idx_omega != idx_X or idx_omega != idx_args or idx_X != idx_args: raise ValueError( "The start index of differential form, vector field and \ vector of argements must be equal") if isinstance(omega, type(X)) and idx_omega != idx_X: raise ValueError( "The start index of differential form and vector field must be \ equal") idx_st = idx_omega # Creating the output array in accordance with start indexes n = omega.shape[0] # the dimensionality of the input array r = len(omega.shape) # the rank of the input array a = Arraypy([r, n, idx_st]) valence_list = [(-1) for k in range(r)] diff_Lie = a.to_tensor(valence_list) # Calculation idx = diff_Lie.start_index if isinstance(args, (TensorArray, Arraypy)): args = args.to_list() if isinstance(X, (TensorArray, Arraypy)): X = X.to_list() l_idx = len(idx) for p in range(len(diff_Lie)): for k in range(l_idx + 1): tuple_list_indx = [ replace_index_to_k(idx, f, k + idx_st) for f in range(l_idx)] # the intermediate value diff_omega = diff(omega[idx], args[k]) * X[k] for j in range(l_idx): diff_Lie[idx] += diff(X[k], args[idx[j] - idx_st]) *\ omega[tuple_list_indx[j]] diff_Lie[idx] = diff_Lie[idx] + diff_omega idx = diff_Lie.next_index(idx) # Output return diff_Lie
def dw(omega, args): """Return a skew-symmetric tensor of type (0, p+1). Indexes the output tensor will start as well as the input tensor (array). If the input parameters of the same type, they must be equal to the initial indexes. Examples: ========= >>> from tensor_analysis.tensor_fields import dw >>> from sympy import symbols >>> from tensor_analysis.arraypy import Arraypy >>> x1, x2, x3 = symbols('x1 x2 x3') omega - differential form, differential which is calculated. It's can be a skew-symmetric tensor of type (0,p) or an array arraypy: >>> omega=Arraypy([2,3,1]).to_tensor((-1,-1)) >>> omega[1,2]=x3 >>> omega[1,3]=-x2 >>> omega[2,1]=-x3 >>> omega[2,3]=x1 >>> omega[3,1]=x2 >>> omega[3,2]=-x1 args it's a list of symbol arguments of differential form. It's can be in list, array of arraypy or contravariant tensor. External differential of a differential forms: >>> domega=dw(omega, [x1,x2,x3]) >>> print(domega) 0 0 0 0 0 3 0 -3 0 0 0 -3 0 0 0 3 0 0 0 3 0 -3 0 0 0 0 0 >>> domega.type_pq (0, 3) """ # Handling of a vector of arguments check_vector_of_arguments(args) # The definition of the start index of args if isinstance(args, list): idx_args = 0 else: idx_args = args.start_index[0] # Handling of a differential form if not isinstance(omega, (TensorArray, Arraypy)): raise ValueError( "The type of differential form must be TensorArray or Arraypy") if omega.rank > 1: if not is_asymmetric(omega): raise ValueError("The differential form must be a skew-symmetric") idx_omega = omega.start_index[0] # Define the start index in the output tensor if isinstance(omega, type(args)) and idx_omega != idx_args: raise ValueError("The start index of the differential form and \ vector of arguments must be equal") idx_st = idx_omega # Creating the output array in accordance with start indexes n = omega.shape[0] # the dimensionality of the input array p = len(omega.shape) # the rank of the input array valence_ind = [(-1) for k in range(p + 1)] d_omega = Arraypy([p + 1, n, idx_st]).to_tensor(valence_ind) # Calculation idx = d_omega.start_index if isinstance(args, (TensorArray, Arraypy)): args = args.to_list() for i in range(len(d_omega)): # tuple_list_indx it's list of tuple. Example:[(0, 1), (0, 1), (0, 0)] tuple_list_indx = [ delete_index_from_list( idx, f) for f in range( len(idx))] for k in range(p + 1): d_omega[idx] += Add(((-1)**k) * diff(omega[tuple_list_indx[k]], args[idx[k] - idx_st])) idx = d_omega.next_index(idx) # Output return d_omega
def test_lie_xy(): x1, x2, x3, t, l, a = symbols('x1 x2 x3 t l a') X = [x1 * x2**3, x2 - cos(x3), x3**3 - x1] Y = [x1**3 * x2**3, x2 * x3 - sin(x1 * x3), x3**3 - x1**2] arg = [x1, x2, x3] res_ar = Arraypy([1, 3, 0]) res_ar[0] = 2 * x1**3 * x2**6 + 3 * x1**3 * x2**2 * \ (x2 - cos(x3)) - 3 * x1 * x2**2 * (x2 * x3 - sin(x1 * x3)) res_ar[1] = -x1 * x2**3 * x3 * cos(x1 * x3) - x2 * x3 + x3 * (x2 - cos( x3)) + (-x1 + x3**3) * (-x1 * cos(x1 * x3) + x2) - (-x1**2 + x3**3) * \ sin(x3) + sin(x1 * x3) res_ar[2] = x1**3 * x2**3 - 2 * x1**2 * x2**3 + 3 * \ x3**2 * (-x1 + x3**3) - 3 * x3**2 * (-x1**2 + x3**3) res_ten = res_ar.to_tensor(1) assert lie_xy(X, Y, arg, 'l') == [2 * x1**3 * x2**6 + 3 * x1**3 * x2**2 * (x2 - cos(x3)) - 3 * x1 * x2**2 * (x2 * x3 - sin(x1 * x3)), - x1 * x2**3 * x3 * cos(x1 * x3) - x2 * x3 + x3 * (x2 - cos(x3)) + (- x1 + x3**3) * (- x1 * cos(x1 * x3) + x2) - (- x1**2 + x3**3) * sin(x3) + sin(x1 * x3), x1**3 * x2**3 - 2 * x1**2 * x2**3 + 3 * x3**2 * (- x1 + x3**3) - 3 * x3**2 * (- x1**2 + x3**3)] assert isinstance(lie_xy(X, Y, arg, 'l'), list) assert lie_xy(X, Y, arg, 'a') == res_ar assert isinstance(lie_xy(X, Y, arg, 'a'), Arraypy) assert lie_xy(X, Y, arg, 't') == res_ten assert isinstance(lie_xy(X, Y, arg, 't'), TensorArray) assert lie_xy(X, Y, arg, 't').type_pq == (1, 0)
def grad(f, args, g=None, output_type=None): """Return the vector field gradient of a function f(x). Examples: ========= >>> from tensor_analysis.tensor_fields import grad >>> from sympy import symbols, sin >>> from tensor_analysis.arraypy import Arraypy >>> x1, x2, x3 = symbols('x1 x2 x3') f it's a function the differential of that is calculated: >>> f=x1**2*x2 + sin(x2*x3 - x2) args it's a list of symbol arguments of function of f. It can be in list, array of arraypy or contravariant tensor: >>> args=[x1,x2,x3] g - optional parameter, metric tensor, which can be a matrix "Matrix", array of arraypy or covariant tensor: >>> g=Arraypy([2,3,1]) >>> g_t=g.to_tensor((-1,-1)) >>> g_t[1,1]=2 >>> g_t[1,2]=1 >>> g_t[1,3]=0 >>> g_t[2,1]=1 >>> g_t[2,2]=3 >>> g_t[2,3]=0 >>> g_t[3,1]=0 >>> g_t[3,2]=0 >>> g_t[3,3]=1 output _ type it is an optional parameter accepting symbol value of 'l', 'a' or 't' and indicative on the type of result of calculations: - 'l' it is a result as a list(list); - 'a' it is a result as an unidimensional array of arraypy; - 't' it is a result as an unidimensional covariant tensor. Gradient: >>> gr=grad(f,args,g_t,'a') >>> print(gr) -x1**2/5 + 6*x1*x2/5 - (x3 - 1)*cos(x2*x3 - x2)/5 2*x1**2/5 - 2*x1*x2/5 + \ 2*(x3 - 1)*cos(x2*x3 - x2)/5 x2*cos(x2*x3 - x2) """ # Handling of a vector of arguments check_vector_of_arguments(args) # The definition of the start index if isinstance(args, list): idx_args = 0 else: idx_args = args.start_index[0] # Handling of the metric tensor # 1. if g is not NULL if g is not None: if output_type is None: output_type = 't' check_metric_tensor(g) # The definition of the start index if isinstance(g, Matrix): idx_st = 0 else: idx_st = g.start_index[0] # The start index is the same if isinstance(g, type(args)) and idx_st != idx_args: raise ValueError( "The start index of the metric tensor and vector of arguments \ must be equal") if isinstance(g, (TensorArray, Arraypy)): g = g.to_matrix() # 2.if g is NULL else: # g - the identity matrix g = eye(len(args)) idx_st = 0 # Creating the output array in accordance with start indexes n = len(args) array = Arraypy([1, n, idx_st]) indices = range(idx_st, idx_st + n) # Calculating g_inv = g.inv() if isinstance(args, (TensorArray, Arraypy)): args = args.to_list() for i in indices: for j in indices: array[i] += (g_inv[i - idx_st, j - idx_st] * diff(f, args[j - idx_st])) # Handling of an output array if output_type == 't' or output_type == Symbol('t'): gradient = Arraypy.to_tensor(array, 1) elif output_type == 'a' or output_type == Symbol('a'): gradient = array elif output_type == 'l' or output_type == Symbol('l') or output_type is \ None: gradient = Arraypy.to_list(array) else: raise TypeError( "The third argument must be 't' - tensor,'a' - Arraypy, \ 'l' - list") # Output return gradient
def lie_xy(X, Y, args, output_type=None): """Return the vector field [X,Y], Lie bracket (commutator) of a vector fields X and Y. Examples: ========= >>> from tensor_analysis.tensor_fields import lie_xy >>> from sympy import symbols, cos, sin >>> x1, x2, x3 = symbols('x1 x2 x3') X, Y is a vector field, args it's a list of symbol arguments. It's can be a list, array arraypy or contravariant tensor: >>> X=[x1*x2**3,x2-cos(x3),x3**3-x1] >>> Y = [x1**3*x2**3, x2*x3 - sin(x1*x3), x3**3 - x1**2] >>> arg = [x1, x2, x3] The Lie brackets of two vector fields: >>> lie = lie_xy(X, Y, arg,'a') >>> print(lie) 2*x1**3*x2**6 + 3*x1**3*x2**2*(x2 - cos(x3)) - 3*x1*x2**2*(x2*x3 - \ sin(x1*x3)) -x1*x2**3*x3*cos(x1*x3) - x2*x3 + x3*(x2 - cos(x3)) + \ (-x1 + x3**3)*(-x1*cos(x1*x3) + x2) - (-x1**2 + x3**3)*sin(x3) + sin(x1*x3) x1**3*x2**3 - 2*x1**2*x2**3 + 3*x3**2*(-x1 + x3**3) - \ 3*x3**2*(-x1**2 + x3**3) """ # Handling of a vector of arguments check_vector_of_arguments(args) # The definition of the start index args if isinstance(args, list): idx_args = 0 else: idx_args = args.start_index[0] # Handling of the first vector field check_the_vector_field(X) # The definition of the start index X and type of output if isinstance(X, (TensorArray, Arraypy)): if isinstance(X, TensorArray): out_t = 't' idx_X = X.start_index[0] else: idx_X = 0 out_t = 'l' # Handling of the second vector field check_the_vector_field(Y) # The definition of the start index Y if isinstance(Y, (TensorArray, Arraypy)): idx_Y = Y.start_index[0] else: idx_Y = 0 if len(Y) != len(X): raise ValueError( "The different number of arguments in the vector fields") elif len(args) != len(X) or len(args) != len(Y): raise ValueError( "The different number of components in the vector field and \ vector of arguments") # Define the start index in the output tensor if type(Y) == type(X) == type(args): if idx_Y != idx_X or idx_Y != idx_args or idx_X != idx_args: raise ValueError( "The start index of vector fields and vector of argements \ must be equal") if idx_Y != idx_X: raise ValueError( "The start index of vector fields must be equal") idx_st = idx_Y if output_type is None: if out_t is not None: output_type = out_t else: output_type = 'a' # Creating the output array in accordance with start indexes Li = Arraypy([1, len(X), idx_st]) # Calculating if isinstance(Y, (TensorArray, Arraypy)): Y = Y.to_list() if isinstance(X, (TensorArray, Arraypy)): X = X.to_list() if isinstance(args, (TensorArray, Arraypy)): args = args.to_list() if X == Y: return 0 else: indices = range(len(args)) for i in indices: for k in indices: Li[i + idx_st] += Add(diff(Y[i], args[k]) * X[k] - diff(X[i], args[k]) * Y[k]) # Handling of an output array if output_type == 't' or output_type == Symbol('t'): Lie = Arraypy.to_tensor(Li, 1) elif output_type == 'a' or output_type == Symbol('a'): Lie = Li elif output_type == 'l' or output_type == Symbol('l'): Lie = Arraypy.to_list(Li) else: raise TypeError( "The third argument must be 't'-TensorArray,'a'-Arraypy, \ 'l'-list") # Output return Lie