예제 #1
0
def get_leg_position(front=True, left=True):
    anchor = Translate(body_width / 2, body_width / 2, 0)

    if not left:
        anchor = ReflectX() @ anchor
    if not front:
        anchor = ReflectY() @ anchor
    atoms = sp.symbols(r'w_b, w_r, w_h, u_b, u_r, u_h')
    rot_from_pivot, rot_y_from_z, rot_d_from_z, u_a, u_r, u_h = atoms
    chain = get_active_kinematic_chain(rot_from_pivot, rot_y_from_z,
                                       rot_d_from_z)

    Leg_Bottom = anchor @ chain[-1] @ origin

    foot_pos = []
    f_a = get_body_linkage_constraint(rot_from_pivot, u_a)
    f_t = get_leg_top_constraint(rot_y_from_z, u_r)
    f_b = get_leg_bottom_constraint(rot_d_from_z, u_h)

    for i in range(0, 3):
        foot_pos.append(
            filter_tiny_numbers(sp.expand_trig(sp.simplify(Leg_Bottom[i]))))

    constraints = [
        2 * sp.expand_trig(sp.simplify(sp.expand(f))) for f in (f_a, f_t, f_b)
    ]

    return atoms, foot_pos, constraints
예제 #2
0
    def _get_Ylm(self, l, m):
        """
        Compute an expression for spherical harmonic of order (l,m)
        in terms of Cartesian unit vectors, :math:`\hat{z}`
        and :math:`\hat{x} + i \hat{y}`

        Parameters
        ----------
        l : int
            the degree of the harmonic
        m : int
            the order of the harmonic; |m| < l

        Returns
        -------
        expr :
            a sympy expression that corresponds to the
            requested Ylm

        References
        ----------
        https://en.wikipedia.org/wiki/Spherical_harmonics
        """
        import sympy as sp

        # the relevant cartesian and spherical symbols
        x, y, z, r = sp.symbols('x y z r', real=True, positive=True)
        xhat, yhat, zhat = sp.symbols('xhat yhat zhat',
                                      real=True,
                                      positive=True)
        xpyhat = sp.Symbol('xpyhat', complex=True)
        phi, theta = sp.symbols('phi theta')
        defs = [(sp.sin(phi), y / sp.sqrt(x**2 + y**2)),
                (sp.cos(phi), x / sp.sqrt(x**2 + y**2)),
                (sp.cos(theta), z / sp.sqrt(x**2 + y**2 + z**2))]

        # the cos(theta) dependence encoded by the associated Legendre poly
        expr = sp.assoc_legendre(l, m, sp.cos(theta))

        # the exp(i*m*phi) dependence
        expr *= sp.expand_trig(sp.cos(
            m * phi)) + sp.I * sp.expand_trig(sp.sin(m * phi))

        # simplifying optimizations
        expr = sp.together(expr.subs(defs)).subs(x**2 + y**2 + z**2, r**2)
        expr = expr.expand().subs([(x / r, xhat), (y / r, yhat),
                                   (z / r, zhat)])
        expr = expr.factor().factor(extension=[sp.I]).subs(
            xhat + sp.I * yhat, xpyhat)
        expr = expr.subs(xhat**2 + yhat**2, 1 - zhat**2).factor()

        # and finally add the normalization
        amp = sp.sqrt((2 * l + 1) / (4 * numpy.pi) * sp.factorial(l - m) /
                      sp.factorial(l + m))
        expr *= amp

        return expr
예제 #3
0
def substitute_trig(l1x,l1y,l2x,l2y,l1,l2):
    phi1 = Symbol('phi1')
    phi2 = Symbol('phi2')
    cos2t12 = sympy.cos(2*(phi1-phi2))
    sin2t12 = sympy.sin(2*(phi1-phi2))
    simpcos = sympy.expand_trig(cos2t12)
    simpsin = sympy.expand_trig(sin2t12)
    cos2t12 = sympy.expand(sympy.simplify(simpcos.subs([(sympy.cos(phi1),l1x/l1),(sympy.cos(phi2),l2x/l2),
                            (sympy.sin(phi1),l1y/l1),(sympy.sin(phi2),l2y/l2)])))
    sin2t12 = sympy.expand(sympy.simplify(simpsin.subs([(sympy.cos(phi1),l1x/l1),(sympy.cos(phi2),l2x/l2),
                            (sympy.sin(phi1),l1y/l1),(sympy.sin(phi2),l2y/l2)])))
    return cos2t12,sin2t12
예제 #4
0
파일: threeptcf.py 프로젝트: bccp/nbodykit
    def _get_Ylm(self, l, m):
        """
        Compute an expression for spherical harmonic of order (l,m)
        in terms of Cartesian unit vectors, :math:`\hat{z}`
        and :math:`\hat{x} + i \hat{y}`

        Parameters
        ----------
        l : int
            the degree of the harmonic
        m : int
            the order of the harmonic; |m| < l

        Returns
        -------
        expr :
            a sympy expression that corresponds to the
            requested Ylm

        References
        ----------
        https://en.wikipedia.org/wiki/Spherical_harmonics
        """
        import sympy as sp

        # the relevant cartesian and spherical symbols
        x, y, z, r = sp.symbols('x y z r', real=True, positive=True)
        xhat, yhat, zhat = sp.symbols('xhat yhat zhat', real=True, positive=True)
        xpyhat = sp.Symbol('xpyhat', complex=True)
        phi, theta = sp.symbols('phi theta')
        defs = [(sp.sin(phi), y/sp.sqrt(x**2+y**2)),
                (sp.cos(phi), x/sp.sqrt(x**2+y**2)),
                (sp.cos(theta), z/sp.sqrt(x**2 + y**2 + z**2))
                ]

        # the cos(theta) dependence encoded by the associated Legendre poly
        expr = sp.assoc_legendre(l, m, sp.cos(theta))

        # the exp(i*m*phi) dependence
        expr *= sp.expand_trig(sp.cos(m*phi)) + sp.I*sp.expand_trig(sp.sin(m*phi))

        # simplifying optimizations
        expr = sp.together(expr.subs(defs)).subs(x**2 + y**2 + z**2, r**2)
        expr = expr.expand().subs([(x/r, xhat), (y/r, yhat), (z/r, zhat)])
        expr = expr.factor().factor(extension=[sp.I]).subs(xhat+sp.I*yhat, xpyhat)
        expr = expr.subs(xhat**2 + yhat**2, 1-zhat**2).factor()

        # and finally add the normalization
        amp = sp.sqrt((2*l+1) / (4*numpy.pi) * sp.factorial(l-m) / sp.factorial(l+m))
        expr *= amp

        return expr
