예제 #1
0
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)
예제 #2
0
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
예제 #3
0
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 sympy.tensor.arraypy import list2arraypy
    >>> from sympy.tensor.tensor_methods import asymmetric
    >>> a = list2arraypy(list(range(9)), (3,3))
    >>> b = asymmetric(a)
    >>> print (b)
    0  -1.00000000000000  -2.00000000000000
    1.00000000000000  0  -1.00000000000000
    2.00000000000000  1.00000000000000  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
        if isinstance(res_arr[tuple(index)], int):
            res_arr[tuple(index)] = float(res_arr[tuple(index)])
        res_arr[tuple(index)] /= factorial(in_arr.rank)

        index = in_arr.next_index(index)

    return res_arr
예제 #4
0
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)
예제 #5
0
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)
예제 #6
0
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)
예제 #7
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)
예제 #8
0
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)
예제 #9
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)
예제 #10
0
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)
예제 #11
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)
예제 #12
0
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)
예제 #13
0
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
예제 #14
0
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)
예제 #15
0
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
예제 #16
0
def wedgearray2tensor(B):
    """Function takes the Wedge_array(or dictionary) and creates a full skew
    array.

    Examples:
    =========
    >>> from sympy import symbols
    >>> from sympy.tensor.arraypy import Arraypy, TensorArray
    >>> from sympy.tensor.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
예제 #17
0
def wedgearray2tensor(B):
    """Function takes the Wedge_array(or dictionary) and creates a full skew
    array.

    Examples:
    =========
    >>> from sympy import symbols
    >>> from sympy.tensor.arraypy import Arraypy, TensorArray
    >>> from sympy.tensor.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
예제 #18
0
def symmetric(in_arr):
    """
    Creates the symmetric form of input tensor.
    Input: Arraypy or TensorArray with equal axes (array shapes).
    Output: symmetric array. Output type - Arraypy or TensorArray, depends of input

    Examples
    ========

    >>> from sympy.tensor.arraypy import list2arraypy
    >>> from sympy.tensor.tensor_methods import symmetric
    >>> a = list2arraypy(list(range(9)), (3,3))
    >>> b = symmetric(a)
    >>> print (b)
    0  2  4
    2  4  6
    4  6  8
    """
    if not isinstance(in_arr, Arraypy):
        raise TypeError('Input must be Arraypy or TensorArray type')

    flag = 0
    for j in range(0, 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)

    index = [in_arr.start_index[i] for i in range(in_arr.rank)]

    for i in range(len(in_arr)):
        perm = list(permutations(index))
        for temp_index in perm:
            res_arr[tuple(index)] += in_arr[tuple(temp_index)]

        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
예제 #19
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)
예제 #20
0
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
예제 #21
0
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)
예제 #22
0
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
예제 #23
0
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)
예제 #24
0
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
예제 #25
0
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
예제 #26
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
예제 #27
0
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))
예제 #28
0
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
예제 #29
0
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)
예제 #30
0
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) == 2
    assert scal_curv(g_ten, ricci, var_list) == 2
    assert scal_curv(g, ricci_ten, var_list) == 2
    assert scal_curv(g_ten, ricci_ten, var_list) == 2
    assert scal_curv(g_ten0, ricci, var_list) == 2
    assert scal_curv(g_ten0, ricci_ten, var_list) == 2
    assert scal_curv(g, ricci_ten0, var_list) == 2
    assert scal_curv(g_ten, ricci_ten0, var_list) == 2
    assert scal_curv(g_ten0, ricci_ten0, var_list) == 2
예제 #31
0
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 riemann(g, var, type_output='t'):
    """Return the Riemann curvature tensor of type (1, -1, -1, -1)
    for the given metric tensor.

    Examples:
    =========

    >>> from sympy.tensor.riemannian_geometry import riemann
    >>> from sympy.tensor.arraypy import Arraypy, TensorArray
    >>> from sympy import symbols, cos
    >>> x1, x2 = symbols('x1, x2')

    var it's a list of symbolic arguments. May be a list, one-dimensional
    arraypy or one-dimensional tensor with valence of indices (+1):

    >>> var = [x1, x2]

    g it's a metric tensor must be symmetric matrix, arraypy or tensor
    with valence indices (-1, -1):

    >>> A = Arraypy((2, 2))
    >>> g = TensorArray(A,(-1, -1))
    >>> g[0,0] = cos(x2)**2
    >>> g[0,1] = 0
    >>> g[1,0] = 0
    >>> g[1,1] = 1

    type_output it's optional parameter function, indicating the type of calculation
    result and receiving the character or string value:
    - symbol 't' means that the type of the result will match TensorArray;
    - symbol 'a' means that the type of the result will be Arraypy;
    - default function takes a parameter 't', so that the result will be a TensorArray.

    The curvature tensor:
    >>> r = riemann(g, var, 'a')
    >>> print(r)
    0  0
    0  0
    0  -cos(x2)**2
    1  0
    0  cos(x2)**2
    -1  0
    0  0
    0  0

    """
    # Handling of input vector of arguments - var
    if not isinstance(var, (list, Arraypy, TensorArray)):
        raise TypeError(
            'The type of vector of arguments must be a list, Arraypy or TensorArray')
    if isinstance(var, (TensorArray, Arraypy)):
        if len(var.shape) != 1:
            raise ValueError("The dimension of vector of arguments must be 1")
        if isinstance(var, TensorArray):
            if not var.type_pq == (1, 0):
                raise ValueError(
                    'The valence of vector of arguments must be (+1)')
    if isinstance(var, (TensorArray, Arraypy)):
        var = var.to_list()

    # Definition of number of variables
    n = len(var)

    # Handling of a input argument - metric tensor g
    if not isinstance(g, (Matrix, Arraypy, TensorArray)):
        raise TypeError(
            'The type of metric tensor must be Matrix, TensorArray or Arraypy')
    else:
        if isinstance(g, (Arraypy, TensorArray)):
            if isinstance(g, TensorArray):
                if not g.type_pq == (0, 2):
                    raise ValueError(
                        'The valence of metric tensor must be (-1,-1)')
            if not is_symmetric(g):
                raise ValueError('The metric tensor must be symmetric.')
            if not (g.start_index[0] == g.start_index[1]):
                raise ValueError(
                    'The starting indices of metric tensor must be identical')
            idx_start = g.start_index[0]
        elif isinstance(g, Matrix):
            if not g.is_symmetric():
                raise ValueError('The metric tensor must be symmetric.')
            idx_start = 0

    # The definition of diapason changes in an index
    [n1, n2] = g.shape
    if not n == n1:
        raise ValueError(
            'The rank of the metric tensor does not coincide with the number of variables.')

    indices = range(idx_start, idx_start + n)

    # Creating of output array with new indices
    R = Arraypy([4, n, idx_start])
    ch_2 = christoffel_2(g, var)

    # Calculation
    for i in indices:
        for j in indices:
            for k in indices:
                for l in indices:
                    R[i,
                      j,
                      k,
                      l] = diff(ch_2[j,
                                     k,
                                     l],
                                var[i - idx_start]) - diff(ch_2[i,
                                                                k,
                                                                l],
                                                           var[j - idx_start]) + sum([ch_2[i,
                                                                                           p,
                                                                                           l] * ch_2[j,
                                                                                                     k,
                                                                                                     p] - ch_2[j,
                                                                                                               p,
                                                                                                               l] * ch_2[i,
                                                                                                                         k,
                                                                                                                         p] for p in indices])

    # Handling of an output array
    if type_output == str('t') or type_output == Symbol('t'):
        riemann = R.to_tensor((1, -1, -1, -1))
    elif type_output == str('a') or type_output == Symbol('a'):
        riemann = R
    else:
        raise ValueError(
            "The parameter of type output result must 'a' - Arraypy or 't' and None - TensorArray.")

    # Output
    return riemann
