1 """Base class for all objects in sympy"""
3 import sympy
.mpmath
as mpmath
5 from assumptions
import AssumeMeths
, make__get_assumption
6 from sympify
import _sympify
, _sympifyit
, sympify
, SympifyError
7 from cache
import cacheit
, Memoizer
, MemoizerArg
9 # from numbers import Number, Integer, Rational, Real /cyclic/
10 # from interval import Interval /cyclic/
11 # from symbol import Symbol, Wild, Temporary /cyclic/
12 # from add import Add /cyclic/
13 # from mul import Mul /cyclic/
14 # from power import Pow /cyclic/
15 # from function import Derivative, FunctionClass /cyclic/
16 # from relational import Equality, Unequality, Inequality, StrictInequality /cyclic/
17 # from sympy.functions.elementary.complexes import abs as abs_ /cyclic/
18 # from sympy.printing import StrPrinter
20 # used for canonical ordering of symbolic sequences
22 # FIXME this is *so* irrelevant and outdated!
23 ordering_of_classes
= [
25 'Zero', 'One','Half','Infinity','NaN','NegativeOne','NegativeInfinity',
27 'Integer','Rational','Real',
29 'Exp1','Pi','ImaginaryUnit',
31 'Symbol','Wild','Temporary',
32 # Functions that should come before Pow/Add/Mul
33 'ApplyConjugate', 'ApplyAbs',
34 # arithmetic operations
38 'ApplyExp','ApplyLog',
39 'ApplySin','ApplyCos','ApplyTan','ApplyCot',
40 'ApplyASin','ApplyACos','ApplyATan','ApplyACot',
41 'ApplySinh','ApplyCosh','ApplyTanh','ApplyCoth',
42 'ApplyASinh','ApplyACosh','ApplyATanh','ApplyACoth',
43 'ApplyRisingFactorial','ApplyFallingFactorial',
44 'ApplyFactorial','ApplyBinomial',
45 'ApplyFloor', 'ApplyCeiling',
46 'ApplyRe','ApplyIm', 'ApplyArg',
47 'ApplySqrt','ApplySign',
49 'ApplyGamma','ApplyLowerGamma','ApplyUpperGamma','ApplyPolyGamma',
51 'ApplyChebyshev','ApplyChebyshev2',
52 'Derivative','Integral',
53 # defined singleton functions
59 'Sin','Cos','Tan','Cot','ASin','ACos','ATan','ACot',
60 'Sinh','Cosh','Tanh','Coth','ASinh','ACosh','ATanh','ACoth',
61 'RisingFactorial','FallingFactorial',
62 'Factorial','Binomial',
63 'Gamma','LowerGamma','UpperGamma','PolyGamma',
66 'Chebyshev','Chebyshev2',
68 'Function','WildFunction',
72 'FDerivative','FApply',
73 # composition of functions
74 'FPow', 'Composition',
77 # relational operations
78 'Equality', 'Unequality', 'StrictInequality', 'Inequality',
82 class BasicType(type):
85 class BasicMeta(BasicType
):
90 def __init__(cls
,*args
,**kws
):
92 c
= BasicMeta
.classnamespace
.get(n
)
94 BasicMeta
.classnamespace
[n
] = cls
96 print 'Ignoring redefinition of %s: %s defined earlier than %s' % (n
, c
, cls
)
97 type.__init
__(cls
, *args
, **kws
)
101 # initialize default_assumptions dictionary
102 default_assumptions
= {}
104 for k
,v
in cls
.__dict
__.iteritems():
105 if not k
.startswith('is_'):
108 # this is not an assumption (e.g. is_Integer)
109 if k
[3:] not in AssumeMeths
._assume
_defined
:
113 if isinstance(v
,(bool,int,long,type(None))):
116 default_assumptions
[k
] = v
117 #print ' %r <-- %s' % (k,v)
120 # XXX maybe we should try to keep ._default_premises out of class ?
121 # XXX __slots__ in class ?
122 cls
._default
_premises
= default_assumptions
124 for base
in cls
.__bases
__:
126 base_premises
= base
._default
_premises
127 except AttributeError:
128 continue # no ._default_premises is ok
130 for k
,v
in base_premises
.iteritems():
132 # if an assumption is already present in child, we should ignore base
133 # e.g. Integer.is_integer=T, but Rational.is_integer=F (for speed)
134 if k
in default_assumptions
:
137 default_assumptions
[k
] = v
141 # deduce all consequences from default assumptions -- make it complete
142 xass
= AssumeMeths
._assume
_rules
.deduce_all_facts(default_assumptions
)
144 # and store completed set into cls -- this way we'll avoid rededucing
145 # extensions of class default assumptions each time on instance
146 # creation -- we keep it prededuced already.
147 cls
.default_assumptions
= xass
149 #print '\t(%2i) %s' % (len(default_assumptions), default_assumptions)
150 #print '\t(%2i) %s' % (len(xass), xass)
154 # let's store new derived assumptions back into class.
155 # this will result in faster access to this attributes.
161 # %timeit a.is_zero -> 20 us (without this optimization)
162 # %timeit a.is_zero -> 2 us (with this optimization)
165 # BTW: it is very important to study the lessons learned here --
166 # we could drop Basic.__getattr__ completely (!)
168 # %timeit x.is_Add -> 2090 ns (Basic.__getattr__ present)
169 # %timeit x.is_Add -> 825 ns (Basic.__getattr__ absent)
171 # so we may want to override all assumptions is_<xxx> methods and
172 # remove Basic.__getattr__
175 # first we need to collect derived premises
176 derived_premises
= {}
178 for k
,v
in xass
.iteritems():
179 if k
not in default_assumptions
:
180 derived_premises
[k
] = v
182 cls
._derived
_premises
= derived_premises
185 for k
,v
in xass
.iteritems():
186 assert v
== cls
.__dict
__.get('is_'+k
, v
), (cls
,k
,v
)
187 # NOTE: this way Integer.is_even = False (inherited from Rational)
188 # NOTE: the next code blocks add 'protection-properties' to overcome this
189 setattr(cls
, 'is_'+k
, v
)
191 # protection e.g. for Initeger.is_even=F <- (Rational.is_integer=F)
192 for base
in cls
.__bases
__:
194 base_derived_premises
= base
._derived
_premises
195 except AttributeError:
196 continue # no ._derived_premises is ok
198 for k
,v
in base_derived_premises
.iteritems():
199 if not cls
.__dict
__.has_key('is_'+k
):
200 #print '%s -- overriding: %s' % (cls.__name__, k)
201 is_k
= make__get_assumption(cls
.__name
__, k
)
202 setattr(cls
, 'is_'+k
, property(is_k
))
206 def __cmp__(cls
, other
):
208 other
= sympify(other
)
210 #if we cannot sympify it, other is definitely not equal to cls
217 UNKNOWN
= len(ordering_of_classes
)+1
219 i1
= ordering_of_classes
.index(n1
)
221 #print 'Add',n1,'to basic.ordering_of_classes list'
225 i2
= ordering_of_classes
.index(n2
)
227 #print 'Add',n2,'to basic.ordering_of_classes list'
230 if i1
== UNKNOWN
and i2
== UNKNOWN
:
236 class Basic(AssumeMeths
):
238 Base class for all objects in sympy.
243 When you want to access parameters of some instance, always use .args:
246 >>> from sympy import symbols, cot
247 >>> x, y = symbols('xy')
262 2) Never use internal methods or variables (the ones prefixed with "_").
265 >>> cot(x)._args #don't use this, use cot(x).args instead
271 __metaclass__
= BasicMeta
273 __slots__
= ['_mhash', # hash value
275 '_assume_type_keys', # assumptions typeinfo keys
278 # To be overridden with True in the appropriate subclasses
289 is_NumberSymbol
= False
292 def __new__(cls
, *args
, **assumptions
):
293 obj
= object.__new
__(cls
)
295 # FIXME we are slowed a *lot* by Add/Mul passing is_commutative as the
298 # .is_commutative is not an assumption -- it's like typeinfo!!!
299 # we should remove it.
301 # initially assumptions are shared between instances and class
302 obj
._assumptions
= cls
.default_assumptions
303 obj
._a
_inprogress
= []
305 # NOTE this could be made lazy -- probably not all instances will need
306 # fully derived assumptions?
308 obj
._learn
_new
_facts
(assumptions
)
310 # FIXME this is slow | another NOTE: speeding this up is *not*
311 # | | important. say for %timeit x+y most of
312 # .------' | the time is spent elsewhere
314 # | XXX _learn_new_facts could be asked about what *new* facts have
315 # v XXX been learned -- we'll need this to append to _hashable_content
316 basek
= set(cls
.default_assumptions
.keys())
317 k2
= set(obj
._assumptions
.keys())
318 newk
= k2
.difference(basek
)
320 obj
._assume
_type
_keys
= frozenset(newk
)
322 obj
._assume
_type
_keys
= None
324 obj
._mhash
= None # will be set by __hash__ method.
325 obj
._args
= args
# all items in args must be Basic objects
331 def assumptions0(self
):
332 """return object `type` assumptions
336 Symbol('x', real=True)
337 Symbol('x', integer=True)
339 are different objects, and besides Python type (Symbol), initial
340 assumptions, are too forming their typeinfo.
344 A
= self
._assumptions
346 # assumptions shared:
347 if A
is cls
.default_assumptions
or (self
._assume
_type
_keys
is None):
350 assumptions0
= dict( (k
, A
[k
]) for k
in self
._assume
_type
_keys
)
355 def new(self
, *args
):
356 """create new 'similar' object
358 this is conceptually equivalent to:
362 but takes type assumptions into account.
366 obj
= type(self
) (*args
, **self
.assumptions0
)
373 # new-style classes + __getattr__ is *very* slow!
375 # def __getattr__(self, name):
376 # raise 'no way, *all* attribute access will be 2.5x slower'
378 # here is what we do instead:
379 for k
in AssumeMeths
._assume
_defined
:
380 exec "is_%s = property(make__get_assumption('Basic', '%s'))" % (k
,k
)
383 # NB: there is no need in protective __setattr__
388 # hash cannot be cached using cache_it because infinite recurrence
389 # occurs as hash is needed for setting cache dictionary keys
392 h
= (type(self
).__name
__,) + self
._hashable
_content
()
394 if self
._assume
_type
_keys
is not None:
396 kv
= self
._assumptions
397 for k
in sorted(self
._assume
_type
_keys
):
398 a
.append( (k
, kv
[k
]) )
400 h
= hash( h
+ tuple(a
) )
412 def _hashable_content(self
):
413 # If class defines additional attributes, like name in Symbol,
414 # then this method should be updated accordingly to return
415 # relevant attributes as tuple.
418 def __nonzero__(self
):
419 """Tests if 'self' is an instance of Zero class.
421 This should be understand as an idiom:
423 [1] bool(x) <=> bool(x is not S.Zero)
425 [2] bool(not x) <=> bool(x is S.Zero)
427 Allowing definition of __nonzero__ method is important in
428 algorithms where uniform handling of int, long values and
429 and sympy expressions is required.
431 >>> from sympy import *
432 >>> x,y = symbols('xy')
450 return self
is not S
.Zero
452 def compare(self
, other
):
454 Return -1,0,1 if the object is smaller, equal, or greater than other
455 (not always in mathematical sense).
456 If the object is of different type from other then their classes
457 are ordered according to sorted_classes list.
459 # all redefinitions of __cmp__ method should start with the
460 # following three lines:
461 if self
is other
: return 0
462 c
= cmp(self
.__class
__, other
.__class
__)
465 st
= self
._hashable
_content
()
466 ot
= other
._hashable
_content
()
467 c
= cmp(len(st
),len(ot
))
469 for l
,r
in zip(st
,ot
):
470 if isinstance(l
, Basic
):
478 def _compare_pretty(a
, b
):
479 from sympy
.series
.order
import Order
480 if isinstance(a
, Order
) and not isinstance(b
, Order
):
482 if not isinstance(a
, Order
) and isinstance(b
, Order
):
485 # FIXME this produces wrong ordering for 1 and 0
486 # e.g. the ordering will be 1 0 2 3 4 ...
487 # because 1 = x^0, but 0 2 3 4 ... = x^1
488 p1
, p2
, p3
= Wild("p1"), Wild("p2"), Wild("p3")
489 r_a
= a
.match(p1
* p2
**p3
)
490 r_b
= b
.match(p1
* p2
**p3
)
491 if r_a
is not None and r_b
is not None:
492 c
= Basic
.compare(r_a
[p3
], r_b
[p3
])
496 return Basic
.compare(a
,b
)
499 def compare_pretty(a
, b
):
501 Is a>b in the sense of ordering in printing?
509 It uses Basic.compare as a fallback, but improves it in many cases,
510 like x**3, x**4, O(x**3) etc. In those simple cases, it just parses the
511 expression and returns the "sane" ordering such as:
513 1 < x < x**2 < x**3 < O(x**4) etc.
526 # both objects are non-SymPy
527 if (not isinstance(a
, Basic
)) and (not isinstance(b
, Basic
)):
530 if not isinstance(a
, Basic
):
531 return -1 # other < sympy
533 if not isinstance(b
, Basic
):
534 return +1 # sympy > other
536 # now both objects are from SymPy, so we can proceed to usual comparison
537 return Basic
._compare
_pretty
(a
, b
)
540 def __eq__(self
, other
):
541 """a == b -> Compare two symbolic trees and see whether they are equal
550 if type(self
) is not type(other
):
552 other
= _sympify(other
)
554 return False # sympy != other
556 if type(self
) is not type(other
):
559 # type(self) == type(other)
560 st
= self
._hashable
_content
()
561 ot
= other
._hashable
_content
()
565 def __ne__(self
, other
):
566 """a != b -> Compare two symbolic trees and see whether they are different
575 if type(self
) is not type(other
):
577 other
= _sympify(other
)
579 return True # sympy != other
581 if type(self
) is not type(other
):
584 # type(self) == type(other)
585 st
= self
._hashable
_content
()
586 ot
= other
._hashable
_content
()
590 # TODO all comparison methods should return True/False directly (?)
595 # Comparisons other than == and != between disparate types will raise an
596 # exception unless explicitly supported by the type
600 # http://www.python.org/dev/peps/pep-0207/
601 # http://www.python.org/dev/peps/pep-3100/#id18
602 # http://mail.python.org/pipermail/python-dev/2004-June/045111.html
604 @_sympifyit('other', False) # sympy > other
605 def __lt__(self
, other
):
606 #return sympify(other) > self
607 return StrictInequality(self
, other
)
609 @_sympifyit('other', True) # sympy > other
610 def __gt__(self
, other
):
611 return StrictInequality(other
, self
)
612 #return sympify(other) < self
614 @_sympifyit('other', False) # sympy > other
615 def __le__(self
, other
):
616 return Inequality(self
, other
)
618 @_sympifyit('other', True) # sympy > other
619 def __ge__(self
, other
):
620 return sympify(other
) <= self
630 return Mul(S
.NegativeOne
, self
)
634 @_sympifyit('other', NotImplemented)
635 def __add__(self
, other
):
636 return Add(self
, other
)
637 @_sympifyit('other', NotImplemented)
638 def __radd__(self
, other
):
639 return Add(other
, self
)
641 @_sympifyit('other', NotImplemented)
642 def __sub__(self
, other
):
643 return Add(self
, -other
)
644 @_sympifyit('other', NotImplemented)
645 def __rsub__(self
, other
):
646 return Add(other
, -self
)
648 @_sympifyit('other', NotImplemented)
649 def __mul__(self
, other
):
650 return Mul(self
, other
)
651 @_sympifyit('other', NotImplemented)
652 def __rmul__(self
, other
):
653 return Mul(other
, self
)
655 @_sympifyit('other', NotImplemented)
656 def __pow__(self
, other
):
657 return Pow(self
, other
)
658 @_sympifyit('other', NotImplemented)
659 def __rpow__(self
, other
):
660 return Pow(other
, self
)
662 @_sympifyit('other', NotImplemented)
663 def __div__(self
, other
):
664 return Mul(self
, Pow(other
, S
.NegativeOne
))
665 @_sympifyit('other', NotImplemented)
666 def __rdiv__(self
, other
):
667 return Mul(other
, Pow(self
, S
.NegativeOne
))
669 __truediv__
= __div__
670 __rtruediv__
= __rdiv__
677 return StrPrinter
.doprint(self
)
680 return StrPrinter
.doprint(self
)
682 def atoms(self
, *types
):
683 """Returns the atoms that form the current object.
685 >>> from sympy import *
686 >>> x,y = symbols('xy')
688 >>> sorted((x+y**2 + 2*x*y).atoms())
691 You can also filter the results by a given type(s) of object:
693 >>> sorted((x+y+2+y**2*sin(x)).atoms(Symbol))
696 >>> sorted((x+y+2+y**3*sin(x)).atoms(Number))
699 >>> sorted((x+y+2+y**2*sin(x)).atoms(Symbol, Number))
702 Or by a type of on object in an impliciy way:
704 >>> sorted((x+y+2+y**2*sin(x)).atoms(x))
708 if len(types
) == 1 and not isinstance(types
[0], type):
709 types
= (sympify(types
[0]).__class
__,)
714 if not types
or isinstance(self
, types
):
717 for obj
in self
.iter_basic_args():
718 result |
= obj
.atoms(*types
)
722 def is_hypergeometric(self
, k
):
723 from sympy
.simplify
import hypersimp
724 return hypersimp(self
, k
) is not None
728 """Returns True if 'self' is a number.
730 >>> from sympy import *
731 >>> x,y = symbols('xy')
737 >>> (2 + log(2)).is_number
741 for obj
in self
.iter_basic_args():
742 if not obj
.is_number
:
750 The top-level function in an expression.
752 The following should hold for all objects::
754 >> x == x.func(*x.args)
757 return self
.__class
__
761 """Returns a tuple of arguments of 'self'.
765 >>> from sympy import symbols, cot
766 >>> x, y = symbols('xy')
780 Note for developers: Never use self._args, always use self.args.
781 Only when you are creating your own new function, use _args
782 in the __new__. Don't override .args() from Basic (so that it's
783 easy to change the interface in the future if needed).
787 def iter_basic_args(self
):
788 """Iterates arguments of 'self' with are Basic instances. """
789 return iter(self
.args
)
791 def is_fraction(self
, *syms
):
792 p
, q
= self
.as_numer_denom()
794 if p
.is_polynomial(*syms
):
795 if q
.is_polynomial(*syms
):
800 def _eval_is_polynomial(self
, syms
):
803 def is_polynomial(self
, *syms
):
805 syms
= map(sympify
, syms
)
807 syms
= list(self
.atoms(Symbol
))
809 if not syms
: # constant polynomial
812 return self
._eval
_is
_polynomial
(syms
)
814 def as_poly(self
, *symbols
, **flags
):
815 """Converts 'self' to a polynomial or returns None.
817 When constructing a polynomial an exception will be raised in
818 case the input expression is not convertible to a polynomial.
819 There are situations when it is easier (simpler or prettier)
820 to receive None on failure.
822 If no symbols were given and 'self' isn't already a polynomial
823 then all available symbols will be collected and used to form
826 >>> from sympy import *
827 >>> x,y = symbols('xy')
829 >>> print (x**2 + x*y).as_poly()
830 Poly(x**2 + x*y, x, y)
832 >>> print (x**2 + x*y).as_poly(x, y)
833 Poly(x**2 + x*y, x, y)
835 >>> print (x**2 + sin(y)).as_poly(x, y)
839 from sympy
.polys
import Poly
, PolynomialError
843 if isinstance(self
, Poly
):
846 symbols
= sorted(self
.atoms(Symbol
))
848 return Poly(self
, *symbols
, **flags
)
849 except PolynomialError
:
853 """Converts polynomial to a valid sympy expression.
855 >>> from sympy import *
856 >>> x,y = symbols('xy')
858 >>> p = (x**2 + x*y).as_poly(x, y)
871 def subs(self
, *args
):
873 Substitutes an expression.
875 Calls either _subs_old_new, _subs_dict or _subs_list depending
876 if you give it two arguments (old, new), a dictionary or a list.
880 >>> from sympy import *
881 >>> x,y = symbols('xy')
882 >>> (1+x*y).subs(x, pi)
884 >>> (1+x*y).subs({x:pi, y:2})
886 >>> (1+x*y).subs([(x,pi), (y,2)])
892 if isinstance(sequence
, dict):
893 return self
._subs
_dict
(sequence
)
894 elif isinstance(sequence
, (list, tuple)):
895 return self
._subs
_list
(sequence
)
897 raise TypeError("Not an iterable container")
900 return self
._subs
_old
_new
(old
, new
)
902 raise Exception("subs accept either 1 or 2 arguments")
905 def _subs_old_new(self
, old
, new
):
906 """Substitutes an expression old -> new."""
909 return self
._eval
_subs
(old
, new
)
911 def _eval_subs(self
, old
, new
):
916 def _subs_list(self
, sequence
):
918 Performs an order sensitive substitution from the
923 >>> from sympy import *
924 >>> x, y = symbols('xy')
925 >>> (x+y)._subs_list( [(x, 3), (y, x**2)] )
927 >>> (x+y)._subs_list( [(y, x**2), (x, 3) ] )
931 if not isinstance(sequence
, (list, tuple)):
932 raise TypeError("Not an iterable container")
934 for old
, new
in sequence
:
935 result
= result
.subs(old
, new
)
938 def _subs_dict(self
, sequence
):
939 """Performs sequential substitution.
941 Given a collection of key, value pairs, which correspond to
942 old and new expressions respectively, substitute all given
943 pairs handling properly all overlapping keys (according to
946 We have to use naive O(n**2) sorting algorithm, as 'in'
947 gives only partial order and all asymptotically faster
948 fail (depending on the initial order).
950 >>> from sympy import *
951 >>> x, y = symbols('xy')
953 >>> a,b,c,d,e = symbols('abcde')
955 >>> A = (sqrt(sin(2*x)), a)
956 >>> B = (sin(2*x), b)
957 >>> C = (cos(2*x), c)
961 >>> expr = sqrt(sin(2*x))*sin(exp(x)*x)*cos(2*x) + sin(2*x)
963 >>> expr._subs_dict([A,B,C,D,E])
967 if isinstance(sequence
, dict):
968 sequence
= sequence
.items()
969 elif not isinstance(sequence
, (list, tuple)):
970 raise TypeError("Not an iterable container")
974 for pattern
in sequence
:
975 for i
, (expr
, _
) in enumerate(subst
):
976 if pattern
[0] in expr
:
977 subst
.insert(i
, pattern
)
980 subst
.append(pattern
)
982 return self
._subs
_list
(subst
)
984 def _seq_subs(self
, old
, new
):
987 #new functions are initialized differently, than old functions
988 if isinstance(self
.func
, FunctionClass
):
991 args
= (self
.func
,)+self
[:]
992 return self
.__class
__(*[s
.subs(old
, new
) for s
in args
])
994 def __contains__(self
, what
):
995 if self
== what
: return True
1002 def has_any_symbols(self
, *syms
):
1003 """Return True if 'self' has any of the symbols.
1005 >>> from sympy import *
1006 >>> x,y,z = symbols('xyz')
1008 >>> (x**2 + sin(x*y)).has_any_symbols(z)
1011 >>> (x**2 + sin(x*y)).has_any_symbols(x, y)
1014 >>> (x**2 + sin(x*y)).has_any_symbols(x, y, z)
1030 for term
in expr
.iter_basic_args():
1039 def has_all_symbols(self
, *syms
):
1040 """Return True if 'self' has all of the symbols.
1042 >>> from sympy import *
1043 >>> x,y,z = symbols('xyz')
1045 >>> (x**2 + sin(x*y)).has_all_symbols(x, y)
1048 >>> (x**2 + sin(x*y)).has_all_symbols(x, y, z)
1059 if expr
.is_Symbol
and expr
in syms
:
1062 for term
in expr
.iter_basic_args():
1072 def has(self
, *patterns
):
1074 Return True if self has any of the patterns.
1082 raise TypeError("has() requires at least 1 argument (got none)")
1083 p
= sympify(patterns
[0])
1084 if p
.is_Symbol
and not isinstance(p
, Wild
): # speeds up
1085 return p
in self
.atoms(p
.__class
__)
1086 if isinstance(p
, BasicType
):
1087 #XXX this is very fragile:
1088 if str(self
).find(str(p
.__name
__)) == -1:
1089 #didn't find p in self, let's try corner cases
1091 if str(self
).find("D(") != -1:
1096 if p
.matches(self
) is not None:
1101 args
= (self
.func
,)+self
.args
[:]
1107 def _eval_power(self
, other
):
1110 def _eval_derivative(self
, s
):
1113 def _eval_fapply(self
, *args
, **assumptions
):
1116 def _eval_fpower(b
, e
):
1119 def _eval_apply_evalf(self
,*args
):
1122 def _eval_eq_nonzero(self
, other
):
1126 def _eval_apply_subs(cls
, *args
):
1129 def _eval_conjugate(self
):
1133 def conjugate(self
):
1134 from sympy
.functions
.elementary
.complexes
import conjugate
as c
1138 "Removes the O(..) symbol if there is one"
1141 for i
,x
in enumerate(self
.args
):
1143 return Add(*(self
.args
[:i
]+self
.args
[i
+1:]))
1147 def matches(pattern
, expr
, repl_dict
={}, evaluate
=False):
1149 Helper method for match() - switches the pattern and expr.
1151 Can be used to solve linear equations:
1152 >>> from sympy import Symbol, Wild, Integer
1153 >>> a,b = map(Symbol, 'ab')
1155 >>> (a+b*x).matches(Integer(0))
1160 # weed out negative one prefixes
1162 if pattern
.is_Mul
and pattern
.args
[0] == -1:
1163 pattern
= -pattern
; sign
= -sign
1164 if expr
.is_Mul
and expr
.args
[0] == -1:
1165 expr
= -expr
; sign
= -sign
1169 for old
,new
in repl_dict
.items():
1170 pat
= pat
.subs(old
, new
)
1172 return pat
.matches(expr
, repl_dict
)
1173 expr
= sympify(expr
)
1174 if not isinstance(expr
, pattern
.__class
__):
1175 # if we can omit the first factor, we can match it to sign * one
1176 if pattern
.is_Mul
and Mul(*pattern
.args
[1:]) == expr
:
1177 return pattern
.args
[0].matches(Rational(sign
), repl_dict
, evaluate
)
1178 # two-factor product: if the 2nd factor matches, the first part must be sign * one
1179 if pattern
.is_Mul
and len(pattern
.args
[:]) == 2:
1180 dd
= pattern
.args
[1].matches(expr
, repl_dict
, evaluate
)
1181 if dd
== None: return None
1182 dd
= pattern
.args
[0].matches(Rational(sign
), dd
, evaluate
)
1186 if len(pattern
.args
[:])==0:
1190 d
= repl_dict
.copy()
1192 # weed out identical terms
1193 pp
= list(pattern
.args
)
1194 ee
= list(expr
.args
)
1195 for p
in pattern
.args
:
1198 if e
in ee
: ee
.remove(e
)
1199 if p
in pp
: pp
.remove(p
)
1201 # only one symbol left in pattern -> match the remaining expression
1202 if len(pp
) == 1 and isinstance(pp
[0], Wild
):
1203 if len(ee
) == 1: d
[pp
[0]] = sign
* ee
[0]
1204 else: d
[pp
[0]] = sign
* (type(expr
)(*ee
))
1207 if len(ee
) != len(pp
):
1211 for p
,e
in zip(pp
, ee
):
1212 if i
== 0 and sign
!= 1:
1214 except TypeError: return None
1215 d
= p
.matches(e
, d
, evaluate
=not i
)
1221 def match(self
, pattern
):
1225 Wild symbols match all.
1227 Return None when expression (self) does not match
1228 with pattern. Otherwise return a dictionary such that
1230 pattern.subs(self.match(pattern)) == self
1233 pattern
= sympify(pattern
)
1234 return pattern
.matches(self
, {})
1236 def solve4linearsymbol(eqn
, rhs
, symbols
= None):
1238 Solve equation "eqn == rhs" with respect to some linear symbol in eqn.
1240 Returns (symbol, solution). If eqn is nonlinear with respect to all
1241 symbols, then return trivial solution (eqn, rhs).
1246 symbols
= eqn
.atoms(Symbol
)
1251 if deqn
.diff(s
) is S
.Zero
:
1252 # eqn = a + b*c, a=eqn(c=0),b=deqn(c=0)
1253 return s
, (rhs
- eqn
.subs(s
,0))/deqn
.subs(s
,0)
1254 # no linear symbol, return trivial solution
1258 def count_ops(self
, symbolic
=True):
1259 """ Return the number of operations in expressions.
1262 >>> (1+a+b**2).count_ops()
1264 >>> (sin(x)*x+sin(x)**2).count_ops()
1265 ADD + MUL + POW + 2 * SIN
1267 return Integer(len(self
[:])-1) + sum([t
.count_ops(symbolic
=symbolic
) for t
in self
])
1269 def doit(self
, **hints
):
1270 """Evaluate objects that are not evaluated by default like limits,
1271 integrals, sums and products. All objects of this kind will be
1272 evaluated unless some species were excluded via 'hints'.
1274 >>> from sympy import *
1275 >>> x, y = symbols('xy')
1277 >>> 2*Integral(x, x)
1280 >>> (2*Integral(x, x)).doit()
1284 terms
= [ term
.doit(**hints
) for term
in self
.args
]
1285 return self
.new(*terms
)
1287 ###########################################################################
1288 ################# EXPRESSION REPRESENTATION METHODS #######################
1289 ###########################################################################
1291 def _eval_expand_basic(self
):
1292 terms
, rewrite
= [], False
1294 for term
in self
.args
:
1295 if not isinstance(term
, Basic
) or \
1296 isinstance(term
, Atom
):
1299 T
= term
._eval
_expand
_basic
()
1308 return self
.new(*terms
)
1312 def _eval_expand_power(self
, *args
):
1315 if not isinstance(self
, C
.Apply
): # FIXME Apply -> Function
1318 sargs
= (self
.func
,)+self
[:]
1319 terms
= [ term
._eval
_expand
_power
(*args
) for term
in sargs
]
1320 return self
.new(*terms
)
1322 def _eval_expand_complex(self
, *args
):
1325 sargs
= self
.args
[:]
1326 terms
= [ term
._eval
_expand
_complex
(*args
) for term
in sargs
]
1327 return self
.new(*terms
)
1329 def _eval_expand_trig(self
, *args
):
1332 sargs
= self
.args
[:]
1333 terms
= [ term
._eval
_expand
_trig
(*args
) for term
in sargs
]
1334 return self
.new(*terms
)
1336 def _eval_expand_func(self
, *args
):
1340 terms
= [ term
._eval
_expand
_func
(*args
) for term
in sargs
]
1341 return self
.new(*terms
)
1343 def expand(self
, **hints
):
1344 """Expand an expression using hints.
1346 Currently supported hints are basic, power, complex, trig
1347 and func. Hints are applied with arbitrary order so your
1348 code shouldn't depend on the way hints are passed to this
1349 method. Expand 'basic' is the default and run always,
1350 provided that it isn't turned off by the user.
1352 >>> from sympy import *
1353 >>> x,y = symbols('xy')
1355 >>> (y*(x + y)**2).expand()
1356 y*x**2 + 2*x*y**2 + y**3
1358 >>> (x+y).expand(complex=True)
1359 I*im(x) + I*im(y) + re(x) + re(y)
1365 if hints
[hint
] == True:
1366 func
= getattr(expr
, '_eval_expand_'+hint
, None)
1368 if func
is not None:
1371 if not hints
.has_key('basic'):
1372 if not expr
.is_Atom
:
1373 result
= expr
._eval
_expand
_basic
()
1375 if result
is not None:
1380 def _eval_rewrite(self
, pattern
, rule
, **hints
):
1384 terms
= [ t
._eval
_rewrite
(pattern
, rule
, **hints
) for t
in sargs
]
1385 return self
.new(*terms
)
1387 def rewrite(self
, *args
, **hints
):
1388 """Rewrites expression containing applications of functions
1389 of one kind in terms of functions of different kind. For
1390 example you can rewrite trigonometric functions as complex
1391 exponentials or combinatorial functions as gamma function.
1393 As a pattern this function accepts a list of functions to
1394 to rewrite (instances of DefinedFunction class). As rule
1395 you can use string or a destination function instance (in
1396 this case rewrite() will use the str() function).
1398 There is also possibility to pass hints on how to rewrite
1399 the given expressions. For now there is only one such hint
1400 defined called 'deep'. When 'deep' is set to False it will
1401 forbid functions to rewrite their contents.
1403 >>> from sympy import *
1404 >>> x, y = symbols('xy')
1406 >>> sin(x).rewrite(sin, exp)
1407 -I*(exp(I*x) - exp(-I*x))/2
1410 if self
.is_Atom
or not args
:
1413 pattern
, rule
= args
[:-1], args
[-1]
1415 if not isinstance(rule
, str):
1421 elif isinstance(rule
, FunctionClass
): # new-style functions
1423 rule
= rule
.__name
__ # XXX proper attribute for name?
1428 rule
= '_eval_rewrite_as_' + rule
1431 return self
._eval
_rewrite
(None, rule
, **hints
)
1433 if isinstance(pattern
[0], (tuple, list)):
1434 pattern
= pattern
[0]
1436 pattern
= [ p
.__class
__ for p
in pattern
if self
.has(p
) ]
1439 return self
._eval
_rewrite
(tuple(pattern
), rule
, **hints
)
1443 def as_coefficient(self
, expr
):
1444 """Extracts symbolic coefficient at the given expression. In
1445 other words, this functions separates 'self' into product
1446 of 'expr' and 'expr'-free coefficient. If such separation
1447 is not possible it will return None.
1449 >>> from sympy import *
1450 >>> x, y = symbols('xy')
1452 >>> E.as_coefficient(E)
1454 >>> (2*E).as_coefficient(E)
1457 >>> (2*E + x).as_coefficient(E)
1458 >>> (2*sin(E)*E).as_coefficient(E)
1460 >>> (2*pi*I).as_coefficient(pi*I)
1463 >>> (2*I).as_coefficient(pi*I)
1471 coeff
= self
.match(w
* expr
)
1473 if coeff
is not None:
1479 if coeff
[w
].has(*expr
):
1486 def as_independent(self
, *deps
):
1487 """Returns a pair with separated parts of a given expression
1488 independent of specified symbols in the first place and
1489 dependent on them in the other. Both parts are valid
1492 >>> from sympy import *
1493 >>> x, y = symbols('xy')
1495 >>> (2*x*sin(x)+y+x).as_independent(x)
1498 >>> (x*sin(x)*cos(y)).as_independent(x)
1501 All other expressions are multiplicative:
1503 >>> (sin(x)).as_independent(x)
1506 >>> (sin(x)).as_independent(y)
1510 indeps
, depend
= [], []
1512 if self
.is_Add
or self
.is_Mul
:
1513 for term
in self
.args
[:]:
1519 return (self
.__class
__(*indeps
),
1520 self
.__class
__(*depend
))
1523 return (S
.One
, self
)
1525 return (self
, S
.One
)
1527 def as_real_imag(self
):
1528 """Performs complex expansion on 'self' and returns a tuple
1529 containing collected both real and imaginary parts. This
1530 method can't be confused with re() and im() functions,
1531 which does not perform complex expansion at evaluation.
1533 However it is possible to expand both re() and im()
1534 functions and get exactly the same results as with
1535 a single call to this function.
1537 >>> from sympy import *
1539 >>> x, y = symbols('xy', real=True)
1541 >>> (x + y*I).as_real_imag()
1544 >>> z, w = symbols('zw')
1546 >>> (z + w*I).as_real_imag()
1547 (-im(w) + re(z), im(z) + re(w))
1550 expr
= self
.expand(complex=True)
1555 re_part
, im_part
= [], []
1556 if isinstance(expr
, Basic
):
1560 coeff
= term
.as_coefficient(S
.ImaginaryUnit
)
1563 re_part
.append(term
)
1565 im_part
.append(coeff
)
1567 return (Add(*re_part
), Add(*im_part
))
1569 def as_powers_dict(self
):
1570 return { self
: S
.One
}
1572 def as_base_exp(self
):
1576 def as_coeff_terms(self
, x
=None):
1580 return self
, tuple()
1581 return S
.One
, (self
,)
1583 def as_coeff_factors(self
, x
=None):
1587 return self
, tuple()
1588 return S
.Zero
, (self
,)
1590 def as_numer_denom(self
):
1592 base
, exp
= self
.as_base_exp()
1593 coeff
, terms
= exp
.as_coeff_terms()
1594 if coeff
.is_negative
:
1596 return S
.One
, base
** (-exp
)
1600 n
, d
= self
.as_numer_denom()
1605 def extract_multiplicatively(self
, c
):
1606 """Return None if it's not possible to make self in the form
1607 c * something in a nice way, i.e. preserving the properties
1608 of arguments of self.
1610 >>> from sympy import *
1612 >>> x, y = symbols('xy', real=True)
1614 >>> ((x*y)**3).extract_multiplicatively(x**2 * y)
1617 >>> ((x*y)**3).extract_multiplicatively(x**4 * y)
1619 >>> (2*x).extract_multiplicatively(2)
1622 >>> (2*x).extract_multiplicatively(3)
1624 >>> (Rational(1,2)*x).extract_multiplicatively(3)
1634 x
= self
.extract_multiplicatively(c
.as_two_terms()[0])
1636 return x
.extract_multiplicatively(c
.as_two_terms()[1])
1639 if self
is S
.Infinity
:
1642 elif self
is S
.NegativeInfinity
:
1646 return S
.NegativeInfinity
1647 elif self
is S
.ComplexInfinity
:
1649 return S
.ComplexInfinity
1652 elif self
.is_Integer
:
1653 if not quotient
.is_Integer
:
1655 elif self
.is_positive
and quotient
.is_negative
:
1659 elif self
.is_Rational
:
1660 if not quotient
.is_Rational
:
1662 elif self
.is_positive
and quotient
.is_negative
:
1667 if not quotient
.is_Real
:
1669 elif self
.is_positive
and quotient
.is_negative
:
1673 elif self
.is_NumberSymbol
or self
.is_Symbol
or self
is S
.ImaginaryUnit
:
1674 if quotient
.is_Mul
and len(quotient
.args
) == 2:
1675 if quotient
.args
[0].is_Integer
and quotient
.args
[0].is_positive
and quotient
.args
[1] == self
:
1677 elif quotient
.is_Integer
:
1681 for arg
in self
.args
:
1682 newarg
= arg
.extract_multiplicatively(c
)
1684 newargs
.append(newarg
)
1687 return C
.Add(*newargs
)
1689 for i
in xrange(len(self
.args
)):
1690 newargs
= list(self
.args
)
1692 tmp
= C
.Mul(*newargs
).extract_multiplicatively(c
)
1694 return tmp
* self
.args
[i
]
1696 if c
.is_Pow
and c
.base
== self
.base
:
1697 new_exp
= self
.exp
.extract_additively(c
.exp
)
1699 return self
.base
** (new_exp
)
1700 elif c
== self
.base
:
1701 new_exp
= self
.exp
.extract_additively(1)
1703 return self
.base
** (new_exp
)
1705 def extract_additively(self
, c
):
1706 """Return None if it's not possible to make self in the form
1707 something + c in a nice way, i.e. preserving the properties
1708 of arguments of self.
1710 >>> from sympy import *
1712 >>> x, y = symbols('xy', real=True)
1714 >>> ((x*y)**3).extract_additively(1)
1716 >>> (x+1).extract_additively(x)
1719 >>> (x+1).extract_additively(2*x)
1721 >>> (x+1).extract_additively(-x)
1724 >>> (-x+1).extract_additively(2*x)
1733 elif self
is S
.Zero
:
1736 x
= self
.extract_additively(c
.as_two_terms()[0])
1738 return x
.extract_additively(c
.as_two_terms()[1])
1742 if not sub
.is_Integer
:
1744 elif self
.is_positive
and sub
.is_negative
:
1748 elif self
.is_Rational
:
1749 if not sub
.is_Rational
:
1751 elif self
.is_positive
and sub
.is_negative
:
1758 elif self
.is_positive
and sub
.is_negative
:
1762 elif self
.is_NumberSymbol
or self
.is_Symbol
or self
is S
.ImaginaryUnit
:
1763 if sub
.is_Mul
and len(sub
.args
) == 2:
1764 if sub
.args
[0].is_Integer
and sub
.args
[0].is_positive
and sub
.args
[1] == self
:
1766 elif sub
.is_Integer
:
1769 terms
= self
.as_two_terms()
1770 subs0
= terms
[0].extract_additively(c
)
1772 return subs0
+ terms
[1]
1774 subs1
= terms
[1].extract_additively(c
)
1776 return subs1
+ terms
[0]
1778 self_coeff
, self_terms
= self
.as_coeff_terms()
1780 c_coeff
, c_terms
= c
.as_coeff_terms()
1781 if c_terms
== self_terms
:
1782 new_coeff
= self_coeff
.extract_additively(c_coeff
)
1783 if new_coeff
!= None:
1784 return new_coeff
* C
.Mul(*self_terms
)
1785 elif c
== self_terms
:
1786 new_coeff
= self_coeff
.extract_additively(1)
1787 if new_coeff
!= None:
1788 return new_coeff
* C
.Mul(*self_terms
)
1790 def could_extract_minus_sign(self
):
1791 """Canonical way to choose an element in the set {e, -e} where
1792 e is any expression. If the canonical element is e, we have
1793 e.could_extract_minus_sign() == True, else
1794 e.could_extract_minus_sign() == False.
1796 For any expression, the set {e.could_extract_minus_sign(),
1797 (-e).could_extract_minus_sign()} must be {True, False}.
1799 >>> from sympy import *
1801 >>> x, y = symbols("xy")
1803 >>> (x-y).could_extract_minus_sign() != (y-x).could_extract_minus_sign()
1807 negative_self
= -self
1808 self_has_minus
= (self
.extract_multiplicatively(-1) != None)
1809 negative_self_has_minus
= ((negative_self
).extract_multiplicatively(-1) != None)
1810 if self_has_minus
!= negative_self_has_minus
:
1811 return self_has_minus
1814 # We choose the one with less arguments with minus signs
1815 arg_signs
= [arg
.could_extract_minus_sign() for arg
in self
.args
]
1816 positive_args
= arg_signs
.count(False)
1817 negative_args
= arg_signs
.count(True)
1818 if positive_args
> negative_args
:
1820 elif positive_args
< negative_args
:
1823 # As a last resort, we choose the one with greater hash
1824 return hash(self
) < hash(negative_self
)
1826 ###################################################################################
1827 ##################### DERIVATIVE, INTEGRAL, FUNCTIONAL METHODS ####################
1828 ###################################################################################
1830 def diff(self
, *symbols
, **assumptions
):
1831 new_symbols
= map(sympify
, symbols
)
1832 if not assumptions
.has_key("evaluate"):
1833 assumptions
["evaluate"] = True
1834 ret
= Derivative(self
, *new_symbols
, **assumptions
)
1837 def fdiff(self
, *indices
):
1839 return C
.FApply(C
.FDerivative(*indices
), self
)
1841 def integral(self
, *symbols
, **assumptions
):
1845 if s
.is_Integer
and new_symbols
:
1846 last_s
= new_symbols
[-1]
1848 new_symbols
+= [last_s
] * (i
-1)
1850 new_symbols
.append(s
)
1852 raise TypeError(".integral() argument must be Symbol|Integer|Equality instance (got %s)" % (s
.__class
__.__name
__))
1853 return C
.Integral(self
, *new_symbols
, **assumptions
)
1855 #XXX fix the removeme
1856 def __call__(self
, *args
, **removeme
):
1857 return Function(self
[0])(*args
)
1859 def __float__(self
):
1860 result
= self
.evalf()
1861 if result
.is_Number
:
1862 return float(result
)
1864 raise ValueError("Symbolic value, can't compute")
1866 def _evalf(self
, prec
):
1867 """Helper for evalf. Does the same thing but takes binary precision"""
1868 r
= self
._eval
_evalf
(prec
)
1873 def _eval_evalf(self
, prec
):
1876 def _seq_eval_evalf(self
, prec
):
1877 return self
.__class
__(*[s
._evalf
(prec
) for s
in self
.args
])
1879 def _to_mpmath(self
, prec
, allow_ints
=True):
1880 # mpmath functions accept ints as input
1881 errmsg
= "cannot convert to mpmath number"
1882 if allow_ints
and self
.is_Integer
:
1884 v
= self
._eval
_evalf
(prec
)
1886 raise ValueError(errmsg
)
1888 return mpmath
.make_mpf(v
._mpf
_)
1889 # Number + Number*I is also fine
1890 re
, im
= v
.as_real_imag()
1891 if allow_ints
and re
.is_Integer
:
1892 re
= mpmath
.lib
.from_int(re
.p
)
1896 raise ValueError(errmsg
)
1897 if allow_ints
and im
.is_Integer
:
1898 im
= mpmath
.lib
.from_int(im
.p
)
1902 raise ValueError(errmsg
)
1903 return mpmath
.make_mpc((re
, im
))
1906 def _from_mpmath(x
, prec
):
1907 if hasattr(x
, "_mpf_"):
1908 return C
.Real
._new
(x
._mpf
_, prec
)
1909 elif hasattr(x
, "_mpc_"):
1911 re
= C
.Real
._new
(re
, prec
)
1912 im
= C
.Real
._new
(im
, prec
)*S
.ImaginaryUnit
1915 raise TypeError("expected mpmath number (mpf or mpc)")
1917 ###################################################################################
1918 ##################### SERIES, LEADING TERM, LIMIT, ORDER METHODS ##################
1919 ###################################################################################
1921 def series(self
, x
, point
=0, n
=6, with_order
=True):
1923 Series expansion of "self" around "point".
1926 Returns the Taylor (Laurent or generalized) series of "self" around
1927 the point "point" (default 0) with respect to "x" until the n-th
1928 term (default n is 6).
1930 with_order .... if False, the order term (see the class Order) is
1934 This method is the most high level method and it returns the
1935 series including the O(x**n) term.
1937 Internally, it executes a method oseries(), which takes an
1938 O instance as the only parameter and it is responsible for
1939 returning a series (without the O term) up to the given order.
1942 point
= sympify(point
)
1944 raise NotImplementedError("series expansion around arbitrary point")
1945 #self = self.subs(x, x + point)
1955 def oseries(self
, order
):
1957 Return the series of an expression up to given Order symbol (without the
1960 The general philosophy is this: simply start with the most simple
1961 Taylor (Laurent) term and calculate one be one and use
1962 order.contains(term) method to determine if your term is still
1963 significant and should be added to the series, or we should stop.
1965 order
= C
.Order(order
)
1968 if order
.contains(self
):
1970 if len(order
.symbols
)>1:
1972 for s
in order
.symbols
:
1973 o
= C
.Order(order
.expr
, s
)
1976 x
= order
.symbols
[0]
1979 obj
= self
._eval
_oseries
(order
)
1981 #obj2 = obj.expand(trig=True)
1984 r
= obj2
.oseries(order
)
1987 raise NotImplementedError('(%s).oseries(%s)' % (self
, order
))
1989 def nseries(self
, x
, x0
, n
):
1991 Calculates a generalized series expansion.
1993 The difference between oseries and nseries is that nseries calculates
1994 "n" terms in the innermost expressions and then builds up the final
1995 series just by "cross-mutliplying" everything out.
1997 Advantage -- it's fast, because we don't have to determine how many
1998 terms we need to calculate in advance.
2000 Disadvantage -- you may endup with less terms than you may have
2001 expected, but the O(x**n) term appended will always be correct, so the
2002 result is correct, but maybe shorter.
2004 raise NotImplementedError("(%s).nseries(%s, %s, %s)" % (self
, x
, x0
, n
))
2006 def _eval_oseries(self
, order
):
2009 def _compute_oseries(self
, arg
, order
, taylor_term
, unevaluated_func
, correction
= 0):
2011 compute series sum(taylor_term(i, arg), i=0..n-1) such
2012 that order.contains(taylor_term(n, arg)). Assumes that arg->0 as x->0.
2014 x
= order
.symbols
[0]
2018 return unevaluated_func(arg
)
2020 e
= ln(order
.expr
*x
)/ln(x
)
2022 e
= ln(order
.expr
)/ln(o
.expr
)
2023 n
= e
.limit(x
,0) + 1 + correction
2025 # requested accuracy gives infinite series,
2026 # order is probably nonpolynomial e.g. O(exp(-1/x), x).
2027 return unevaluated_func(arg
)
2031 #well, the n is something more complicated (like 1+log(2))
2032 n
= int(n
.evalf()) + 1
2036 for i
in xrange(n
+2):
2037 g
= taylor_term(i
, arg
, g
)
2038 g
= g
.oseries(order
)
2042 def limit(self
, x
, xlim
, direction
='+'):
2043 """ Compute limit x->xlim.
2045 from sympy
.series
.limits
import limit
2046 return limit(self
, x
, xlim
, direction
)
2049 def as_leading_term(self
, *symbols
):
2053 c
= c
.as_leading_term(x
)
2057 x
= sympify(symbols
[0])
2058 assert x
.is_Symbol
, `x`
2061 expr
= self
.expand(trig
=True)
2062 obj
= expr
._eval
_as
_leading
_term
(x
)
2065 raise NotImplementedError('as_leading_term(%s, %s)' % (self
, x
))
2067 def as_coeff_exponent(self
, x
):
2068 """ c*x**e -> c,e where x can be any symbolic expression.
2073 c
, terms
= self
.as_coeff_terms()
2076 if d
is not None and we
in d
:
2080 def leadterm(self
, x
):
2082 c
,e
= self
.as_leading_term(x
).as_coeff_exponent(x
)
2085 raise ValueError("cannot compute leadterm(%s, %s), got c=%s" % (self
, x
, c
))
2088 ##########################################################################
2089 ##################### END OF BASIC CLASS #################################
2090 ##########################################################################
2094 A parent class for atomic things.
2096 Examples: Symbol, Number, Rational, Integer, ...
2097 But not: Add, Mul, Pow, ...
2104 def _eval_derivative(self
, s
):
2105 if self
==s
: return S
.One
2108 def pattern_match(pattern
, expr
, repl_dict
):
2113 def as_numer_denom(self
):
2116 def count_ops(self
, symbolic
=True):
2119 def doit(self
, **hints
):
2122 def _eval_is_polynomial(self
, syms
):
2125 def _eval_oseries(self
, order
):
2126 # .oseries() method checks for order.contains(self)
2129 def _eval_as_leading_term(self
, x
):
2133 def is_number(self
):
2136 def nseries(self
, x
, x0
, n
):
2140 class SingletonMeta(BasicMeta
):
2141 """Metaclass for all singletons
2143 All singleton classes should put this into their __metaclass__, and
2144 _not_ to define __new__
2148 class Zero(Integer):
2149 __metaclass__ = SingletonMeta
2155 def __init__(cls
, *args
, **kw
):
2156 BasicMeta
.__init
__(cls
, *args
, **kw
)
2158 # we are going to inject singletonic __new__, here it is:
2161 obj
= getattr(SingletonFactory
, cls
.__name
__)
2163 except AttributeError:
2164 obj
= Basic
.__new
__(cls
, *(), **{})
2165 setattr(SingletonFactory
, cls
.__name
__, obj
)
2169 cls_new
.__name
__ = '%s.__new__' % (cls
.__name
__)
2171 assert not cls
.__dict
__.has_key('__new__'), \
2172 'Singleton classes are not allowed to redefine __new__'
2174 # inject singletonic __new__
2175 cls
.__new
__ = staticmethod(cls_new
)
2177 # tag the class appropriately (so we could verify it later when doing
2179 cls
.is_Singleton
= True
2181 class SingletonFactory
:
2183 A map between singleton classes and the corresponding instances.
2184 E.g. S.Exp == C.Exp()
2187 def __getattr__(self
, clsname
):
2188 if clsname
== "__repr__":
2191 cls
= getattr(C
, clsname
)
2192 assert cls
.is_Singleton
2195 # store found object in own __dict__, so the next lookups will be
2196 # serviced without entering __getattr__, and so will be fast
2197 setattr(self
, clsname
, obj
)
2200 S
= SingletonFactory()
2202 class ClassesRegistry
:
2203 """Namespace for SymPy classes
2205 This is needed to avoid problems with cyclic imports.
2206 To get a SymPy class you do this:
2216 def __getattr__(self
, name
):
2218 cls
= BasicMeta
.classnamespace
[name
]
2220 raise AttributeError("No SymPy class '%s'" % name
)
2222 setattr(self
, name
, cls
)
2225 C
= ClassesRegistry()
2227 # XXX this is ugly, but needed for Memoizer('str', ...) to work
2235 _
.BasicType
= BasicType