def __new__(cls, *args, **assumptions): if len(args) == 0: return cls.identity args = map(_sympify, args) if len(args) == 1: return args[0] if not assumptions.pop('evaluate', True): obj = Expr.__new__(cls, *args, **assumptions) obj.is_commutative = all(a.is_commutative for a in args) return obj c_part, nc_part, order_symbols = cls.flatten(args) if len(c_part) + len(nc_part) <= 1: if c_part: obj = c_part[0] elif nc_part: obj = nc_part[0] else: obj = cls.identity else: obj = Expr.__new__(cls, *(c_part + nc_part), **assumptions) obj.is_commutative = not nc_part if order_symbols is not None: obj = C.Order(obj, *order_symbols) return obj
def __new__(cls, *args, **options): if len(args) == 0: return cls.identity args = map(_sympify, args) if len(args) == 1: return args[0] if not options.pop('evaluate', True): obj = Expr.__new__(cls, *args) obj.is_commutative = all(a.is_commutative for a in args) return obj c_part, nc_part, order_symbols = cls.flatten(args) if len(c_part) + len(nc_part) <= 1: if c_part: obj = c_part[0] elif nc_part: obj = nc_part[0] else: obj = cls.identity else: obj = Expr.__new__(cls, *(c_part + nc_part)) obj.is_commutative = not nc_part if order_symbols is not None: obj = C.Order(obj, *order_symbols) return obj
def is_number(self): """Returns True if 'self' is a number. >>> from sympy import log, Integral >>> from sympy.abc import x, y >>> x.is_number False >>> (2*x).is_number False >>> (2 + log(2)).is_number True >>> (2 + Integral(2, x)).is_number False >>> (2 + Integral(2, (x, 1, 2))).is_number True """ if not self.args: return False return all(obj.is_number for obj in self.iter_basic_args())
def _new_rawargs(self, *args, **kwargs): """create new instance of own class with args exactly as provided by caller but returning the self class identity if args is empty. This is handy when we want to optimize things, e.g. >>> from sympy import Mul, symbols, S >>> from sympy.abc import x, y >>> e = Mul(3, x, y) >>> e.args (3, x, y) >>> Mul(*e.args[1:]) x*y >>> e._new_rawargs(*e.args[1:]) # the same as above, but faster x*y Note: use this with caution. There is no checking of arguments at all. This is best used when you are rebuilding an Add or Mul after simply removing one or more terms. If modification which result, for example, in extra 1s being inserted (as when collecting an expression's numerators and denominators) they will not show up in the result but a Mul will be returned nonetheless: >>> m = (x*y)._new_rawargs(S.One, x); m x >>> m == x False >>> m.is_Mul True Another issue to be aware of is that the commutativity of the result is based on the commutativity of self. If you are rebuilding the terms that came from a commutative object then there will be no problem, but if self was non-commutative then what you are rebuilding may now be commutative. Although this routine tries to do as little as possible with the input, getting the commutativity right is important, so this level of safety is enforced: commutativity will always be recomputed if either a) self has no is_commutate attribute or b) self is non-commutative and kwarg `reeval=False` has not been passed. If you don't have an existing Add or Mul and need one quickly, try the following. >>> m = object.__new__(Mul) >>> m._new_rawargs(x, y) x*y Note that the commutativity is always computed in this case since m doesn't have an is_commutative attribute; reeval is ignored: >>> _.is_commutative True >>> hasattr(m, 'is_commutative') False >>> m._new_rawargs(x, y, reeval=False).is_commutative True It is possible to define the commutativity of m. If it's False then the new Mul's commutivity will be re-evaluated: >>> m.is_commutative = False >>> m._new_rawargs(x, y).is_commutative True But if reeval=False then a non-commutative self can pass along its non-commutativity to the result (but at least you have to *work* to get this wrong): >>> m._new_rawargs(x, y, reeval=False).is_commutative False """ if len(args) > 1: obj = Expr.__new__(type(self), *args) # NB no assumptions for Add/Mul if (hasattr(self, 'is_commutative') and (self.is_commutative or not kwargs.pop('reeval', True))): obj.is_commutative = self.is_commutative else: obj.is_commutative = all(a.is_commutative for a in args) elif len(args) == 1: obj = args[0] else: obj = self.identity return obj
def _eval_is_rational_function(self, syms): return all(term._eval_is_rational_function(syms) for term in self.args)
def _eval_is_polynomial(self, syms): return all(term._eval_is_polynomial(syms) for term in self.args)
def has(self, *patterns, **flags): """Return True if self has any of the patterns. If the `all` flag is True then return True if all of the patterns are present. >>> from sympy import sin, S >>> from sympy.abc import x, y, z >>> (x**2 + sin(x*y)).has(z) False >>> (x**2 + sin(x*y)).has(x, y, z) True When `all` is True then True is returned only if all of the patterns are present: >>> (x**2 + sin(x*y)).has(x, y, z, all=True) False If there are no patterns, False is always returned: "something doesn't have nothing" >>> (x).has() False >>> (S.One).has() False """ from sympy.core.symbol import Wild def search(expr, target, hit): if hasattr(expr, '__iter__') and hasattr(expr, '__len__'): # this 'if' clause is needed until all objects use # sympy containers for i in expr: if search(i, target, hit): return True elif not isinstance(expr, Basic): pass elif target(expr) and hit(expr): return True else: for term in expr.iter_basic_args(): if search(term, target, hit): return True return False def _has(p): p = sympify(p) if isinstance(p, BasicType): return search(self, lambda w: isinstance(w, p), lambda w: True) if p.is_Atom and not isinstance(p, Wild): return search(self, lambda w: isinstance(w, p.func), lambda w: w in [p]) return search(self, lambda w: p.matches(w) is not None, lambda w: True) if not patterns: return False # something doesn't have nothing patterns = set(patterns) if flags.get('all', False): return all(_has(p) for p in patterns) else: return any(_has(p) for p in patterns)
def is_arcade_part(part): """Try to work out if the given block is a table generated by ARCADE. This is true if the first, third and last line satisfies is_line.""" lines = part.split("\n") return (len(lines) >= 5 and all(map(is_line, [lines[0], lines[2], lines[-1]])))