Beispiel #1
0
def tensor2wedgearray(A):
    """Function takes a skew-symmetric array and will give array in
    which the indices are in ascending order. Return array of type
    WedgeArray.

    Examples:
    =========

    >>> from sympy import symbols
    >>> from sympy.tensor.arraypy import Arraypy, TensorArray
    >>> from sympy.tensor.tensor_fields import tensor2wedgearray

    >>> 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)
    >>> for key in sorted(A._output):
    ...     print(str(key) +'=>'+ str(A._output[key]))
    (0, 1)=>x3
    (0, 2)=>-x2
    (1, 2)=>x1

    """

    # Handling of a tensor
    if not isinstance(A, (Arraypy, TensorArray)):
        raise ValueError("The type of form must be Arraypy")
    if not is_asymmetric(A):
        raise ValueError("The form must be a skew-symmetric")

    # The valency (0,q)
    if isinstance(A, (TensorArray)) and A.type_pq[0] != 0:
        raise ValueError("The valency of tensor must be (0,q)")

    # The definition of the start index
    start_idx_A = A.start_index[0]

    lst_of_new_index = []

    # index it'a a one index of A(tuple)
    for index in A.index_list:
        index_list_sort = sorted(index)
        if(index_list_sort == list(index)) and \
                len(set(list(index))) == len(index):
            lst_of_new_index.append(index)

    # creating class instance
    wedge = WedgeArray()

    # wedge._output - it's a dictionary Wedge_array
    for index in lst_of_new_index:
        wedge._output[index] = A[index]
    return wedge
def tensor2wedgearray(A):
    """
    Function takes a skew-symmetric array and will give array in
    which the indices are in ascending order. Return array of type
    Wedge_array.

    Examples:
    =========
    >>> from sympy import symbols
    >>> from sympy.tensor.arraypy import Arraypy, TensorArray
    >>> from sympy.tensor.tensor_fields import tensor2wedgearray

    >>> 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)
    >>> for key in sorted(A._output):
    ...     print(str(key) +'=>'+ str(A._output[key]))
    (0, 1)=>x3
    (0, 2)=>-x2
    (1, 2)=>x1

    """
    # Handling of a tensor
    if not isinstance(A, (Arraypy, TensorArray)):
        raise ValueError("The type of form must be Arraypy")
    if not is_asymmetric(A):
        raise ValueError("The form must be a skew-symmetric")

    # The valency (0,q)
    if isinstance(A, (TensorArray)) and A.type_pq[0] != 0:
        raise ValueError("The valency of tensor must be (0,q)")

    # The definition of the start index
    start_idx_A = A.start_index[0]

    lst_of_new_index = []

    # index it'a a one index of A(tuple)
    for index in A.index_list:
        index_list_sort = sorted(index)
        if(index_list_sort == list(index)) and \
                len(set(list(index))) == len(index):
            lst_of_new_index.append(index)

    # creating class instance
    wedge = Wedge_array()

    # wedge._output - it's a dictionary Wedge_array
    for index in lst_of_new_index:
        wedge._output[index] = A[index]
    return wedge
Beispiel #3
0
def test_is_symmetric():
    a = list2arraypy([0, 3, 5, 3, 0, 0, 5, 0, 0], (3, 3))
    assert not is_asymmetric(a)
    assert is_symmetric(a)
