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