예제 #5
0
def challenge16_9():
    a, b, c = symbols('a b c')
    expr1 = (b * ((2 * a * cos(theta)) - b))
    expr2 = ((a - c) * (c + a))
    expr = (Eq(expr1, expr2))

    print(solve(expr1))
    print(expand_trig(expr1))

    print(solve(expr2))
    print(expand_trig(expr2))

    print(solve(expr))
    print(expand_trig(expr))
예제 #6
0
def form_to_fform(form, M=16):
    """Convert instance of `FormContainer` to instance of `fFormContainer`

    Parameters
    ----------
    form : FormContainer
        Instance of :class:`~shgpy.core.data_handler.FormContainer`
    M : int, optional
        Number of Fourier frequencies, defaults to `16`.

    Returns
    -------
    fform : fFormContainer
        Instance of :class:`~shgpy.core.data_handler.fFormContainer`

    Notes
    -----
    This function operates by taking an instance of the `FormContainer`
    class and performing a Fourier transform.

    """
    iterable = {}
    for k,v in form.get_items():
        iterable[k] = np.zeros((2*M+1,), dtype=object)
        _logger.info(f'Currently computing {k}.')
        for m in np.arange(-M, M+1):
            _logger.debug(f'Currently computing m={m}.')
            expr = sp.expand_trig(v*(sp.cos(-m*S.phi)+1j*sp.sin(-m*S.phi))).expand()
            expr_re = _no_I_component(expr)
            expr_im = _I_component(expr)
            iterable[k][n2i(m, M)] = 1/2/sp.pi*sp.integrate(expr_re, (S.phi, 0, 2*sp.pi)) + 1/2/sp.pi*sp.I*sp.integrate(expr_im, (S.phi, 0, 2*sp.pi))
    return fFormContainer(iterable, M=M)
예제 #7
0
    def dddd(self, mu: int, nu: int, rho: int, sigma: int):
        """
		Calculates the component of the Riemann tensor R_mu,nu,rho,sigma.

		Parameters
		----------
		mu : int
			The first lower index
		nu : int
			The second lower index
		rho : int
			The third lower index
		sigma : int
			The fourth lower index

		Returns
		-------
		sympy expression
			the expression representing the specified component of the Riemann tensor
		"""
        if self.dddd_evaluated[mu, nu, rho, sigma]:
            return self.dddd_values[mu, nu, rho, sigma]
        R = 0
        for lam in range(self.g.dim()):
            R += self.g.dd(mu, lam) * self.uddd(lam, nu, rho, sigma)
        self.dddd_values[mu, nu, rho,
                         sigma] = sym.simplify(sym.expand_trig(R.simplify()))
        self.dddd_evaluated[mu, nu, rho, sigma] = True
        return self.dddd_values[mu, nu, rho, sigma]
예제 #8
0
def test_csch():
    x, y = symbols('x,y')

    k = Symbol('k', integer=True)
    n = Symbol('n', positive=True)

    assert csch(nan) is nan
    assert csch(zoo) is nan

    assert csch(oo) == 0
    assert csch(-oo) == 0

    assert csch(0) is zoo

    assert csch(-1) == -csch(1)

    assert csch(-x) == -csch(x)
    assert csch(-pi) == -csch(pi)
    assert csch(-2**1024 * E) == -csch(2**1024 * E)

    assert csch(pi * I) is zoo
    assert csch(-pi * I) is zoo
    assert csch(2 * pi * I) is zoo
    assert csch(-2 * pi * I) is zoo
    assert csch(-3 * 10**73 * pi * I) is zoo
    assert csch(7 * 10**103 * pi * I) is zoo

    assert csch(pi * I / 2) == -I
    assert csch(-pi * I / 2) == I
    assert csch(pi * I * Rational(5, 2)) == -I
    assert csch(pi * I * Rational(7, 2)) == I

    assert csch(pi * I / 3) == -2 / sqrt(3) * I
    assert csch(pi * I * Rational(-2, 3)) == 2 / sqrt(3) * I

    assert csch(pi * I / 4) == -sqrt(2) * I
    assert csch(-pi * I / 4) == sqrt(2) * I
    assert csch(pi * I * Rational(7, 4)) == sqrt(2) * I
    assert csch(pi * I * Rational(-3, 4)) == sqrt(2) * I

    assert csch(pi * I / 6) == -2 * I
    assert csch(-pi * I / 6) == 2 * I
    assert csch(pi * I * Rational(7, 6)) == 2 * I
    assert csch(pi * I * Rational(-7, 6)) == -2 * I
    assert csch(pi * I * Rational(-5, 6)) == 2 * I

    assert csch(pi * I / 105) == -1 / sin(pi / 105) * I
    assert csch(-pi * I / 105) == 1 / sin(pi / 105) * I

    assert csch(x * I) == -1 / sin(x) * I

    assert csch(k * pi * I) is zoo
    assert csch(17 * k * pi * I) is zoo

    assert csch(k * pi * I / 2) == -1 / sin(k * pi / 2) * I

    assert csch(n).is_real is True

    assert expand_trig(csch(x +
                            y)) == 1 / (sinh(x) * cosh(y) + cosh(x) * sinh(y))
 def is_equal(self, eq1, eq2):
     """Compare answers"""
     #answer=eq1, solution=eq2
     equation_types = [
         Equality, Unequality, StrictLessThan, LessThan, StrictGreaterThan,
         GreaterThan
     ]
     #Symbolic equality/Perfect match
     if self._comparison_type == "perfect_match":
         return eq1 == eq2
     eq1 = factor(
         simplify(eq1)
     )  #simplify is mandatory to counter expand_trig and expand_log weaknesses
     eq2 = factor(simplify(eq2))
     #Trigonometric simplifications
     if self._use_trigo:
         eq1 = expand_trig(eq1)
         eq2 = expand_trig(eq2)
     #Logarithmic simplifications
     if self._use_log:
         if self._use_complex:
             eq1 = expand_log(eq1)
             eq2 = expand_log(eq2)
         else:
             eq1 = expand_log(eq1, force=True)
             eq2 = expand_log(eq2, force=True)
     if self._tolerance:
         eq1 = eq1.subs([(E, math.e), (pi, math.pi)])
         eq2 = eq2.subs([(E, math.e), (pi, math.pi)])
     #Numbers
     if (isinstance(eq1, Number)
             and isinstance(eq2, Number)) or self._tolerance:
         return round(float(abs(N(eq1 - eq2))), 10) <= round(
             float(self._tolerance), 10) if self._tolerance else abs(
                 N(eq1 - eq2)) == 0
     #Numerical Evaluation
     if not type(eq1) == type(eq2):
         return N(eq1) == N(eq2)
     #Equality and inequalities
     if type(eq1) in equation_types:
         return eq1 == eq2 or simplify(eq1) == simplify(eq2)
     #Direct match
     if eq1 == eq2 or simplify(eq1) == simplify(eq2):
         return True
     #Uncaught
     return abs(N(eq1 - eq2)) == 0