Beispiel #4
0
def inner_product(w, X):
    """Calculation of the inner product of the form and the vector field.

    Examples:
    =========

    >>> from sympy import symbols
    >>> from sympy.tensor.arraypy import Arraypy
    >>> from sympy.tensor.tensor_fields import inner_product

    >>> x1, x2, x3, l, m, n = symbols('x1 x2 x3 l m n')
    >>> omega2=Arraypy([2,3,1]).to_tensor((-1,-1))
    >>> omega2[1,2]=x3
    >>> omega2[1,3]=-x2
    >>> omega2[2,1]=-x3
    >>> omega2[2,3]=x1
    >>> omega2[3,1]=x2
    >>> omega2[3,2]=-x1

    >>> X_t=Arraypy([1,3,1]).to_tensor((1))
    >>> X_t[1]=l
    >>> X_t[2]=m
    >>> X_t[3]=n

    >>> print(inner_product(omega2, X_t))
    -m*x3 + n*x2  l*x3 - n*x1  -l*x2 + m*x1

    """
    # Handling of a differential form
    if not isinstance(w, (TensorArray, Arraypy)):
        raise ValueError(
            "The type of differential form must be TensorArray or Arraypy")

    # The valency (0,q)
    if (len(w.type_pq) == 1 and w.type_pq[0] != 1) or (len(w.type_pq) > 1
                                                       and w.type_pq[0] != 0):
        raise ValueError("The valency of tensor must be (0,q)")
    if not is_asymmetric(w):
        raise ValueError("The form must be a skew-symmetric")

    # Handling of a vector field
    check_the_vector_field(X)
    if isinstance(X, (TensorArray, Arraypy)):
        idx_start_X = X.start_index[0]
    else:
        idx_start_X = 0

    # Define the start index in the output form
    idx_start_w = w.start_index[0]
    if idx_start_w != idx_start_X:
        raise ValueError(
            "The start index of tensor and vector field must be equal")

    # Creating the output array in accordance with start indexes
    n = w.shape[0]  # the dimension of the input array
    q = len(w.shape)  # the rank of the input array
    if (q != 1):
        result_tensor = Arraypy([q - 1, n, idx_start_w])
        # all indices are -1
        valence_list = [(-1) for k in range(q - 1)]
        # result tensor
        int_prod = result_tensor.to_tensor(valence_list)

        for index in int_prod.index_list:
            # the sum on k.k is [0,n-1], n is len(X)
            for k in range(len(X)):
                idx = list(index)
                idx.insert(0, k + idx_start_w)
                int_prod[index] += w[tuple(idx)] * X[k + idx_start_w]
    if q == 1:
        # int_prod is number(symbolic expression)
        int_prod = 0
        for index in w.index_list:
            for k in range(len(X)):
                int_prod += w[index] * X[k + idx_start_w]
    # Output
    return int_prod
