Example #1
0
def test_solveset():
    x = Symbol('x')
    A = Matrix([[x, 2, x * x], [4, 5, x], [x, 8, 9]])

    solns = solve(det(A), x)
    solns_set = list(solveset(det(A), x))

    print(solns)
    print('\n')
    print(solns_set)

    print('\n\n\n')
    print((solns[0]))
    print('\n')
    print((solns_set[0]))

    soln_sub = solns[0].subs(x, 1)
    solnset_sub = solns_set[0].subs(x, 1)

    s1 = soln_sub.evalf()
    s1set = solnset_sub.evalf()

    s2set = solns_set[1].subs(x, 1).evalf()

    print(s1)
    print(s1set)
    print(s2set)
Example #2
0
def gauss_neg_log_dens(pdf, var_and_param_names_and_values={}, **kw_var_and_param_names_and_values):
    var_and_param_names_and_values = combine_dict_and_kwargs(var_and_param_names_and_values,
                                                             kw_var_and_param_names_and_values)
    if not pdf.PreProcessed:
        pdf.preprocess()
    if pdf.LogDetCov is None:
        neg_log_dens = (pdf.NumDims * log(2 * pi) + log(det(pdf.Cov)) +
                        det(pdf.DemeanedVarVector * pdf.Cov.inverse() * pdf.DemeanedVarVector.T)) / 2
    else:
        neg_log_dens = (pdf.NumDims * log(2 * pi) + pdf.LogDetCov +
                        det(pdf.DemeanedVarVector * Matrix(pdf.InvCov) * pdf.DemeanedVarVector.T)) / 2
    return sympy_xreplace(neg_log_dens, var_and_param_names_and_values)
Example #3
0
def gauss_neg_log_dens(pdf, var_and_param_names_and_values={}, **kw_var_and_param_names_and_values):
    var_and_param_names_and_values = combine_dict_and_kwargs(var_and_param_names_and_values,
                                                             kw_var_and_param_names_and_values)
    if not pdf.PreProcessed:
        pdf.preprocess()
    if pdf.LogDetCov is None:
        neg_log_dens = (pdf.NumDims * log(2 * pi) + log(det(pdf.Cov)) +
                        det(pdf.DemeanedVarVector * pdf.Cov.inverse() * pdf.DemeanedVarVector.T)) / 2
    else:
        neg_log_dens = (pdf.NumDims * log(2 * pi) + pdf.LogDetCov +
                        det(pdf.DemeanedVarVector * Matrix(pdf.InvCov) * pdf.DemeanedVarVector.T)) / 2
    return sympy_xreplace(neg_log_dens, var_and_param_names_and_values)
Example #4
0
def test_dft():
    n, i, j = symbols('n i j')
    assert DFT(4).shape == (4, 4)
    assert ask(Q.unitary(DFT(4)))
    assert Abs(simplify(det(Matrix(DFT(4))))) == 1
    assert DFT(n) * IDFT(n) == Identity(n)
    assert DFT(n)[i, j] == exp(-2 * S.Pi * I / n)**(i * j) / sqrt(n)
Example #5
0
    def cross(self, other):
        """
        Returns the cross product of this Vector with another Vector or
        Dyadic instance.
        The cross product is a Vector, if 'other' is a Vector. If 'other'
        is a Dyadic, this returns a Dyadic instance.

        Parameters
        ==========

        other: Vector/Dyadic
            The Vector or Dyadic we are crossing with.

        Examples
        ========

        >>> from sympy.vector import CoordSys3D
        >>> C = CoordSys3D('C')
        >>> C.i.cross(C.j)
        C.k
        >>> C.i ^ C.i
        0
        >>> v = 3*C.i + 4*C.j + 5*C.k
        >>> v ^ C.i
        5*C.j + (-4)*C.k
        >>> d = C.i.outer(C.i)
        >>> C.j.cross(d)
        (-1)*(C.k|C.i)

        """

        # Check special cases
        if isinstance(other, Dyadic):
            if isinstance(self, VectorZero):
                return Dyadic.zero
            outdyad = Dyadic.zero
            for k, v in other.components.items():
                cross_product = self.cross(k.args[0])
                outer = cross_product.outer(k.args[1])
                outdyad += v * outer
            return outdyad
        elif not isinstance(other, Vector):
            raise TypeError(str(other) + " is not a vector")
        elif (isinstance(self, VectorZero) or
                isinstance(other, VectorZero)):
            return Vector.zero

        outvec = Vector.zero
        for system, vect in other.separate().items():
            tempm = [[system.i, system.j, system.k],
                     [self & system.i, self & system.j, self & system.k],
                     [vect & system.i, vect & system.j, vect & system.k]]
            outvec += det(Matrix(tempm))
        return outvec
