def getn(e): """ Returns the order of the expression "e". The order is determined either from the O(...) term. If there is no O(...) term, it returns None. Example: >>> getn(1+x+O(x**2)) 2 >>> getn(1+x) >>> """ o = geto(e) if o is None: return None else: o = o.expr if o.is_Symbol: return Integer(1) if o.is_Pow: return o.args[1] n, d = o.as_numer_denom() if isinstance(d, log): # i.e. o = x**2/log(x) if n.is_Symbol: return Integer(1) if n.is_Pow: return n.args[1] raise NotImplementedError()
def getattr(self, name): if name == u'length': return Integer(len(self.string)) if name == u'utf8': return space.to_uint8array( self.string.encode('utf-8')) return Object.getattr(self, name)
def Dict_update(self, other): if isinstance(other, Dict): self.data.update(other.data) elif isinstance(other, space.Exnihilo): for name in other.map.attribute_indexes: self.setitem(space.String(name), other.getattr(name)) else: it = other.iter() try: while True: item = it.callattr(u"next", []) key = item.getitem(Integer(0)) val = item.getitem(Integer(1)) self.setitem(key, val) except StopIteration as stop: pass return space.null
def removeO(self): "Removes the O(..) symbol if there is one" if self.is_Order: return Integer(0) for i, x in enumerate(self.args): if x.is_Order: return Add(*(self.args[:i] + self.args[i + 1:])) return self
def instantiate(argv): dict_ = Dict() if len(argv) > 0: other = argv[0] if isinstance(other, Dict): dict_.data.update(other.data) else: it = other.iter() try: while True: item = it.callattr(u"next", []) key = item.getitem(Integer(0)) val = item.getitem(Integer(1)) dict_.setitem(key, val) except StopIteration as stop: pass return dict_
def String_count(self, ch): if len(ch.string) != 1: raise space.unwind(space.LError(u"str.count expected char")) count = 0 x = ch.string[0] for ch in self.string: if ch == x: count += 1 return Integer(count)
def instantiate(other): dict_ = Dict() if other is not None: if isinstance(other, Dict): dict_.data.update(other.data) elif isinstance(other, space.Exnihilo): for name in other.map.attribute_indexes: dict_.setitem(space.String(name), other.getattr(name)) else: it = other.iter() try: while True: item = it.callattr(u"next", []) key = item.getitem(Integer(0)) val = item.getitem(Integer(1)) dict_.setitem(key, val) except StopIteration as stop: pass return dict_
def getattr(self, index): if index == u"arity": return space.Integer(self.arity) if index == u"default": return self.default if index == u"doc": return self.doc if index == u"size": # Used for ensuring that the gc+sleep can a = len(self.multimethod_table) # bite into the weak references. return Integer(a) return Object.getattr(self, index)
def as_base_exp(self): """Return base and exp of self unless base is 1/Integer, then return Integer, -exp. If this extra processing is not needed, the base and exp properties will give the raw arguments, e.g. (1/2, 2) for (1/2)**2 rather than (2, -2). """ b, e = self.args if b.is_Rational and b.p == 1: return Integer(b.q), -e return b, e
def int_shl(a, b): a_v = int(a.value) b_v = int(b.value) if b_v < LONG_BIT: # 0 <= b < LONG_BIT c = ovfcheck(a_v << b_v) return Integer(rffi.r_long(c)) if b_v < 0: raise space.unwind(space.LError(u"negative shift count")) # b_v >= LONG_BIT if a_v == 0: return a raise OverflowError
def int_shr(a, b): a_v = a.value b_v = b.value if b_v >= LONG_BIT: # not (0 <= b < LONG_BIT) if b_v < 0: raise space.unwind(space.LError(u"negative shift count")) # b >= LONG_BIT if a_v == 0: return a a_v = -1 if a_v < 0 else 0 else: a_v = a_v >> b_v return Integer(a_v)
def as_base_exp(self): """Return base and exp of self. If base is 1/Integer, then return Integer, -exp. If this extra processing is not needed, the base and exp properties will give the raw arguments Examples ======== >>> from sympy import Pow, S >>> p = Pow(S.Half, 2, evaluate=False) >>> p.as_base_exp() (2, -2) >>> p.args (1/2, 2) """ b, e = self.args if b.is_Rational and b.p == 1: return Integer(b.q), -e return b, e
def _(a): return Integer(+a.value)
def _eval_expand_multinomial(self, **hints): """(a+b+..) ** n -> a**n + n*a**(n-1)*b + .., n is nonzero integer""" base, exp = self.args result = self if exp.is_Rational and exp.p > 0 and base.is_Add: if not exp.is_Integer: n = Integer(exp.p // exp.q) if not n: return result else: radical, result = Pow(base, exp - n), [] expanded_base_n = Pow(base, n) if expanded_base_n.is_Pow: expanded_base_n = \ expanded_base_n._eval_expand_multinomial() for term in Add.make_args(expanded_base_n): result.append(term*radical) return Add(*result) n = int(exp) if base.is_commutative: order_terms, other_terms = [], [] for b in base.args: if b.is_Order: order_terms.append(b) else: other_terms.append(b) if order_terms: # (f(x) + O(x^n))^m -> f(x)^m + m*f(x)^{m-1} *O(x^n) f = Add(*other_terms) o = Add(*order_terms) if n == 2: return expand_multinomial(f**n, deep=False) + n*f*o else: g = expand_multinomial(f**(n - 1), deep=False) return expand_mul(f*g, deep=False) + n*g*o if base.is_number: # Efficiently expand expressions of the form (a + b*I)**n # where 'a' and 'b' are real numbers and 'n' is integer. a, b = base.as_real_imag() if a.is_Rational and b.is_Rational: if not a.is_Integer: if not b.is_Integer: k = Pow(a.q * b.q, n) a, b = a.p*b.q, a.q*b.p else: k = Pow(a.q, n) a, b = a.p, a.q*b elif not b.is_Integer: k = Pow(b.q, n) a, b = a*b.q, b.p else: k = 1 a, b, c, d = int(a), int(b), 1, 0 while n: if n & 1: c, d = a*c - b*d, b*c + a*d n -= 1 a, b = a*a - b*b, 2*a*b n //= 2 I = S.ImaginaryUnit if k == 1: return c + I*d else: return Integer(c)/k + I*d/k p = other_terms # (x+y)**3 -> x**3 + 3*x**2*y + 3*x*y**2 + y**3 # in this particular example: # p = [x,y]; n = 3 # so now it's easy to get the correct result -- we get the # coefficients first: from sympy import multinomial_coefficients from sympy.polys.polyutils import basic_from_dict expansion_dict = multinomial_coefficients(len(p), n) # in our example: {(3, 0): 1, (1, 2): 3, (0, 3): 1, (2, 1): 3} # and now construct the expression. return basic_from_dict(expansion_dict, *p) else: if n == 2: return Add(*[f*g for f in base.args for g in base.args]) else: multi = (base**(n - 1))._eval_expand_multinomial() if multi.is_Add: return Add(*[f*g for f in base.args for g in multi.args]) else: # XXX can this ever happen if base was an Add? return Add(*[f*multi for f in base.args]) elif (exp.is_Rational and exp.p < 0 and base.is_Add and abs(exp.p) > exp.q): return 1 / Pow(base, -exp)._eval_expand_multinomial() elif exp.is_Add and base.is_Number: # a + b a b # n --> n n , where n, a, b are Numbers coeff, tail = S.One, S.Zero for term in exp.args: if term.is_Number: coeff *= Pow(base, term) else: tail += term return coeff * Pow(base, tail) else: return result
def sympify(a, locals=None, convert_xor=True): """Converts an arbitrary expression to a type that can be used inside sympy. For example, it will convert python int's into instance of sympy.Rational, floats into intances of sympy.Real, etc. It is also able to coerce symbolic expressions which does inherit after Basic. This can be useful in cooperation with SAGE. It currently accepts as arguments: - any object defined in sympy (except maybe matrices [TODO]) - standard numeric python types: int, long, float, Decimal - strings (like "0.09" or "2e-19") - booleans (will leave them unchanged) If the argument is already a type that sympy understands, it will do nothing but return that value. This can be used at the begining of a function to ensure you are working with the correct type. >>> from sympy import * >>> sympify(2).is_integer True >>> sympify(2).is_real True >>> sympify(2.0).is_real True >>> sympify("2.0").is_real True >>> sympify("2e-45").is_real True """ # XXX instead of duplicating _sympify it would be better to call _sympify # directly from here, but a lot of SymPy still calls sympify (no '_') and # this will add unneccesary overhead. # # When everything settles, let's refactor this. # -- kirr if locals is None: locals = {} if isinstance(a, Basic): return a if isinstance(a, BasicType): return a elif isinstance(a, bool): return a elif isinstance(a, (int, long)): return Integer(a) elif isinstance(a, (float, decimal.Decimal)): return Real(a) elif isinstance(a, complex): real, imag = map(sympify, (a.real, a.imag)) ireal, iimag = int(real), int(imag) if ireal + iimag * 1j == a: return ireal + iimag * S.ImaginaryUnit return real + S.ImaginaryUnit * imag elif isinstance(a, (list, tuple, set)): return type(a)([sympify(x) for x in a]) # let's see if 'a' implements conversion methods such as '_sympy_' or # '__int__', that returns a SymPy (by definition) or SymPy compatible # expression, so we just use it for methname, conv in [ ('_sympy_', None), ('__float__', Real), ('__int__', Integer), ]: meth = getattr(a, methname, None) if meth is None: continue # we have to be careful -- calling Class.__int__() almost always is not # a good idea try: v = meth() except TypeError: continue if conv is not None: v = conv(v) return v else: # XXX this is here because of cyclic-import issues from sympy.matrices import Matrix if isinstance(a, Matrix): raise NotImplementedError('matrix support') if not isinstance(a, str): # At this point we were given an arbitrary expression # which does not inherit from Basic and doesn't implement # _sympy_ (which is a canonical and robust way to convert # anything to SymPy expression). # # As a last chance, we try to take "a"'s normal form via str() # and try to parse it. If it fails, then we have no luck and # return an exception a = str(a) if convert_xor: a = a.replace('^', '**') import ast_parser return ast_parser.parse_expr(a, locals) raise SympifyError("%r is NOT a valid SymPy expression" % a)
def _sympify(a): """short version of sympify for internal usage When adding and comparing symbolic expressions, it is unwise to allow e.g. strings to mixin. On the other hand Python integers and floats are allowed. So we don't use full-featured sympify in __add__ and __eq__ methods, but instead use this small-crafted function there instead. >>> Integer(1) == 1 True >>> Integer(1) == '1' False >>> from sympy import Symbol >>> x = Symbol('x') >>> x + 1 1 + x >>> x + '1' Traceback (most recent call last): ... TypeError: unsupported operand type(s) for +: 'Symbol' and 'str' see: sympify """ if isinstance(a, Basic): return a if isinstance(a, BasicType): return a elif isinstance(a, (int, long)): return Integer(a) elif isinstance(a, (float, decimal.Decimal)): return Real(a) elif isinstance(a, complex): real, imag = map(sympify, (a.real, a.imag)) ireal, iimag = int(real), int(imag) if ireal + iimag * 1j == a: return ireal + iimag * S.ImaginaryUnit return real + S.ImaginaryUnit * imag # let's see if 'a' implements conversion methods such as '_sympy_' or # '__int__', that returns a SymPy (by definition) or SymPy compatible # expression, so we just use it for methname, conv in [ ('_sympy_', None), ('__float__', Real), ('__int__', Integer), ]: meth = getattr(a, methname, None) if meth is None: continue # we have to be careful -- calling Class.__int__() almost always is not # a good idea try: v = meth() except TypeError: continue if conv is not None: v = conv(v) return v raise SympifyError("%r is NOT a valid SymPy expression" % (a, ))
def _(a, b): return List([Integer(int(a.flag)), Integer(int(b.flag))])
def List_index(self, obj): for index, item in enumerate(self.contents): if item.eq(obj): self.contents.pop(index) return Integer(index) raise space.unwind(space.LValueError(self, obj))
def _rgcd(a, b): return Rational(Integer(igcd(a.p, b.p)), Integer(ilcm(a.q, b.q)))
def _(a, b): return Integer(operation(a.value, b.value))
def List_count(self, obj): count = 0 for item in self.contents: if item.eq(obj): count += 1 return Integer(count)
def _(a, b): return Integer(a.value // b.value)
def getattr(self, name): if name == u'length': return Integer(len(self.contents)) return Object.getattr(self, name)
def __sympifyit_wrapper(a, b): # our task is to call `func` with `b` _sympified. # # if we _sympify from the beginning, we'll get unneccesary overhead, # because _sympify has far non-zero cost even for Basic instances. # # the idea is to first run `func` with `b` as is, catch any error, and # try to rerun with b _sympified. # # so for Basic instances we'll get almost no overhead, and for other # objects we agree to take additional overhead because `func` has to be # run first, and only when it raises we can proceed with the second # phase. # # however there is one important exception -- python ints. # ints are used heavily, e.g. in sum([x**i for i in range(n)]) and # other places, so it is important to sympify ints as fast as possible # too. # python ints are used frequently -- it is important to convert them as # fast as possible # # %timeit type(1) is int -> 1.43 us # %timeit type('abc') is int -> 1.48 us # %timeit isinstance(1, int) -> 1.29 us # %timeit isinstance('abc', int) -> 2.23 us # %timeit isinstance(x, int) -> 4.28 us # z = S.Half # %timeit isinstance(z, int) -> 5.2 us # # so we use: if type(b) is int: from numbers import Integer b = Integer(b) try: # fast-path: let's hope b is already SymPy object return func(a, b) except Exception, e: from sympify import SympifyError # we've got an exception. # maybe it's from nested __sympifyit? then we have to quit. if isinstance(e, SympifyError): #print 'double deep sympify' if retval is not None: return retval else: raise # slow-path: b seems to be not SymPy object -- let's _sympify it from sympify import _sympify try: b = _sympify(b) #print 'deep sympify' except SympifyError: # sympify failed, let's return requested value if retval is not None: return retval else: # or pass exception through raise # b successfully _sympified, lets call func again. # if it raises here -- exception goes to caller return func(a, b)
def _eval_expand_multinomial(self, deep=True, **hints): """(a+b+..) ** n -> a**n + n*a**(n-1)*b + .., n is nonzero integer""" if deep: b = self.base.expand(deep=deep, **hints) e = self.exp.expand(deep=deep, **hints) else: b = self.base e = self.exp if b is None: base = self.base else: base = b if e is None: exp = self.exp else: exp = e if e is not None or b is not None: result = Pow(base, exp) if result.is_Pow: base, exp = result.base, result.exp else: return result else: result = None if exp.is_Rational and exp.p > 0 and base.is_Add: if not exp.is_Integer: n = Integer(exp.p // exp.q) if not n: return Pow(base, exp) else: radical, result = Pow(base, exp - n), [] for term in Add.make_args( Pow(base, n)._eval_expand_multinomial(deep=False)): result.append(term * radical) return Add(*result) n = int(exp) if base.is_commutative: order_terms, other_terms = [], [] for order in base.args: if order.is_Order: order_terms.append(order) else: other_terms.append(order) if order_terms: # (f(x) + O(x^n))^m -> f(x)^m + m*f(x)^{m-1} *O(x^n) f = Add(*other_terms) g = (f**(n - 1)).expand() return (f * g).expand() + n * g * Add(*order_terms) if base.is_number: # Efficiently expand expressions of the form (a + b*I)**n # where 'a' and 'b' are real numbers and 'n' is integer. a, b = base.as_real_imag() if a.is_Rational and b.is_Rational: if not a.is_Integer: if not b.is_Integer: k = Pow(a.q * b.q, n) a, b = a.p * b.q, a.q * b.p else: k = Pow(a.q, n) a, b = a.p, a.q * b elif not b.is_Integer: k = Pow(b.q, n) a, b = a * b.q, b.p else: k = 1 a, b, c, d = int(a), int(b), 1, 0 while n: if n & 1: c, d = a * c - b * d, b * c + a * d n -= 1 a, b = a * a - b * b, 2 * a * b n //= 2 I = S.ImaginaryUnit if k == 1: return c + I * d else: return Integer(c) / k + I * d / k p = other_terms # (x+y)**3 -> x**3 + 3*x**2*y + 3*x*y**2 + y**3 # in this particular example: # p = [x,y]; n = 3 # so now it's easy to get the correct result -- we get the # coefficients first: from sympy import multinomial_coefficients expansion_dict = multinomial_coefficients(len(p), n) # in our example: {(3, 0): 1, (1, 2): 3, (0, 3): 1, (2, 1): 3} # and now construct the expression. # An elegant way would be to use Poly, but unfortunately it is # slower than the direct method below, so it is commented out: #b = {} #for k in expansion_dict: # b[k] = Integer(expansion_dict[k]) #return Poly(b, *p).as_expr() from sympy.polys.polyutils import basic_from_dict result = basic_from_dict(expansion_dict, *p) return result else: if n == 2: return Add(*[f * g for f in base.args for g in base.args]) else: multi = (base**(n - 1))._eval_expand_multinomial(deep=False) if multi.is_Add: return Add( *[f * g for f in base.args for g in multi.args]) else: return Add(*[f * multi for f in base.args]) elif exp.is_Rational and exp.p < 0 and base.is_Add and abs( exp.p) > exp.q: return 1 / Pow(base, -exp)._eval_expand_multinomial(deep=False) elif exp.is_Add and base.is_Number: # a + b a b # n --> n n , where n, a, b are Numbers coeff, tail = S.One, S.Zero for term in exp.args: if term.is_Number: coeff *= Pow(base, term) else: tail += term return coeff * Pow(base, tail) else: return result
def _(c, start, stop): start, stop, step = c.clamped(start.value, stop.value) return Slice(Integer(start), Integer(stop), Integer(step))