return outdcm      def _dcm(self, parent, parent_orient):        # Reset the _dcm_cache of this frame, and remove it from the        # _dcm_caches of the frames it is linked to. Also remove it from the        # _dcm_dict of its parent        # If parent.oreint(self) is already defined,then        # update the _dcm_dict of parent while over write        # all content of self._dcm_dict and self._dcm_cache        # with new dcm relation.        # Else update _dcm_cache and _dcm_dict of both        # self and parent.         frames = self._dcm_cache.keys()         dcm_dict_del = []         dcm_cache_del = []        for frame in frames:            if frame in self._dcm_dict:                dcm_dict_del += [frame]            dcm_cache_del += [frame]        for frame in dcm_dict_del:            del frame._dcm_dict[self]        for frame in dcm_cache_del:            del frame._dcm_cache[self]        if parent in frames:            for frame in frames:                if frame in self._dcm_dict:                    dcm_dict_del += [frame]                dcm_cache_del += [frame]            # Reset the _dcm_cache of this frame, and remove it from the            # _dcm_caches of the frames it is linked to. Also remove it from the            # _dcm_dict of its parent            for frame in dcm_dict_del:                del frame._dcm_dict[self]            for frame in dcm_cache_del:                del frame._dcm_cache[self]        # Reset the _dcm_dict            self._dcm_dict = self._dlist[0] = {}        # Reset the _dcm_cache            self._dcm_cache = {}         # Add the dcm relationship to _dcm_dict        self._dcm_dict = self._dlist[0] = {}         self._dcm_dict.update({parent: parent_orient.T})         parent._dcm_dict.update({self: parent_orient})        # Also update the dcm cache after resetting it        self._dcm_cache = {}        # Update the dcm cache         self._dcm_cache.update({parent: parent_orient.T})         parent._dcm_cache.update({self: parent_orient})


>>> B1.orient_axis(N, N.z, q1)         >>> B2.orient_axis(B1, N.x, q2)         >>> B.orient_axis(B2, N.y, q3)        >>> B.dcm(N).simplify() # doctest: +SKIP        >>> B.dcm(N).simplify()         Matrix([         [ sin(q1)*sin(q2)*sin(q3) + cos(q1)*cos(q3), sin(q1)*cos(q2), sin(q1)*sin(q2)*cos(q3) - sin(q3)*cos(q1)],         [-sin(q1)*cos(q3) + sin(q2)*sin(q3)*cos(q1), cos(q1)*cos(q2), sin(q1)*sin(q3) + sin(q2)*cos(q1)*cos(q3)],


from sympy import Set, symbols, exp, log, S, Wild, Dummy, oofrom sympy import Set, symbols, exp, log, S, Wild, Dummy, oo, Float from sympy.core import Expr, Add from sympy.core.function import Lambda, _coeff_isneg, FunctionClass from sympy.logic.boolalg import true


a = Wild('a', exclude=[n])     b = Wild('b', exclude=[n])     match = expr.match(a*n + b)    if match and match[a]:    if match and match[a] and (            not match[a].atoms(Float) and            not match[b].atoms(Float)):         # canonical shift         a, b = match[a], match[b]         if a in [1, -1]:


from sympy.core.mul import Mul         from sympy.core.singleton import S         from sympy.core.exprtools import gcd_terms<ins>        from sympy.polys.polyerrors import PolynomialError</ins>         from sympy.polys.polytools import gcd          def doit(p, q):


# XXX other possibilities?          # extract gcd; any further simplification should be done by the user        G = gcd(p, q)        if G != 1:            p, q = [                gcd_terms(i/G, clear=False, fraction=False) for i in (p, q)]        try:            G = gcd(p, q)            if G != 1:                p, q = [gcd_terms(i/G, clear=False, fraction=False)                        for i in (p, q)]        except PolynomialError:  # issue 21373            G = S.One         pwas, qwas = p, q          # simplify terms


return obj         if not isinstance(arg, Expr):             raise TypeError("Bad argument type for Abs(): %s" % type(arg))<ins></ins>         # handle what we can         arg = signsimp(arg, evaluate=False)         n, d = arg.as_numer_denom()


if isinstance(arg, exp):             return exp(re(arg.args[0]))         if isinstance(arg, AppliedUndef):<ins>            if arg.is_positive:                return arg            elif arg.is_negative:                return -arg</ins>             return         if arg.is_Add and arg.has(S.Infinity, S.NegativeInfinity):             if any(a.is_infinite for a in arg.as_real_imag()):


arg_ = sign(c)*arg_         else:             arg_ = arg        if arg_.atoms(AppliedUndef):        if any(i.is_extended_positive is None for i in arg_.atoms(AppliedUndef)):             return         x, y = arg_.as_real_imag()         rv = atan2(y, x)diff --git a/sympy/simplify/powsimp.py b/sympy/simplify/powsimp.py-- a/sympy/simplify/powsimp.py++ b/sympy/simplify/powsimp.py


from sympy.simplify.simplify import posify      if force:        eq, rep = posify(eq)        return powdenest(eq, force=False).xreplace(rep)        def _denest(b, e):            if not isinstance(b, (Pow, exp)):                return b.is_positive, Pow(b, e, evaluate=False)            return _denest(b.base, b.exp*e)        reps = []        for p in eq.atoms(Pow, exp):            if isinstance(p.base, (Pow, exp)):                ok, dp = _denest(*p.args)                if ok is not False:                    reps.append((p, dp))        if reps:            eq = eq.subs(reps)        eq, reps = posify(eq)        return powdenest(eq, force=False, polar=polar).xreplace(reps)      if polar:         eq, rep = polarify(eq)


relations : dict, optional         Key is a tuple of two strings, who are the names of the systems where        the coordinates transform from and transform to. Value is a tuple of        transformed coordinates.        the coordinates transform from and transform to.        Value is a tuple of the symbols before transformation and a tuple of        the expressions after transformation.      Examples     ========


>>> x, y = symbols('x y', real=True)     >>> r, theta = symbols('r theta', nonnegative=True)     >>> relation_dict = {    ... ('Car2D', 'Pol'): (sqrt(x**2 + y**2), atan2(y, x)),    ... ('Pol', 'Car2D'): (r*cos(theta), r*sin(theta))    ... ('Car2D', 'Pol'): [(x, y), (sqrt(x**2 + y**2), atan2(y, x))],    ... ('Pol', 'Car2D'): [(r, theta), (r*cos(theta), r*sin(theta))]     ... }     >>> Car2D = CoordSystem('Car2D', p, (x, y), relation_dict)     >>> Pol = CoordSystem('Pol', p, (r, theta), relation_dict)


if not isinstance(s2, Str):                 s2 = Str(s2)             key = Tuple(s1, s2)            # Old version used Lambda as a value.             if isinstance(v, Lambda):                v = tuple(v(*symbols))                v = (tuple(v.signature), tuple(v.expr))            else:                v = (tuple(v[0]), tuple(v[1]))             rel_temp[key] = v         relations = Dict(rel_temp)


if self == sys:             expr = Matrix(self.symbols)         elif key in self.relations:            expr = Matrix(self.relations[key])            expr = Matrix(self.relations[key][1])         elif key[::-1] in self.relations:             expr = Matrix(self._inverse_transformation(sys, self))         else:


return Lambda(signature, expr)      @staticmethod    def _inverse_transformation(sys1, sys2):        # Find the transformation relation from sys2 to sys1        forward_transform_expressions = sys1.transform(sys2)        inv_results = solve(            [t[0] - t[1] for t in zip(sys2.symbols, forward_transform_expressions)],            list(sys1.symbols), dict=True)        if len(inv_results) == 0:            raise NotImplementedError(                "Cannot solve inverse of transformation from {} to {}".format(sys1, sys2))        elif len(inv_results) > 1:            raise ValueError(                "Obtained multiple results for inverse of transformation from {} to {}".format(sys1, sys2)            )    def _solve_inverse(sym1, sym2, exprs, sys1_name, sys2_name):        ret = solve(            [t[0] - t[1] for t in zip(sym2, exprs)],            list(sym1), dict=True)        if len(ret) == 0:            temp = "Cannot solve inverse relation from {} to {}."            raise NotImplementedError(temp.format(sys1_name, sys2_name))        elif len(ret) > 1:            temp = "Obtained multiple inverse relation from {} to {}."            raise ValueError(temp.format(sys1_name, sys2_name))        return ret[0]         inv_results = inv_results[0]    @classmethod    def _inverse_transformation(cls, sys1, sys2):        # Find the transformation relation from sys2 to sys1        forward = sys1.transform(sys2)        inv_results = cls._solve_inverse(sys1.symbols, sys2.symbols, forward,                                         sys1.name, sys2.name)         signature = tuple(sys1.symbols)         return [inv_results[s] for s in signature]      @classmethod     @cacheit     def _indirect_transformation(cls, sys1, sys2):        # Find the transformation relation between two indirectly connected coordinate systems        # Find the transformation relation between two indirectly connected        # coordinate systems        rel = sys1.relations         path = cls._dijkstra(sys1, sys2)        Lambdas = []        for i in range(len(path) - 1):            s1, s2 = path[i], path[i + 1]            Lambdas.append(s1.transformation(s2))        syms = Lambdas[-1].signature        expr = syms        for l in reversed(Lambdas):            expr = l(*expr)        return Lambda(syms, expr)        transforms = []        for s1, s2 in zip(path, path[1:]):            if (s1, s2) in rel:                transforms.append(rel[(s1, s2)])            else:                sym2, inv_exprs = rel[(s2, s1)]                sym1 = tuple(Dummy() for i in sym2)                ret = cls._solve_inverse(sym2, sym1, inv_exprs, s2, s1)                ret = tuple(ret[s] for s in sym2)                transforms.append((sym1, ret))        syms = sys1.args[2]        exprs = syms        for newsyms, newexprs in transforms:            exprs = tuple(e.subs(zip(newsyms, exprs)) for e in newexprs)        return exprs      @staticmethod     def _dijkstra(sys1, sys2):         # Use Dijkstra algorithm to find the shortest path between two indirectly-connected         # coordinate systems        # return value is the list of the names of the systems.         relations = sys1.relations         graph = {}         for s1, s2 in relations.keys():