Example #6
0
def aff2trpzs(affmat):
    tvec = affmat[:-1,-1]
    rpzsmat = affmat[:-1,:-1]
    zsmat = (rpzsmat.T*rpzsmat).cholesky().T
    zfac = Mat([zsmat[0,0], zsmat[1,1], zsmat[2,2]])
    zmat = zfac2zmat(zfac)
    smat = zmat.inv() * zsmat
    stri = smat2stri(smat)
    rpmat = rpzsmat * zsmat.inv()
    parity = det(rpmat)
    rquat = rmat2rquat(rpmat*parity)
    return tvec, rquat, parity, zfac, stri
Example #7
0
def solve_diel(chiL,
               chiR,
               chiZ,
               THETA,
               Bfield,
               verbose=False,
               force_numeric=False,
               use_old_method=False):
    '''
	Solves the wave equation to find the two propagating normal modes of the system,
	for a given magnetic field angle THETA. For the general case, use symbolic python to
	solve for the roots of n-squared.
	(Escapes this slow approach for the two analytic cases for the Voigt and Faraday geometries)

	Returns the rotation matrix to transform the coordinate system into the normal mode basis,
	and returns the two refractive index arrays.

	Inputs:

		chiL, chiR, chiZ	:	1D lists or numpy arrays, of length N, that are the frequency-dependent electric susceptibilities
		THETA				:	Float, Magnetic field angle in radians
		Bfield				:	Float, Magnitude of applied magnetic field (skips slow approach if magnetic field is very close to zero)

	Options:

		verbose			:	Boolean to output more print statements (timing reports mostly)
		force_numeric	:	If True, forces all angles to go through the numeric approach, rather than escaping for the analytic cases (THETA=0, THETA=pi/2...)
		use_old_method	:	If True, forces use of numerical method rather than analytical method.


	Outputs:
		RotMat	:	Rotation matrix to transform coordinate system, dimensions (3, 3, N)
		n1		:	First solution for refractive index, dimensions (N)
		n2		:	Second solution for refractive index, dimensions (N)

	'''

    approx_threshold = 1e-4  ##Value used do determine if THETA is close enough
    ##to Voigt or Faraday geometries to use an approximation

    if verbose:
        print(('B-field angle (rad, pi rad): ', THETA, THETA / np.pi))

    stt = time.clock()

    # make chiL,R,Z arrays if not already
    chiL = np.array(chiL)
    chiR = np.array(chiR)
    chiZ = np.array(chiZ)

    #verbose=True

    #### Escape the slow loop for analytic (Faraday and Voigt) cases
    ## For these analytic cases we can use array operations and it is therefore
    ## much faster to compute
    if (abs(THETA % (2 * np.pi) - np.pi / 2) <
            approx_threshold) or (abs(THETA % (2 * np.pi) - 3 * np.pi / 2) <
                                  approx_threshold) and (not force_numeric):
        # ANALYTIC SOLNS FOR VOIGT
        if verbose: print('Voigt - analytic')

        # solutions for elements of the dielectric tensor:
        ex = 0.5 * (2. + chiL + chiR)
        exy = 0.5j * (chiR - chiL)
        ez = 1.0 + chiZ

        # refractive indices to propagate
        n1 = np.sqrt(ex + exy**2 / ex)
        n2 = np.sqrt(ez)

        #ev1 = [np.zeros(len(ex)),ex/exy,np.ones(len(ex))]
        #ev2 = [np.ones(len(ex)),np.zeros(len(ex)),np.zeros(len(ex))]
        #ev3 = [np.zeros(len(ex)),np.zeros(len(ex)),np.ones(len(ex))]

        #RotMat = np.array([ev1,ev2,ev3])

        ones = np.ones(len(ex))
        zeros = np.zeros(len(ex))

        # *Changed output to new array format

        RotMat = np.array([[zeros, ones, zeros], [ex / exy, zeros, zeros],
                           [ones, zeros, ones]]).T

        if verbose:
            print('Shortcut:')
            print((RotMat.shape))
            print((n1.shape))
            print((n2.shape))

    elif ((abs(THETA) < approx_threshold) or
          ((abs(THETA - np.pi)) < approx_threshold) or abs(Bfield) < 1e-2
          ) and (not force_numeric
                 ):  ## Use Faraday geometry if Bfield is very close to zero
        # ANALYTIC SOLNS FOR FARADAY
        #if verbose:
        if verbose: print('Faraday - analytic TT')

        ex = 0.5 * (2. + chiL + chiR)
        exy = 0.5j * (chiR - chiL)
        e_z = 1.0 + chiZ

        n1 = np.sqrt(ex + 1.j * exy)
        n2 = np.sqrt(ex - 1.j * exy)

        #ev1 = np.array([-1.j*np.ones(len(ex)),np.ones(len(ex)),np.zeros(len(ex))])
        #ev2 = np.array([1.j*np.ones(len(ex)),np.ones(len(ex)),np.zeros(len(ex))])
        #ev3 = [np.zeros(len(ex)),np.zeros(len(ex)),np.ones(len(ex))]

        ones = np.ones(len(ex))
        zeros = np.zeros(len(ex))

        # *Changed output to new array format

        if (abs(THETA) < approx_threshold):
            #RotMat = np.array([ev1,ev2,ev3])

            RotMat = np.array([[-1.j * ones, 1.j * ones, zeros],
                               [ones, ones, zeros], [zeros, zeros, ones]]).T

        else:
            #if anti-aligned, swap the two eigenvectors
            #RotMat = np.array([ev2,ev1,ev3])

            RotMat = np.array([[1.j * ones, -1.j * ones, zeros],
                               [ones, ones, zeros], [zeros, zeros, ones]]).T

        if verbose:
            print('Shortcut:')
            print((RotMat.shape))
            print((n1.shape))
            print((n2.shape))

    elif use_old_method:
        print("using old method")
        if verbose:
            print('Non-analytic angle.. This will take a while...'
                  )  ##### THIS IS THE ONE THAT's WRONG....
        # set up sympy symbols
        theta = Symbol('theta', real=True)
        n_sq = Symbol('n_sq')
        e_x = Symbol('e_x')
        e_xy = Symbol('e_xy')
        e_z = Symbol('e_z')

        # General form of the dielectric tensor
        DielMat = Matrix(([(e_x - n_sq) * cos(theta), e_xy, e_x * sin(theta)],
                          [-e_xy * cos(theta), e_x - n_sq,
                           -e_xy * sin(theta)], [(n_sq - e_z) * sin(theta), 0,
                                                 e_z * cos(theta)]))

        et1 = time.clock() - stt

        # Substitute in angle
        DielMat_sub = DielMat.subs(theta, pi * THETA / np.pi)

        et2 = time.clock() - stt

        # Find solutions for complex indices for a given angle
        solns = solve(det(DielMat_sub), n_sq)

        et3a = time.clock() - stt
        #print et3a

        # Find first refractive index
        DielMat_sub1 = DielMat_sub.subs(n_sq, solns[0])
        n1 = np.zeros(len(chiL), dtype='complex')
        n1old = np.zeros(len(chiL), dtype='complex')
        # Find second refractive index
        DielMat_sub2 = DielMat_sub.subs(n_sq, solns[1])
        n2 = np.zeros(len(chiL), dtype='complex')
        n2old = np.zeros(len(chiL), dtype='complex')

        et3b = time.clock() - stt

        Dsub1 = lambdify((e_x, e_xy, e_z), DielMat_sub1, 'numpy')
        Dsub2 = lambdify((e_x, e_xy, e_z), DielMat_sub2, 'numpy')

        nsub1 = lambdify((e_x, e_xy, e_z), solns[0], 'numpy')
        nsub2 = lambdify((e_x, e_xy, e_z), solns[1], 'numpy')

        # Initialise rotation matrix
        RotMat = np.zeros((3, 3, len(chiL)), dtype='complex')

        et3c = time.clock() - stt

        # populate refractive index arrays
        n1 = np.sqrt(
            nsub1(0.5 * (2. + chiL + chiR), 0.5j * (chiR - chiL),
                  (1.0 + chiZ)))
        n2 = np.sqrt(
            nsub2(0.5 * (2. + chiL + chiR), 0.5j * (chiR - chiL),
                  (1.0 + chiZ)))

        et3 = time.clock() - stt

        if verbose:
            print(('setup time:', et1, et1))
            print(('solve nsq: (total/solve/sub in) ', et3a, et3a - et2,
                   et2 - et1))
            print((
                'get nsq arrays (tot time / populate ref. index / gen. lambdify / sub in): ',
                et3, et3 - et3c, et3c - et3b, et3b - et3a))

        # loop over all elements of chiL,R,Z to populate eigenvectors
        # time-limiting step for arrays of length >~ 5000
        for i, (cL, cR, cZ) in enumerate(zip(chiL, chiR, chiZ)):
            #if verbose: print 'Detuning point i: ',i

            #time diagnostics
            st = time.clock()
            '''	
		## OLD and slow method::
			# Sub in values of susceptibility
			DielMat_sub1a = DielMat_sub1.subs(e_x, 0.5*(2.+cL+cR))
			DielMat_sub1a = DielMat_sub1a.subs(e_xy, 0.5j*(cR-cL))
			DielMat_sub1a = DielMat_sub1a.subs(e_z, (1.0+cZ))
			
			et1 = time.clock() - st
			
			# Evaluate and convert to numpy array
			DM = np.array(DielMat_sub1a.evalf())
			DMa = np.zeros((3,3),dtype='complex')
			for ii in range(3):
				for jj in range(3):
					DMa[ii,jj] = np.complex128(DM[ii,jj])
			
			et2 = time.clock() - st
		
			# use scipy to find eigenvector
			#ev1 = Matrix(DMa).nullspace()
			#print 'Sympy: ', ev1
			
			ev1old = nullOld(DMa).T[0]
			#ev1 = null(DMaNP).T
			
			# sub in for ref. index
			n1soln = solns[0].subs(e_x, 0.5*(2.+cL+cR))
			n1soln = n1soln.subs(e_xy, 0.5j*(cR-cL))
			n1soln = n1soln.subs(e_z, (1.0+cZ))
			
			# Populate the refractive index array
			n1old[i] = np.sqrt(np.complex128(n1soln.evalf()))
		## /OLD method
			'''

            # NEW method

            # Sub in values of susceptibility
            DMaNP = Dsub1(0.5 * (2. + cL + cR), 0.5j * (cR - cL), (1.0 + cZ))
            #print DMa
            ev1 = null(DMaNP).T
            # Populate the refractive index array
            #n1[i] = np.sqrt(nsub1(0.5*(2.+cL+cR), 0.5j*(cR-cL), (1.0+cZ)))
            '''
			## METHOD COMPARISON
			
			print 'SymPy:'
			print DMa
			print DMa.shape, type(DMa)
			print 'Numpy'
			print DMaNP
			print DMaNP.shape, type(DMaNP)
			
			print 'Eigenvectors ...'
			print 'Old: ', ev1old			
			print 'New: ',ev1
			'''

            #print '\n\n\n'

            #print 'scipy: ', ev1

            et3 = time.clock() - st

            et4 = time.clock() - st

            #
            ## Now repeat the above for second eigenvector
            #

            ## NEW
            # Sub in values of susceptibility
            DMaNP = Dsub2(0.5 * (2. + cL + cR), 0.5j * (cR - cL), (1.0 + cZ))
            # Find null eigenvector
            ev2 = null(DMaNP).T
            # Populate the refractive index array
            #n2[i] = np.sqrt(nsub2(0.5*(2.+cL+cR), 0.5j*(cR-cL), (1.0+cZ)))

            et5 = time.clock() - st
            '''
		## OLD
			# Evaluate and convert to numpy array
			DielMat_sub2a = DielMat_sub2.subs(e_x, 0.5*(2.+cL+cR))
			DielMat_sub2a = DielMat_sub2a.subs(e_xy, 0.5j*(cR-cL))
			DielMat_sub2a = DielMat_sub2a.subs(e_z, (1.0+cZ))
			
			DM = np.array(DielMat_sub2a.evalf())
			DMa = np.zeros((3,3),dtype='complex')
			for ii in range(3):
				for jj in range(3):
					DMa[ii,jj] = np.complex128(DM[ii,jj])
					
			et6 = time.clock() - st
			
			# use scipy to find eigenvector
			ev2old = nullOld(DMa).T[0]
			
			et7 = time.clock() - st
			
			# sub in for ref. index
			n2soln = solns[1].subs(e_x, 0.5*(2.+cL+cR))
			n2soln = n2soln.subs(e_xy, 0.5j*(cR-cL))
			n2soln = n2soln.subs(e_z, (1.0+cZ))
			
			# Populate the refractive index array
			n2old[i] = np.sqrt(np.complex128(n2soln.evalf()))
			'''

            # Populate the rotation matrix
            RotMat[:, :, i] = [ev1, ev2, [0, 0, 1]]

        et_tot = time.clock() - stt
        if verbose:
            print(('Time elapsed (non-analytic angle):', et_tot))

    else:
        if verbose: print("Using analytical method")

        #Uses analytical method
        n1, n2, RotMat = non_standard_n1_n2_RotMat(chiL, chiR, chiZ, THETA)

    #print("RotMat =", RotMat)
    #print("n1 = ", n1)
    #print("n2 = ", n2, '\n')

    if verbose: print('SD done')
    return RotMat, n1, n2
