示例#1
0
def Symmetric(In_Arr):
     """
     Creates the symmetric form of input tensor.
     Input: arraypy or tensor with equal axes (array shapes).
     Output: symmetric array. Output type - arraypy or tensor, depends of input
     
     Examples:
     =========
     
     >>> from sympy import *
     >>> from sympy.tensor.arraypy import *
     >>> from sympy.tensor.tensor_methods import *
     >>> a = list2arraypy(range(9), (3,3))
     >>> print (a)
     0 1 2 
     3 4 5 
     6 7 8 
     >>> b = Symmetric(a)
     >>> print (b)
     0.0 2.0 4.0 
     2.0 4.0 6.0 
     4.0 6.0 8.0 
     """
     if not isinstance(In_Arr, arraypy):
	  raise TypeError('Input must be arraypy or Tensor 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 tensor, then ResArr will be tensor, else it will be arraypy	  
     if isinstance(In_Arr, tensor):
	  ResArr = tensor ( arraypy(arg), In_Arr.ind_char)
     else:
	  ResArr = 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:
	       ResArr[tuple(index)]+=In_Arr[tuple(temp_index)]
	  if isinstance(ResArr[tuple(index)], int):     
	       ResArr[tuple(index)] = float(ResArr[tuple(index)]) 	  
	  ResArr[tuple(index)] /= fac(In_Arr.rank) 
	 
	  index = In_Arr.Next_index(index)
	      
     return ResArr
示例#2
0
def df(f,args,output_type='l'):
    """ 
    Returns the 1-form df, differential of function f(x).

    Examples:
    ========

    >>> from sympy import *
    >>> from sympy.tensor.arraypy import *
    >>> from sympy.tensor.tensor_fields import *
    >>> x1, x2, x3, a= symbols('x1 x2 x3 a')
    >>> args=[x1, x2, x3]
    >>> f=x1**2*x2+sin(x2*x3-x2)
    >>> D=df(f,args,'t')   
    >>> print D
    2*x1*x2 x1**2 + (x3 - 1)*cos(x2*x3 - x2) x2*cos(x2*x3 - x2)
    """
# Handling of a vector of arguments
    if not isinstance(args, (list,tensor,arraypy)):
	    raise TypeError('The type of vector of arguments must be list, Tensor or arraypy')
    if isinstance(args, (tensor,arraypy)):
	    if len(args.shape)!=1:
		    raise ValueError("The dimension of argument must be 1")
	    if isinstance(args,tensor):
		    if args.type_pq != (1,0):
			    raise ValueError('The valency(ind_char) of tensor must be (+1)') 		
	    idx=args.start_index[0]    
    if isinstance(args, list):
	    idx=0
	
# Creating the output array in accordance with start indexes
    n=len(args) 
    array=arraypy([1,n,idx])
    indices = range(idx,idx+n)
    
# Calculation
    for k in indices:
	    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 arguments must be 't'-tensor,'a'-massiv arraypy,'l'-list")
# Output  
    return differential    
示例#3
0
def Christoffel_1(g, var, type_output='t'):
    """
    Returns the Christoffel symbols of tesor type (-1,-1,-1) for the given metric.
    Christoffel_1[i,j,k] = (diff(g[j,k],x[i])+diff(g[i,k],x[j])-diff(g[i,j],x[k]))/2.
    
    Examples:
    ========

    >>> from sympy import *	
    >>> from sympy.tensor.arraypy import *
    >>> from sympy.tensor.riemannian_geometry import *
    >>> phi, theta = symbols('phi, theta')
    >>> arg = [phi, theta]    
    >>> A = arraypy((2,2))
    >>> g = tensor(A,(-1,-1))
    >>> g[0,0] = cos(theta)**2
    >>> g[0,1] = 0
    >>> g[1,0] = 0
    >>> g[1,1] = 1
    >>> christoffel1=Christoffel_1(g, arg, 't')
    >>> print christoffel_1
        0 sin(theta)*cos(theta) 
	-sin(theta)*cos(theta) 0 
	-sin(theta)*cos(theta) 0 
	0 0
    """
# Handling of input vector arguments var
    if not isinstance(var,(list, arraypy, tensor)):
	raise TypeError('The type of vector arguments(var) must be a list, arraypy or tensor')
    if isinstance(var, (tensor,arraypy)):
	if len(var.shape) != 1:
	    raise ValueError("The dimension of variables must be 1!")
	if type(var) == tensor:
	    if not var.type_pq == (1,0):
		raise ValueError('The valence or ind_char of vector variables must be (+1)')
    if isinstance(var, (tensor,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, tensor)):
	raise TypeError('The type of metric tensor must be Matrix, tensor or arraypy')
    else:
	if isinstance(g, (arraypy, tensor)):
	    if type(g) == tensor:
		if not g.type_pq == (0,2):
		    raise ValueError('The valence or ind_char of metric tensor must be (-1,-1)')
	    if not (g.To_matrix()).is_symmetric():
		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 type(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
    Ch = arraypy([3, n, idx_start])
    
# Calculation
    for i in indices:
	for j in indices:
	    for k in indices:
		Ch[i,j,k] = (diff(g[j,k],var[i-idx_start]) + diff(g[i,k],var[j-idx_start]) - diff(g[i,j],var[k-idx_start]))/2 
    
# Handling of an output array
    if type_output == str('t') or type_output == Symbol('t'):
	Christoffel_1 = Ch.To_tensor((-1, -1, -1))
    elif type_output == str('a') or type_output == Symbol('a'):
	Christoffel_1 = Ch
    else: raise ValueError("The parameter of type output result must 'a' - arraypy or 't' and None - tensor.") 
    
# Output  
    return Christoffel_1
示例#4
0
def Ricci(riemann, var, type_output='t'):
    """
    Returns the Ricci tensor of type (-1,-1) for given Riemann curvature tensor.
    Ricci[j,k] = Sum_{i}(Riemann[i,j,k,i])

    Examples:
    =========

    >>> from sympy import *	
    >>> from sympy.tensor.arraypy import *
    >>> from sympy.tensor.riemannian_geometry import *
    >>> phi, theta = symbols('phi, theta')
    >>> arg = [phi, theta]    
    >>> A = arraypy((2,2))
    >>> g = tensor(A,(-1,-1))
    >>> g[0,0] = cos(theta)**2
    >>> g[0,1] = 0
    >>> g[1,0] = 0
    >>> g[1,1] = 1
    >>> R = Riemann(g, arg)
    >>> Ric = Ricci(R, arg)
    >>> print Ric
       cos(theta)**2 0 
       0 1 
    """
# Handling of input vector arguments var
    if not isinstance(var,(list, arraypy, tensor)):
	raise TypeError('The type of vector arguments(var) must be a list, arraypy or tensor')
    if isinstance(var, (tensor,arraypy)):
	if len(var.shape) != 1:
	    raise ValueError("The dimension of variables must be 1!")
	if type(var) == tensor:
	    if not var.type_pq == (1,0):
		raise ValueError('The valence or ind_char of vector variables must be (+1)')
    if isinstance(var, (tensor,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,(arraypy, tensor)):
	raise TypeError('The type of Riemann curvature tensor must be arraypy or tensor')
    if type(riemann) == tensor:
	if not riemann.type_pq == (1,3):
	    raise ValueError('The valence or ind_char of Riemann curvature tensor must be (-1,-1,-1,+1)')
    idx_start = riemann.start_index[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 - tensor.") 
    
    # Output  	
    return Ricci
示例#5
0
def Riemann(g, var, type_output='t'):
    """
    Returns the Riemann curvature tensor of type (-1,-1,-1,+1)  for the given metric tensor.
    Riemann[i,j,k,l] = diff(Gamma_2[j,k,l],x[i])-diff(Gamma_2[i,k,l],x[j]) + Sum_{p}( Gamma_2[i,p,l]*Gamma_2[j,k,p] -Gamma_2[j,p,l]*Gamma_2[i,k,p]    

    Examples:
    =========

    >>> from sympy import *	
    >>> from sympy.tensor.arraypy import *
    >>> from sympy.tensor.riemannian_geometry import *
    >>> phi, theta = symbols('phi, theta')
    >>> arg = [phi, theta]    
    >>> A = arraypy((2,2))
    >>> g = tensor(A,(-1,-1))
    >>> g[0,0] = cos(theta)**2
    >>> g[0,1] = 0
    >>> g[1,0] = 0
    >>> g[1,1] = 1
    >>> R = Riemann(g, arg)
    >>> print R
        0 0 
	0 0 
	0 -cos(theta)**2 
	1 0 
	0 cos(theta)**2 
	-1 0 
	0 0 
	0 0  
    """    
# Handling of input vector arguments var
    if not isinstance(var,(list, arraypy, tensor)):
	raise TypeError('The type of vector arguments(var) must be a list, arraypy or tensor')
    if isinstance(var, (tensor,arraypy)):
	if len(var.shape) != 1:
	    raise ValueError("The dimension of variables must be 1!")
	if type(var) == tensor:
	    if not var.type_pq == (1,0):
		raise ValueError('The valence or ind_char of vector variables must be (+1)')
    if isinstance(var, (tensor,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, tensor)):
	raise TypeError('The type of metric tensor must be Matrix, tensor or arraypy')
    else:
	if isinstance(g, (arraypy, tensor)):
	    if type(g) == tensor:
		if not g.type_pq == (0,2):
		    raise ValueError('The valence or ind_char of metric tensor must be (-1,-1)')
	    if not (g.To_matrix()).is_symmetric():
		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 type(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 - tensor.") 
    
# Output  
    return Riemann
示例#6
0
def Covar_der_XY(X, Y, g, var, type_output='t'):
    """
    Returns the covariant derivative the vector field along another field.
    nabla_Y(X)[j] = Sum_{i}(nabla X[i,j]*Y[i])

    Examples:
    =========

    >>> from sympy import *	
    >>> from sympy.tensor.arraypy import *
    >>> from sympy.tensor.riemannian_geometry import *
    >>> phi, theta = symbols('phi, theta')
    >>> arg = [phi, theta]    
    >>> A = arraypy((2,2))
    >>> g = tensor(A,(-1,-1))
    >>> g[0,0] = cos(theta)**2
    >>> g[0,1] = 0
    >>> g[1,0] = 0
    >>> g[1,1] = 1
    >>> X = [phi,theta]
    >>> Y = [1, 2]
    >>> NablaX_Y=Covar_der_XY(X, Y, g, arg)
    >>> print NablaX_Y
        -2*phi*sin(theta)/cos(theta) - theta*sin(theta)/cos(theta) + 1 phi*sin(theta)*cos(theta) + 2 
    """
    # Handling of input vector arguments var
    if not isinstance(var,(list, arraypy, tensor)):
	raise TypeError('The type of vector arguments(var) must be a list, arraypy or tensor')
    if isinstance(var, (tensor,arraypy)):
	if len(var.shape) != 1:
	    raise ValueError("The dimension of variables must be 1!")
	if type(var) == tensor:
	    if not var.type_pq == (1,0):
		raise ValueError('The valence or ind_char of vector variables must be (+1)')
    if isinstance(var, (tensor,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, tensor)):
	raise TypeError('The type of metric tensor must be Matrix, tensor or arraypy')
    else:
	if isinstance(g, (arraypy, tensor)):
	    if type(g) == tensor:
		if not g.type_pq == (0,2):
		    raise ValueError('The valence or ind_char of metric tensor must be (-1,-1)')
	    if not (g.To_matrix()).is_symmetric():
		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 type(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, tensor)):
	raise TypeError('The type of vector field must be list, tensor or arraypy')
    else:
	if isinstance(X, (arraypy, tensor)):
	    if len(X.shape) != 1:
			raise ValueError("The dimension of X must be 1!")	    
	    if type(X) == tensor:
		if not X.type_pq == (1,0):
		    raise ValueError('The valence or ind_char of vector field must be (+1)')
	    idx_X = X.start_index[0]
	elif type(X) == list:
	    idx_X = 0
    
    # Handling of a input argument - vector field Y		   
    if not isinstance(Y,(list, arraypy, tensor)):
	raise TypeError('The type of vector field must be list, tensor or arraypy')
    else:
	if isinstance(Y, (arraypy, tensor)):
	    if len(Y.shape) != 1:
			raise ValueError("The dimension of Y must be 1!")	    
	    if type(Y) == tensor:
		if not Y.type_pq == (1,0):
		    raise ValueError('The valence or ind_char of vector field must be (+1)')
	    idx_Y = Y.start_index[0]
	elif type(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 - tensor.") 
    
    # Output  
    return Cov_der_XY
示例#7
0
def Covar_der(X, g, var, type_output='t'):
    """
    Returns the covariant derivative the vector field.
    nabla X[i,j] = diff(X[j],x[i])+Sum_{k}(Gamma2[k,i,j]*X[k])

    Examples:
    =========

    >>> from sympy import *	
    >>> from sympy.tensor.arraypy import *
    >>> from sympy.tensor.riemannian_geometry import *
    >>> phi, theta = symbols('phi, theta')
    >>> arg = [phi, theta]    
    >>> A = arraypy((2,2))
    >>> g = tensor(A,(-1,-1))
    >>> g[0,0] = cos(theta)**2
    >>> g[0,1] = 0
    >>> g[1,0] = 0
    >>> g[1,1] = 1
    >>> X = [phi*theta**3,phi-cos(theta)]
    >>> Nabla=Covar_der(X, g, arg)
    >>> print Nabla
        theta**3 - (phi - cos(theta))*sin(theta)/cos(theta) phi*theta**3*sin(theta)*cos(theta) + 1 
	-phi*theta**3*sin(theta)/cos(theta) + 3*phi*theta**2 sin(theta) 
    """	
 # Handling of input vector arguments var
    if not isinstance(var,(list, arraypy, tensor)):
	raise TypeError('The type of vector arguments(var) must be a list, arraypy or tensor')
    if isinstance(var, (tensor,arraypy)):
	if len(var.shape) != 1:
	    raise ValueError("The dimension of variables must be 1!")
	if type(var) == tensor:
	    if not var.type_pq == (1,0):
		raise ValueError('The valence or ind_char of vector variables must be (+1)')
    if isinstance(var, (tensor,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, tensor)):
	raise TypeError('The type of metric tensor must be Matrix, tensor or arraypy')
    else:
	if isinstance(g, (arraypy, tensor)):
	    if type(g) == tensor:
		if not g.type_pq == (0,2):
		    raise ValueError('The valence or ind_char of metric tensor must be (-1,-1)')
	    if not (g.To_matrix()).is_symmetric():
		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 type(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, tensor)):
	raise TypeError('The type of vector field must be list, tensor or arraypy')
    else:
	if isinstance(X, (arraypy, tensor)):
	    if len(X.shape) != 1:
			raise ValueError("The dimension of X must be 1!")	    
	    if type(X) == tensor:
		if not X.type_pq == (1,0):
		    raise ValueError('The valence or ind_char of vector field must be (+1)')
	    idx_X = X.start_index[0]
	elif type(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 - tensor.") 
    
# Output  
    return Cov_der
示例#8
0
def grad(f,args,g=None,output_type=None):
    """
    Returns the vector field Gradient(f(x)) of a function f(x).               

    Examples:
    ========

    >>> from sympy import *
    >>> from sympy.tensor.arraypy import *
    >>> from sympy.tensor.tensor_fields import *
    >>> x1, x2, x3, a= symbols('x1 x2 x3 a')
    >>> args=[x1, x2, x3]
    >>> f=x1**2*x2+sin(x2*x3-x2)
    >>> g=Matrix([[2,1,0],[1,3,0],[0,0,1]])   
    >>> Gr=grad(f,args,g)   
    >>> 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
    if not isinstance(args, (list,tensor,arraypy)):
	    raise TypeError('The type of vector of arguments must be list, tensor or arraypy')
    if isinstance(args, (tensor,arraypy)):
	    if len(args.shape)!=1:
		    raise ValueError("The dimension of argument must be 1")
	    if isinstance(args,tensor):
		    if args.type_pq != (1,0):
			    raise ValueError('The valency of tensor must be (+1)')	    
	    idx_args=args.start_index[0]
    if isinstance(args, list):
	    idx_args=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'
	    if not isinstance(g,(tensor,Matrix,arraypy)):
		    raise ValueError('Type must be Matrix or tensor or arraypy')
	    if isinstance(g,tensor):
		    if g.type_pq != (0,2):
			    raise ValueError('The indices of tensor must be (-1,-1)')
			
   #The definition of the start index
	    if isinstance(g,Matrix):
		    idx_st=0
	    else:
		    idx_st=g.start_index[0] 
	    if type(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,(tensor,arraypy)):	    
		    g = g.To_matrix()
	    if not g.is_symmetric():
		    raise ValueError('The metric is not symmetric')		    
  # 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,(tensor,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 arguments must be 't'-tensor,'a'-massiv arraypy,'l'-list")
# Output  
    return gradient  
示例#9
0
def Lie_w(omega, X, args):
    """
    Returns the Lie derivative of a differential form 

    Examples:    
    =========
    
    >>> from sympy import *
    >>> from sympy.tensor.arraypy import *
    >>> from sympy.tensor.tensor_fields import *
    >>> x1, x2, x3, a= symbols('x1 x2 x3 a')
    >>> args=[x1, x2, x3]
    >>> X=[1,2,3]
    >>> om=arraypy((3,3))
    >>> omega = tensor(om, (-1, -1))
    >>> omega[0,1]=x3*x2
    >>> omega[1,0]=-x3*x2
    >>> omega[0,2]=-x2*x1 
    >>> omega[2,0]=x2*x1 
    >>> omega[1,2]=x1*x3
    >>> omega[2,1]=-x1*x3
    >>> LwX=Lie_w(omega,X,args)  
    >>> print(LwX)
    0 3*x2 + 2*x3 -2*x1 - x2 
    -3*x2 - 2*x3 0 3*x1 + x3 
    2*x1 + x2 -3*x1 - x3 0 
    """
# Handling of a vector of arguments
    if not isinstance(args, (list,tensor,arraypy)):
	    raise ValueError('The type of arguments vector must be list, tensor or arraypy')
    if isinstance(args, (tensor,arraypy)):
	    if len(args.shape)!=1:
		    raise ValueError("The lenght of argument must be 1")	    
	    if isinstance(args,tensor):
		    if args.type_pq != (1,0):
				raise ValueError('The valency of tensor must be (+1)') 		
	    idx_args=args.start_index[0]
    if isinstance(args, list):
		idx_args=0

# Handling of a vector field
    if not isinstance(X, (list,tensor,arraypy)):
	    raise ValueError('The type of vector fields must be list, tensor or arraypy')	   
    if isinstance(X, (tensor,arraypy)):
	    if len(X.shape)!=1:
		    raise ValueError("The dim of argument must be 1")
	    if isinstance(X,tensor):
		    if X.type_pq != (1,0):
			    raise ValueError('The valency of tensor must be (+1)') 		
	    idx_X=X.start_index[0]
    if isinstance(X, list):
		idx_X=0
		
# Handling of a differential form
    if not isinstance(omega, (tensor,arraypy)):
	    raise ValueError("Type must be Tensor or arraypy") 
    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 tensor,vector field and vetcor of argements must be equal')
    if type(omega)==type(X) and idx_omega!=idx_X:
		    raise ValueError('The start index of tensor 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,(tensor,arraypy)):
	    args=args.To_list()
    if isinstance(X,(tensor,arraypy)):
	    X=X.To_list()
		
    for p in range(len(diff_Lie)):
	for k in range(len(idx)+1):			    
		tuple_list_indx = [NeedElementK(idx, f, k+idx_st) for f in range(len(idx))]
		diff_omega=diff(omega[idx],args[k])*X[k]
		for j in range(len(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
示例#10
0
def dw(omega, args):
    """ 
    Returns the exterior differential of a differential form

    Examples:    
    =========
    
    >>> from sympy import *
    >>> from sympy.tensor.arraypy import *
    >>> from sympy.tensor.tensor_fields import *
    >>> x1, x2, x3, a= symbols('x1 x2 x3 a')
    >>> args=[x1, x2, x3]
    >>> om=arraypy((3,3))
    >>> omega = tensor(om, (-1, -1))
    >>> omega[0,1]=x3*x2
    >>> omega[1,0]=-x3*x2
    >>> omega[0,2]=-x2*x1 
    >>> omega[2,0]=x2*x1 
    >>> omega[1,2]=x1*x3
    >>> omega[2,1]=-x1*x3
    >>> d_omega = dw(omega, args)  
    >>> print(d_omega)
    0 0 0 
    0 0 x1 + x2 + x3 
    0 -x1 - x2 - x3 0 
    0 0 -x1 - x2 - x3 
    0 0 0 
    x1 + x2 + x3 0 0 
    0 x1 + x2 + x3 0 
    -x1 - x2 - x3 0 0 
    0 0 0
    """
# Handling of a vector of arguments
    if not isinstance(args, (list,tensor,arraypy)):
	    raise ValueError('The type of arguments vector must be list, tensor or arraypy')
    if isinstance(args, (tensor,arraypy)):
	    if len(args.shape)!=1:
		    raise ValueError("The lenght of argument must be 1")	    
	    if isinstance(args,tensor):
		    if args.type_pq != (1,0):
			    raise ValueError('The valency of tensor must be (+1)') 		
	    idx_args=args.start_index[0]
    if isinstance(args, list):
	    idx_args=0

# Handling of a differential form
    if not isinstance(omega, (tensor,arraypy)):
	    raise ValueError("Type must be Tensor or arraypy") 
    idx_omega = omega.start_index[0]
    
# Define the start index in the output tensor
    if type(omega)==type(args) and idx_omega!=idx_args:
		    raise ValueError("Raznie indeksi!!!")		    
    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
    a=arraypy([p+1,n,idx_st])
    valence_ind=[(-1) for k in range(p+1)]
    d_omega=a.To_tensor(valence_ind)
    
# Calculation
    idx=d_omega.start_index 
    if isinstance(args, (tensor,arraypy)):
	        args=args.To_list()
		
    for i in range(len(d_omega)):
	    #list of tuple. example:[(0, 1), (0, 1), (0, 0)]
	    tuple_list_indx = [NotNeedElement(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
示例#11
0
def LieXY(X,Y,args,output_type=None):
    """ 
    Returns the vector field [X,Y], Lie bracket (commutator) of a vector fields X and Y
	
    Examples:    
    =========
    
    >>> from sympy import *
    >>> from sympy.tensor.arraypy import *
    >>> from sympy.tensor.tensor_fields import *
    >>> x1, x2, x3, a= symbols('x1 x2 x3 a')
    >>> args=[x1, x2, x3]
    >>> X=[-x1**3+x2**2,9*x2**2+x1,5*x3+x2]
    >>> Y=[-x1**3+x3**2,x2**2+x1**2,x3+x2]
    >>> L=LieXY(X,Y,args)   
    >>> print L
    [-3*x1**2*(-x1**3 + x2**2) + 3*x1**2*(-x1**3 + x3**2) - 2*x2*(x1**2 + x2**2) + 2*x3*(x2 + 5*x3), x1**3 + 2*x1*(-x1**3 + x2**2) + 2*x2*(x1 + 9*x2**2) - 18*x2*(x1**2 + x2**2) - x3**2, -x1**2 + x1 + 8*x2**2 - 4*x2]
    """
# Handling of a vector of arguments
    if not isinstance(args, (list,tensor,arraypy)):
	    raise ValueError('The type of arguments vector must be list, tensor or arraypy')
    if isinstance(args, (tensor,arraypy)):
	    if len(args.shape)!=1:
		    raise ValueError("The lenght of argument must be 1")	    
	    if isinstance(args,tensor):
		    if args.type_pq != (1,0):
			    raise ValueError('The valency of tensor must be (+1)') 		
	    idx_args=args.start_index[0]
    if isinstance(args, list):
	    idx_args=0   
	    
# Handling of the first vector field
    if not isinstance(X, (list,tensor,arraypy)):
	    raise ValueError('The type of vector fields must be list, tensor or arraypy')	   
    if isinstance(X, (tensor,arraypy)):
	    if len(X.shape)!=1:
		    raise ValueError("The dim of argument must be 1")
	    if isinstance(X,tensor):
		    out_t='t'
		    if X.type_pq != (1,0):
			    raise ValueError('The valency of tensor must be (+1)') 		
	    idx_X=X.start_index[0]
    if isinstance(X, list):
	    idx_X=0 
	    out_t='l'
	
# Handling of the second vector field
    if not isinstance(Y, (list,tensor,arraypy)):
	    raise ValueError('The type of vector fields must be list, tensor or arraypy')	   
    if isinstance(Y, (tensor,arraypy)):
	    if len(Y.shape)!=1:
		    raise ValueError("The dim of argument must be 1")
	    if isinstance(Y,tensor):
		    if Y.type_pq != (1,0):
			    raise ValueError('The valency of tensor must be (+1)') 		
	    idx_Y=Y.start_index[0]
    if isinstance(Y, list):
	    idx_Y=0	
	        
    if len(Y)!=len(X):
	    raise ValueError('The different number of arguments of the vector fields')
    elif len(args)!=len(X) or len(args)!=len(Y):
	    raise ValueError('The different number of components at the vector field and vector of variables') 
    
# 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 vetcor of argements must be equal')
    if idx_Y!=idx_X:
		    raise ValueError('The start index of tensor and the vector field 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, (tensor,arraypy)):
	    Y=Y.To_list()
    if isinstance(X, (tensor,arraypy)):
	    X=X.To_list()	
    if isinstance(args, (tensor,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 arguments must be 't'-tensor,'a'-massiv arraypy,'l'-list")    
	             
# Output  
    return Lie
示例#12
0
def rot(X,args,output_type=None):
    """
    Returns the vorticity vector field rot(X) of a vector field X in R^3 (curl, rotation, rotor, vorticity). The rotor can be calculated for only in three-dimensional Euclidean space. 
    
    Examples:
    ========
    
    >>> from sympy import *
    >>> from sympy.tensor.arraypy import *
    >>> from sympy.tensor.tensor_fields import *
    >>> x1, x2, x3, a= symbols('x1 x2 x3 a')
    >>> args=[x1, x2, x3]
    >>> X=[-x1**3+x2**2,9*x2**2+x1,5*x3+x2]
    >>> g=Matrix([[2,1,0],[1,3,0],[0,0,1]])   
    >>> R=rot(X,arg)   
    >>> print R
    [1, 0, -2*x2 + 1]
    """
# Handling of a vector of arguments
    if not isinstance(args, (list,tensor,arraypy)):
	    raise ValueError('The type of arguments vector must be list, tensor or arraypy')
    if len(args)!=3:
	    raise ValueError('ERROW:three variables are required')
    if isinstance(args, (tensor,arraypy)):
	    if len(args.shape)!=1:
		    raise ValueError("The lenght of argument must be 1")	    
	    if isinstance(args,tensor):
		    if args.type_pq != (1,0):
			    raise ValueError('The valency of tensor must be (+1)') 		
	    idx_args=args.start_index[0]
    if isinstance(args, list):
	    idx_args=0
	       
# Handling of a vector field
    if not isinstance(X, (list,tensor,arraypy)):
	    raise ValueError('The type of vector fields must be list, tensor or arraypy')	
    if len(X)!=3:
	    raise ValueError('ERROW:a three-dimensional vector is necessary')
	
    if isinstance(X, (tensor,arraypy)):
	    if len(X.shape)!=1:
		    raise ValueError("The dim of argument must be 1")
	    if isinstance(X,tensor):
		    out_t='t'
		    if X.type_pq != (1,0):
			    raise ValueError('The valency of tensor must be (+1)') 		
	    idx_X=X.start_index[0]
    elif isinstance(X, list):
	    idx_X=0
	    out_t='l'
	    
    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 type(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 start indexes
    array=arraypy([1,3,idx_st])

# Calculation
    if isinstance(X, (tensor,arraypy)):
	    X=X.To_list()
    if isinstance(args, (tensor,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 arguments must be 't'-tensor,'a'-massiv arraypy,'l'-list")    
# Output  
    return rotor