예제 #10
0
def expands_trig(expression):
    '''
    Expand a trig function 
    Syntax:

    sympy.expand_trig(expression)
    '''
    return expand_trig(expression)
예제 #11
0
def sin(x):
    if isinstance(x, sp.core.basic.Basic):
        s = sp.sin(x)
        s = sp.expand_trig(s)
        s = sp.simplify(s)
        s = sp.trigsimp(s)
        return s
    else:
        return np.sin(x)
예제 #12
0
def cos(x):
    if isinstance(x, sp.core.basic.Basic):
        c = sp.cos(x)
        c = sp.expand_trig(c)
        c = sp.simplify(c)
        c = sp.trigsimp(c)
        return c
    else:
        return np.cos(x)
예제 #13
0
def test_sech():
    x, y = symbols('x, y')

    k = Symbol('k', integer=True)
    n = Symbol('n', positive=True)

    assert sech(nan) is nan
    assert sech(zoo) is nan

    assert sech(oo) == 0
    assert sech(-oo) == 0

    assert sech(0) == 1

    assert sech(-1) == sech(1)
    assert sech(-x) == sech(x)

    assert sech(pi * I) == sec(pi)

    assert sech(-pi * I) == sec(pi)
    assert sech(-2**1024 * E) == sech(2**1024 * E)

    assert sech(pi * I / 2) is zoo
    assert sech(-pi * I / 2) is zoo
    assert sech((-3 * 10**73 + 1) * pi * I / 2) is zoo
    assert sech((7 * 10**103 + 1) * pi * I / 2) is zoo

    assert sech(pi * I) == -1
    assert sech(-pi * I) == -1
    assert sech(5 * pi * I) == -1
    assert sech(8 * pi * I) == 1

    assert sech(pi * I / 3) == 2
    assert sech(pi * I * Rational(-2, 3)) == -2

    assert sech(pi * I / 4) == sqrt(2)
    assert sech(-pi * I / 4) == sqrt(2)
    assert sech(pi * I * Rational(5, 4)) == -sqrt(2)
    assert sech(pi * I * Rational(-5, 4)) == -sqrt(2)

    assert sech(pi * I / 6) == 2 / sqrt(3)
    assert sech(-pi * I / 6) == 2 / sqrt(3)
    assert sech(pi * I * Rational(7, 6)) == -2 / sqrt(3)
    assert sech(pi * I * Rational(-5, 6)) == -2 / sqrt(3)

    assert sech(pi * I / 105) == 1 / cos(pi / 105)
    assert sech(-pi * I / 105) == 1 / cos(pi / 105)

    assert sech(x * I) == 1 / cos(x)

    assert sech(k * pi * I) == 1 / cos(k * pi)
    assert sech(17 * k * pi * I) == 1 / cos(17 * k * pi)

    assert sech(n).is_real is True

    assert expand_trig(sech(x +
                            y)) == 1 / (cosh(x) * cosh(y) + sinh(x) * sinh(y))
예제 #14
0
    def __init__(self,
                 shape,
                 wcs,
                 theory=None,
                 theory_norm=None,
                 lensed_cls=None):
        ModeCoupling.__init__(self, shape, wcs)
        self.Lx, self.Ly, self.L = get_Ls()
        self.Ldl1 = (self.Lx * self.l1x + self.Ly * self.l1y)
        self.Ldl2 = (self.Lx * self.l2x + self.Ly * self.l2y)
        self.l1dl2 = (self.l1x * self.l2x + self.l2x * self.l2y)

        phi1 = Symbol('phi1')
        phi2 = Symbol('phi2')
        cos2t12 = sympy.cos(2 * (phi1 - phi2))
        sin2t12 = sympy.sin(2 * (phi1 - phi2))
        simpcos = sympy.expand_trig(cos2t12)
        simpsin = sympy.expand_trig(sin2t12)

        self.cos2t12 = sympy.expand(
            sympy.simplify(
                simpcos.subs([(sympy.cos(phi1), self.l1x / self.l1),
                              (sympy.cos(phi2), self.l2x / self.l2),
                              (sympy.sin(phi1), self.l1y / self.l1),
                              (sympy.sin(phi2), self.l2y / self.l2)])))

        self.sin2t12 = sympy.expand(
            sympy.simplify(
                simpsin.subs([(sympy.cos(phi1), self.l1x / self.l1),
                              (sympy.cos(phi2), self.l2x / self.l2),
                              (sympy.sin(phi1), self.l1y / self.l1),
                              (sympy.sin(phi2), self.l2y / self.l2)])))

        self.theory2d = None
        if theory is not None:
            self.theory2d = self._load_theory(theory, lensed_cls=lensed_cls)
        if theory_norm is None:
            self.theory2d_norm = self.theory2d
        else:
            self.theory2d_norm = self._load_theory(theory_norm,
                                                   lensed_cls=lensed_cls)

        self.Als = {}
예제 #15
0
def secular_DF(e, e1, w, w1, order):
    """ 
    Return the secular component of the disturbing function for coplanet planets up to
    the specified order in the planets' eccentricities for an inner plaent with eccentricity 
    and longitude of periapse (e,w) and outer planet eccentricity/longitude of periape (e1,w1)
    """
    s = 0
    dw = w1 - w
    # Introduce `eps' as order parameter multiplying eccentricities.
    # 'eps' is set to 1 at teh end of calculation.
    eps = S('epsilon')
    maxM = int(np.floor(order / 2.))
    for i in range(maxM + 1):
        term = secular_DF_harmonic_term(eps * e, eps * e1, dw, i, order)
        term = term.series(eps, 0, order + 1).removeO()
        s = s + expand_trig(term)
    return s.subs(eps, 1)