def diverg(X, args, g=None):
    """Return the divergence of a vector field X. Compute divergence of vector
    field consisting of N elements.

    Examples:
    =========

    >>> from tensor_analysis.tensor_fields import diverg
    >>> from sympy import symbols, cos
    >>> from sympy.matrices import Matrix
    >>> x1, x2, x3 = symbols('x1 x2 x3')

    X is a vector field, args it's a list of symbol arguments of the vector
    field X. It's can be in list, array of arraypy or contravariant tensor:

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

    g - optional parameter, metric tensor, which can be a matrix "Matrix",
    array of arraypy or covariant tensor:

    >>> g = Matrix([[2,1,0],[1,3,0],[0,0,1]])

    >>> dv = diverg(X,arg,g)
    >>> print(dv)
    x2**3 + 3*x3**2 + 1

    """

    # 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 the first vector field
    check_the_vector_field(X)
    if isinstance(X, (TensorArray, Arraypy)):
        idx_X = X.start_index[0]
    else:
        idx_X = 0

    if idx_args != idx_X:
        raise ValueError(
            "The start index of vector field and vector of arguments must be \
                    equal")

    # Handling of the metric tensor
    if g is not None:
        if isinstance(g, (TensorArray, Arraypy)):
            g = g.to_matrix()
    else:
        g = eye(len(args))

    # Calculation
    sq = sqrt(abs(det(g)))
    diver = 0
    for k in range(len(args)):
        diver += simplify(1 / sq *
                          sum([diff(X[k + idx_X] * sq, args[k + idx_X])]))
    # Output
    return diver