Beispiel #5
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
Beispiel #6
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
Beispiel #7
0
def hodge_star(T, g):
    """The calculation actions on the forms of the Hodge operator's.

    Examples:
    =========
    >>> from sympy import symbols, Matrix
    >>> from sympy.tensor.arraypy import Arraypy, TensorArray
    >>> from sympy.tensor.tensor_fields import hodge_star

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

    >>> y2 = TensorArray(Arraypy((3, 3)), (-1, -1))
    >>> y2[0, 1] = x3*x4
    >>> y2[0, 2] = -x2**3
    >>> y2[1, 0] = -x3*x4
    >>> y2[1, 2] = x1*x2
    >>> y2[2, 0] = x2**3
    >>> y2[2, 1] = -x1*x2
    >>> g = Matrix([[1,3,0],[-3,1,0],[0,0,1]])
    >>> print(hodge_star(y2,g))
    sqrt(10)*x1*x2/5 - 3*sqrt(10)*x2**3/5  3*sqrt(10)*x1*x2/5 + sqrt(10)*x2**3/5  sqrt(10)*x3*x4/5

    """

    if not isinstance(T, (TensorArray)):
        raise ValueError("The type of tensor must be TensorArray")

    if (len(T.type_pq) == 1 and T.type_pq[0] != 1) or (len(T.type_pq) > 1
                                                       and T.type_pq[0] != 0):
        raise ValueError("The valency of tensor must be (0,q)")
    if T.rank > 1:
        if not is_asymmetric(T):
            raise ValueError("The tensor must be a skew-symmetric")

    # Handling of the metric tensor
    check_metric_tensor(g)
    if isinstance(g, (TensorArray, Arraypy)):
        idx_start_g = g.start_index[0]
        det_g = det(g.to_matrix())
    else:
        idx_start_g = 0
        det_g = det(g)
        g = matrix2tensor(g)

    # The definition of the start index
    idx_start_T = T.start_index[0]

    if idx_start_T != idx_start_g:
        raise ValueError(
            "The start index of the tensor and metric must be equal")

    # 1. Calculating of tensor mu
    n = T.shape[0]  # the dimension of the input array
    k = T.rank
    sqrt_det_g = simplify(sqrt(abs(det_g)))

    valence_list_mu = [(-1) for i in range(n)]
    mu = Arraypy([n, n, idx_start_g]).to_tensor(valence_list_mu)

    for idx in mu.index_list:
        mu[idx] = simplify(sqrt_det_g * sign_permutations(list(idx)))

    # 2. Tensor product mu and T
    uT = tensor_product(mu, T)

    # 3.Convolution by the first k-index and the last k-index
    # low_idx_numbers it is a list with the positions on which are the lower
    # indices
    low_idx_numbers = [i + 1 for i in range(k)]
    # Upping of the first k-lower indices of a tensor
    for position in low_idx_numbers:
        uT = raise_index(uT, g, position)

    # Convolution
    kn = n + 1
    for i in range(k):
        uT = uT.contract(1, kn)
        kn = kn - 1

    return uT
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 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 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 hodge_star(T, g):
    """The calculation actions on the forms of the Hodge operator's.

    Examples:
    =========
    >>> from sympy import symbols, Matrix
    >>> from sympy.tensor.arraypy import Arraypy, TensorArray
    >>> from sympy.tensor.tensor_fields import hodge_star

    >>> x1, x2, x3 = symbols('x1 x2 x3')
    >>> y3 = TensorArray(Arraypy((3, 3, 3)), (-1, -1, -1))
    >>> y3[0, 1, 2] = 3
    >>> y3[0, 2, 1] = -3
    >>> y3[1, 0, 2] = -3
    >>> y3[1, 2, 0] = 3
    >>> y3[2, 0, 1] = 3
    >>> y3[2, 1, 0] = -3
    >>> g = Matrix([[2,1,0],[1,3,0],[0,0,1]])
    >>> print(hodge_star(y3,g))
    96*sqrt(5)/5

    """

    if not isinstance(T, (TensorArray)):
        raise ValueError(
            "The type of tensor must be TensorArray")

    if (len(T.type_pq) == 1 and T.type_pq[0] != 1) or (len(T.type_pq) > 1 and
                                                       T.type_pq[0] != 0):
        raise ValueError("The valency of tensor must be (0,q)")
    if T.rank > 1:
        if not is_asymmetric(T):
            raise ValueError("The tensor must be a skew-symmetric")

    # Handling of the metric tensor
    check_metric_tensor(g)
    if isinstance(g, (TensorArray, Arraypy)):
        idx_start_g = g.start_index[0]
        det_g = det(g.to_matrix())
    else:
        idx_start_g = 0
        det_g = det(g)
        g = matrix2tensor(g)

    # The definition of the start index
    idx_start_T = T.start_index[0]

    if idx_start_T != idx_start_g:
        raise ValueError(
            "The start index of the tensor and metric must be equal")

    # 1. Calculating of tensor mu
    n = T.shape[0]  # the dimension of the input array
    k = T.rank
    sqrt_det_g = simplify(sqrt(abs(det_g)))

    valence_list_mu = [(-1) for i in range(n)]
    mu = Arraypy([n, n, idx_start_g]).to_tensor(valence_list_mu)

    for idx in mu.index_list:
        mu[idx] = simplify(sqrt_det_g * sign_permutations(list(idx)))

    # 2. Tensor product mu and T
    uT = tensor_product(mu, T)

    # 3.Convolution by the first k-index and the last k-index
    # low_idx_numbers it is a list with the positions on which are the lower
    # indices
    low_idx_numbers = [i + 1 for i in range(k)]
    # Upping of the first k-lower indices of a tensor
    for position in low_idx_numbers:
        uT = raise_index(uT, g, position)

    # Convolution
    for i in range(k):
        uT = uT.contract(1, k + 1)
        k = k - 1

    return uT