Beispiel #1
0
def g_tensor(T, S, g):
    """The scalar product in the space of tensors.
    The result is a skew-symmetric form of (0, p-1).

    Examples:
    =========

    >>> from sympy import symbols, Matrix
    >>> from sympy.tensor.arraypy import Arraypy
    >>> from sympy.tensor.tensor_fields import g_tensor

    >>> x, y, z, w = symbols('x, y, z, w')
    >>> omega=Arraypy([2,3,0]).to_tensor((-1,1))
    >>> omega[0,0]=w
    >>> omega[0,1]=x
    >>> omega[1,0]=y
    >>> omega[1,1]=z
    >>> omega[2,1]=y*y
    >>> omega[2,2]=x*y*w
    >>> g = Matrix([[2,1,0],[1,3,0],[0,0,1]])
    >>> print(g_tensor(omega,omega,g))
    w**2*x**2*y**2 + 3*y**4 + (-w/5 + 2*y/5)*(2*y + z) + (3*w/5 - y/5)*(2*w + x) + (w + 3*x)*(3*x/5 - z/5) + (-x/5 + 2*z/5)*(y + 3*z)

    """
    # Handling of a input tensors
    if not isinstance(T, TensorArray) and not isinstance(S, TensorArray):
        raise ValueError(
            "The type of first and second arguments must be TensorArray")

    if sum(T.type_pq) != sum(S.type_pq):
        raise ValueError("The valency of tensor must be equal")

    # Handling of the metric tensor
    check_metric_tensor(g)
    if isinstance(g, Matrix):
        g = matrix2tensor(g, (-1, -1))

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

    if idx_start_S != idx_start_T:
        raise ValueError("The start index of the tensors must be equal")
    if isinstance(g, Matrix):
        idx_start_g = 0
    else:
        idx_start_g = g.start_index[0]
    if idx_start_S != idx_start_g:
        raise ValueError(
            "The start index of the tensor and metric must be equal")

    # 1.Lowering of the top indices of a tensor T
    # upper_idx_numbers it is a list with the positions on which are the upper
    # indices
    upper_idx_numbers = [
        k + 1 for k in range(len(T.ind_char)) if T.ind_char[k] == 1
    ]
    if len(upper_idx_numbers) != 0:
        for position in upper_idx_numbers:
            T = lower_index(T, g, position)

    # 2. Upping of the lower indices of a tensor S
    # low_idx_numbers it is a list with the positions on which are the lower
    # indices
    low_idx_numbers = [
        k + 1 for k in range(len(S.ind_char)) if S.ind_char[k] == -1
    ]

    if len(low_idx_numbers) != 0:
        for position in low_idx_numbers:
            S = raise_index(S, g, position)

    # 3.Convolution of the first index
    result = 0
    for index in S.index_list:
        result += T[index] * S[index]

    return result
Beispiel #2
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
Beispiel #3
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 g_tensor(T, S, g):
    """
    The scalar product in the space of tensors.
    The result is a skew-symmetric form of (0, p-1).

    Examples:
    =========

    >>> from sympy import symbols, Matrix
    >>> from sympy.tensor.arraypy import Arraypy
    >>> from sympy.tensor.tensor_fields import g_tensor

    >>> x, y, z, w = symbols('x, y, z, w')
    >>> omega=Arraypy([2,3,0]).to_tensor((-1,1))
    >>> omega[0,0]=w
    >>> omega[0,1]=x
    >>> omega[1,0]=y
    >>> omega[1,1]=z
    >>> omega[2,1]=y*y
    >>> omega[2,2]=x*y*w
    >>> g = Matrix([[2,1,0],[1,3,0],[0,0,1]])
    >>> print(g_tensor(omega,omega,g))
    w**2*x**2*y**2 + 3*y**4 + (-w/5 + 2*y/5)*(2*y + z) + (3*w/5 - y/5)*(2*w + x) + (w + 3*x)*(3*x/5 - z/5) + (-x/5 + 2*z/5)*(y + 3*z)

    """
    # Handling of a input tensors
    if not isinstance(T, TensorArray) and not isinstance(S, TensorArray):
        raise ValueError(
            "The type of first and second arguments must be TensorArray")

    if sum(T.type_pq) != sum(S.type_pq):
        raise ValueError("The valency of tensor must be equal")

    # Handling of the metric tensor
    check_metric_tensor(g)
    if isinstance(g, Matrix):
        g = matrix2tensor(g, (-1, -1))

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

    if idx_start_S != idx_start_T:
        raise ValueError("The start index of the tensors must be equal")
    if isinstance(g, Matrix):
        idx_start_g = 0
    else:
        idx_start_g = g.start_index[0]
    if idx_start_S != idx_start_g:
        raise ValueError(
            "The start index of the tensor and metric must be equal")

    # 1.Lowering of the top indices of a tensor T
    # upper_idx_numbers it is a list with the positions on which are the upper
    # indices
    upper_idx_numbers = [k + 1 for k in range(len(T.ind_char))
                         if T.ind_char[k] == 1]
    if len(upper_idx_numbers) != 0:
        for position in upper_idx_numbers:
            T = lower_index(T, g, position)

    # 2. Upping of the lower indices of a tensor S
    # low_idx_numbers it is a list with the positions on which are the lower
    # indices
    low_idx_numbers = [k + 1 for k in range(len(S.ind_char))
                       if S.ind_char[k] == -1]

    if len(low_idx_numbers) != 0:
        for position in low_idx_numbers:
            S = raise_index(S, g, position)

    # 3.Convolution of the first index
    result = 0
    for index in S.index_list:
        result += T[index] * S[index]

    return result
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
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