def hodge_star(T, g):
    """The calculation actions on the forms of the Hodge operator's.

    Examples:
    =========
    >>> from sympy import symbols, Matrix
    >>> from tensor_analysis.arraypy import Arraypy, TensorArray
    >>> from tensor_analysis.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
Example #10
0
def test_dft():
    assert DFT(4).shape == (4, 4)
    assert ask(Q.unitary(DFT(4)))
    assert Abs(simplify(det(Matrix(DFT(4))))) == 1
    assert DFT(n)*IDFT(n) == Identity(n)
    assert DFT(n)[i, j] == exp(-2*S.Pi*I/n)**(i*j) / sqrt(n)
def FindScalarCurvature(reset=True):
    global x,X,ginv
    global christoffel1, christoffel2, riemanncurvature, riccitensor
    if reset:
        christoffel1 = {}
        christoffel2 = {}
        riemanncurvature = {}
        riccitensor = {}
    a = 1
    if a==0:
        x = ["t","x"]
        dx = ["dt","dx"]
        n = len(x)
        [t,x1] = list(map(Symbol,x))
        Xs = ["f1","f2"]
        [f1,f2] = list(map(Function,Xs))
        X = [f1(t,x1), f2(t,x1)]
        
        X = [cos(t),x1**2*t]
    elif a==1:
        x = ["r","theta","phi"]
        dx = ["dr","dtheta","dphi"]
        n = len(x)
        [x1,x2,x3] = list(map(Symbol,x))
    
        X = [x1*sin(x2)*cos(x3),x1*sin(x2)*sin(x3),x1*cos(x2)]

    print("\nX=%s" % (str(X)))
    N = len(X)

    J = zeros( len(x), len(X))
    for i in range(N):
        for j in range(n):
            J[i,j] = X[i].diff(Symbol(x[j]))
    J = Matrix(J)
    for i in range(n**2):
        L = Base(i,n,2)
        a = L[0]
        b = L[1]
    g = (J.T)*(J)
    for i in range(N):
        for j in range(n):
            g[i,j] = g[i,j].simplify()
    s = "\nCalculating with metric tensor g_ij = \n"
    print(s)
    ginv = g.inv() 

    for i in range(n**2):
        L = Base(i,n,2)
        a = L[0]
        b = L[1]
        s = "%s%s: %s" % (str(a),str(b),str(g[a,b]))
        print(s)

    print("\n(Christoffel Symbols 1st) \n\nGamma1_ijk = ", end=' ')
    for i in range(n**3):
        L = Base(i,n,3)
        c = L[0]
        a = L[1]
        b = L[2]
        print(str(c)+str(a)+str(b)+":",Christoffel1(g,c,a,b),",", end=' ')

    print("\n\n(Christoffel Symbols 2nd) Gamma2_Ijk = ", end=' ')
    for i in range(n**3):
        L = Base(i,n,3)
        c = L[0]
        a = L[1]
        b = L[2]
        print(str(c)+str(a)+str(b)+":",Christoffel2(g,c,a,b),",", end=' ')


    
    dA = sqrt(det(g))
    for j in range(n):
        dA *= Symbol(dx[j])
    s = "\ndA = sqrt(det(g[i,j]))*dx*dy = %s" % (str(dA))
    print(s)
    
    s = "\n\nds**2 = %s" % str(LineElement(g,dx))
    print(s)


    s = "\n\n(Ricci Tensor) R_ij = \n"
    print(s)
    for i in range(n**2):
        L = Base(i,n,2)
        a = L[0]
        b = L[1]
        R2 = RicciTensor(g,a,b).expand().simplify()
        s = "%s%s: %s" % (str(a),str(b),str(R2))
        print(s)
        
    R = ScalarCurvature(g).expand().simplify()
    s = "\n\nScalar Curvature R = %s" % str(R)
    print(s)
    return
Example #12
0
from sympy import symbols, simplify, expand, factor, fraction
from sympy.matrices import Matrix, det

# %% 2by2

l11, l12, l21, l22 = symbols('l11 l12 l21 l22')

l = Matrix(((l11, l12), (l21, l22)))

# %% 3by3

(l11, l12, l13, l21, l22, l23, l31, l32, l33) = symbols('\
    l11 l12 l13 \
    l21 l22 l23 \
    l31 l32 l33 \
    ')

l = Matrix(((l11, l12, l13), (l21, l22, l23), (l31, l32, l33)))

# %% compute

result = factor((l.T @ l).inv().trace())
num, denom = fraction(result)

print('\n\nnum\n----------\n')
print(num)
print('\n\ndenom\n----------\n')
print(denom)
print('\n\ndet\n----------\n')
print(factor(det(l.T @ l)))
Example #13
0
def diverg(X, args, g=None):
    """Return the divergence of a vector field X. Compute divergence of vector
    field consisting of N elements.

    Examples:
    =========

    >>> from sympy.tensor.tensor_fields import diverg
    >>> from sympy import symbols, cos
    >>> from sympy.matrices import Matrix
    >>> x1, x2, x3 = symbols('x1 x2 x3')

    X is a vector field, args it's a list of symbol arguments of the vector
    field X. It's can be in list, array of arraypy or contravariant tensor:

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

    g - optional parameter, metric tensor, which can be a matrix "Matrix",
    array of arraypy or covariant tensor:

    >>> g = Matrix([[2,1,0],[1,3,0],[0,0,1]])

    >>> dv = diverg(X,arg,g)
    >>> print(dv)
    x2**3 + 3*x3**2 + 1

    """

    # 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 the first vector field
    check_the_vector_field(X)
    if isinstance(X, (TensorArray, Arraypy)):
        idx_X = X.start_index[0]
    else:
        idx_X = 0

    if idx_args != idx_X:
        raise ValueError(
            "The start index of vector field and vector of arguments must be \
                    equal")

    # Handling of the metric tensor
    if g is not None:
        if isinstance(g, (TensorArray, Arraypy)):
            g = g.to_matrix()
    else:
        g = eye(len(args))

    # Calculation
    sq = sqrt(abs(det(g)))
    diver = 0
    for k in range(len(args)):
        diver += simplify(1 / sq *
                          sum([diff(X[k + idx_X] * sq, args[k + idx_X])]))
    # Output
    return diver
Example #14
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