예제 #16
0
    def fromTransformation(symbols, to_base_point):
        """
		Creates a new metric from the given to_base_point transformation.

		Parameters
		----------
		symbols : numpy array or array_like of sympy.core.symbol.Symbol
			The symbols representing the different dimensions, e.g. `sympy.symbols('r theta z', real=True)`
		to_base_point : numpy array or array_like
			The transformation equation to get from the current coordinate system into the base coordinate system. 
			Should be expressed using the `symbols` and sympy functions for, e.g., the cosine.

		Returns
		-------
		Metric
			the (analytical) metric as derived from the transformation for a point into the base coordinate system
		"""
        if to_base_point is None:
            raise Exception(
                "You need to specify the point-to-base-transformation!")

        print("Reconstructing metric from point-to-base-transformation...")
        dim = len(to_base_point)
        partial_derivatives = [[0 for i in range(dim)] for i in range(dim)]

        for i in range(dim):
            for j in range(dim):
                partial_derivatives[i][j] = sym.diff(to_base_point[j],
                                                     symbols[i])

        g = [[0 for i in range(dim)] for i in range(dim)]
        for i in range(dim):
            for j in range(dim):
                for k in range(dim):
                    g[i][j] += partial_derivatives[i][k] * partial_derivatives[
                        j][k]
                g[j][i] = g[i][j] = sym.simplify(
                    sym.expand_trig(g[i][j].simplify()))  # catch some zeros

        print("Metric successfully reconstructed!")

        return Metric(symbols, sym.Matrix(g), to_base_point)
예제 #17
0
def quantization_form(expr, initial_expand=True):
    """Brings a sympy expression on a form that the quantizers can understand.

    Parameters
    ----------
    expr : sympy expression
        The expression. Typically a symbolic potential or kinetic term
    Returns
    -------
    sympy expr
        The rewritten expression.

    """
    if initial_expand:
        expr = sp.expand(expr)
    if expr.func == sp.Add:
        expr = sp.Add(*[
            quantization_form(term, initial_expand=False) for term in expr.args
        ])
    if expr.func == sp.Mul:
        expr = sp.Mul(*[
            quantization_form(factor, initial_expand=False)
            for factor in expr.args
        ])
    if (expr.func == sp.cos) or (expr.func == sp.sin):
        if expr.args[0].func == sp.Add:
            arg_terms = expr.args[0].args
            arg_terms_dummy = sp.symbols('arg_dummy0:' + str(len(arg_terms)))
            # The reason for these subs shenanigans are to ensure that we don't mess with the coefficients of the arguments, so cos(2x)->cos(2x) and not cos(2x)->2*cos(x)**2-1
            expr = expr.subs([
                (arg, arg_dummy)
                for arg, arg_dummy in zip(arg_terms, arg_terms_dummy)
            ])
            expr = sp.expand_trig(expr)
            expr = expr.subs([
                (arg_dummy, arg)
                for arg_dummy, arg in zip(arg_terms_dummy, arg_terms)
            ])
    if initial_expand:  # Used to cancel out terms
        expr = sp.expand(expr)
    return expr
예제 #18
0
파일: util.py 프로젝트: zizai/pydy
def function_from_partials(df_dq, q, zero_constants=False):
    """Returns a function given a list of partial derivatives of the
    function and a list of variables of which the partial derivative is
    given. For a function f(q1, ..., qn):

    'df_dq' is the list [∂ℱ/∂q1, ..., ∂ℱ/∂qn]
    'q' is the list [q1, ..., qn]
    'zero_constants' is True if zero should be used for integration constants.
        Symbols C, α1, ..., αn are used for integration constants.
    """
    alpha = symbols('α1:{0}'.format(len(q) + 1))
    f, zeta = symbols('C ζ')
    q_alpha = zip(q, alpha)
    for i, df_dqr in enumerate(df_dq):
        if hasattr(df_dqr, 'subs'):
            integrand = df_dqr.subs(dict(q_alpha[i + 1:])).subs(q[i], zeta)
        else:
            integrand = df_dqr
        f += integrate(expand_trig(integrand), (zeta, alpha[i], q[i]))
    if zero_constants:
        f = f.subs(dict(zip([symbols('C')] + list(alpha), [0] * (len(q) + 1))))
    return f
예제 #19
0
def angles_to_complex(equations, angles, control_angles):

    x = {theta: sp.symbols(f'z_{i}') for i, theta in enumerate(angles)}
    u = {theta: sp.symbols(f'w_{i}') for i, theta in enumerate(control_angles)}
    substitutions = []

    X = list(x.values()) + list(u.values())

    for i, x_i in enumerate(x):
        z = x[x_i]
        substitutions += [(sp.sin(x_i), (z - 1 / z) / 2j),
                          (sp.cos(x_i), (z + 1 / z) / 2)]

    for i, u_i in enumerate(u):
        z = u[u_i]
        substitutions += [(sp.sin(u_i), (z - 1 / z) / 2j),
                          (sp.cos(u_i), (z + 1 / z) / 2)]

    out_equations = [
        sp.expand_trig(equation).subs(substitutions) for equation in equations
    ]

    return X, out_equations, substitutions, (x, u)
예제 #20
0
def function_from_partials(df_dq, q, zero_constants=False):
    """Returns a function given a list of partial derivatives of the
    function and a list of variables of which the partial derivative is
    given. For a function f(q1, ..., qn):

    'df_dq' is the list [∂ℱ/∂q1, ..., ∂ℱ/∂qn]
    'q' is the list [q1, ..., qn]
    'zero_constants' is True if zero should be used for integration constants.
        Symbols C, α1, ..., αn are used for integration constants.
    """
    alpha = symbols('α1:{0}'.format(len(q) + 1))
    f, zeta = symbols('C ζ')
    q_alpha = zip(q, alpha)
    for i, df_dqr in enumerate(df_dq):
        if hasattr(df_dqr, 'subs'):
            integrand = df_dqr.subs(dict(q_alpha[i + 1:])).subs(q[i], zeta)
        else:
            integrand = df_dqr
        f += integrate(expand_trig(integrand), (zeta, alpha[i], q[i]))
    if zero_constants:
        f = f.subs(dict(zip([symbols('C')] + list(alpha),
                            [0] * (len(q) + 1))))
    return f
예제 #21
0
    v = p.vel(N).express(N).subs(kde_map).subs(eq_gen_speed_map)
    partials[p] = dict(zip(u, map(lambda x: v.diff(x, N), u)))

u1d, u2d, u3d = ud = [x.diff(t) for x in u]
for k, v in vc_map.items():
    vc_map[k.diff(t)] = v.diff(t).subs(kde_map).subs(vc_map)

# generalized active/inertia forces
Fr, _ = generalized_active_forces(partials, forces + torques)
Fr_star, _ = generalized_inertia_forces(partials, bodies, kde_map)
print('Fr')
for i, fr in enumerate(Fr, 1):
    print('{0}: {1}'.format(i, msprint(fr)))
print('Fr_star')
for i, fr in enumerate(Fr_star, 1):
    fr = trigsimp(expand(expand_trig(fr)), deep=True, recursive=True)
    print('{0}: {1}'.format(i, msprint(fr)))

# The dynamical equations would be of the form Fr = Fr* (r = 1, 2, 3).
Fr_expected = [
    alpha2 + a * (R1 * cos(q1) - R3 * sin(q1)),
    b * (R1 * cos(q2) + R3 * sin(q2)), Q3 - R3
]
Fr_star_expected = [
    -mA * (a_star**2 + kA**2) * u1d,
    -mB * ((b_star**2 + kB**2) * u2d - b_star * sin(q2) * u3d),
    -1 * ((mB + mC) * u3d - mB * b_star * sin(q2) * u2d +
          mB * b_star * cos(q2) * u2**2)
]
for x, y in zip(Fr, Fr_expected):
    assert expand(x - y) == 0
예제 #22
0
파일: fkp.py 프로젝트: twobombs/nbodykit
def get_real_Ylm(l, m):
    """
    Return a function that computes the real spherical
    harmonic of order (l,m)

    Parameters
    ----------
    l : int
        the degree of the harmonic
    m : int
        the order of the harmonic; abs(m) <= l

    Returns
    -------
    Ylm : callable
        a function that takes 4 arguments: (xhat, yhat, zhat)
        unit-normalized Cartesian coordinates and returns the
        specified Ylm

    References
    ----------
    https://en.wikipedia.org/wiki/Spherical_harmonics#Real_form
    """
    import sympy as sp

    # make sure l,m are integers
    l = int(l)
    m = int(m)

    # the relevant cartesian and spherical symbols
    x, y, z, r = sp.symbols('x y z r', real=True, positive=True)
    xhat, yhat, zhat = sp.symbols('xhat yhat zhat', real=True, positive=True)
    phi, theta = sp.symbols('phi theta')
    defs = [(sp.sin(phi), y / sp.sqrt(x**2 + y**2)),
            (sp.cos(phi), x / sp.sqrt(x**2 + y**2)),
            (sp.cos(theta), z / sp.sqrt(x**2 + y**2 + z**2))]

    # the normalization factors
    if m == 0:
        amp = sp.sqrt((2 * l + 1) / (4 * numpy.pi))
    else:
        amp = sp.sqrt(2 * (2 * l + 1) / (4 * numpy.pi) *
                      sp.factorial(l - abs(m)) / sp.factorial(l + abs(m)))

    # the cos(theta) dependence encoded by the associated Legendre poly
    expr = (-1)**m * sp.assoc_legendre(l, abs(m), sp.cos(theta))

    # the phi dependence
    if m < 0:
        expr *= sp.expand_trig(sp.sin(abs(m) * phi))
    elif m > 0:
        expr *= sp.expand_trig(sp.cos(m * phi))

    # simplify
    expr = sp.together(expr.subs(defs)).subs(x**2 + y**2 + z**2, r**2)
    expr = amp * expr.expand().subs([(x / r, xhat), (y / r, yhat),
                                     (z / r, zhat)])
    Ylm = sp.lambdify((xhat, yhat, zhat), expr, 'numexpr')

    # attach some meta-data
    Ylm.expr = expr
    Ylm.l = l
    Ylm.m = m

    return Ylm
예제 #23
0
 def simp(x): return simplify(expand_trig(expand_complex(expand(x))))
 def sinc(x): return sin(pi*x)/(pi*x)
예제 #24
0
    def prep_geodesic_eqns(self, parameters: Dict = None):
        r"""
        Define geodesic equations.

        Args:
            parameters:
                dictionary of model parameter values to be used for
                equation substitutions

        Attributes:
            gstar_ij_tanbeta_mat (`Matrix`_):
                :math:`\dots`

            g_ij_tanbeta_mat (`Matrix`_):
                :math:`\dots`

            tanbeta_poly_eqn (:class:`~sympy.core.relational.Equality`):
                :math:`\dots` where :math:`a := \tan\alpha`

            tanbeta_eqn (:class:`~sympy.core.relational.Equality`):
                :math:`\tan{\left(\beta \right)} = \dots` where
                :math:`a := \tan\alpha`

            gstar_ij_tanalpha_mat (`Matrix`_):
                a symmetric tensor with components (using shorthand
                :math:`a := \tan\alpha`)

                :math:`g^*[1,1] = \dots`

                :math:`g^*[1,2] = g^*[2,1] = \dots`

                :math:`g^*[2,2] = \dots`

            gstar_ij_mat (`Matrix`_):
                a symmetric tensor with components
                (using shorthand :math:`a := \tan\alpha`, and with a
                particular choice of model parameters)

                :math:`g^*[1,1] = \dots`

                :math:`g^*[1,2] = g^*[2,1] = \dots`

                :math:`g^*[2,2] =  \dots`

            g_ij_tanalpha_mat (`Matrix`_):
                a symmetric tensor with components (using shorthand
                :math:`a := \tan\alpha`)

                :math:`g[1,1] = \dots`

                :math:`g[1,2] = g[2,1] = \dots`

                :math:`g[2,2] = \dots`

            g_ij_mat (`Matrix`_):
                a symmetric tensor with components
                (using shorthand :math:`a := \tan\alpha`, and with a
                particular choice of model parameters)

                :math:`g[1,1] =\dots`

                :math:`g[1,2] = g[2,1] = \dots`

                :math:`g[2,2] = \dots`

            g_ij_mat_lambdified   (function) :
                lambdified version of `g_ij_mat`

            gstar_ij_mat_lambdified (function) :
                lambdified version of `gstar_ij_mat`
        """
        logging.info("gme.core.geodesic.prep_geodesic_eqns")
        self.gstar_ij_tanbeta_mat = None
        self.g_ij_tanbeta_mat = None
        self.tanbeta_poly_eqn = None
        self.tanbeta_eqn = None
        self.gstar_ij_tanalpha_mat = None
        self.gstar_ij_mat = None
        self.g_ij_tanalpha_mat = None
        self.g_ij_mat = None
        self.g_ij_mat_lambdified = None
        self.gstar_ij_mat_lambdified = None

        mu_eta_sub = {mu: self.mu_, eta: self.eta_}

        # if parameters is None: return
        H_ = self.H_eqn.rhs.subs(mu_eta_sub)

        # Assume indexing here ranges in [1,2]
        def p_i_lambda(i):
            return [px, pz][i - 1]

        # r_i_lambda = lambda i: [rx, rz][i-1]
        # rdot_i_lambda = lambda i: [rdotx, rdotz][i-1]

        def gstar_ij_lambda(i, j):
            return simplify(
                Rational(2, 2) * diff(diff(H_, p_i_lambda(i)), p_i_lambda(j)))

        gstar_ij_mat = Matrix([
            [gstar_ij_lambda(1, 1),
             gstar_ij_lambda(2, 1)],
            [gstar_ij_lambda(1, 2),
             gstar_ij_lambda(2, 2)],
        ])
        gstar_ij_pxpz_mat = gstar_ij_mat.subs({varphi_r(rvec): varphi})
        g_ij_pxpz_mat = gstar_ij_mat.inv().subs({varphi_r(rvec): varphi})

        cosbeta_eqn = Eq(cos(beta), 1 / sqrt(1 + tan(beta)**2))
        sinbeta_eqn = Eq(sin(beta), sqrt(1 - 1 / (1 + tan(beta)**2)))
        sintwobeta_eqn = Eq(sin(2 * beta), cos(beta)**2 - sin(beta)**2)

        self.gstar_ij_tanbeta_mat = expand_trig(
            simplify(gstar_ij_pxpz_mat.subs(e2d(
                self.px_pz_tanbeta_eqn)))).subs(e2d(cosbeta_eqn))
        self.g_ij_tanbeta_mat = expand_trig(
            simplify(g_ij_pxpz_mat.subs(e2d(self.px_pz_tanbeta_eqn)))).subs(
                e2d(cosbeta_eqn))

        tanalpha_beta_eqn = self.tanalpha_beta_eqn.subs(mu_eta_sub)
        tanbeta_poly_eqn = Eq(
            numer(tanalpha_beta_eqn.rhs) -
            tanalpha_beta_eqn.lhs * denom(tanalpha_beta_eqn.rhs),
            0,
        ).subs({tan(alpha): ta})

        tanbeta_eqn = Eq(tan(beta), solve(tanbeta_poly_eqn, tan(beta))[0])
        self.tanbeta_poly_eqn = tanbeta_poly_eqn
        self.tanbeta_eqn = tanbeta_eqn

        # Replace all refs to beta with refs to alpha
        self.gstar_ij_tanalpha_mat = (self.gstar_ij_tanbeta_mat.subs(
            e2d(sintwobeta_eqn)).subs(e2d(sinbeta_eqn)).subs(
                e2d(cosbeta_eqn)).subs(e2d(tanbeta_eqn))).subs(mu_eta_sub)
        self.gstar_ij_mat = (self.gstar_ij_tanalpha_mat.subs({
            ta: tan(alpha)
        }).subs(e2d(self.tanalpha_rdot_eqn)).subs(
            e2d(self.varphi_rx_eqn.subs(
                {varphi_r(rvec): varphi}))).subs(parameters)).subs(mu_eta_sub)
        self.g_ij_tanalpha_mat = (expand_trig(self.g_ij_tanbeta_mat).subs(
            e2d(sintwobeta_eqn)).subs(e2d(sinbeta_eqn)).subs(
                e2d(cosbeta_eqn)).subs(e2d(tanbeta_eqn))).subs(mu_eta_sub)
        self.g_ij_mat = (self.g_ij_tanalpha_mat.subs({
            ta: rdotz / rdotx
        }).subs(e2d(self.varphi_rx_eqn.subs(
            {varphi_r(rvec): varphi}))).subs(parameters)).subs(mu_eta_sub)
        self.g_ij_mat_lambdified = lambdify((rx, rdotx, rdotz, varepsilon),
                                            self.g_ij_mat, "numpy")
        self.gstar_ij_mat_lambdified = lambdify((rx, rdotx, rdotz, varepsilon),
                                                self.gstar_ij_mat, "numpy")
예제 #25
0
# Space variable
x = sympy.Symbol('x')
u = 0

exp = []
eig = []

for i in range(ns + nf):
    exp.append(expa(i))
    eig.append(eigenfunctions(i))
    u += coefficients[i] * exp[i]

# Calculation of the nonlinearity
nonlinear_term = sympy.collect(
    sympy.expand(sympy.expand_trig(nonlinearity(u))),
    [sympy.sin(x), sympy.cos(x)])

print("Nonlinearity:")
print(nonlinear_term)

# Projection of the nonlinearity
# TODO: justify division by sqrt(pi)
projections = []
for i in range(ns + nf):
    product = sympy.expand(nonlinear_term * sympy.expand_trig(eig[i]))
    result_integration = sympy.integrate(product,
                                         (x, L, R)) / sympy.sqrt(sympy.pi)
    projections.append(sympy.simplify(result_integration))
    print(projections[i])
예제 #26
0
# 合并同类项 collect
expr = x**2 + 2 * x + x + 1
print(sympy.collect(expr, x))
# 分式化简 cancel
expr = (x**2 + 2 * x + 1) / (x**2 + x)
print(sympy.cancel(expr))
# 分式裂项  apart
expr = (4 * x**3 + 21 * x**2 + 10 * x + 12) / (x**4 + 5 * x**3 + 5 * x**2 +
                                               4 * x)
print(sympy.apart(expr))
# 三角化简 trigsimp
expr = sympy.sin(x) / sympy.cos(x)
print(sympy.trigsimp(expr))
# 三角展开 expand_trig
expr = sympy.sin(x + y)
print(sympy.expand_trig(expr))
# 指数化简 powsimp / 指数展开 expand_power_exp
a, b = sympy.symbols('a b')
expr = x**a * x**b
print(sympy.powsimp(expr))
# 化简指数的指数 powdenest
# 必须满足条件 底数 positive=True
x = sympy.symbols('x', positive=True)
expr = (x**a)**b
print(sympy.powdenest(expr))
# 对数展开 expand_log / 对数合并 logcombine
# 需要指出 log ln 在 sympy 中都是自然对数
# symbol 也需要满足条件
x, y = sympy.symbols('x y', positive=True)
n = sympy.symbols('n', real=True)
print(sympy.expand_log(sympy.log(x**n)))
예제 #27
0
파일: Ex10.4.py 프로젝트: 3nrique/pydy
from sympy.physics.mechanics import dot, dynamicsymbols, inertia, msprint