path_dict[newsys][1] = [i for i in path_dict[sys][1]]                     path_dict[newsys][1].append(sys)         visit(sys1)        visit(sys1.name)          while True:             min_distance = max(path_dict.values(), key=lambda x:x[0])[0]


break             visit(newsys)         result = path_dict[sys2][1]        result.append(sys2)        result = path_dict[sys2.name][1]        result.append(sys2.name)         if result == [sys2]:        if result == [sys2.name]:             raise KeyError("Two coordinate systems are not connected.")         return result diff --git a/sympy/diffgeom/rn.py b/sympy/diffgeom/rn.py-- a/sympy/diffgeom/rn.py++ b/sympy/diffgeom/rn.py


r, theta = symbols('rho theta', nonnegative=True)  relations_2d = {    ('rectangular', 'polar'): (sqrt(x**2 + y**2), atan2(y, x)),    ('polar', 'rectangular'): (r*cos(theta), r*sin(theta)),    ('rectangular', 'polar'): [(x, y), (sqrt(x**2 + y**2), atan2(y, x))],    ('polar', 'rectangular'): [(r, theta), (r*cos(theta), r*sin(theta))], }  R2_r = CoordSystem('rectangular', R2_origin, (x, y), relations_2d)  # type: Any


rho, psi, r, theta, phi = symbols('rho psi r theta phi', nonnegative=True)  relations_3d = {    ('rectangular', 'cylindrical'): (sqrt(x**2 + y**2), atan2(y, x), z),    ('cylindrical', 'rectangular'): (rho*cos(psi), rho*sin(psi), z),    ('rectangular', 'spherical'): (sqrt(x**2 + y**2 + z**2),                                   acos(z/sqrt(x**2 + y**2 + z**2)),                                   atan2(y, x)),    ('spherical', 'rectangular'): (r*sin(theta)*cos(phi),                                   r*sin(theta)*sin(phi),                                   r*cos(theta)),    ('cylindrical', 'spherical'): (sqrt(rho**2 + z**2),                                   acos(z/sqrt(rho**2 + z**2)),                                   psi),    ('spherical', 'cylindrical'): (r*sin(theta), phi, r*cos(theta)),    ('rectangular', 'cylindrical'): [(x, y, z),                                     (sqrt(x**2 + y**2), atan2(y, x), z)],    ('cylindrical', 'rectangular'): [(rho, psi, z),                                     (rho*cos(psi), rho*sin(psi), z)],    ('rectangular', 'spherical'): [(x, y, z),                                   (sqrt(x**2 + y**2 + z**2),                                    acos(z/sqrt(x**2 + y**2 + z**2)),                                    atan2(y, x))],    ('spherical', 'rectangular'): [(r, theta, phi),                                   (r*sin(theta)*cos(phi),                                    r*sin(theta)*sin(phi),                                    r*cos(theta))],    ('cylindrical', 'spherical'): [(rho, psi, z),                                   (sqrt(rho**2 + z**2),                                    acos(z/sqrt(rho**2 + z**2)),                                    psi)],    ('spherical', 'cylindrical'): [(r, theta, phi),                                   (r*sin(theta), phi, r*cos(theta))], }  R3_r = CoordSystem('rectangular', R3_origin, (x, y, z), relations_3d)  # type: Any


float_numbers.append(x)                     if y.is_Float:                         float_numbers.append(y)            if is_algebraic(coeff):            elif is_algebraic(coeff):                 if floats:                     # there are both algebraics and reals -> EX                     return Falsediff --git a/sympy/polys/matrices/ddm.py b/sympy/polys/matrices/ddm.py-- a/sympy/polys/matrices/ddm.py++ b/sympy/polys/matrices/ddm.py


def rref(a):         """Reduced-row echelon form of a and list of pivots"""         b = a.copy()        pivots = ddm_irref(b)        K = a.domain        partial_pivot = K.is_RealField or K.is_ComplexField        pivots = ddm_irref(b, _partial_pivot=partial_pivot)         return b, pivots      def nullspace(a):diff --git a/sympy/polys/matrices/dense.py b/sympy/polys/matrices/dense.py-- a/sympy/polys/matrices/dense.py++ b/sympy/polys/matrices/dense.py


ai[j] = sum(map(mul, bi, cTj), ai[j])  def ddm_irref(a):def ddm_irref(a, _partial_pivot=False):     """a  <--  rref(a)"""     # a is (m x n)     m = len(a)


pivots = []      for j in range(n):        # Proper pivoting should be used for all domains for performance        # reasons but it is only strictly needed for RR and CC (and possibly        # other domains like RR(x)). This path is used by DDM.rref() if the        # domain is RR or CC. It uses partial (row) pivoting based on the        # absolute value of the pivot candidates.        if _partial_pivot:            ip = max(range(i, m), key=lambda ip: abs(a[ip][j]))            a[i], a[ip] = a[ip], a[i]         # pivot         aij = a[i][j] diff --git a/sympy/polys/matrices/linsolve.py b/sympy/polys/matrices/linsolve.py-- a/sympy/polys/matrices/linsolve.py++ b/sympy/polys/matrices/linsolve.py


Aaug = sympy_dict_to_dm(eqsdict, rhs, syms)     K = Aaug.domain     # sdm_irref has issues with float matrices. This uses the ddm_rref()    # function. When sdm_rref() can handle float matrices reasonably this    # should be removed...    if K.is_RealField or K.is_ComplexField:        Aaug = Aaug.to_ddm().rref()[0].to_sdm()     # Compute reduced-row echelon form (RREF)     Arref, pivots, nzcols = sdm_irref(Aaug) diff --git a/sympy/polys/matrices/sdm.py b/sympy/polys/matrices/sdm.py-- a/sympy/polys/matrices/sdm.py++ b/sympy/polys/matrices/sdm.py


Ajnz = set(Aj)             for k in Ajnz - Ainz:                 Ai[k] = - Aij * Aj[k]<ins>            Ai.pop(j)            Ainz.remove(j)</ins>             for k in Ajnz & Ainz:                 Aik = Ai[k] - Aij * Aj[k]                 if Aik:


for l in Ainz - Aknz:                 Ak[l] = - Akj * Ai[l]                 nonzero_columns[l].add(k)<ins>            Ak.pop(j)            Aknz.remove(j)</ins>             for l in Ainz & Aknz:                 Akl = Ak[l] - Akj * Ai[l]                 if Akl:


from sympy.core.logic import fuzzy_or, fuzzy_and <del></del> def _rewrite_hyperbolics_as_exp(expr):     expr = sympify(expr)     return expr.xreplace({h: h.rewrite(exp)


else:             return self.func(arg) <ins>    def _eval_expand_trig(self, **hints):        arg = self.args[0]        if arg.is_Add:            from sympy import symmetric_poly            CX = [coth(x, evaluate=False)._eval_expand_trig() for x in arg.args]            p = [[], []]            n = len(arg.args)            for i in range(n, -1, -1):                p[(n - i) % 2].append(symmetric_poly(i, CX))            return Add(*p[0])/Add(*p[1])        elif arg.is_Mul:            from sympy import binomial            coeff, x = arg.as_coeff_Mul(rational=True)            if coeff.is_Integer and coeff > 1:                c = coth(x, evaluate=False)                p = [[], []]                for i in range(coeff, -1, -1):                    p[(coeff - i) % 2].append(binomial(coeff, i)*c**i)                return Add(*p[0])/Add(*p[1])        return coth(arg)</ins>  class ReciprocalHyperbolicFunction(HyperbolicFunction):     """Base class for reciprocal functions of hyperbolic functions. """


re_part, im_part = self.as_real_imag(deep=True, **hints)         return re_part + S.ImaginaryUnit*im_part <ins>    def _eval_expand_trig(self, **hints):        return self._calculate_reciprocal("_eval_expand_trig", **hints)</ins>     def _eval_as_leading_term(self, x, cdir=0):         return (1/self._reciprocal_of(self.args[0]))._eval_as_leading_term(x)


while ns:     _k, _ = ns.popitem()     if _k in _greek:        _clash2[_k] = Symbol(_k)        _clash2[_k] = None         _greek.remove(_k)     elif _k in _latin:        _clash1[_k] = Symbol(_k)        _clash1[_k] = None         _latin.remove(_k) _clash = {} _clash.update(_clash1)diff --git a/sympy/core/assumptions.py b/sympy/core/assumptions.py-- a/sympy/core/assumptions.py++ b/sympy/core/assumptions.py


>>> check_assumptions(2*x + 1, x)     True <ins>    To see if a number matches the assumptions of an expression, pass    the number as the first argument, else its specific assumptions    may not have a non-None value in the expression:    >>> check_assumptions(x, 3)    >>> check_assumptions(3, x)    True</ins>     ``None`` is returned if ``check_assumptions()`` could not conclude.      >>> check_assumptions(2*x - 1, x)


"""     expr = sympify(expr)    if against:        if against is not None and assume:    if against is not None:        if assume:             raise ValueError(                 'Expecting `against` or `assume`, not both.')         assume = assumptions(against)diff --git a/sympy/core/sympify.py b/sympy/core/sympify.py-- a/sympy/core/sympify.py++ b/sympy/core/sympify.py


names that are defined in abc).      >>> from sympy.abc import _clash1    >>> _clash1    {'E': E, 'I': I, 'N': N, 'O': O, 'Q': Q, 'S': S}    >>> set(_clash1)    {'E', 'I', 'N', 'O', 'Q', 'S'}     >>> sympify('I & Q', _clash1)     I & Q diff --git a/sympy/parsing/sympy_parser.py b/sympy/parsing/sympy_parser.py-- a/sympy/parsing/sympy_parser.py++ b/sympy/parsing/sympy_parser.py


from sympy.core.compatibility import iterable from sympy.core.basic import Basic from sympy.core import Symbolfrom sympy.core.function import arityfrom sympy.core.function import arity, Function from sympy.utilities.misc import filldedent, func_name


name = tokVal              if (name in ['True', 'False', 'None']                or iskeyword(name)                # Don't convert attribute access                or (prevTok[0] == OP and prevTok[1] == '.')                # Don't convert keyword arguments                or (prevTok[0] == OP and prevTok[1] in ('(', ',')                    and nextTokNum == OP and nextTokVal == '=')):                    or iskeyword(name)                    # Don't convert attribute access                    or (prevTok[0] == OP and prevTok[1] == '.')                    # Don't convert keyword arguments                    or (prevTok[0] == OP and prevTok[1] in ('(', ',')                        and nextTokNum == OP and nextTokVal == '=')                    # the name has already been defined                    or name in local_dict and local_dict[name] is not None):                 result.append((NAME, name))                 continue             elif name in local_dict:                if isinstance(local_dict[name], Symbol) and nextTokVal == '(':                    result.extend([(NAME, 'Function'),                                   (OP, '('),                                   (NAME, repr(str(local_dict[name]))),                                   (OP, ')')])                local_dict.setdefault(None, set()).add(name)                if nextTokVal == '(':                    local_dict[name] = Function(name)                 else:                    result.append((NAME, name))                    local_dict[name] = Symbol(name)                result.append((NAME, name))                 continue             elif name in global_dict:                 obj = global_dict[name]


code = compile(evaluateFalse(code), '<string>', 'eval')      try:        return eval_expr(code, local_dict, global_dict)        rv = eval_expr(code, local_dict, global_dict)        # restore neutral definitions for names        for i in local_dict.pop(None, ()):            local_dict[i] = None        return rv     except Exception as e:        # restore neutral definitions for names        for i in local_dict.pop(None, ()):            local_dict[i] = None         raise e from ValueError(f"Error from parse_expr with transformed code: {code!r}")


from sympy.sets.fancysets import (Integers, Naturals, Reals, Range,     ImageSet, Rationals) from sympy.sets.sets import UniversalSet, imageset, ProductSetfrom sympy.simplify.radsimp import numer  @dispatch(ConditionSet, ConditionSet)  # type: ignore # noqa:F811 def intersection_sets(a, b): # noqa:F811


from sympy.core.function import expand_complex         from sympy.solvers.solvers import denoms, solve_linear         from sympy.core.relational import Eq<ins>        def _solution_union(exprs, sym):            # return a union of linear solutions to i in expr;            # if i cannot be solved, use a ConditionSet for solution            sols = []            for i in exprs:                x, xis = solve_linear(i, 0, [sym])                if x == sym:                    sols.append(FiniteSet(xis))                else:                    sols.append(ConditionSet(sym, Eq(i, 0)))            return Union(*sols)</ins>         f = self.lamda.expr         n = self.lamda.variables[0]


elif ifree != {n}:             return None         else:            # univarite imaginary part in same variable            x, xis = zip(*[solve_linear(i, 0) for i in Mul.make_args(im) if n in i.free_symbols])            if x and all(i == n for i in x):                base_set -= FiniteSet(xis)            else:                base_set -= ConditionSet(n, Eq(im, 0), S.Integers)            # univarite imaginary part in same variable;            # use numer instead of as_numer_denom to keep            # this as fast as possible while still handling            # simple cases            base_set &= _solution_union(                Mul.make_args(numer(im)), n)         # exclude values that make denominators 0        for i in denoms(f):            if i.has(n):                sol = list(zip(*[solve_linear(i, 0) for i in Mul.make_args(im) if n in i.free_symbols]))                if sol != []:                    x, xis = sol                    if x and all(i == n for i in x):                        base_set -= FiniteSet(xis)                else:                    base_set -= ConditionSet(n, Eq(i, 0), S.Integers)        base_set -= _solution_union(denoms(f), n)         return imageset(lam, base_set)      elif isinstance(other, Interval):


b.append(apow(item))                 else:                     if (len(item.args[0].args) != 1 and                            isinstance(item.base, Mul)):                            isinstance(item.base, (Mul, Pow))):                         # To avoid situations like #14160                         pow_paren.append(item)                     b.append(item.base)


ret.update(count.free_symbols)         return ret <ins>    @property    def kind(self):        return self.args[0].kind</ins>     def _eval_subs(self, old, new):         # The substitution (old, new) cannot be done inside         # Derivative(expr, vars) for a variety of reasons


arg2 = -S.ImaginaryUnit * arg             if arg2.is_extended_nonnegative:                 return arg2<ins>        if arg.is_extended_real:            return</ins>         # reject result if all new conjugates are just wrappers around         # an expression that was already in the arg         conj = signsimp(arg.conjugate(), evaluate=False)


from sympy.functions.special.tensor_functions import KroneckerDelta from sympy.physics.wigner import clebsch_gordan, wigner_3j, wigner_6j, wigner_9j<ins>from sympy.printing.precedence import PRECEDENCE</ins>  __all__ = [     'CG',


coefficients are defined as [1]_:      .. math ::        C^{j_1,m_1}_{j_2,m_2,j_3,m_3} = \left\langle j_1,m_1;j_2,m_2 | j_3,m_3\right\rangle        C^{j_3,m_3}_{j_1,m_1,j_2,m_2} = \left\langle j_1,m_1;j_2,m_2 | j_3,m_3\right\rangle      Parameters     ==========     j1, m1, j2, m2, j3, m3 : Number, Symbol        Terms determining the angular momentum of coupled angular momentum        systems.    j1, m1, j2, m2 : Number, Symbol        Angular momenta of states 1 and 2.    j3, m3: Number, Symbol        Total angular momentum of the coupled system.      Examples     ========


CG(3/2, 3/2, 1/2, -1/2, 1, 1)         >>> cg.doit()         sqrt(3)/2<ins>        >>> CG(j1=S(1)/2, m1=-S(1)/2, j2=S(1)/2, m2=+S(1)/2, j3=1, m3=0).doit()        sqrt(2)/2    Compare [2]_.</ins>      See Also     ========


==========      .. [1] Varshalovich, D A, Quantum Theory of Angular Momentum. 1988.    .. [2] `Clebsch-Gordan Coefficients, Spherical Harmonics, and d Functions        <https://pdg.lbl.gov/2020/reviews/rpp2020-rev-clebsch-gordan-coefs.pdf>`_        in P.A. Zyla *et al.* (Particle Data Group), Prog. Theor. Exp. Phys.        2020, 083C01 (2020).     """    precedence = PRECEDENCE["Pow"] - 1      def doit(self, **hints):         if self.is_symbolic:


from sympy import integrate from sympy import Matrix from sympy import sympify<ins>from sympy.core.evalf import prec_to_dps</ins> from sympy.core.expr import Expr


return Quaternion(a, b, c, d) <ins>    def _eval_evalf(self, prec):        """Returns the floating point approximations (decimal numbers) of the quaternion.        Returns        =======        Quaternion            Floating point approximations of quaternion(self)        Examples        ========        >>> from sympy.algebras.quaternion import Quaternion        >>> from sympy import sqrt        >>> q = Quaternion(1/sqrt(1), 1/sqrt(2), 1/sqrt(3), 1/sqrt(4))        >>> q.evalf()        1.00000000000000        + 0.707106781186547*i        + 0.577350269189626*j        + 0.500000000000000*k        """        return Quaternion(*[arg.evalf(n=prec_to_dps(prec)) for arg in self.args])</ins>     def pow_cos_sin(self, p):         """Computes the pth power in the cos-sin form.


for variable in item:                     if variable != 1:                         powers[variable] += 1                if max(powers.values()) >= min_degree:                if sum(powers.values()) >= min_degree:                     monomials_list_comm.append(Mul(*item))             yield from set(monomials_list_comm)         else:


for variable in item:                     if variable != 1:                         powers[variable] += 1                if max(powers.values()) >= min_degree:                if sum(powers.values()) >= min_degree:                     monomials_list_non_comm.append(Mul(*item))             yield from set(monomials_list_non_comm)     else:


def _print_Object(self, object):         return self._print(Symbol(object.name))     def _print_LambertW(self, expr):    def _print_LambertW(self, expr, exp=None):        arg0 = self._print(expr.args[0])        exp = r"^{%s}" % (exp,) if exp is not None else ""         if len(expr.args) == 1:            return r"W\left(%s\right)" % self._print(expr.args[0])        return r"W_{%s}\left(%s\right)" % \            (self._print(expr.args[1]), self._print(expr.args[0]))            result = r"W%s\left(%s\right)" % (exp, arg0)        else:            arg1 = self._print(expr.args[1])            result = "W{0}_{{{1}}}\\left({2}\\right)".format(exp, arg1, arg0)        return result      def _print_Morphism(self, morphism):         domain = self._print(morphism.domain)


return (12, label, h)      def _latex(self, printer):        return "%s^{%s}_{%s}" % (        return "{%s^{%s}_{%s}}" % (             self.symbol,             "".join([ i.name for i in self.args[1]]),             "".join([ i.name for i in self.args[2]])


return "CreateBoson(%s)" % self.state      def _latex(self, printer):        return "b^\\dagger_{%s}" % self.state.name        return "{b^\\dagger_{%s}}" % self.state.name  B = AnnihilateBoson Bd = CreateBoson


return "CreateFermion(%s)" % self.state      def _latex(self, printer):        return "a^\\dagger_{%s}" % self.state.name        return "{a^\\dagger_{%s}}" % self.state.name  Fd = CreateFermion F = AnnihilateFermion


def __iter__(self):         n = self.size  # validate<ins>        if not (n.has(S.Infinity) or n.has(S.NegativeInfinity) or n.is_Integer):            raise TypeError("Cannot iterate over symbolic Range")</ins>         if self.start in [S.NegativeInfinity, S.Infinity]:             raise TypeError("Cannot iterate over Range with infinite start")         elif self.start != self.stop:


n = dif/self.step         if n.is_infinite:             return S.Infinity        if not n.is_Integer or not all(i.is_integer for i in self.args):            raise ValueError('invalid method for symbolic range')        return abs(n)        if  n.is_extended_nonnegative and all(i.is_integer for i in self.args):            from sympy.functions.elementary.integers import floor            return abs(floor(n))        raise ValueError('Invalid method for symbolic Range')      @property     def is_finite_set(self):


if not (all(i.is_integer or i.is_infinite                     for i in self.args) and ((self.stop - self.start)/                     self.step).is_extended_positive):                raise ValueError('invalid method for symbolic range')                raise ValueError('Invalid method for symbolic Range')             if i == 0:                 if self.start.is_infinite:                     raise ValueError(ooslice)


rv = (self.stop if i < 0 else self.start) + i*self.step             if rv.is_infinite:                 raise ValueError(ooslice)            if 0 <= (rv - self.start)/self.step <= n:            val = (rv - self.start)/self.step            rel = fuzzy_or([val.is_infinite,                            fuzzy_and([val.is_nonnegative, (n-val).is_nonnegative])])            if rel:                 return rv            if rel is None:                raise ValueError('Invalid method for symbolic Range')             raise IndexError("Range index out of range")      @propertydiff --git a/sympy/stats/stochastic_process_types.py b/sympy/stats/stochastic_process_types.py-- a/sympy/stats/stochastic_process_types.py++ b/sympy/stats/stochastic_process_types.py


# try to convert to tuple         try:             itr = Tuple(*(sympify(i) if isinstance(i, str) else i for i in itr))        except ValueError:        except (TypeError, ValueError):             pass      else:


#_eval_is_integer = lambda self: _fuzzy_group(     #    (a.is_integer for a in self.args), quick_exit=True)     def _eval_is_integer(self):<ins>        from sympy import trailing</ins>         is_rational = self._eval_is_rational()         if is_rational is False:             return False


denominators = []         for a in self.args:             if a.is_integer:                numerators.append(a)                if abs(a) is not S.One:                    numerators.append(a)             elif a.is_Rational:                 n, d = a.as_numer_denom()                numerators.append(n)                denominators.append(d)                if abs(n) is not S.One:                    numerators.append(n)                if d is not S.One:                    denominators.append(d)             elif a.is_Pow:                 b, e = a.as_base_exp()                 if not b.is_integer or not e.is_integer: return


if not denominators:             return True         odd = lambda ints: all(i.is_odd for i in ints)        even = lambda ints: any(i.is_even for i in ints)        allodd = lambda x: all(i.is_odd for i in x)        alleven = lambda x: all(i.is_even for i in x)        anyeven = lambda x: any(i.is_even for i in x)         if odd(numerators) and even(denominators):        if allodd(numerators) and anyeven(denominators):             return False        elif even(numerators) and denominators == [2]:        elif anyeven(numerators) and denominators == [2]:             return True        elif alleven(numerators) and allodd(denominators                ) and (Mul(*denominators, evaluate=False) - 1                ).is_positive:            return False        if len(denominators) == 1:            d = denominators[0]            if d.is_Integer and d.is_even:                # if minimal power of 2 in num vs den is not                # negative then we have an integer                if (Add(*[i.as_base_exp()[1] for i in                        numerators if i.is_even]) - trailing(d.p)                        ).is_nonnegative:                    return True        if len(numerators) == 1:            n = numerators[0]            if n.is_Integer and n.is_even:                # if minimal power of 2 in den vs num is positive                # then we have have a non-integer                if (Add(*[i.as_base_exp()[1] for i in                        denominators if i.is_even]) - trailing(n.p)                        ).is_positive:                    return False      def _eval_is_polar(self):         has_polar = any(arg.is_polar for arg in self.args)


return self._eval_pos_neg(-1)      def _eval_is_odd(self):        from sympy import trailing, fraction         is_integer = self.is_integer         if is_integer:            if self.is_zero:                return False            n, d = fraction(self)            if d.is_Integer and d.is_even:                # if minimal power of 2 in num vs den is                # positive then we have an even number                if (Add(*[i.as_base_exp()[1] for i in                        Mul.make_args(n) if i.is_even]) - trailing(d.p)                        ).is_positive:                    return False                return             r, acc = True, 1             for t in self.args:                if not t.is_integer:                    return None                elif t.is_even:                if abs(t) is S.One:                    continue                assert t.is_integer                if t.is_even:                    return False                if r is False:                    pass                elif acc != 1 and (acc + t).is_odd:                     r = False                elif t.is_integer:                    if r is False:                        pass                    elif acc != 1 and (acc + t).is_odd:                        r = False                    elif t.is_odd is None:                        r = None                elif t.is_even is None:                    r = None                 acc = t             return r        # !integer -> !odd        elif is_integer is False:            return False        return is_integer # !integer -> !odd      def _eval_is_even(self):        from sympy import trailing, fraction         is_integer = self.is_integer          if is_integer:             return fuzzy_not(self.is_odd)         elif is_integer is False:            return False        n, d = fraction(self)        if n.is_Integer and n.is_even:            # if minimal power of 2 in den vs num is not            # negative then this is not an integer and            # can't be even            if (Add(*[i.as_base_exp()[1] for i in                    Mul.make_args(d) if i.is_even]) - trailing(n.p)                    ).is_nonnegative:                return False        return is_integer      def _eval_is_composite(self):         """diff --git a/sympy/core/numbers.py b/sympy/core/numbers.py-- a/sympy/core/numbers.py++ b/sympy/core/numbers.py


>>> r.p/r.q     0.75 <ins>    If an unevaluated Rational is desired, ``gcd=1`` can be passed and    this will keep common divisors of the numerator and denominator    from being eliminated. It is not possible, however, to leave a    negative value in the denominator.    >>> Rational(2, 4, gcd=1)    2/4    >>> Rational(2, -4, gcd=1).q    4</ins>     See Also     ========     sympy.core.sympify.sympify, sympy.simplify.simplify.nsimplify


from sympy.core.mul import _keep_coeff from sympy.core.symbol import Symbol from sympy.printing.str import StrPrinterfrom sympy.printing.precedence import precedencefrom sympy.printing.precedence import precedence, PRECEDENCE   class requires:


a = a or [S.One]         a_str = [self.parenthesize(x, prec) for x in a]        if len(a) == 1 and sign == "-":            # Unary minus does not have a SymPy class, and hence there's no            # precedence weight associated with it, Python's unary minus has            # an operator precedence between multiplication and exponentiation,            # so we use this to compute a weight.            a_str = [self.parenthesize(a[0], 0.5*(PRECEDENCE["Pow"]+PRECEDENCE["Mul"]))]        else:            a_str = [self.parenthesize(x, prec) for x in a]         b_str = [self.parenthesize(x, prec) for x in b]          # To parenthesize Pow with exp = -1 and having more than one Symboldiff --git a/sympy/printing/precedence.py b/sympy/printing/precedence.py-- a/sympy/printing/precedence.py++ b/sympy/printing/precedence.py


"MatAdd": PRECEDENCE["Add"],     "MatPow": PRECEDENCE["Pow"],     "MatrixSolve": PRECEDENCE["Mul"],<ins>    "Mod": PRECEDENCE["Mul"],</ins>     "TensAdd": PRECEDENCE["Add"],     # As soon as `TensMul` is a subclass of `Mul`, remove this:     "TensMul": PRECEDENCE["Mul"],


_singularities = True      def doit(self, **hints):        if self.args[0].is_zero is False:        s = super().doit()        if s == self and self.args[0].is_zero is False:             return self.args[0] / Abs(self.args[0])        return self        return s      @classmethod     def eval(cls, arg):diff --git a/sympy/parsing/sympy_parser.py b/sympy/parsing/sympy_parser.py-- a/sympy/parsing/sympy_parser.py++ b/sympy/parsing/sympy_parser.py


ast.BitAnd: 'And',         ast.BitXor: 'Not',     }<ins>    functions = (        'Abs', 'im', 're', 'sign', 'arg', 'conjugate',        'acos', 'acot', 'acsc', 'asec', 'asin', 'atan',        'acosh', 'acoth', 'acsch', 'asech', 'asinh', 'atanh',        'cos', 'cot', 'csc', 'sec', 'sin', 'tan',        'cosh', 'coth', 'csch', 'sech', 'sinh', 'tanh',        'exp', 'ln', 'log', 'sqrt', 'cbrt',    )</ins>      def flatten(self, args, func):         result = []


return new_node         return node<ins>    def visit_Call(self, node):        new_node = self.generic_visit(node)        if isinstance(node.func, ast.Name) and node.func.id in self.functions:            new_node.keywords.append(ast.keyword(arg='evaluate', value=ast.NameConstant(value=False, ctx=ast.Load())))        return new_node</ins>


import os  if sys.version_info < (3, 6):    sys.exit("This script requires Python 3.6 or newer")if sys.version_info < (3, 7):    sys.exit("This script requires Python 3.7 or newer")  from subprocess import run, PIPE from sympy.external.importtools import version_tuplediff --git a/bin/mailmap_update.py b/bin/mailmap_update.py-- a/bin/mailmap_update.py++ b/bin/mailmap_update.py


import os  if sys.version_info < (3, 6):    sys.exit("This script requires Python 3.6 or newer")if sys.version_info < (3, 7):    sys.exit("This script requires Python 3.7 or newer")  from subprocess import run, PIPE from sympy.external.importtools import version_tuplediff --git a/setup.py b/setup.py-- a/setup.py++ b/setup.py


% min_mpmath_version)         sys.exit(-1) if sys.version_info < (3, 6):    print("SymPy requires Python 3.6 or newer. Python %d.%d detected"if sys.version_info < (3, 7):    print("SymPy requires Python 3.7 or newer. Python %d.%d detected"           % sys.version_info[:2])     sys.exit(-1)


'antlr': antlr,                     'sdist': sdist_sympy,                     },          python_requires='>=3.6',          python_requires='>=3.7',           classifiers=[             'License :: OSI Approved :: BSD License',             'Operating System :: OS Independent',


'Topic :: Scientific/Engineering :: Mathematics',             'Topic :: Scientific/Engineering :: Physics',             'Programming Language :: Python :: 3',            'Programming Language :: Python :: 3.6',             'Programming Language :: Python :: 3.7',             'Programming Language :: Python :: 3.8',            'Programming Language :: Python :: 3.9',             'Programming Language :: Python :: 3 :: Only',             'Programming Language :: Python :: Implementation :: CPython',             'Programming Language :: Python :: Implementation :: PyPy',diff --git a/sympy/__init__.py b/sympy/__init__.py-- a/sympy/__init__.py++ b/sympy/__init__.py


import sysif sys.version_info < (3, 6):    raise ImportError("Python version 3.6 or above is required for SymPy.")if sys.version_info < (3, 7):    raise ImportError("Python version 3.7 or above is required for SymPy.") del sys  diff --git a/sympy/core/numbers.py b/sympy/core/numbers.py-- a/sympy/core/numbers.py++ b/sympy/core/numbers.py


if isinstance(num, str):             # Float accepts spaces as digit separators             num = num.replace(' ', '').lower()<del>            # in Py 3.6            # underscores are allowed. In anticipation of that, we ignore            # legally placed underscores            if '_' in num:                parts = num.split('_')                if not (all(parts) and                        all(parts[i][-1].isdigit()                            for i in range(0, len(parts), 2)) and                        all(parts[i][0].isdigit()                            for i in range(1, len(parts), 2))):                    # copy Py 3.6 error                    raise ValueError("could not convert string to float: '%s'" % num)                num = ''.join(parts)</del>             if num.startswith('.') and len(num) > 1:                 num = '0' + num             elif num.startswith('-.') and len(num) > 2:


from sympy.core.relational import (Ge, Gt, Le, Lt) from sympy.core import Symbol, Tuple, Dummy from sympy.core.basic import Basicfrom sympy.core.expr import Exprfrom sympy.core.expr import Expr, Atom from sympy.core.numbers import Float, Integer, oo from sympy.core.sympify import _sympify, sympify, SympifyError from sympy.utilities.iterables import (iterable, topological_sort,


else:             return kwargs <del></del> class BreakToken(Token):     """ Represents 'break' in C/Python ('exit' in Fortran).


return _sympify(itr)  class String(Token):class String(Atom, Token):     """ SymPy object representing a string.      Atomic object which is not an expression (as opposed to Symbol).


def _sympystr(self, printer, *args, **kwargs):         return self.text <ins>    def kwargs(self, exclude = (), apply = None):        return {}    #to be removed when Atom is given a suitable func    @property    def func(self):        return lambda: self</ins>  class QuotedString(String):     """ Represents a string which should be printed with quotes. """


e = Mul._from_args(dargs)                 d[i] = Pow(di.base, e, evaluate=False) if e - 1 else di.base             pre = []             # don't parenthesize first factor if negative            if n[0].could_extract_minus_sign():            if n and n[0].could_extract_minus_sign():                 pre = [str(n.pop(0))]            else:                pre = []             nfactors = pre + [self.parenthesize(a, prec, strict=False)                 for a in n]            if not nfactors:                nfactors = ['1']              # don't parenthesize first of denominator unless singleton             if len(d) > 1 and d[0].could_extract_minus_sign():


'warn' or 'ignore'.'''))         if any(coords[dim:]):             raise ValueError('Nonzero coordinates cannot be removed.')        if any(a.is_number and im(a) for a in coords):        if any(a.is_number and im(a).is_zero is False for a in coords):             raise ValueError('Imaginary coordinates are not permitted.')         if not all(isinstance(a, Expr) for a in coords):             raise TypeError('Coordinates must be valid SymPy expressions.')


def _print_Piecewise(self, expr):         "Piecewise function printer"        from sympy.logic.boolalg import ITE, simplify_logic        def print_cond(cond):            """ Problem having an ITE in the cond. """            if cond.has(ITE):                return self._print(simplify_logic(cond))            else:                return self._print(cond)         exprs = '[{}]'.format(','.join(self._print(arg.expr) for arg in expr.args))        conds = '[{}]'.format(','.join(self._print(arg.cond) for arg in expr.args))        conds = '[{}]'.format(','.join(print_cond(arg.cond) for arg in expr.args))         # If [default_value, True] is a (expr, cond) sequence in a Piecewise object         #     it will behave the same as passing the 'default' kwarg to select()         #     *as long as* it is the last element in expr.args.


def _print_ArrayAdd(self, expr):         return self._expand_fold_binary_op(self._module + '.add', expr.args) <ins>    def _print_NDimArray(self, expr):        if len(expr.shape) == 1:            return self._module + '.array(' + self._print(expr.args[0]) + ')'        if len(expr.shape) == 2:            return self._print(expr.tomatrix())        # Should be possible to extend to more dimensions        return CodePrinter._print_not_supported(self, expr)</ins>     _print_lowergamma = CodePrinter._print_not_supported     _print_uppergamma = CodePrinter._print_not_supported     _print_fresnelc = CodePrinter._print_not_supported


Substitutions containing any Symbol from ``ignore`` will be ignored.     """     from sympy.matrices.expressions import MatrixExpr, MatrixSymbol, MatMul, MatAdd<ins>    from sympy.matrices.expressions.matexpr import MatrixElement</ins>     from sympy.polys.rootoftools import RootOf      if opt_subs is None:


if isinstance(expr, RootOf):             return         if isinstance(expr, Basic) and (expr.is_Atom or expr.is_Order):        if isinstance(expr, Basic) and (                expr.is_Atom or                expr.is_Order or                isinstance(expr, (MatrixSymbol, MatrixElement))):             if expr.is_Symbol:                 excluded_symbols.add(expr)             return


_known_functions = {     'Abs': 'abs',<ins>    'Min': 'min',    'Max': 'max',</ins> } _known_functions_math = {     'acos': 'acos',


return mapping.get(gen)**int(e/eg)                 if e.is_Integer and e is not S.One:                     return _rebuild(b)**int(e)<ins>            elif mapping.get(1/expr) is not None:                return 1/mapping.get(1/expr)</ins>              try:                 return domain.convert(expr)


z : the distance to waist, and     w : the waist, or     z_r : the rayleigh range.<ins>    n : the refractive index of medium.</ins>      Examples     ========


# subclass it. See:     # https://groups.google.com/d/topic/sympy/7XkU07NRBEs/discussion     def __new__(cls, wavelen, z, z_r=None, w=None):    def __new__(cls, wavelen, z, z_r=None, w=None, n=1):         wavelen = sympify(wavelen)         z = sympify(z)        n = sympify(n)          if z_r is not None and w is None:             z_r = sympify(z_r)         elif w is not None and z_r is None:            z_r = waist2rayleigh(sympify(w), wavelen)        else:            raise ValueError('Constructor expects exactly one named argument.')            z_r = waist2rayleigh(sympify(w), wavelen, n)        elif z_r is None and w is None:            raise ValueError('Must specify one of w and z_r.')         return Expr.__new__(cls, wavelen, z, z_r)        return Expr.__new__(cls, wavelen, z, z_r, n)      @property     def wavelen(self):


def z_r(self):         return self.args[2] <ins>    @property    def n(self):        return self.args[3]</ins>     @property     def q(self):         """


@property     def w(self):         """        The beam radius at `1/e^2` intensity.        The radius of the beam w(z), at any position z along the beam.        The beam radius at `1/e^2` intensity (axial value).          See Also         ========


@property     def w_0(self):         """        The beam waist (minimal radius).         The minimal radius of beam at `1/e^2` intensity (peak value).          See Also         ========         w : the beam radius at `1/e^2` intensity        w : the beam radius at `1/e^2` intensity (axial value).          Examples         ========


>>> p.w_0         0.00100000000000000         """        return sqrt(self.z_r/pi*self.wavelen)        return sqrt(self.z_r/(pi*self.n)*self.wavelen)      @property     def divergence(self):


# Utilities ### def waist2rayleigh(w, wavelen):def waist2rayleigh(w, wavelen, n=1):     """     Calculate the rayleigh range from the waist of a gaussian beam.


pi*w**2/wavelen     """     w, wavelen = map(sympify, (w, wavelen))    return w**2*pi/wavelen    return w**2*n*pi/wavelen   def rayleigh2waist(z_r, wavelen):


from sympy.core.singleton import S from sympy.polys import Poly, decompose from sympy.utilities.misc import func_name<ins>from sympy.functions.elementary.miscellaneous import Min, Max</ins>   def decompogen(f, symbol):


if symbol not in f.free_symbols:         return [f] <del>    result = []</del>      # ===== Simple Functions ===== #     if isinstance(f, (Function, Pow)):


arg = f.args[0]         if arg == symbol:             return [f]        result += [f.subs(arg, symbol)] + decompogen(arg, symbol)        return result        return [f.subs(arg, symbol)] + decompogen(arg, symbol)    # ===== Min/Max Functions ===== #    if isinstance(f, (Min, Max)):        args = list(f.args)        d0 = None        for i, a in enumerate(args):            if not a.has_free(symbol):                continue            d = decompogen(a, symbol)            if len(d) == 1:                d = [symbol] + d            if d0 is None:                d0 = d[1:]            elif d[1:] != d0:                # decomposition is not the same for each arg:                # mark as having no decomposition                d = [symbol]                break            args[i] = d[0]        if d[0] == symbol:            return [f]        return [f.func(*args)] + d0      # ===== Convert to Polynomial ===== #     fp = Poly(f)


if len(gens) == 1 and gens[0] != symbol:         f1 = f.subs(gens[0], symbol)         f2 = gens[0]        result += [f1] + decompogen(f2, symbol)        return result        return [f1] + decompogen(f2, symbol)      # ===== Polynomial decompose() ====== #     try:        result += decompose(f)        return result        return decompose(f)     except ValueError:         return [f]


def _parse_index(self, index):         if isinstance(index, (SYMPY_INTS, Integer)):            raise ValueError("Only a tuple index is accepted")            if index >= self._loop_size:                raise ValueError("Only a tuple index is accepted")            return index          if self._loop_size == 0:            raise ValueError("Index not valide with an empty array")            raise ValueError("Index not valid with an empty array")          if len(index) != self._rank:             raise ValueError('Wrong number of array axes')


if not isinstance(pointer, Iterable):                 return [pointer], () <ins>            if len(pointer) == 0:                return [], (0,)</ins>             result = []             elems, shapes = zip(*[f(i) for i in pointer])             if len(set(shapes)) != 1:


def _check_index_for_getitem(self, index):         if isinstance(index, (SYMPY_INTS, Integer, slice)):            index = (index, )            index = (index,)          if len(index) < self.rank():            index = tuple([i for i in index] + \                          [slice(None) for i in range(len(index), self.rank())])            index = tuple(index) + \                          tuple(slice(None) for i in range(len(index), self.rank()))          if len(index) > self.rank():             raise ValueError('Dimension of index greater than rank of array')


from sympy.core import S, diff, Expr, Symbol from sympy.core.sympify import _sympify from sympy.geometry import Segment2D, Polygon, Point, Point2Dfrom sympy.polys.polytools import LC, gcd_list, degree_listfrom sympy.polys.polytools import LC, gcd_list, degree_list, Poly from sympy.simplify.simplify import nsimplify


if max_degree is None:             if expr is None:                raise TypeError('Input expression be must'                                'be a valid SymPy expression')                raise TypeError('Input expression must be a valid SymPy expression')             return main_integrate3d(expr, facets, vertices, hp_params)      if max_degree is not None:         result = {}        if expr is not None:            f_expr = []            for e in expr:                _ = decompose(e)                if len(_) == 1 and not _.popitem()[0]:                    f_expr.append(e)                elif Poly(e).total_degree() <= max_degree:                    f_expr.append(e)            expr = f_expr         if not isinstance(expr, list) and expr is not None:             raise TypeError('Input polynomials must be list of expressions')


return result      if expr is None:        raise TypeError('Input expression be must'                        'be a valid SymPy expression')        raise TypeError('Input expression must be a valid SymPy expression')      return main_integrate(expr, facets, hp_params)


coeff = LC(monom)         return coeff, monom / coeff <ins>def _polynomial_integrate(polynomials, facets, hp_params):    dims = (x, y)    dim_length = len(dims)    integral_value = S.Zero    for deg in polynomials:        poly_contribute = S.Zero        facet_count = 0        for hp in hp_params:            value_over_boundary = integration_reduction(facets,                                                        facet_count,                                                        hp[0], hp[1],                                                        polynomials[deg],                                                        dims, deg)            poly_contribute += value_over_boundary * (hp[1] / norm(hp[0]))            facet_count += 1        poly_contribute /= (dim_length + deg)        integral_value += poly_contribute    return integral_value</ins>  def main_integrate3d(expr, facets, vertices, hp_params, max_degree=None):     """Function to translate the problem of integrating uni/bi/tri-variate


dims = (x, y)     dim_length = len(dims)     result = {}<del>    integral_value = S.Zero</del>      if max_degree:         grad_terms = [[0, 0, 0, 0]] + gradient_terms(max_degree)


(b / norm(a)) / (dim_length + degree)         return result     else:        polynomials = decompose(expr)        for deg in polynomials:            poly_contribute = S.Zero            facet_count = 0            for hp in hp_params:                value_over_boundary = integration_reduction(facets,                                                            facet_count,                                                            hp[0], hp[1],                                                            polynomials[deg],                                                            dims, deg)                poly_contribute += value_over_boundary * (hp[1] / norm(hp[0]))                facet_count += 1            poly_contribute /= (dim_length + deg)            integral_value += poly_contribute    return integral_value        if not isinstance(expr, list):            polynomials = decompose(expr)            return _polynomial_integrate(polynomials, facets, hp_params)        else:            return {e: _polynomial_integrate(decompose(e), facets, hp_params) for e in expr}   def polygon_integrate(facet, hp_param, index, facets, vertices, expr, degree):


if '\n' in partstr:                 tempstr = partstr                 tempstr = tempstr.replace(vectstrs[i], '')                if '\N{right parenthesis extension}' in tempstr:   # If scalar is a fraction                if '\N{RIGHT PARENTHESIS EXTENSION}' in tempstr:   # If scalar is a fraction                     for paren in range(len(tempstr)):                         flag[i] = 1                        if tempstr[paren] == '\N{right parenthesis extension}':                            tempstr = tempstr[:paren] + '\N{right parenthesis extension}'\                        if tempstr[paren] == '\N{RIGHT PARENTHESIS EXTENSION}' and tempstr[paren + 1] == '\n':                            # We want to place the vector string after all the right parentheses, because                            # otherwise, the vector will be in the middle of the string                            tempstr = tempstr[:paren] + '\N{RIGHT PARENTHESIS EXTENSION}'\                                          + ' '  + vectstrs[i] + tempstr[paren + 1:]                             break                 elif '\N{RIGHT PARENTHESIS LOWER HOOK}' in tempstr:                    flag[i] = 1                    tempstr = tempstr.replace('\N{RIGHT PARENTHESIS LOWER HOOK}',                                        '\N{RIGHT PARENTHESIS LOWER HOOK}'                                        + ' ' + vectstrs[i])                else:                    tempstr = tempstr.replace('\N{RIGHT PARENTHESIS UPPER HOOK}',                                        '\N{RIGHT PARENTHESIS UPPER HOOK}'                                        + ' ' + vectstrs[i])                    # We want to place the vector string after all the right parentheses, because                    # otherwise, the vector will be in the middle of the string. For this reason,                    # we insert the vector string at the rightmost index.                    index = tempstr.rfind('\N{RIGHT PARENTHESIS LOWER HOOK}')                    if index != -1: # then this character was found in this string                        flag[i] = 1                        tempstr = tempstr[:index] + '\N{RIGHT PARENTHESIS LOWER HOOK}'\                                     + ' '  + vectstrs[i] + tempstr[index + 1:]                 o1[i] = tempstr          o1 = [x.split('\n') for x in o1]


return doprint(arg)     elif iterable(arg):         if isinstance(arg, list):            left, right = "[]"            left, right = "[", "]"         elif isinstance(arg, tuple):            left, right = "()"            left, right = "(", ",)"         else:             raise NotImplementedError("unhandled type: %s, %s" % (type(arg), arg))         return left +', '.join(_recursive_to_string(doprint, e) for e in arg) + right


fds = [self._collect_factor_and_dimension(                 arg) for arg in expr.args]             return (expr.func(*(f[0] for f in fds)),                    expr.func(*(d[1] for d in fds)))                    *(d[1] for d in fds))         elif isinstance(expr, Dimension):             return S.One, expr         else:


if not A.domain.is_ZZ:         raise DMDomainError('Matrix must be over domain ZZ.')     # We work one row at a time, starting from the bottom row, and working our    # way up. The total number of rows we will consider is min(m, n), where    # A is an m x n matrix.    # way up.     m, n = A.shape    rows = min(m, n)     A = A.to_dense().rep.copy()     # Our goal is to put pivot entries in the rightmost columns.     # Invariant: Before processing each row, k should be the index of the     # leftmost column in which we have so far put a pivot.     k = n    for i in range(m - 1, m - 1 - rows, -1):    for i in range(m - 1, -1, -1):        if k == 0:            # This case can arise when n < m and we've already found n pivots.            # We don't need to consider any more rows, because this is already            # the maximum possible number of pivots.            break         k -= 1         # k now points to the column in which we want to put a pivot.         # We want zeros in all entries to the left of the pivot column.


return tuple(result)     else:         for name in names:            result.append(symbols(name, **args))            result.append(symbols(name, cls=cls, **args))          return type(names)(result)


from .exceptions import GeometryError from .point import Point, Point2D, Point3D from sympy.core.containers import OrderedSetfrom sympy.core.function import Functionfrom sympy.core.exprtools import factor_termsfrom sympy.core.function import Function, expand_mul from sympy.core.sorting import ordered from sympy.core.symbol import Symbolfrom sympy.core.singleton import Sfrom sympy.polys.polytools import cancel from sympy.functions.elementary.miscellaneous import sqrtfrom sympy.solvers.solvers import solve from sympy.utilities.iterables import is_sequence


eq = eq.subs(f)     derivs = {}     for i in range(n):        yp = solve(eq.diff(x), dydx)[0].subs(derivs)        # equation will be linear in dydx, a*dydx + b, so dydx = -b/a        deq = eq.diff(x)        b = deq.xreplace({dydx: S.Zero})        a = (deq - b).xreplace({dydx: S.One})        yp = factor_terms(expand_mul(cancel((-b/a).subs(derivs)), deep=False))         if i == n - 1:             return yp.subs([(v, k) for k, v in f.items()])         derivs[dydx] = yp


def pow_rep_recursive(n_i, k, n_remaining, terms, p):    # Invalid arguments    if n_i <= 0 or k <= 0:        return    # No solutions may exist    if n_remaining < k:        return    if k * pow(n_i, p) < n_remaining:        return      if k == 0 and n_remaining == 0:         yield tuple(terms)    elif k == 1:        # next_term^p must equal to n_remaining        next_term, exact = integer_nthroot(n_remaining, p)        if exact and next_term <= n_i:            yield tuple(terms + [next_term])        return     else:        # TODO: Fall back to diop_DN when k = 2         if n_i >= 1 and k > 0:            yield from pow_rep_recursive(n_i - 1, k, n_remaining, terms, p)            residual = n_remaining - pow(n_i, p)            if residual >= 0:                yield from pow_rep_recursive(n_i, k - 1, residual, terms + [n_i], p)            for next_term in range(1, n_i + 1):                residual = n_remaining - pow(next_term, p)                if residual < 0:                    break                yield from pow_rep_recursive(next_term, k - 1, residual, terms + [next_term], p)   def sum_of_squares(n, k, zeros=False):


# If `first_dum_pos` is not zero, it means that there are trailing free gamma     # matrices in front of `expression`, so multiply by them:    for i in range(0, first_dum_pos):        [ri.insert(0, free_pos[i]) for ri in resulting_indices]    resulting_indices = list( free_pos[0:first_dum_pos] + ri for ri in resulting_indices )      resulting_expr = S.Zero     for i in resulting_indices:


isinstance(i, (Eq, Ne))])      def as_set(self):        raise NotImplementedError()        return self.args[1]


dim /= idim**count             return factor, dim         elif isinstance(expr, Function):            fds = [self._collect_factor_and_dimension(                arg) for arg in expr.args]            return (expr.func(*(f[0] for f in fds)),                    *(d[1] for d in fds))            fds = [self._collect_factor_and_dimension(arg) for arg in expr.args]            dims = [Dimension(1) if self.get_dimension_system().is_dimensionless(d[1]) else d[1] for d in fds]            return (expr.func(*(f[0] for f in fds)), *dims)         elif isinstance(expr, Dimension):             return S.One, expr         else:


code_splits[i] = code_split          # Tokenize the input strings with a regular expression:        token_lists = [tokenizer.findall(i) if isinstance(i, str) else [i] for i in code_splits]        token_lists = [tokenizer.findall(i) if isinstance(i, str) and i.isascii() else [i] for i in code_splits]         tokens = [j for i in token_lists for j in i]          # Remove newlines at the beginning


if isinstance(args[i], Add):                 for aa in args[i].args:                     tp = TensorProduct(*args[:i] + (aa,) + args[i + 1:])                    if isinstance(tp, TensorProduct):                        tp = tp._eval_expand_tensorproduct()                    add_args.append(tp)                    c_part, nc_part = tp.args_cnc()                    # Check for TensorProduct object: is the one object in nc_part, if any:                    # (Note: any other object type to be expanded must be added here)                    if len(nc_part) == 1 and isinstance(nc_part[0], TensorProduct):                        nc_part = (nc_part[0]._eval_expand_tensorproduct(), )                    add_args.append(Mul(*c_part)*Mul(*nc_part))                 break          if add_args:


for addend in expr.args[1:]:                 addend_factor, addend_dim = \                     self._collect_factor_and_dimension(addend)                if dim != addend_dim:                if not self.get_dimension_system().equivalent_dims(dim, addend_dim):                     raise ValueError(                         'Dimension of "{}" is {}, '                         'but it should be {}'.format(


cgs_gauss.set_quantity_scale_factor(maxwell, sqrt(centimeter**3*gram)/second)  # SI units expressed in CGS-gaussian units:cgs_gauss.set_quantity_scale_factor(coulomb, speed_of_light*statcoulomb/10)cgs_gauss.set_quantity_scale_factor(ampere, speed_of_light*statcoulomb/second/10)cgs_gauss.set_quantity_scale_factor(volt, speed_of_light*statvolt/10**6)cgs_gauss.set_quantity_scale_factor(coulomb, 10*speed_of_light*statcoulomb)cgs_gauss.set_quantity_scale_factor(ampere, 10*speed_of_light*statcoulomb/second)cgs_gauss.set_quantity_scale_factor(volt, 10**6/speed_of_light*statvolt) cgs_gauss.set_quantity_scale_factor(weber, 10**8*maxwell) cgs_gauss.set_quantity_scale_factor(tesla, 10**4*gauss) cgs_gauss.set_quantity_scale_factor(debye, One/10**18*statcoulomb*centimeter) cgs_gauss.set_quantity_scale_factor(oersted, sqrt(gram/centimeter)/second)cgs_gauss.set_quantity_scale_factor(ohm, 10**9/speed_of_light**2*second/centimeter)cgs_gauss.set_quantity_scale_factor(farad, One/10**9*speed_of_light**2*centimeter)cgs_gauss.set_quantity_scale_factor(henry, 10**9/speed_of_light**2/centimeter*second**2)cgs_gauss.set_quantity_scale_factor(ohm, 10**5/speed_of_light**2*second/centimeter)cgs_gauss.set_quantity_scale_factor(farad, One/10**5*speed_of_light**2*centimeter)cgs_gauss.set_quantity_scale_factor(henry, 10**5/speed_of_light**2/centimeter*second**2)  # Coulomb's constant: cgs_gauss.set_quantity_dimension(coulomb_constant, 1)


return NotImplemented         if isinstance(other, Integer):             return Integer(self.p // other)        return Integer(divmod(self, other)[0])        return divmod(self, other)[0]      def __rfloordiv__(self, other):         return Integer(Integer(other).p // self.p)


return GroupHomomorphism(domain, codomain, images)  def _check_homomorphism(domain, codomain, images):    if hasattr(domain, 'relators'):        rels = domain.relators    else:        gens = domain.presentation().generators        rels = domain.presentation().relators    """    Check that a given mapping of generators to images defines a homomorphism.    Parameters    ==========    domain : PermutationGroup, FpGroup, FreeGroup    codomain : PermutationGroup, FpGroup, FreeGroup    images : dict        The set of keys must be equal to domain.generators.        The values must be elements of the codomain.    """    pres = domain if hasattr(domain, 'relators') else domain.presentation()    rels = pres.relators    gens = pres.generators    symbols = [g.ext_rep[0] for g in gens]    symbols_to_domain_generators = dict(zip(symbols, domain.generators))     identity = codomain.identity      def _image(r):        if r.is_identity:            return identity        else:            w = identity            r_arr = r.array_form            i = 0            j = 0            # i is the index for r and j is for            # r_arr. r_arr[j] is the tuple (sym, p)            # where sym is the generator symbol            # and p is the power to which it is            # raised while r[i] is a generator            # (not just its symbol) or the inverse of            # a generator - hence the need for            # both indices            while i < len(r):                power = r_arr[j][1]                if isinstance(domain, PermutationGroup) and r[i] in gens:                    s = domain.generators[gens.index(r[i])]                else:                    s = r[i]                if s in images:                    w = w*images[s]**power                elif s**-1 in images:                    w = w*images[s**-1]**power                i += abs(power)                j += 1            return w        w = identity        for symbol, power in r.array_form:            g = symbols_to_domain_generators[symbol]            w *= images[g]**power        return w      for r in rels:         if isinstance(codomain, FpGroup):


self._is_abelian = True                 return True         for p in factors:            pgens = []            for g in self.generators:                pgens.append(g**p)            if self.index(self.subgroup(pgens)) != p:                self._is_cyclic = False                return False        if not self.is_abelian:            self._is_cyclic = False            return False         self._is_cyclic = True        self._is_abelian = True        return True        self._is_cyclic = all(            any(g**(order//p) != self.identity for g in self.generators)            for p, e in factors.items() if e > 1        )        return self._is_cyclic      @property     def is_dihedral(self):


return new_ring.from_dict(self, self.ring.domain)      def as_expr(self, *symbols):        if symbols and len(symbols) != self.ring.ngens:            raise ValueError("not enough symbols, expected %s got %s" % (self.ring.ngens, len(symbols)))        else:        if not symbols:             symbols = self.ring.symbols        elif len(symbols) != self.ring.ngens:            raise ValueError(                "Wrong number of symbols, expected %s got %s" %                (self.ring.ngens, len(symbols))            )          return expr_from_dict(self.as_expr_dict(), *symbols)


q = 1             gcd = 1        Q = 1          if not isinstance(p, SYMPY_INTS):             p = Rational(p)            q *= p.q            Q *= p.q             p = p.p         else:             p = int(p)


if not isinstance(q, SYMPY_INTS):             q = Rational(q)             p *= q.q            q = q.p            Q *= q.p         else:            q = int(q)            Q *= int(q)        q = Q          # p and q are now ints         if q == 0:


from sympy.matrices.expressions.hadamard import HadamardProduct from sympy.matrices.expressions.inverse import Inverse from sympy.matrices.expressions.matexpr import (MatrixExpr, MatrixSymbol)from sympy.matrices.expressions.special import Identityfrom sympy.matrices.expressions.special import Identity, OneMatrix from sympy.matrices.expressions.transpose import Transpose from sympy.combinatorics.permutations import _af_invert from sympy.matrices.expressions.applyfunc import ElementwiseApplyFunction


return ZeroArray(*(x.shape + expr.shape))  <ins>@array_derive.register(OneMatrix)def _(expr: OneMatrix, x: _ArrayExpr):    return ZeroArray(*(x.shape + expr.shape))</ins> @array_derive.register(Transpose) def _(expr: Transpose, x: Expr):     # D(A.T, A) ==> (m,n,i,j) ==> D(A_ji, A_mn) = d_mj d_ni


'exp', 'ln', 'log', 'sqrt', 'cbrt',     ) <ins>    relational_operators = {        ast.NotEq: 'Ne',        ast.Lt: 'Lt',        ast.LtE: 'Le',        ast.Gt: 'Gt',        ast.GtE: 'Ge',        ast.Eq: 'Eq'    }    def visit_Compare(self, node):        if node.ops[0].__class__ in self.relational_operators:            sympy_class = self.relational_operators[node.ops[0].__class__]            right = self.visit(node.comparators[0])            left = self.visit(node.left)            new_node = ast.Call(                func=ast.Name(id=sympy_class, ctx=ast.Load()),                args=[left, right],                keywords=[ast.keyword(arg='evaluate', value=ast.NameConstant(value=False, ctx=ast.Load()))],                starargs=None,                kwargs=None            )            return new_node        return node</ins>     def flatten(self, args, func):         result = []         for arg in args:


"or MatrixSymbol" % str(x))         term1 = Inverse(V)*Transpose(x - M)*Inverse(U)*(x - M)         num = exp(-Trace(term1)/S(2))        den = (2*pi)**(S(n*p)/2) * Determinant(U)**S(p)/2 * Determinant(V)**S(n)/2        den = (2*pi)**(S(n*p)/2) * Determinant(U)**(S(p)/2) * Determinant(V)**(S(n)/2)         return num/den  def MatrixNormal(symbol, location_matrix, scale_matrix_1, scale_matrix_2):


>>> M = MatrixNormal('M', [[1, 2]], [1], [[1, 0], [0, 1]])     >>> X = MatrixSymbol('X', 1, 2)     >>> density(M)(X).doit()    2*exp(-Trace((Matrix([    exp(-Trace((Matrix([     [-1],    [-2]]) + X.T)*(Matrix([[-1, -2]]) + X))/2)/pi    [-2]]) + X.T)*(Matrix([[-1, -2]]) + X))/2)/(2*pi)     >>> density(M)([[3, 4]]).doit()    2*exp(-4)/pi    exp(-4)/(2*pi)      References     ==========


""" from sympy.core.expr import Expr from sympy.core.sympify import sympifyfrom sympy.core.singleton import S  class Prefix(Expr):     """


fact = self.scale_factor * other.scale_factor         if fact == 1:            return 1        elif isinstance(other, Prefix):        if isinstance(other, Prefix):            if fact == 1:                return S.One             # simplify prefix             for p in PREFIXES:                 if PREFIXES[p].scale_factor == fact:


fact = self.scale_factor / other.scale_factor          if fact == 1:            return 1            return S.One         elif isinstance(other, Prefix):             for p in PREFIXES:                 if PREFIXES[p].scale_factor == fact: