예제 #1
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)
예제 #2
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))
예제 #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_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)
예제 #5
0
def test_lie_w():

    x1, x2, x3 = symbols('x1, x2, x3')

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

    arr = Arraypy((3, 3))
    y = TensorArray(arr, (-1, -1))
    y1 = TensorArray(arr, (-1, -1))

    y[0, 1] = x3
    y[0, 2] = -x2
    y[1, 0] = -x3
    y[1, 2] = x1
    y[2, 0] = x2
    y[2, 1] = -x1

    y1[0, 1] = x2**3 * x3 + x3**3 + x3
    y1[0, 2] = -x2**4 - 3 * x2 * x3**2 - x2 + x3 * sin(x3) + cos(x3)
    y1[1, 0] = -x2**3 * x3 - x3**3 - x3
    y1[1, 2] = -2 * x1 * x2**3 + 3 * x1 * x3**2 + x1
    y1[2, 0] = x2**4 + 3 * x2 * x3**2 + x2 - x3 * sin(x3) - cos(x3)
    y1[2, 1] = 2 * x1 * x2**3 - 3 * x1 * x3**2 - x1

    assert lie_w(y, X, [x1, x2, x3]) == y1
    assert isinstance(lie_w(y, X, [x1, x2, x3]), TensorArray)
    assert lie_w(y, X, [x1, x2, x3]).type_pq == (0, 2)

    omega = TensorArray(arr, (-1, -1))
    omega[0, 1] = x2
    omega[1, 0] = -x2
    omega[0, 2] = -x1
    omega[2, 0] = x1

    ten = TensorArray(arr, (-1, -1))
    ten[0, 1] = x2**4 + 2 * x2 - cos(x3)
    ten[0, 2] = -2 * x1 * x2**3 - 3 * x1 * x3**2 + x2 * sin(x3)
    ten[1, 0] = -x2**4 - 2 * x2 + cos(x3)
    ten[1, 2] = -3 * x1**2 * x2**2
    ten[2, 0] = 2 * x1 * x2**3 + 3 * x1 * x3**2 - x2 * sin(x3)
    ten[2, 1] = 3 * x1**2 * x2**2

    assert lie_w(omega, X, [x1, x2, x3]) == ten
    assert isinstance(lie_w(omega, X, [x1, x2, x3]), TensorArray)
    assert lie_w(omega, X, [x1, x2, x3]).type_pq == (0, 2)