m, B11, B22, B33, B12, B23, B31 = symbols('m B11 B22 B33 B12 B23 B31')
q1, q2, q3, q4, q5, q6 = dynamicsymbols('q1:7')

# reference frames
A = ReferenceFrame('A')
B = A.orientnew('B', 'body', [q4, q5, q6], 'xyz')
omega = B.ang_vel_in(A)

# points B*, O
pB_star = Point('B*')
pO = pB_star.locatenew('O', q1*B.x + q2*B.y + q3*B.z)
pO.set_vel(A, 0)
pO.set_vel(B, 0)
pB_star.v2pt_theory(pO, A, B)

# rigidbody B
I_B_O = inertia(B, B11, B22, B33, B12, B23, B31)
rbB = RigidBody('rbB', pB_star, B, m, (I_B_O, pO))

# kinetic energy
K = rbB.kinetic_energy(A)
print('K = {0}'.format(msprint(trigsimp(K))))

K_expected = dot(dot(omega, I_B_O), omega)/2
print('K_expected = 1/2*omega*I*omega = {0}'.format(
        msprint(trigsimp(K_expected))))
assert expand(expand_trig(K - K_expected)) == 0
init_printing()

from sympy import (symbols, sin, expand, expand_trig)

#%% 1.-
print('1.-')

x, y = symbols('x y')  # Consola: 'expr1'
expr1 = (x**3 + 3 * y + 2)**2
sol1 = expr1.expand()  # Consola: 'sol1'

#%% 2.-
print('2.-')

expr2 = (3 * x**2 - 2 * x + 1) / (x - 1)**2  # Consola: 'expr2'
sol2 = expr2.apart()  # Consola: 'sol2'

#%% 3.-
print('3.-')

expr3 = x**3 + 9 * x**2 + 27 * x + 27  # Consola: 'expr3'
sol3 = expr3.factor()  # Consola: 'sol3'

#%% 4.-
print('4.-')

expr4 = sin(x + 2 * y)  # Consola: 'expr4'
expr4_exp = expand(expr4)
expr4_exp2 = expand_trig(expr4)
sol4 = expand(expr4, trig=True)  # Consola: 'sol4'
예제 #29
0
for k, v in kde_map.items():
    kde_map[k.diff(t)] = v.diff(t)

# f1, f2 are forces the panes of glass exert on P1, P2 respectively
R1 = f1*B.z + C*E.x - m1*g*B.y
R2 = f2*B.z - C*E.x - m2*g*B.y

forces = [(pP1, R1), (pP2, R2)]
system = [Particle('P1', pP1, m1), Particle('P2', pP2, m2)]

partials = partial_velocities([pP1, pP2], u, A, kde_map)
Fr, _ = generalized_active_forces(partials, forces)
Fr_star, _ = generalized_inertia_forces(partials, system, kde_map)

# dynamical equations
dyn_eq = [x + y for x, y in zip(Fr, Fr_star)]
u1d, u2d, u3d = ud = [x.diff(t) for x in u]
dyn_eq_map = solve(dyn_eq, ud)

for x in ud:
    print('{0} = {1}'.format(msprint(x),
                             msprint(cancel(trigsimp(dyn_eq_map[x])))))

u1d_expected = (-g*sin(q3) + omega**2*q1*cos(q3) + u2*u3 +
                (omega**2*cos(q3)**2 + u3**2)*L*m2/(m1 + m2))
u2d_expected = -g*cos(q3) - (omega**2*q1*sin(q3) + u3*u1)
u3d_expected = -omega**2*sin(q3)*cos(q3)
assert expand(cancel(expand_trig(dyn_eq_map[u1d] - u1d_expected))) == 0
assert expand(cancel(expand_trig(dyn_eq_map[u2d] - u2d_expected))) == 0
assert expand(expand_trig(dyn_eq_map[u3d] - u3d_expected)) == 0
예제 #30
0
 def simp(x):
     return simplify(expand_trig(expand_complex(expand(x))))
예제 #31
0
 def expand_trig(self):
     return SymbolicVector(expand_trig(self.x),
                           expand_trig(self.y),
                           expand_trig(self.z))
예제 #32
0
    v = p.vel(N).express(N).subs(kde_map).subs(eq_gen_speed_map)
    partials[p] = dict(zip(u, map(lambda x: v.diff(x, N), u)))

u1d, u2d, u3d = ud = [x.diff(t) for x in u]
for k, v in vc_map.items():
    vc_map[k.diff(t)] = v.diff(t).subs(kde_map).subs(vc_map)

# generalized active/inertia forces
Fr, _ = generalized_active_forces(partials, forces + torques)
Fr_star, _ = generalized_inertia_forces(partials, bodies, kde_map)
print('Fr')
for i, fr in enumerate(Fr, 1):
    print('{0}: {1}'.format(i, msprint(fr)))
print('Fr_star')
for i, fr in enumerate(Fr_star, 1):
    fr = trigsimp(expand(expand_trig(fr)), deep=True, recursive=True)
    print('{0}: {1}'.format(i, msprint(fr)))

# The dynamical equations would be of the form Fr = Fr* (r = 1, 2, 3).
Fr_expected = [
        alpha2 + a*(R1*cos(q1) - R3*sin(q1)),
        b*(R1*cos(q2) + R3*sin(q2)),
        Q3 - R3]
Fr_star_expected = [
        -mA*(a_star**2 + kA**2)*u1d,
        -mB*((b_star**2 + kB**2)*u2d - b_star*sin(q2)*u3d),
        -1*((mB + mC)*u3d - mB*b_star*sin(q2)*u2d + mB*b_star*cos(q2)*u2**2)]
for x, y in zip(Fr, Fr_expected):
    assert expand(x - y) == 0
for x, y in zip(Fr_star, Fr_star_expected):
    assert trigsimp(expand(expand_trig((x - y).subs(vc_map)))) == 0
예제 #33
0
def _expand_trig():
    # 展开三角函数
    x = sympy.Symbol('x')
    y = sympy.Symbol('y')
    print(sympy.expand_trig(sympy.sin(x + y)))
예제 #34
0
파일: Ex3.10.py 프로젝트: 3nrique/pydy
pO = Point('O')
pS_star = pO.locatenew('S*', b*A.y)
pS_hat = pS_star.locatenew('S^', -r*B.y) # S^ touches the cone
pS1 = pS_star.locatenew('S1', -r*A.z) # S1 touches horizontal wall of the race
pS2 = pS_star.locatenew('S2', r*A.y) # S2 touches vertical wall of the race

pO.set_vel(R, 0)
pS_star.v2pt_theory(pO, R, A)
pS1.v2pt_theory(pS_star, R, S)
pS2.v2pt_theory(pS_star, R, S)

# Since S is rolling against R, v_S1_R = 0, v_S2_R = 0.
vc = [dot(p.vel(R), basis) for p in [pS1, pS2] for basis in R]

pO.set_vel(C, 0)
pS_star.v2pt_theory(pO, C, A)
pS_hat.v2pt_theory(pS_star, C, S)

# Since S is rolling against C, v_S^_C = 0.
# Cone has only angular velocity in R.z direction.
vc += [dot(pS_hat.vel(C), basis).subs(vc_map) for basis in A]
vc += [dot(C.ang_vel_in(R), basis) for basis in [R.x, R.y]]
vc_map = solve(vc, u)

# Pure rolling between S and C, dot(ω_C_S, B.y) = 0.
b_val = solve([dot(C.ang_vel_in(S), B.y).subs(vc_map).simplify()], b)[0][0]
print('b = {0}'.format(msprint(collect(cancel(expand_trig(b_val)), r))))

b_expected = r*(1 + sin(theta))/(cos(theta) - sin(theta))
assert trigsimp(b_val - b_expected) == 0
예제 #35
0
def test_coth():
    x, y = symbols('x,y')

    k = Symbol('k', integer=True)

    assert coth(nan) is nan
    assert coth(zoo) is nan

    assert coth(oo) == 1
    assert coth(-oo) == -1

    assert coth(0) is zoo
    assert unchanged(coth, 1)
    assert coth(-1) == -coth(1)

    assert unchanged(coth, x)
    assert coth(-x) == -coth(x)

    assert coth(pi * I) == -I * cot(pi)
    assert coth(-pi * I) == cot(pi) * I

    assert unchanged(coth, 2**1024 * E)
    assert coth(-2**1024 * E) == -coth(2**1024 * E)

    assert coth(pi * I) == -I * cot(pi)
    assert coth(-pi * I) == I * cot(pi)
    assert coth(2 * pi * I) == -I * cot(2 * pi)
    assert coth(-2 * pi * I) == I * cot(2 * pi)
    assert coth(-3 * 10**73 * pi * I) == I * cot(3 * 10**73 * pi)
    assert coth(7 * 10**103 * pi * I) == -I * cot(7 * 10**103 * pi)

    assert coth(pi * I / 2) == 0
    assert coth(-pi * I / 2) == 0
    assert coth(pi * I * Rational(5, 2)) == 0
    assert coth(pi * I * Rational(7, 2)) == 0

    assert coth(pi * I / 3) == -I / sqrt(3)
    assert coth(pi * I * Rational(-2, 3)) == -I / sqrt(3)

    assert coth(pi * I / 4) == -I
    assert coth(-pi * I / 4) == I
    assert coth(pi * I * Rational(17, 4)) == -I
    assert coth(pi * I * Rational(-3, 4)) == -I

    assert coth(pi * I / 6) == -sqrt(3) * I
    assert coth(-pi * I / 6) == sqrt(3) * I
    assert coth(pi * I * Rational(7, 6)) == -sqrt(3) * I
    assert coth(pi * I * Rational(-5, 6)) == -sqrt(3) * I

    assert coth(pi * I / 105) == -cot(pi / 105) * I
    assert coth(-pi * I / 105) == cot(pi / 105) * I

    assert unchanged(coth, 2 + 3 * I)

    assert coth(x * I) == -cot(x) * I

    assert coth(k * pi * I) == -cot(k * pi) * I
    assert coth(17 * k * pi * I) == -cot(17 * k * pi) * I

    assert coth(k * pi * I) == -cot(k * pi) * I

    assert coth(log(tan(2))) == coth(log(-tan(2)))
    assert coth(1 + I * pi / 2) == tanh(1)

    assert coth(x).as_real_imag(
        deep=False) == (sinh(re(x)) * cosh(re(x)) /
                        (sin(im(x))**2 + sinh(re(x))**2), -sin(im(x)) *
                        cos(im(x)) / (sin(im(x))**2 + sinh(re(x))**2))
    x = Symbol('x', extended_real=True)
    assert coth(x).as_real_imag(deep=False) == (coth(x), 0)

    assert expand_trig(coth(2 * x)) == (coth(x)**2 + 1) / (2 * coth(x))
    assert expand_trig(coth(
        3 * x)) == (coth(x)**3 + 3 * coth(x)) / (1 + 3 * coth(x)**2)

    assert expand_trig(
        coth(x + y)) == (1 + coth(x) * coth(y)) / (coth(x) + coth(y))
예제 #36
0
 def simp(x):
     return simplify(expand_trig(expand_complex(expand(x))))
예제 #37
0
# print(a)

x = sym.symbols("x")
y = sym.symbols("y")
z = sym.symbols("z")

# simplify function
a = sym.simplify(sym.sin(x)**2 + sym.cos(x)**2)
b = sym.simplify((x**3 + x**2 - x - 1) / (x**2 + 2 * x + 1))
print(f"simplification of sin(x)**2 + cos(x)**2= {a}")
print(f"simplification of (x**3 + x**2 - x - 1)/(x**2 + 2*x + 1) = {b}")

# expand function
c = sym.expand((x + 1)**2)
d = sym.expand((x + 2) * (x + 3))
e = sym.expand_trig(sym.sin(x + y))
print(f"Development of (x + 1)**2 = {c}")
print(f"Development of (x+2)*(x+3) = {d}")
print(f"Development of sin(x+y) = {e}")

# factor function
f = sym.factor(x**2 * z + 4 * x * y * z + a * y**2 * z)
g = sym.factor(sym.cos(x)**2 + 2 * sym.cos(x) * sym.sin(x) + sym.sin(x)**2)
print(f"Factor of x**2*z + 4*x*y*z + a*y**2*z = {f}")
print(f"Factor of cos(x)**x + 2*cos(x)*sin(x) + sin(x)**2 = {g}")

# derivative function
h = sym.diff(sym.cos(x), x)
i = sym.diff(x**4, x, 3)
print(f"The derivative of cos(x) = {h}")
print(f"The 3rd derivative of x**4 = {i}")