예제 #33
0
def grad(f, args, g=None, output_type=None):
    """Return the vector field gradient of a function f(x).

    Examples:
    =========

    >>> from sympy.tensor.tensor_fields import grad
    >>> from sympy import symbols, sin
    >>> from sympy.tensor.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
예제 #34
0
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 sympy.tensor.tensor_fields import curl
    >>> from sympy import symbols, cos
    >>> from sympy.tensor.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
예제 #35
0
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 sympy.tensor.tensor_fields import lie_w
    >>> from sympy import symbols, cos
    >>> from sympy.tensor.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 covar_der(X, g, var, type_output='t'):
    """Return the covariant derivative the vector field.

    Examples:
    =========

    >>> from sympy.tensor.riemannian_geometry import covar_der
    >>> from sympy.tensor.arraypy import Arraypy, TensorArray
    >>> from sympy import symbols, cos
    >>> x1, x2 = symbols('x1, x2')

    var it's a list of symbolic arguments. May be a list, one-dimensional
    arraypy or one-dimensional tensor with valence of indices (+1):

    >>> var = [x1, x2]

    g it's a metric tensor must be symmetric matrix, arraypy or tensor
    with valence indices (-1, -1):

    >>> A = Arraypy((2, 2))
    >>> g = TensorArray(A,(-1, -1))
    >>> g[0,0] = cos(x2)**2
    >>> g[0,1] = 0
    >>> g[1,0] = 0
    >>> g[1,1] = 1

    X it's vector field can be a list, one-dimensional arraypy, or one-dimensional
    tensor with valences of indices (+1):

    >>> X = [x1 * x2**3, x1 - cos(x2)]

    type_output it's optional parameter function, indicating the type of calculation
    result and receiving the character or string value:
    - symbol 't' means that the type of the result will match TensorArray;
    - symbol 'a' means that the type of the result will be Arraypy;
    - default function takes a parameter 't', so that the result will be a TensorArray.

    The covariant derivative:
    >>> c_v = covar_der(X, g, var, 't')
    >>> print(c_v)
    x2**3 - (x1 - cos(x2))*sin(x2)/cos(x2)  x1*x2**3*sin(x2)*cos(x2) + 1
    -x1*x2**3*sin(x2)/cos(x2) + 3*x1*x2**2  sin(x2)
    >>> c_v.type_pq
    (1, 1)

    """
    # Handling of input vector of arguments - var
    if not isinstance(var, (list, Arraypy, TensorArray)):
        raise TypeError(
            'The type of vector of arguments must be a list, Arraypy or TensorArray')
    if isinstance(var, (TensorArray, Arraypy)):
        if len(var.shape) != 1:
            raise ValueError("The dimension of vector of arguments must be 1")
        if isinstance(var, TensorArray):
            if not var.type_pq == (1, 0):
                raise ValueError(
                    'The valence of vector of arguments must be (+1)')
    if isinstance(var, (TensorArray, Arraypy)):
        var = var.to_list()

    # Definition of number of variables
    n = len(var)

    # Handling of a input argument - metric tensor g
    if not isinstance(g, (Matrix, Arraypy, TensorArray)):
        raise TypeError(
            'The type of metric tensor must be Matrix, TensorArray or Arraypy')
    else:
        if isinstance(g, (Arraypy, TensorArray)):
            if isinstance(g, TensorArray):
                if not g.type_pq == (0, 2):
                    raise ValueError(
                        'The valence of metric tensor must be (-1,-1)')
            if not is_symmetric(g):
                raise ValueError('The metric tensor must be symmetric.')
            if not (g.start_index[0] == g.start_index[1]):
                raise ValueError(
                    'The starting indices of metric tensor must be identical')
            idx_g = g.start_index[0]
        elif isinstance(g, Matrix):
            if not g.is_symmetric():
                raise ValueError('The metric tensor must be symmetric.')
            idx_g = 0

    # Handling of a input argument - vector field X
    if not isinstance(X, (list, Arraypy, TensorArray)):
        raise TypeError(
            'The type of vector field must be list, TensorArray or Arraypy')
    else:
        if isinstance(X, (Arraypy, TensorArray)):
            if len(X.shape) != 1:
                raise ValueError("The dimension of vector field must be 1")
            if isinstance(X, TensorArray):
                if not X.type_pq == (1, 0):
                    raise ValueError(
                        'The valence of vector field must be (+1)')
            idx_X = X.start_index[0]
        elif isinstance(X, list):
            idx_X = 0

    # The definition of diapason changes in an index
    [n1, n2] = g.shape
    if not n == n1:
        raise ValueError(
            'The rank of the metric tensor does not coincide with the number of variables.')

    if (idx_g != idx_X):
        raise ValueError(
            'The start index of the metric tensor and vector field must be equal')
    else:
        idx_start = idx_g

    indices = range(idx_start, idx_start + n)

    # Creating of output array with new indices
    cov = Arraypy([2, n, idx_start])
    ch_2 = christoffel_2(g, var)
    # Calculation
    for i in indices:
        for j in indices:
            cov[i, j] = diff(X[j], var[i - idx_start]) + \
                Add(*[ch_2[k, i, j] * X[k] for k in indices])

    # Handling of an output array
    if type_output == str('t') or type_output == Symbol('t'):
        cov_der = cov.to_tensor((1, -1))
    elif type_output == str('a') or type_output == Symbol('a'):
        cov_der = cov
    else:
        raise ValueError(
            "The parameter of type output result must 'a' - Arraypy or 't' and None - TensorArray.")

    # Output
    return cov_der
예제 #37
0
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 sympy.tensor.tensor_fields import dw
    >>> from sympy import symbols
    >>> from sympy.tensor.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 covar_der_XY(X, Y, g, var, type_output='t'):
    """Return the covariant derivative the vector field along another field.

    Examples:
    =========

    >>> from sympy.tensor.riemannian_geometry import covar_der_XY
    >>> from sympy.tensor.arraypy import Arraypy, TensorArray
    >>> from sympy import symbols, cos
    >>> x1, x2 = symbols('x1, x2')

    var it's a list of symbolic arguments. May be a list, one-dimensional arraypy
    or one-dimensional tensor with valence of indices (+1):

    >>> var = [x1, x2]

    g it's a metric tensor must be symmetric matrix, arraypy or tensor
    with valences indices (-1, -1):

    >>> A = Arraypy((2, 2))
    >>> g = TensorArray(A,(-1, -1))
    >>> g[0,0] = cos(x2)**2
    >>> g[0,1] = 0
    >>> g[1,0] = 0
    >>> g[1,1] = 1

    X, Y it's vector fields may be lists, one-dimensional arraypy,
    or one-dimensional tensor indices with valences (+ 1):

    >>> X = [x1 * x2**3, x1 - cos(x2)]
    >>> Y = [1, 2]

    type_output it's optional parameter function, indicating the type of calculation
    result and receiving the character or string value:
    - symbol 't' means that the type of the result will match TensorArray;
    - symbol 'a' means that the type of the result will be Arraypy;
    - default function takes a parameter 't', so that the result will be a TensorArray.

    The covariant derivative along another vector field:
    >>> c_v_XY = covar_der_XY(X, Y, g, var, 't')
    >>> print(c_v_XY)
    -2*x1*x2**3*sin(x2)/cos(x2) + 6*x1*x2**2 + x2**3 - (x1 - cos(x2))*sin(x2)/cos(x2) \
    x1*x2**3*sin(x2)*cos(x2) + 2*sin(x2) + 1

    """
    # Handling of input vector of arguments - var
    if not isinstance(var, (list, Arraypy, TensorArray)):
        raise TypeError(
            'The type of vector of arguments must be a list, Arraypy or TensorArray')
    if isinstance(var, (TensorArray, Arraypy)):
        if len(var.shape) != 1:
            raise ValueError("The dimension of vector of arguments must be 1!")
        if isinstance(var, TensorArray):
            if not var.type_pq == (1, 0):
                raise ValueError(
                    'The valence of vector of arguments must be (+1)')
    if isinstance(var, (TensorArray, Arraypy)):
        var = var.to_list()

    # Definition of number of variables
    n = len(var)

    # Handling of a input argument - metric tensor g
    if not isinstance(g, (Matrix, Arraypy, TensorArray)):
        raise TypeError(
            'The type of metric tensor must be Matrix, TensorArray or Arraypy')
    else:
        if isinstance(g, (Arraypy, TensorArray)):
            if isinstance(g, TensorArray):
                if not g.type_pq == (0, 2):
                    raise ValueError(
                        'The valence of metric tensor must be (-1,-1)')
            if not is_symmetric(g):
                raise ValueError('The metric tensor must be symmetric.')
            if not (g.start_index[0] == g.start_index[1]):
                raise ValueError(
                    'The starting indices of metric tensor must be identical')
            idx_g = g.start_index[0]
        elif isinstance(g, Matrix):
            if not g.is_symmetric():
                raise ValueError('The metric tensor must be symmetric.')
            idx_g = 0

    # Handling of a input argument - vector field X
    if not isinstance(X, (list, Arraypy, TensorArray)):
        raise TypeError(
            'The type of vector field must be list, TensorArray or Arraypy')
    else:
        if isinstance(X, (Arraypy, TensorArray)):
            if len(X.shape) != 1:
                raise ValueError("The dimension of vector field must be 1")
            if isinstance(X, TensorArray):
                if not X.type_pq == (1, 0):
                    raise ValueError(
                        'The valence of vector field must be (+1)')
            idx_X = X.start_index[0]
        elif isinstance(X, list):
            idx_X = 0

    # Handling of a input argument - vector field Y
    if not isinstance(Y, (list, Arraypy, TensorArray)):
        raise TypeError(
            'The type of vector field must be list, TensorArray or Arraypy')
    else:
        if isinstance(Y, (Arraypy, TensorArray)):
            if len(Y.shape) != 1:
                raise ValueError("The dimension of vector field must be 1")
            if isinstance(Y, TensorArray):
                if not Y.type_pq == (1, 0):
                    raise ValueError(
                        'The valence of vector field must be (+1)')
            idx_Y = Y.start_index[0]
        elif isinstance(Y, list):
            idx_Y = 0

    [n1, n2] = g.shape
    if not len(X) == len(Y):
        raise ValueError('The vectors must be identical length')
    elif not idx_X == idx_Y:
        raise ValueError('The start index of vector fields must be equal')
    elif not(idx_g == idx_X):
        raise ValueError(
            'The start index of the metric tensor and vector field must be equal')
    else:
        idx_start = idx_g
    if len(X) != n1:
        raise ValueError(
            'The vector fields and dimension of metric tensor must be identical length')

    # The definition of diapason changes in an index
    if not n == n1:
        raise ValueError(
            'The rank of the metric tensor does not concide with the number of variables.')
    indices = range(idx_start, idx_start + n)

    # Creating of output array with new indices
    nabla_XY = Arraypy([1, n, idx_start])
    nabla_X = covar_der(X, g, var)

    # Calculation
    for j in indices:
        nabla_XY[j] = sum([nabla_X[i, j] * Y[i] for i in indices])

    # Handling of an output array
    if type_output == str('t') or type_output == Symbol('t'):
        cov_der_XY = nabla_XY.to_tensor((1))
    elif type_output == str('a') or type_output == Symbol('a'):
        cov_der_XY = nabla_XY
    else:
        raise ValueError(
            "The parameter of type output result must 'a' - Arraypy or 't' and None - TensorArray.")

    # Output
    return cov_der_XY
예제 #39
0
def df(f, args, output_type='l'):
    """Return an the 1-form df, differential of function f(x).

    Examples:
    =========

    >>> from sympy.tensor.tensor_fields import df
    >>> from sympy import symbols, sin
    >>> from sympy.tensor.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
예제 #40
0
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 sympy.tensor.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
예제 #41
0
def int_product(w, X):
    """Calculation of the inner product of the form and the vector field.
    Return.

    Examples:
    =========
    >>> from sympy import symbols
    >>> from sympy.tensor.arraypy import Arraypy
    >>> from sympy.tensor.tensor_fields import int_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(int_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 ricci(riemann, var, type_output='t'):
    """Return the tensor Ricci of type (-1, -1), is symmetric tensor
    for given Riemann curvature tensor.

    Examples:
    =========

    >>> from sympy.tensor.riemannian_geometry import ricci, riemann
    >>> from sympy.tensor.arraypy import Arraypy, TensorArray
    >>> from sympy import symbols, cos
    >>> x1, x2 = symbols('x1, x2')

    var it's a list of symbolic arguments. May be a list, one-dimensional
    arraypy or one-dimensional tensor with valence of indices (+1):

    >>> var = [x1, x2]

    g it's a metric tensor must be symmetric matrix, arraypy or tensor
    with valence indices (-1, -1):

    >>> A = Arraypy((2,2))
    >>> g = TensorArray(A,(-1,-1))
    >>> g[0,0] = cos(x2)**2
    >>> g[0,1] = 0
    >>> g[1,0] = 0
    >>> g[1,1] = 1

    riemann it's a Riemann curvature tensor must be symmetric matrix,
    arraypy or tensor with valences indices (-1, -1, -1, 1):

    >>> cur = riemann(g, var, 't')

    type_output it's optional parameter function, indicating the type of calculation
    result and receiving the character or string value:
    - symbol 't' means that the type of the result will match TensorArray;
    - symbol 'a' means that the type of the result will be Arraypy;
    - default function takes a parameter 't', so that the result will be a TensorArray.

    The Ricci tensor:
    >>> r = ricci(cur, var, 't')
    >>> print(r)
    cos(x2)**2  0
    0  1
    >>> r.type_pq
    (0, 2)
    """
    # Handling of input vector of arguments - var
    if not isinstance(var, (list, Arraypy, TensorArray)):
        raise TypeError(
            'The type of vector of arguments must be a list, Arraypy or TensorArray')
    if isinstance(var, (TensorArray, Arraypy)):
        if len(var.shape) != 1:
            raise ValueError("The dimension of vector of arguments must be 1")
        if isinstance(var, TensorArray):
            if not var.type_pq == (1, 0):
                raise ValueError(
                    'The valence of vector of arguments must be (+1)')
    if isinstance(var, (TensorArray, Arraypy)):
        var = var.to_list()

    # Definition of number of variables
    n = len(var)

    # Handling of a input argument Riemann curvature tensor - riemann
    if not isinstance(riemann, (Matrix, Arraypy, TensorArray)):
        raise TypeError(
            'The type of Riemann curvature tensor must be Matrix, Arraypy or TensorArray')
    else:
        if isinstance(riemann, (Arraypy, TensorArray)):
            if isinstance(riemann, TensorArray):
                if not riemann.type_pq == (1, 3):
                    raise ValueError(
                        'The valence of Riemann curvature tensor must be (1, -1, -1, -1)')
                if not (
                    riemann.start_index.count(
                        riemann.start_index[0]) == 4):
                    raise ValueError(
                        'The starting indices of Riemann curvature tensor must be identical')
            idx_start = riemann.start_index[0]
        else:
            idx_start = 0

    # The definition of diapason changes in an index
    [n1, n2, n3, n4] = riemann.shape
    if not n == n1:
        raise ValueError(
            'The rank of the Riemann curvature tensor does not coincide with the number of variables.')

    indices = range(idx_start, idx_start + n)

    # Creating of output array with new indices
    Ri = Arraypy([2, n, idx_start])

    # Calculation
    for j in indices:
        for k in indices:
            Ri[j, k] = sum([riemann[i, j, k, i] for i in indices])

    # Handling of an output array
    if type_output == str('t') or type_output == Symbol('t'):
        ricci = Ri.to_tensor((-1, -1))
    elif type_output == str('a') or type_output == Symbol('a'):
        ricci = Ri
    else:
        raise ValueError(
            "The parameter of type output result must 'a' - Arraypy or 't' and None - TensorArray.")

    # Output
    return ricci
def christoffel_2(g, var, type_output='t'):
    """Return the (1, -1, -1) - tensor of Christoffel symbols for the given metric.
    This returns the Christoffel symbol of second kind that represents the
    Levi-Civita connection for the given metric.

    Examples:
    =========

    >>> from sympy.tensor.riemannian_geometry import christoffel_2
    >>> from sympy.tensor.arraypy import Arraypy, TensorArray
    >>> from sympy import symbols, cos
    >>> x1, x2 = symbols('x1, x2')

    var it's a list of symbolic arguments. May be a list, one-dimensional
    arraypy or one-dimensional tensor with valence of indices (+1):

    >>> var = [x1, x2]

    g it's a metric tensor must be symmetric matrix, arraypy or tensor
    with valence indices (-1, -1):

    >>> A = Arraypy((2, 2))
    >>> g = TensorArray(A,(-1, -1))
    >>> g[0,0] = cos(x2)**2
    >>> g[0,1] = 0
    >>> g[1,0] = 0
    >>> g[1,1] = 1

    type_output it's optional parameter function, indicating the type of calculation
    result and receiving the character or string value:
    - symbol 't' means that the type of the result will match TensorArray;
    - symbol 'a' means that the type of the result will be Arraypy;
    - default function takes a parameter 't', so that the result will be a TensorArray.

    The Christoffel symbols of the second kind:
    >>> ch_2 = christoffel_2(g, var, 'a')
    >>> print(ch_2)
    0  sin(x2)*cos(x2)
    -sin(x2)/cos(x2)  0
    -sin(x2)/cos(x2)  0
    0  0

    """
    # Handling of input vector of arguments - var
    if not isinstance(var, (list, Arraypy, TensorArray)):
        raise TypeError(
            'The type of vector of arguments must be a list, Arraypy or TensorArray')
    if isinstance(var, (TensorArray, Arraypy)):
        if len(var.shape) != 1:
            raise ValueError("The dimension of vector of arguments must be 1")
        if isinstance(var, TensorArray):
            if not var.type_pq == (1, 0):
                raise ValueError(
                    'The valence of vector of arguments must be (+1)')
    if isinstance(var, (TensorArray, Arraypy)):
        var = var.to_list()
    # Definition of number of variables
    n = len(var)

    # Handling of a input argument - metric tensor g
    if not isinstance(g, (Matrix, Arraypy, TensorArray)):
        raise TypeError(
            'The type of metric tensor must be Matrix, TensorArray or Arraypy')
    else:
        if isinstance(g, (Arraypy, TensorArray)):
            if isinstance(g, TensorArray):
                if not g.type_pq == (0, 2):
                    raise ValueError(
                        'The valence of metric tensor must be (-1,-1)')
            if not is_symmetric(g):
                raise ValueError('The metric tensor must be symmetric.')
            if not (g.start_index[0] == g.start_index[1]):
                raise ValueError(
                    'The starting indices of metric tensor must be identical')
            idx_start = g.start_index[0]
            g_inv = (g.to_matrix()).inv()
        elif isinstance(g, Matrix):
            if not g.is_symmetric():
                raise ValueError('The metric tensor must be symmetric.')
            idx_start = 0
            g_inv = g.inv()

    # The definition of diapason changes in an index
    [n1, n2] = g.shape
    if not n == n1:
        raise ValueError(
            'The rank of the metric tensor does not coincide with the number of variables.')

    indices = range(idx_start, idx_start + n)

    # Creating of output array with new indices
    Ch = Arraypy([3, n, idx_start])

    # Calculation
    for i in indices:
        for j in indices:
            for k in indices:
                Ch[i,
                   j,
                   k] = Add(*[g_inv[k - idx_start,
                                    l - idx_start] * (diff(g[j,
                                                             l],
                                                           var[i - idx_start]) + diff(g[i,
                                                                                        l],
                                                                                      var[j - idx_start]) - diff(g[i,
                                                                                                                   j],
                                                                                                                 var[l - idx_start])) / 2 for l in indices])

    # Other variant calculation
    # christ_1 = christoffel_1(g, var)
    # for i in indices:
        # for j in indices:
            # for k in indices:
                # Ch[i,
                # j,
                # k] = Add(*[g_inv[k,
                # l] *christ_1[i,
                # j,
                # l] for l in indices])

    # Handling of an output array
    if type_output == str('t') or type_output == Symbol('t'):
        christoffel_2 = Ch.to_tensor((1, -1, -1))
    elif type_output == str('a') or type_output == Symbol('a'):
        christoffel_2 = Ch
    else:
        raise ValueError(
            "The parameter of type output result must 'a' - Arraypy or 't' and None - TensorArray.")

    # Output
    return christoffel_2