예제 #6
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
예제 #7
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
예제 #8
0
def tensor_product(first_tensor, second_tensor):
    """Returns tensor product. Rank of resulted tensor is a summary rank of two
    tensors.

    Examples
    ========

    >>> from sympy.tensor.arraypy import Arraypy, TensorArray
    >>> from sympy.tensor.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
예제 #9
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
예제 #10
0
def test_dw():
    x1, x2, x3 = symbols('x1 x2 x3')

    y = TensorArray(Arraypy((3, 3)), (-1, -1))
    y1 = TensorArray(Arraypy((3, 3, 3)), (-1, -1, -1))

    y[0, 1] = x3
    y[0, 2] = -x2
    y[1, 0] = -x3
    y[1, 2] = x1
    y[2, 0] = x2
    y[2, 1] = -x1

    y1[0, 1, 2] = 3
    y1[0, 2, 1] = -3
    y1[1, 0, 2] = -3
    y1[1, 2, 0] = 3
    y1[2, 0, 1] = 3
    y1[2, 1, 0] = -3

    assert dw(y, [x1, x2, x3]) == y1
    assert isinstance(dw(y, [x1, x2, x3]), TensorArray)
    assert dw(y, [x1, x2, x3]).type_pq == (0, 3)
예제 #11
0
def change_basis(tensor, transformation_matrix, old_to_new=True):
    """WORK IN PROGRESS.

    Changes basis of input TensorArray with help of transformation
    matrix from old to new (if corresponding argument is True) or from
    new to old (if False).

    """
    if not isinstance(tensor, TensorArray):
        raise TypeError('First argument must be of TensorArray type')
    if not isinstance(transformation_matrix, TensorArray):
        raise TypeError('Transformation matrix must be of TensorArray type')
    if transformation_matrix.rank != 2:
        raise ValueError('Transformation matrix must be of rank == 2')
    if transformation_matrix.ind_char != (1, -1):
        raise ValueError('Transformation matrix valency must be (1, -1)')

    temp_matrix = transformation_matrix.to_matrix().inv()
    inv_transformation_matrix = copy(transformation_matrix)
    # This is a strange way to transfer data from Matrix to TensorArray bellow.
    # But it's neccecery because TensorArray might have different index range.
    index = transformation_matrix.start_index
    for i in temp_matrix:
        inv_transformation_matrix[index] = i
        index = inv_transformation_matrix.next_index(index)
    # for testing reasons
    # inv_transformation_matrix = TensorArray(Arraypy((2,2), 'B'), (-1, 1))

    # forming list of tuples for Arraypy constructor of type a = Arraypy( [(a,
    # b), (c, d), ... , (y, z)] )
    arg = [(tensor.start_index[i], tensor.end_index[i])
           for i in range(tensor.rank)]
    temp_tensor = TensorArray(Arraypy(arg), tensor.ind_char)
    result_tensor = TensorArray(Arraypy(arg), tensor.ind_char)

    # lists, that represents where is upper index and where is low
    upper_idx_position = [
        i for i in range(len(tensor.ind_char)) if tensor.ind_char[i] == 1
    ]
    low_idx_position = [
        i for i in range(len(tensor.ind_char)) if tensor.ind_char[i] == -1
    ]

    # summ over upper indicies
    for idx in tensor.index_list:
        for i in upper_idx_position:
            for j in range(tensor.start_index[i], tensor.end_index[i] + 1):
                # forming index for multiplied tensor element
                # resulted index will be e.g. (1, j, 1).
                temp_idx = copy(idx)
                temp_idx[i] = j

                temp_tensor[idx] += transformation_matrix[
                    (idx[i], j)] * tensor[tuple(temp_idx)]

    # summ over low indicies
    for idx in tensor.index_list:
        for i in low_idx_position:
            for j in range(tensor.start_index[i], tensor.end_index[i] + 1):
                # forming index for multiplied tensor element
                # resulted index will be e.g. (1, j, 1).
                temp_idx = copy(idx)
                temp_idx[i] = j

                result_tensor[idx] += temp_tensor[tuple(
                    temp_idx)] * inv_transformation_matrix[(idx[i], j)]

    # expanding for more clear view. Should I do this?
    for idx in result_tensor.index_list:
        result_tensor[idx] = expand(result_tensor[idx])

    return result_tensor
예제 #12
0
def raise_index(tensor, metric_tensor, *index_numbers_to_raise):
    """Raising one lower index of the tensor.
    The index count starts from 1.

    Examples
    ========
    >>> from sympy import symbols, sin
    >>> from sympy.tensor.arraypy import list2tensor
    >>> from sympy.tensor.tensor_methods import raise_index
    >>> x, y, z, w, r, phi = symbols('x y z w r phi')
    >>> A = list2tensor([1, 0, 0, 0, r**2, 0, 0, 0, (r**2)*sin(phi)], (3, 3) ,(-1, -1))
    >>> print(A)
    1  0  0
    0  r**2  0
    0  0  r**2*sin(phi)

    >>> T = list2tensor([w, x, 0, y, z, 0, 0, y**2, x*y*w], (3, 3) ,(1, -1))
    >>> print(T)
    w  x  0
    y  z  0
    0  y**2  w*x*y

    >>> S = raise_index(T, A, 2)
    >>> print(S)
    w  x/r**2  0
    y  z/r**2  0
    0  y**2/r**2  w*x*y/(r**2*sin(phi))

    >>> print(S.ind_char)
    (1, 1)

    """
    index_numbers_to_raise = list(index_numbers_to_raise)
    for i in range(len(index_numbers_to_raise)):
        index_numbers_to_raise[i] -= 1

    if not isinstance(tensor, TensorArray):
        raise TypeError('Input tensor must be of TensorArray type')

    if not isinstance(metric_tensor, TensorArray):
        raise TypeError('Metric tensor must be of TensorArray type')

    if not metric_tensor.rank == 2:
        raise ValueError('Metric tensor rank must be equal to 2')

    if not metric_tensor.ind_char == (-1, -1):
        raise ValueError('Metric tensor must be covariant')

    for index_number in index_numbers_to_raise:
        if tensor.ind_char[index_number] == 1:
            raise ValueError('Index number should point on lower index')

    # forming list of tuples for Arraypy constructor of type a = Arraypy( [(a,
    # b), (c, d), ... , (y, z)] )
    arg = [(tensor.start_index[i], tensor.end_index[i])
           for i in range(tensor.rank)]
    new_ind_char = [i for i in tensor.ind_char]
    for i in index_numbers_to_raise:
        new_ind_char[i] = 1
    result_tensor = TensorArray(Arraypy(arg), new_ind_char)

    # finding contravariant reversed matrix
    matrix_reversed_metric_tensor = metric_tensor.to_matrix().inv()
    reversed_metric_tensor = copy(metric_tensor)

    # This is a strange way to transfer data from Matrix to TensorArray bellow.
    # But it's neccecery because TensorArray might have different index range.
    index = reversed_metric_tensor.start_index
    for i in matrix_reversed_metric_tensor:
        reversed_metric_tensor[index] = i
        index = reversed_metric_tensor.next_index(index)

    for index_number in index_numbers_to_raise:
        # loop over all tensor elements
        for cur_index in tensor.index_list:
            # loop over dimension pointed in index_number_to_low
            for j in range(tensor.start_index[index_number],
                           tensor.end_index[index_number] + 1):
                # forming indexes
                metric_tensor_index = (j, cur_index[index_number])
                temp_index = [i for i in cur_index]
                temp_index[index_number] = j
                result_tensor[cur_index] += tensor[tuple(
                    temp_index)] * reversed_metric_tensor[metric_tensor_index]
        tensor = copy(result_tensor)

    return result_tensor
예제 #13
0
def lower_index(tensor, metric_tensor, *index_numbers_to_low):
    """Lowering one upper index of the tensor.
    The index count starts from 1.

    Examples
    ========
    >>> from sympy import symbols, sin
    >>> from sympy.tensor.arraypy import list2tensor
    >>> from sympy.tensor.tensor_methods import lower_index
    >>> x, y, z, w, r, phi = symbols('x y z w r phi')
    >>> A = list2tensor([1, 0, 0, 0, r**2, 0, 0, 0, (r**2)*sin(phi)], (3, 3) ,(-1, -1))
    >>> print(A)
    1  0  0
    0  r**2  0
    0  0  r**2*sin(phi)

    >>> T = list2tensor([w, x, 0, y, z, 0, 0, y**2, x*y*w], (3, 3) ,(1, -1))
    >>> print(T)
    w  x  0
    y  z  0
    0  y**2  w*x*y

    >>> S1 = lower_index(T, A, 1)
    >>> print(S1)
    w  x  0
    r**2*y  r**2*z  0
    0  r**2*y**2*sin(phi)  r**2*w*x*y*sin(phi)

    >>> print(S1.ind_char)
    (-1, -1)

    """
    index_numbers_to_low = list(index_numbers_to_low)
    for i in range(len(index_numbers_to_low)):
        index_numbers_to_low[i] -= 1

    if not isinstance(tensor, TensorArray):
        raise TypeError('Input tensor must be of TensorArray type')

    if not isinstance(metric_tensor, TensorArray):
        raise TypeError('Metric tensor must be of TensorArray type')

    if not metric_tensor.rank == 2:
        raise ValueError('Metric tensor rank must be equal to 2')

    if not metric_tensor.ind_char == (-1, -1):
        raise ValueError('Metric tensor must be covariant')

    for index_number in index_numbers_to_low:
        if tensor.ind_char[index_number] == -1:
            raise ValueError('Index number should point on upper index')

    # forming list of tuples for Arraypy constructor of type a = Arraypy( [(a,
    # b), (c, d), ... , (y, z)] )
    arg = [(tensor.start_index[i], tensor.end_index[i])
           for i in range(tensor.rank)]
    new_ind_char = [i for i in tensor.ind_char]
    for i in index_numbers_to_low:
        new_ind_char[i] = -1
    result_tensor = TensorArray(Arraypy(arg), new_ind_char)

    for index_number in index_numbers_to_low:
        # loop over all tensor elements
        for cur_index in tensor.index_list:
            # loop over dimension pointed in index_number_to_low
            for j in range(tensor.start_index[index_number],
                           tensor.end_index[index_number] + 1):
                # forming indexes
                metric_tensor_index = (j, cur_index[index_number])
                temp_index = [i for i in cur_index]
                temp_index[index_number] = j
                result_tensor[cur_index] += tensor[tuple(
                    temp_index)] * metric_tensor[metric_tensor_index]
        tensor = copy(result_tensor)

    return result_tensor